From 1782928f9def11e99014d8b5b339290d6e823008 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E4=BD=B3=E5=AE=9D?= <1197995518@qq.com> Date: Sun, 19 Apr 2026 15:53:25 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 889 ++++++++++++++++++++++++++++++++++++++++++--- package.json | 3 +- src/main.ts | 2 +- src/shims-vue.d.ts | 2 +- 4 files changed, 844 insertions(+), 52 deletions(-) diff --git a/package-lock.json b/package-lock.json index 01bcea5..4758b72 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "1.1.9", "dependencies": { "@element-plus/icons-vue": "^2.0.9", + "@iamzzg/data-view": "^2.10.0", "@jiaminghi/data-view": "^2.10.0", "axios": "^0.27.2", "core-js": "^3.8.3", @@ -1723,6 +1724,111 @@ "vue": "^3.2.0" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmmirror.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "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.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "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.2", + "resolved": "https://registry.npmmirror.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "license": "MIT", + "peer": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmmirror.com/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "license": "(MIT OR CC0-1.0)", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmmirror.com/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@floating-ui/core": { "version": "1.0.1", "resolved": "https://registry.npmmirror.com/@floating-ui/core/-/core-1.0.1.tgz", @@ -1751,6 +1857,54 @@ "@hapi/hoek": "^9.0.0" } }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmmirror.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/@iamzzg/data-view": { + "version": "2.10.0", + "resolved": "https://registry.npmmirror.com/@iamzzg/data-view/-/data-view-2.10.0.tgz", + "integrity": "sha512-UafIJaEqHIgEC+8CaEL0qQxG34JsgKOc13RkYjlupOIAoELNkWXCrYN89xOP+RkSreBTpgaTEt43PfW4EMMjcQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "@jiaminghi/charts": "*" + } + }, "node_modules/@jiaminghi/bezier-curve": { "version": "0.0.9", "resolved": "https://registry.npmmirror.com/@jiaminghi/bezier-curve/-/bezier-curve-0.0.9.tgz", @@ -1900,7 +2054,6 @@ "version": "2.1.5", "resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -1913,7 +2066,6 @@ "version": "2.0.5", "resolved": "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, "engines": { "node": ">= 8" } @@ -1922,7 +2074,6 @@ "version": "1.2.8", "resolved": "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -2278,6 +2429,13 @@ "@types/node": "*" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC", + "peer": true + }, "node_modules/@vue/babel-helper-vue-jsx-merge-props": { "version": "1.4.0", "resolved": "https://registry.npmmirror.com/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.4.0.tgz", @@ -3213,10 +3371,10 @@ } }, "node_modules/acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", - "dev": true, + "version": "8.16.0", + "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -3233,6 +3391,16 @@ "acorn": "^8" } }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "license": "MIT", + "peer": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/acorn-walk": { "version": "8.2.0", "resolved": "https://registry.npmmirror.com/acorn-walk/-/acorn-walk-8.2.0.tgz", @@ -3263,7 +3431,6 @@ "version": "6.12.6", "resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -3340,7 +3507,6 @@ "version": "5.0.1", "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -3381,6 +3547,13 @@ "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", "dev": true }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0", + "peer": true + }, "node_modules/array-flatten": { "version": "2.1.2", "resolved": "https://registry.npmmirror.com/array-flatten/-/array-flatten-2.1.2.tgz", @@ -3526,8 +3699,7 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/base64-js": { "version": "1.5.1", @@ -3646,7 +3818,6 @@ "version": "1.1.11", "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3720,7 +3891,6 @@ "version": "3.1.0", "resolved": "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, "engines": { "node": ">=6" } @@ -4095,8 +4265,7 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/connect-history-api-fallback": { "version": "2.0.0", @@ -4583,6 +4752,13 @@ } } }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "license": "MIT", + "peer": true + }, "node_modules/deepmerge": { "version": "4.2.2", "resolved": "https://registry.npmmirror.com/deepmerge/-/deepmerge-4.2.2.tgz", @@ -4807,6 +4983,19 @@ "node": ">=6" } }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/docx-preview": { "version": "0.1.14", "resolved": "https://registry.npmmirror.com/docx-preview/-/docx-preview-0.1.14.tgz", @@ -5056,6 +5245,63 @@ "node": ">=0.8.0" } }, + "node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmmirror.com/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "license": "MIT", + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -5076,6 +5322,360 @@ "node": ">=10" } }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT", + "peer": true + }, + "node_modules/eslint/node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "peer": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "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/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "license": "MIT", + "peer": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "license": "ISC", + "peer": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmmirror.com/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "license": "MIT", + "peer": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "license": "MIT", + "peer": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "peer": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "license": "(MIT OR CC0-1.0)", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "peer": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmmirror.com/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "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/espree/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "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/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmmirror.com/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmmirror.com/esrecurse/-/esrecurse-4.3.0.tgz", @@ -5112,7 +5712,6 @@ "version": "2.0.3", "resolved": "https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -5240,8 +5839,7 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-glob": { "version": "3.2.11", @@ -5262,14 +5860,19 @@ "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "license": "MIT", + "peer": true }, "node_modules/fastq": { "version": "1.13.0", "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.13.0.tgz", "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, "dependencies": { "reusify": "^1.0.4" } @@ -5298,6 +5901,19 @@ "node": ">=4" } }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "license": "MIT", + "peer": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, "node_modules/file-saver": { "version": "2.0.5", "resolved": "https://registry.npmmirror.com/file-saver/-/file-saver-2.0.5.tgz", @@ -5375,6 +5991,28 @@ "node": ">=8" } }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "license": "MIT", + "peer": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmmirror.com/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "license": "ISC", + "peer": true + }, "node_modules/follow-redirects": { "version": "1.15.1", "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.1.tgz", @@ -5601,8 +6239,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.2", @@ -5668,7 +6305,6 @@ "version": "7.2.3", "resolved": "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -5730,6 +6366,13 @@ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "license": "MIT", + "peer": true + }, "node_modules/gsap": { "version": "3.11.3", "resolved": "https://registry.npmmirror.com/gsap/-/gsap-3.11.3.tgz", @@ -6042,7 +6685,6 @@ "version": "5.2.0", "resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.2.0.tgz", "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, "engines": { "node": ">= 4" } @@ -6062,7 +6704,6 @@ "version": "3.3.0", "resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -6071,11 +6712,20 @@ "node": ">=6" } }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.8.19" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -6138,7 +6788,6 @@ "version": "2.1.1", "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -6165,7 +6814,6 @@ "version": "4.0.3", "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -6191,6 +6839,16 @@ "node": ">=0.12.0" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-obj": { "version": "3.0.0", "resolved": "https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz", @@ -6250,8 +6908,7 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/isobject": { "version": "3.0.1", @@ -6330,6 +6987,19 @@ "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "peer": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz", @@ -6341,6 +7011,13 @@ "node": ">=4" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "license": "MIT", + "peer": true + }, "node_modules/json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmmirror.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -6356,8 +7033,14 @@ "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "license": "MIT", + "peer": true }, "node_modules/json5": { "version": "2.2.1", @@ -6425,6 +7108,16 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "license": "MIT", + "peer": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz", @@ -6462,6 +7155,20 @@ "launch-editor": "^2.6.0" } }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/lie": { "version": "3.3.0", "resolved": "https://registry.npmmirror.com/lie/-/lie-3.3.0.tgz", @@ -6570,6 +7277,13 @@ "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", "dev": true }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "license": "MIT", + "peer": true + }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmmirror.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -7004,7 +7718,6 @@ "version": "3.1.2", "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -7097,6 +7810,13 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "license": "MIT", + "peer": true + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.3.tgz", @@ -7306,7 +8026,6 @@ "version": "1.4.0", "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "dependencies": { "wrappy": "1" } @@ -7346,6 +8065,24 @@ "opener": "bin/opener-bin.js" } }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmmirror.com/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "license": "MIT", + "peer": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/ora": { "version": "5.4.1", "resolved": "https://registry.npmmirror.com/ora/-/ora-5.4.1.tgz", @@ -7504,7 +8241,6 @@ "version": "1.0.1", "resolved": "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "dependencies": { "callsites": "^3.0.0" }, @@ -7571,7 +8307,6 @@ "version": "4.0.0", "resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, "engines": { "node": ">=8" } @@ -7580,7 +8315,6 @@ "version": "1.0.1", "resolved": "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -8218,6 +8952,16 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "dev": true }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/prettier": { "version": "2.7.1", "resolved": "https://registry.npmmirror.com/prettier/-/prettier-2.7.1.tgz", @@ -8305,7 +9049,6 @@ "version": "2.1.1", "resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, "engines": { "node": ">=6" } @@ -8325,8 +9068,7 @@ "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" }, "node_modules/randombytes": { "version": "2.1.0", @@ -8574,7 +9316,6 @@ "version": "4.0.0", "resolved": "https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, "engines": { "node": ">=4" } @@ -8605,7 +9346,6 @@ "version": "1.0.4", "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -8615,7 +9355,6 @@ "version": "3.0.2", "resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, "dependencies": { "glob": "^7.1.3" }, @@ -8627,7 +9366,6 @@ "version": "1.2.0", "resolved": "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "dependencies": { "queue-microtask": "^1.2.2" } @@ -9154,7 +9892,6 @@ "version": "6.0.1", "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -9180,6 +9917,19 @@ "node": ">=6" } }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/stylehacks": { "version": "5.1.0", "resolved": "https://registry.npmmirror.com/stylehacks/-/stylehacks-5.1.0.tgz", @@ -9323,6 +10073,13 @@ "node": ">= 10.13.0" } }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "license": "MIT", + "peer": true + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmmirror.com/thenify/-/thenify-3.3.1.tgz", @@ -9541,6 +10298,19 @@ "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", "dev": true }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "license": "MIT", + "peer": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/type-fest": { "version": "0.6.0", "resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-0.6.0.tgz", @@ -9653,7 +10423,6 @@ "version": "4.4.1", "resolved": "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -10385,6 +11154,16 @@ "node": ">=0.8" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -10432,8 +11211,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/ws": { "version": "7.5.9", @@ -10527,6 +11305,19 @@ "node": ">=10" } }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/zrender": { "version": "4.3.2", "resolved": "https://registry.npmmirror.com/zrender/-/zrender-4.3.2.tgz", diff --git a/package.json b/package.json index fb1cc7b..258f5b9 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ }, "dependencies": { "@element-plus/icons-vue": "^2.0.9", + "@iamzzg/data-view": "^2.10.0", "@jiaminghi/data-view": "^2.10.0", "axios": "^0.27.2", "core-js": "^3.8.3", @@ -41,4 +42,4 @@ "not dead", "not ie 11" ] -} \ No newline at end of file +} diff --git a/src/main.ts b/src/main.ts index 9672b09..ff49dd1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,7 +2,7 @@ import { createApp } from 'vue' import App from './App.vue' import router from './router' import ElementPlus from 'element-plus' -import dataV from '@jiaminghi/data-view' +import dataV from '@iamzzg/data-view/dist/vue3/datav.map.vue.esm' import 'element-plus/dist/index.css' import * as ElementPlusIconsVue from '@element-plus/icons-vue'//添加elementplus图标 diff --git a/src/shims-vue.d.ts b/src/shims-vue.d.ts index 4a8e253..8648ed2 100644 --- a/src/shims-vue.d.ts +++ b/src/shims-vue.d.ts @@ -9,7 +9,7 @@ declare module 'three.meshline' declare module 'gsap' declare module 'three/examples/jsm/controls/OrbitControls' declare module 'echarts' -declare module '@jiaminghi/data-view' +declare module '@iamzzg/data-view/dist/vue3/datav.map.vue.esm' declare module 'file-saver' declare module "*.png" declare module "*.jpg" From 655bde59b2eabc5b116d9f2969f4546428381a0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E4=BD=B3=E5=AE=9D?= <1197995518@qq.com> Date: Mon, 20 Apr 2026 14:46:44 +0800 Subject: [PATCH 2/3] =?UTF-8?q?refactor:=20=E5=B0=86=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E4=BB=8EVue=E8=BF=81=E7=A7=BB=E5=88=B0React=E5=B9=B6=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E4=BB=A3=E7=A0=81=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 重构项目框架,从Vue迁移到React,主要变更包括: 1. 将Vue组件转换为React组件 2. 更新项目配置和依赖项 3. 重构样式文件结构 4. 优化类型定义和接口 5. 重写工具函数和API调用 6. 调整项目目录结构 7. 更新构建配置 迁移过程中保持原有功能不变,同时改进代码组织和类型安全 --- babel.config.js | 5 - public/index.html => index.html | 8 +- package.json | 82 +- pnpm-lock.yaml | 2753 +++++++++++++++++++++++++++ src/App.tsx | 24 + src/App.vue | 3 - src/api/http.ts | 57 +- src/api/request.ts | 54 +- src/components/AddNumber.scss | 3 + src/components/AddNumber.tsx | 63 + src/components/PointMsg.scss | 29 + src/components/PointMsg.tsx | 45 + src/components/PointMsg.vue | 66 - src/components/RiskDetails.scss | 57 + src/components/RiskDetails.tsx | 177 ++ src/components/RiskDetails.vue | 192 -- src/components/SetDrawer.scss | 73 + src/components/SetDrawer.tsx | 341 ++++ src/components/SetDrawer.vue | 317 --- src/components/addNumber.vue | 71 - src/main.tsx | 10 + src/router/index.ts | 17 - src/shims-vue.d.ts | 17 - src/styles/global.scss | 125 ++ src/utils/addVersion.js | 20 - src/utils/echartsAutoTooltip.js | 200 -- src/utils/echartsAutoTooltip.ts | 180 ++ src/utils/getWordBlob.js | 22 - src/utils/getWordBlob.ts | 25 + src/utils/jsonpUtils.ts | 15 +- src/utils/jsonpUtils1.ts | 8 - src/utils/xlsxUtils.ts | 121 +- src/views/ChinaEchartDrawer.scss | 128 ++ src/views/ChinaEchartDrawer.tsx | 719 +++++++ src/views/ChinaEchartDrawer.vue | 743 -------- src/views/ChinaTabDrawer.scss | 30 + src/views/ChinaTabDrawer.tsx | 334 ++++ src/views/ChinaTabDrawer.vue | 293 --- src/views/HomeView.scss | 22 + src/views/HomeView.tsx | 13 + src/views/HomeView.vue | 40 - src/views/ProvinceEchartDrawer.scss | 142 ++ src/views/ProvinceEchartDrawer.tsx | 716 +++++++ src/views/ProvinceEchartDrawer.vue | 715 ------- src/views/ReportDrawer.scss | 26 + src/views/ReportDrawer.tsx | 115 ++ src/views/ReportDrawer.vue | 131 -- src/views/Sphere.scss | 208 ++ src/views/Sphere.tsx | 1289 +++++++++++++ src/views/Sphere.vue | 1351 ------------- src/views/SphereTabDrawer.scss | 26 + src/views/SphereTabDrawer.tsx | 152 ++ src/views/SphereTabDrawer.vue | 165 -- tsconfig.json | 55 +- tsconfig.node.json | 10 + vite.config.ts | 43 + vue.config.js | 41 - 57 files changed, 8060 insertions(+), 4627 deletions(-) delete mode 100644 babel.config.js rename public/index.html => index.html (71%) create mode 100644 pnpm-lock.yaml create mode 100644 src/App.tsx delete mode 100644 src/App.vue create mode 100644 src/components/AddNumber.scss create mode 100644 src/components/AddNumber.tsx create mode 100644 src/components/PointMsg.scss create mode 100644 src/components/PointMsg.tsx delete mode 100644 src/components/PointMsg.vue create mode 100644 src/components/RiskDetails.scss create mode 100644 src/components/RiskDetails.tsx delete mode 100644 src/components/RiskDetails.vue create mode 100644 src/components/SetDrawer.scss create mode 100644 src/components/SetDrawer.tsx delete mode 100644 src/components/SetDrawer.vue delete mode 100644 src/components/addNumber.vue create mode 100644 src/main.tsx delete mode 100644 src/router/index.ts delete mode 100644 src/shims-vue.d.ts create mode 100644 src/styles/global.scss delete mode 100644 src/utils/addVersion.js delete mode 100644 src/utils/echartsAutoTooltip.js create mode 100644 src/utils/echartsAutoTooltip.ts delete mode 100644 src/utils/getWordBlob.js create mode 100644 src/utils/getWordBlob.ts delete mode 100644 src/utils/jsonpUtils1.ts create mode 100644 src/views/ChinaEchartDrawer.scss create mode 100644 src/views/ChinaEchartDrawer.tsx delete mode 100644 src/views/ChinaEchartDrawer.vue create mode 100644 src/views/ChinaTabDrawer.scss create mode 100644 src/views/ChinaTabDrawer.tsx delete mode 100644 src/views/ChinaTabDrawer.vue create mode 100644 src/views/HomeView.scss create mode 100644 src/views/HomeView.tsx delete mode 100644 src/views/HomeView.vue create mode 100644 src/views/ProvinceEchartDrawer.scss create mode 100644 src/views/ProvinceEchartDrawer.tsx delete mode 100644 src/views/ProvinceEchartDrawer.vue create mode 100644 src/views/ReportDrawer.scss create mode 100644 src/views/ReportDrawer.tsx delete mode 100644 src/views/ReportDrawer.vue create mode 100644 src/views/Sphere.scss create mode 100644 src/views/Sphere.tsx delete mode 100644 src/views/Sphere.vue create mode 100644 src/views/SphereTabDrawer.scss create mode 100644 src/views/SphereTabDrawer.tsx delete mode 100644 src/views/SphereTabDrawer.vue create mode 100644 tsconfig.node.json create mode 100644 vite.config.ts delete mode 100644 vue.config.js diff --git a/babel.config.js b/babel.config.js deleted file mode 100644 index e955840..0000000 --- a/babel.config.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - presets: [ - '@vue/cli-plugin-babel/preset' - ] -} diff --git a/public/index.html b/index.html similarity index 71% rename from public/index.html rename to index.html index 575a1c8..0f4b59a 100644 --- a/public/index.html +++ b/index.html @@ -12,11 +12,11 @@ -
- +
+ - \ No newline at end of file + diff --git a/package.json b/package.json index 258f5b9..83e51cf 100644 --- a/package.json +++ b/package.json @@ -1,45 +1,41 @@ { - "name": "covid19-visualization", - "version": "1.1.9", - "private": true, - "scripts": { - "serve": "vue-cli-service serve", - "build": "node ./src/utils/addVersion.js && vue-cli-service build" - }, - "dependencies": { - "@element-plus/icons-vue": "^2.0.9", - "@iamzzg/data-view": "^2.10.0", - "@jiaminghi/data-view": "^2.10.0", - "axios": "^0.27.2", - "core-js": "^3.8.3", - "docx-preview": "^0.1.14", - "docxtemplater": "^3.31.4", - "echarts": "^4.9.0", - "element-plus": "^2.2.16", - "file-saver": "^2.0.5", - "gsap": "^3.11.3", - "jszip-utils": "^0.1.0", - "pizzip": "^3.1.3", - "three": "^0.144.0", - "three.meshline": "^1.4.0", - "vue": "^3.2.13", - "vue-class-component": "^8.0.0-0", - "vue-router": "^4.0.3", - "xlsx": "^0.18.5" - }, - "devDependencies": { - "@vue/cli-plugin-babel": "~5.0.0", - "@vue/cli-plugin-router": "~5.0.0", - "@vue/cli-plugin-typescript": "~5.0.0", - "@vue/cli-service": "~5.0.0", - "sass": "^1.32.7", - "sass-loader": "^12.0.0", - "typescript": "~4.5.5" - }, - "browserslist": [ - "> 1%", - "last 2 versions", - "not dead", - "not ie 11" - ] + "name": "covid19-visualization-react", + "version": "1.1.9", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@ant-design/icons": "^5.2.6", + "@types/three": "^0.160.0", + "antd": "^5.12.0", + "axios": "^1.6.0", + "dayjs": "^1.11.10", + "docx-preview": "^0.1.20", + "docxtemplater": "^3.37.12", + "echarts": "^5.4.3", + "file-saver": "^2.0.5", + "gsap": "^3.12.2", + "jszip-utils": "^0.1.0", + "pizzip": "^3.1.4", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.21.0", + "three": "^0.160.0", + "three.meshline": "^1.4.0", + "xlsx": "^0.18.5" + }, + "devDependencies": { + "@types/file-saver": "^2.0.7", + "@types/node": "^20.10.0", + "@types/react": "^18.2.45", + "@types/react-dom": "^18.2.18", + "@vitejs/plugin-react": "^4.2.1", + "sass": "^1.69.5", + "typescript": "^5.3.3", + "vite": "^5.0.8" + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..d7dcca8 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,2753 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@ant-design/icons': + specifier: ^5.2.6 + version: 5.6.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@types/three': + specifier: ^0.160.0 + version: 0.160.0 + antd: + specifier: ^5.12.0 + version: 5.29.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + axios: + specifier: ^1.6.0 + version: 1.15.1 + dayjs: + specifier: ^1.11.10 + version: 1.11.20 + docx-preview: + specifier: ^0.1.20 + version: 0.1.22 + docxtemplater: + specifier: ^3.37.12 + version: 3.68.5 + echarts: + specifier: ^5.4.3 + version: 5.6.0 + file-saver: + specifier: ^2.0.5 + version: 2.0.5 + gsap: + specifier: ^3.12.2 + version: 3.15.0 + jszip-utils: + specifier: ^0.1.0 + version: 0.1.0 + pizzip: + specifier: ^3.1.4 + version: 3.2.0 + react: + specifier: ^18.2.0 + version: 18.3.1 + react-dom: + specifier: ^18.2.0 + version: 18.3.1(react@18.3.1) + react-router-dom: + specifier: ^6.21.0 + version: 6.30.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + three: + specifier: ^0.160.0 + version: 0.160.1 + three.meshline: + specifier: ^1.4.0 + version: 1.4.0 + xlsx: + specifier: ^0.18.5 + version: 0.18.5 + devDependencies: + '@types/file-saver': + specifier: ^2.0.7 + version: 2.0.7 + '@types/node': + specifier: ^20.10.0 + version: 20.19.39 + '@types/react': + specifier: ^18.2.45 + version: 18.3.28 + '@types/react-dom': + specifier: ^18.2.18 + version: 18.3.7(@types/react@18.3.28) + '@vitejs/plugin-react': + specifier: ^4.2.1 + version: 4.7.0(vite@5.4.21(@types/node@20.19.39)(sass@1.99.0)) + sass: + specifier: ^1.69.5 + version: 1.99.0 + typescript: + specifier: ^5.3.3 + version: 5.9.3 + vite: + specifier: ^5.0.8 + version: 5.4.21(@types/node@20.19.39)(sass@1.99.0) + +packages: + + '@ant-design/colors@7.2.1': + resolution: {integrity: sha512-lCHDcEzieu4GA3n8ELeZ5VQ8pKQAWcGGLRTQ50aQM2iqPpq2evTxER84jfdPvsPAtEcZ7m44NI45edFMo8oOYQ==} + + '@ant-design/cssinjs-utils@1.1.3': + resolution: {integrity: sha512-nOoQMLW1l+xR1Co8NFVYiP8pZp3VjIIzqV6D6ShYF2ljtdwWJn5WSsH+7kvCktXL/yhEtWURKOfH5Xz/gzlwsg==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@ant-design/cssinjs@1.24.0': + resolution: {integrity: sha512-K4cYrJBsgvL+IoozUXYjbT6LHHNt+19a9zkvpBPxLjFHas1UpPM2A5MlhROb0BT8N8WoavM5VsP9MeSeNK/3mg==} + peerDependencies: + react: '>=16.0.0' + react-dom: '>=16.0.0' + + '@ant-design/fast-color@2.0.6': + resolution: {integrity: sha512-y2217gk4NqL35giHl72o6Zzqji9O7vHh9YmhUVkPtAOpoTCH4uWxo/pr4VE8t0+ChEPs0qo4eJRC5Q1eXWo3vA==} + engines: {node: '>=8.x'} + + '@ant-design/icons-svg@4.4.2': + resolution: {integrity: sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==} + + '@ant-design/icons@5.6.1': + resolution: {integrity: sha512-0/xS39c91WjPAZOWsvi1//zjx6kAp4kxWwctR6kuU6p133w8RU0D2dSCvZC19uQyharg/sAvYxGYWl01BbZZfg==} + engines: {node: '>=8'} + peerDependencies: + react: '>=16.0.0' + react-dom: '>=16.0.0' + + '@ant-design/react-slick@1.1.2': + resolution: {integrity: sha512-EzlvzE6xQUBrZuuhSAFTdsr4P2bBBHGZwKFemEfq8gIGyIQCxalYfZW/T2ORbtQx5rU69o+WycP3exY/7T1hGA==} + peerDependencies: + react: '>=16.9.0' + + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-transform-react-jsx-self@7.27.1': + resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.27.1': + resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.29.2': + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + + '@emotion/hash@0.8.0': + resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==} + + '@emotion/unitless@0.7.5': + resolution: {integrity: sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==} + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@parcel/watcher-android-arm64@2.5.6': + resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-darwin-arm64@2.5.6': + resolution: {integrity: sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.5.6': + resolution: {integrity: sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-freebsd-x64@2.5.6': + resolution: {integrity: sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-linux-arm-glibc@2.5.6': + resolution: {integrity: sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-arm-musl@2.5.6': + resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + libc: [musl] + + '@parcel/watcher-linux-arm64-glibc@2.5.6': + resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-arm64-musl@2.5.6': + resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@parcel/watcher-linux-x64-glibc@2.5.6': + resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-x64-musl@2.5.6': + resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@parcel/watcher-win32-arm64@2.5.6': + resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-ia32@2.5.6': + resolution: {integrity: sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + + '@parcel/watcher-win32-x64@2.5.6': + resolution: {integrity: sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher@2.5.6': + resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==} + engines: {node: '>= 10.0.0'} + + '@rc-component/async-validator@5.1.0': + resolution: {integrity: sha512-n4HcR5siNUXRX23nDizbZBQPO0ZM/5oTtmKZ6/eqL0L2bo747cklFdZGRN2f+c9qWGICwDzrhW0H7tE9PptdcA==} + engines: {node: '>=14.x'} + + '@rc-component/color-picker@2.0.1': + resolution: {integrity: sha512-WcZYwAThV/b2GISQ8F+7650r5ZZJ043E57aVBFkQ+kSY4C6wdofXgB0hBx+GPGpIU0Z81eETNoDUJMr7oy/P8Q==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/context@1.4.0': + resolution: {integrity: sha512-kFcNxg9oLRMoL3qki0OMxK+7g5mypjgaaJp/pkOis/6rVxma9nJBF/8kCIuTYHUQNr0ii7MxqE33wirPZLJQ2w==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/mini-decimal@1.1.3': + resolution: {integrity: sha512-bk/FJ09fLf+NLODMAFll6CfYrHPBioTedhW6lxDBuuWucJEqFUd4l/D/5JgIi3dina6sYahB8iuPAZTNz2pMxw==} + engines: {node: '>=8.x'} + + '@rc-component/mutate-observer@1.1.0': + resolution: {integrity: sha512-QjrOsDXQusNwGZPf4/qRQasg7UFEj06XiCJ8iuiq/Io7CrHrgVi6Uuetw60WAMG1799v+aM8kyc+1L/GBbHSlw==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/portal@1.1.2': + resolution: {integrity: sha512-6f813C0IsasTZms08kfA8kPAGxbbkYToa8ALaiDIGGECU4i9hj8Plgbx0sNJDrey3EtHO30hmdaxtT0138xZcg==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/qrcode@1.1.1': + resolution: {integrity: sha512-LfLGNymzKdUPjXUbRP+xOhIWY4jQ+YMj5MmWAcgcAq1Ij8XP7tRmAXqyuv96XvLUBE/5cA8hLFl9eO1JQMujrA==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/tour@1.15.1': + resolution: {integrity: sha512-Tr2t7J1DKZUpfJuDZWHxyxWpfmj8EZrqSgyMZ+BCdvKZ6r1UDsfU46M/iWAAFBy961Ssfom2kv5f3UcjIL2CmQ==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/trigger@2.3.1': + resolution: {integrity: sha512-ORENF39PeXTzM+gQEshuk460Z8N4+6DkjpxlpE7Q3gYy1iBpLrx0FOJz3h62ryrJZ/3zCAUIkT1Pb/8hHWpb3A==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@remix-run/router@1.23.2': + resolution: {integrity: sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==} + engines: {node: '>=14.0.0'} + + '@rolldown/pluginutils@1.0.0-beta.27': + resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} + + '@rollup/rollup-android-arm-eabi@4.60.2': + resolution: {integrity: sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.60.2': + resolution: {integrity: sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.60.2': + resolution: {integrity: sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.60.2': + resolution: {integrity: sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.60.2': + resolution: {integrity: sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.60.2': + resolution: {integrity: sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.60.2': + resolution: {integrity: sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-musleabihf@4.60.2': + resolution: {integrity: sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==} + cpu: [arm] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm64-gnu@4.60.2': + resolution: {integrity: sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm64-musl@4.60.2': + resolution: {integrity: sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-loong64-gnu@4.60.2': + resolution: {integrity: sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==} + cpu: [loong64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-loong64-musl@4.60.2': + resolution: {integrity: sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-ppc64-gnu@4.60.2': + resolution: {integrity: sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-ppc64-musl@4.60.2': + resolution: {integrity: sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==} + cpu: [ppc64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-riscv64-gnu@4.60.2': + resolution: {integrity: sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-musl@4.60.2': + resolution: {integrity: sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-s390x-gnu@4.60.2': + resolution: {integrity: sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-gnu@4.60.2': + resolution: {integrity: sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-musl@4.60.2': + resolution: {integrity: sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rollup/rollup-openbsd-x64@4.60.2': + resolution: {integrity: sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.60.2': + resolution: {integrity: sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.60.2': + resolution: {integrity: sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.60.2': + resolution: {integrity: sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.60.2': + resolution: {integrity: sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.60.2': + resolution: {integrity: sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==} + cpu: [x64] + os: [win32] + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/file-saver@2.0.7': + resolution: {integrity: sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==} + + '@types/node@20.19.39': + resolution: {integrity: sha512-orrrD74MBUyK8jOAD/r0+lfa1I2MO6I+vAkmAWzMYbCcgrN4lCrmK52gRFQq/JRxfYPfonkr4b0jcY7Olqdqbw==} + + '@types/prop-types@15.7.15': + resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} + + '@types/react-dom@18.3.7': + resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==} + peerDependencies: + '@types/react': ^18.0.0 + + '@types/react@18.3.28': + resolution: {integrity: sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==} + + '@types/stats.js@0.17.4': + resolution: {integrity: sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==} + + '@types/three@0.160.0': + resolution: {integrity: sha512-jWlbUBovicUKaOYxzgkLlhkiEQJkhCVvg4W2IYD2trqD2om3VK4DGLpHH5zQHNr7RweZK/5re/4IVhbhvxbV9w==} + + '@types/webxr@0.5.24': + resolution: {integrity: sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==} + + '@vitejs/plugin-react@4.7.0': + resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + + '@xmldom/xmldom@0.9.10': + resolution: {integrity: sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw==} + engines: {node: '>=14.6'} + + adler-32@1.3.1: + resolution: {integrity: sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==} + engines: {node: '>=0.8'} + + antd@5.29.3: + resolution: {integrity: sha512-3DdbGCa9tWAJGcCJ6rzR8EJFsv2CtyEbkVabZE14pfgUHfCicWCj0/QzQVLDYg8CPfQk9BH7fHCoTXHTy7MP/A==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios@1.15.1: + resolution: {integrity: sha512-WOG+Jj8ZOvR0a3rAn+Tuf1UQJRxw5venr6DgdbJzngJE3qG7X0kL83CZGpdHMxEm+ZK3seAbvFsw4FfOfP9vxg==} + + baseline-browser-mapping@2.10.20: + resolution: {integrity: sha512-1AaXxEPfXT+GvTBJFuy4yXVHWJBXa4OdbIebGN/wX5DlsIkU0+wzGnd2lOzokSk51d5LUmqjgBLRLlypLUqInQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + caniuse-lite@1.0.30001788: + resolution: {integrity: sha512-6q8HFp+lOQtcf7wBK+uEenxymVWkGKkjFpCvw5W25cmMwEDU45p1xQFBQv8JDlMMry7eNxyBaR+qxgmTUZkIRQ==} + + cfb@1.2.2: + resolution: {integrity: sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==} + engines: {node: '>=0.8'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + classnames@2.5.1: + resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} + + codepage@1.15.0: + resolution: {integrity: sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==} + engines: {node: '>=0.8'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + compute-scroll-into-view@3.1.1: + resolution: {integrity: sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + copy-to-clipboard@3.3.3: + resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + dayjs@1.11.20: + resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + docx-preview@0.1.22: + resolution: {integrity: sha512-kypaERaxOExSVFBsj3qTKQ0fvFSsjRR81R7XlScyaLfeX6CISzjk0AnNtNZ/FJn62fBhn8nuyXncKlCjutP9Lg==} + deprecated: this version contains breking changes and it should be published under 0.3.0 + + docxtemplater@3.68.5: + resolution: {integrity: sha512-2xcHvTXjMA0jdX6PRh1BUTLrcRQ86Re/QJKWCUCX/vv5RKzntjNNkpR/O4AUoJY1TdoqxA+d04L4xgoAUNf/kw==} + engines: {node: '>=0.10'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + echarts@5.6.0: + resolution: {integrity: sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==} + + electron-to-chromium@1.5.340: + resolution: {integrity: sha512-908qahOGocRMinT2nM3ajCEM99H4iPdv84eagPP3FfZy/1ZGeOy2CZYzjhms81ckOPCXPlW7LkY4XpxD8r1DrA==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + fflate@0.6.10: + resolution: {integrity: sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==} + + file-saver@2.0.5: + resolution: {integrity: sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==} + + follow-redirects@1.16.0: + resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + engines: {node: '>= 6'} + + frac@1.1.2: + resolution: {integrity: sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==} + engines: {node: '>=0.8'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + gsap@3.15.0: + resolution: {integrity: sha512-dMW4CWBTUK1AEEDeZc1g4xpPGIrSf9fJF960qbTZmN/QwZIWY5wgliS6JWl9/25fpTGJrMRtSjGtOmPnfjZB+A==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.3: + resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} + engines: {node: '>= 0.4'} + + immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + + immutable@5.1.5: + resolution: {integrity: sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json2mq@0.2.0: + resolution: {integrity: sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jszip-utils@0.1.0: + resolution: {integrity: sha512-tBNe0o3HAf8vo0BrOYnLPnXNo5A3KsRMnkBFYjh20Y3GPYGfgyoclEMgvVchx0nnL+mherPi74yLPIusHUQpZg==} + + jszip@3.10.1: + resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + + lie@3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + meshoptimizer@0.18.1: + resolution: {integrity: sha512-ZhoIoL7TNV4s5B6+rx5mC//fw8/POGyNxS/DZyCJeiZ12ScLfVwRE/GfsxwiTkMYYD5DmK2/JXnEVXqL4rF+Sw==} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + + node-releases@2.0.37: + resolution: {integrity: sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==} + + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + + pako@2.1.0: + resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + + pizzip@3.2.0: + resolution: {integrity: sha512-X4NPNICxCfIK8VYhF6wbksn81vTiziyLbvKuORVAmolvnUzl1A1xmz9DAWKxPRq9lZg84pJOOAMq3OE61bD8IQ==} + + postcss@8.5.10: + resolution: {integrity: sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==} + engines: {node: ^10 || ^12 || >=14} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + proxy-from-env@2.1.0: + resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} + engines: {node: '>=10'} + + rc-cascader@3.34.0: + resolution: {integrity: sha512-KpXypcvju9ptjW9FaN2NFcA2QH9E9LHKq169Y0eWtH4e/wHQ5Wh5qZakAgvb8EKZ736WZ3B0zLLOBsrsja5Dag==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-checkbox@3.5.0: + resolution: {integrity: sha512-aOAQc3E98HteIIsSqm6Xk2FPKIER6+5vyEFMZfo73TqM+VVAIqOkHoPjgKLqSNtVLWScoaM7vY2ZrGEheI79yg==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-collapse@3.9.0: + resolution: {integrity: sha512-swDdz4QZ4dFTo4RAUMLL50qP0EY62N2kvmk2We5xYdRwcRn8WcYtuetCJpwpaCbUfUt5+huLpVxhvmnK+PHrkA==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-dialog@9.6.0: + resolution: {integrity: sha512-ApoVi9Z8PaCQg6FsUzS8yvBEQy0ZL2PkuvAgrmohPkN3okps5WZ5WQWPc1RNuiOKaAYv8B97ACdsFU5LizzCqg==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-drawer@7.3.0: + resolution: {integrity: sha512-DX6CIgiBWNpJIMGFO8BAISFkxiuKitoizooj4BDyee8/SnBn0zwO2FHrNDpqqepj0E/TFTDpmEBCyFuTgC7MOg==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-dropdown@4.2.1: + resolution: {integrity: sha512-YDAlXsPv3I1n42dv1JpdM7wJ+gSUBfeyPK59ZpBD9jQhK9jVuxpjj3NmWQHOBceA1zEPVX84T2wbdb2SD0UjmA==} + peerDependencies: + react: '>=16.11.0' + react-dom: '>=16.11.0' + + rc-field-form@2.7.1: + resolution: {integrity: sha512-vKeSifSJ6HoLaAB+B8aq/Qgm8a3dyxROzCtKNCsBQgiverpc4kWDQihoUwzUj+zNWJOykwSY4dNX3QrGwtVb9A==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-image@7.12.0: + resolution: {integrity: sha512-cZ3HTyyckPnNnUb9/DRqduqzLfrQRyi+CdHjdqgsyDpI3Ln5UX1kXnAhPBSJj9pVRzwRFgqkN7p9b6HBDjmu/Q==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-input-number@9.5.0: + resolution: {integrity: sha512-bKaEvB5tHebUURAEXw35LDcnRZLq3x1k7GxfAqBMzmpHkDGzjAtnUL8y4y5N15rIFIg5IJgwr211jInl3cipag==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-input@1.8.0: + resolution: {integrity: sha512-KXvaTbX+7ha8a/k+eg6SYRVERK0NddX8QX7a7AnRvUa/rEH0CNMlpcBzBkhI0wp2C8C4HlMoYl8TImSN+fuHKA==} + peerDependencies: + react: '>=16.0.0' + react-dom: '>=16.0.0' + + rc-mentions@2.20.0: + resolution: {integrity: sha512-w8HCMZEh3f0nR8ZEd466ATqmXFCMGMN5UFCzEUL0bM/nGw/wOS2GgRzKBcm19K++jDyuWCOJOdgcKGXU3fXfbQ==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-menu@9.16.1: + resolution: {integrity: sha512-ghHx6/6Dvp+fw8CJhDUHFHDJ84hJE3BXNCzSgLdmNiFErWSOaZNsihDAsKq9ByTALo/xkNIwtDFGIl6r+RPXBg==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-motion@2.9.5: + resolution: {integrity: sha512-w+XTUrfh7ArbYEd2582uDrEhmBHwK1ZENJiSJVb7uRxdE7qJSYjbO2eksRXmndqyKqKoYPc9ClpPh5242mV1vA==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-notification@5.6.4: + resolution: {integrity: sha512-KcS4O6B4qzM3KH7lkwOB7ooLPZ4b6J+VMmQgT51VZCeEcmghdeR4IrMcFq0LG+RPdnbe/ArT086tGM8Snimgiw==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-overflow@1.5.0: + resolution: {integrity: sha512-Lm/v9h0LymeUYJf0x39OveU52InkdRXqnn2aYXfWmo8WdOonIKB2kfau+GF0fWq6jPgtdO9yMqveGcK6aIhJmg==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-pagination@5.1.0: + resolution: {integrity: sha512-8416Yip/+eclTFdHXLKTxZvn70duYVGTvUUWbckCCZoIl3jagqke3GLsFrMs0bsQBikiYpZLD9206Ej4SOdOXQ==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-picker@4.11.3: + resolution: {integrity: sha512-MJ5teb7FlNE0NFHTncxXQ62Y5lytq6sh5nUw0iH8OkHL/TjARSEvSHpr940pWgjGANpjCwyMdvsEV55l5tYNSg==} + engines: {node: '>=8.x'} + peerDependencies: + date-fns: '>= 2.x' + dayjs: '>= 1.x' + luxon: '>= 3.x' + moment: '>= 2.x' + react: '>=16.9.0' + react-dom: '>=16.9.0' + peerDependenciesMeta: + date-fns: + optional: true + dayjs: + optional: true + luxon: + optional: true + moment: + optional: true + + rc-progress@4.0.0: + resolution: {integrity: sha512-oofVMMafOCokIUIBnZLNcOZFsABaUw8PPrf1/y0ZBvKZNpOiu5h4AO9vv11Sw0p4Hb3D0yGWuEattcQGtNJ/aw==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-rate@2.13.1: + resolution: {integrity: sha512-QUhQ9ivQ8Gy7mtMZPAjLbxBt5y9GRp65VcUyGUMF3N3fhiftivPHdpuDIaWIMOTEprAjZPC08bls1dQB+I1F2Q==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-resize-observer@1.4.3: + resolution: {integrity: sha512-YZLjUbyIWox8E9i9C3Tm7ia+W7euPItNWSPX5sCcQTYbnwDb5uNpnLHQCG1f22oZWUhLw4Mv2tFmeWe68CDQRQ==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-segmented@2.7.1: + resolution: {integrity: sha512-izj1Nw/Dw2Vb7EVr+D/E9lUTkBe+kKC+SAFSU9zqr7WV2W5Ktaa9Gc7cB2jTqgk8GROJayltaec+DBlYKc6d+g==} + peerDependencies: + react: '>=16.0.0' + react-dom: '>=16.0.0' + + rc-select@14.16.8: + resolution: {integrity: sha512-NOV5BZa1wZrsdkKaiK7LHRuo5ZjZYMDxPP6/1+09+FB4KoNi8jcG1ZqLE3AVCxEsYMBe65OBx71wFoHRTP3LRg==} + engines: {node: '>=8.x'} + peerDependencies: + react: '*' + react-dom: '*' + + rc-slider@11.1.9: + resolution: {integrity: sha512-h8IknhzSh3FEM9u8ivkskh+Ef4Yo4JRIY2nj7MrH6GQmrwV6mcpJf5/4KgH5JaVI1H3E52yCdpOlVyGZIeph5A==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-steps@6.0.1: + resolution: {integrity: sha512-lKHL+Sny0SeHkQKKDJlAjV5oZ8DwCdS2hFhAkIjuQt1/pB81M0cA0ErVFdHq9+jmPmFw1vJB2F5NBzFXLJxV+g==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-switch@4.1.0: + resolution: {integrity: sha512-TI8ufP2Az9oEbvyCeVE4+90PDSljGyuwix3fV58p7HV2o4wBnVToEyomJRVyTaZeqNPAp+vqeo4Wnj5u0ZZQBg==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-table@7.54.0: + resolution: {integrity: sha512-/wDTkki6wBTjwylwAGjpLKYklKo9YgjZwAU77+7ME5mBoS32Q4nAwoqhA2lSge6fobLW3Tap6uc5xfwaL2p0Sw==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-tabs@15.7.0: + resolution: {integrity: sha512-ZepiE+6fmozYdWf/9gVp7k56PKHB1YYoDsKeQA1CBlJ/POIhjkcYiv0AGP0w2Jhzftd3AVvZP/K+V+Lpi2ankA==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-textarea@1.10.2: + resolution: {integrity: sha512-HfaeXiaSlpiSp0I/pvWpecFEHpVysZ9tpDLNkxQbMvMz6gsr7aVZ7FpWP9kt4t7DB+jJXesYS0us1uPZnlRnwQ==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-tooltip@6.4.0: + resolution: {integrity: sha512-kqyivim5cp8I5RkHmpsp1Nn/Wk+1oeloMv9c7LXNgDxUpGm+RbXJGL+OPvDlcRnx9DBeOe4wyOIl4OKUERyH1g==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-tree-select@5.27.0: + resolution: {integrity: sha512-2qTBTzwIT7LRI1o7zLyrCzmo5tQanmyGbSaGTIf7sYimCklAToVVfpMC6OAldSKolcnjorBYPNSKQqJmN3TCww==} + peerDependencies: + react: '*' + react-dom: '*' + + rc-tree@5.13.1: + resolution: {integrity: sha512-FNhIefhftobCdUJshO7M8uZTA9F4OPGVXqGfZkkD/5soDeOhwO06T/aKTrg0WD8gRg/pyfq+ql3aMymLHCTC4A==} + engines: {node: '>=10.x'} + peerDependencies: + react: '*' + react-dom: '*' + + rc-upload@4.11.0: + resolution: {integrity: sha512-ZUyT//2JAehfHzjWowqROcwYJKnZkIUGWaTE/VogVrepSl7AFNbQf4+zGfX4zl9Vrj/Jm8scLO0R6UlPDKK4wA==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-util@5.44.4: + resolution: {integrity: sha512-resueRJzmHG9Q6rI/DfK6Kdv9/Lfls05vzMs1Sk3M2P+3cJa+MakaZyWY8IPfehVuhPJFKrIY1IK4GqbiaiY5w==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-virtual-list@3.19.2: + resolution: {integrity: sha512-Ys6NcjwGkuwkeaWBDqfI3xWuZ7rDiQXlH1o2zLfFzATfEgXcqpk8CkgMfbJD81McqjcJVez25a3kPxCR807evA==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + react-refresh@0.17.0: + resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} + engines: {node: '>=0.10.0'} + + react-router-dom@6.30.3: + resolution: {integrity: sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + + react-router@6.30.3: + resolution: {integrity: sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + resize-observer-polyfill@1.5.1: + resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} + + rollup@4.60.2: + resolution: {integrity: sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + sass@1.99.0: + resolution: {integrity: sha512-kgW13M54DUB7IsIRM5LvJkNlpH+WhMpooUcaWGFARkF1Tc82v9mIWkCbCYf+MBvpIUBSeSOTilpZjEPr2VYE6Q==} + engines: {node: '>=14.0.0'} + hasBin: true + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + scroll-into-view-if-needed@3.1.0: + resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + ssf@0.11.2: + resolution: {integrity: sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==} + engines: {node: '>=0.8'} + + string-convert@0.2.1: + resolution: {integrity: sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + stylis@4.4.0: + resolution: {integrity: sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==} + + three.meshline@1.4.0: + resolution: {integrity: sha512-A8IsiMrWP8zmHisGDAJ76ZD7t/dOF/oCe/FUKNE6Bu01ZYEx8N6IlU/1Plb2aOZtAuWM2A8s8qS3hvY0OFuvOw==} + + three@0.160.1: + resolution: {integrity: sha512-Bgl2wPJypDOZ1stAxwfWAcJ0WQf7QzlptsxkjYiURPz+n5k4RBDLsq+6f9Y75TYxn6aHLcWz+JNmwTOXWrQTBQ==} + + throttle-debounce@5.0.2: + resolution: {integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==} + engines: {node: '>=12.22'} + + toggle-selection@1.0.6: + resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} + + tslib@2.3.0: + resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vite@5.4.21: + resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + wmf@1.0.2: + resolution: {integrity: sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==} + engines: {node: '>=0.8'} + + word@0.3.0: + resolution: {integrity: sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==} + engines: {node: '>=0.8'} + + xlsx@0.18.5: + resolution: {integrity: sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==} + engines: {node: '>=0.8'} + hasBin: true + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + zrender@5.6.1: + resolution: {integrity: sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==} + +snapshots: + + '@ant-design/colors@7.2.1': + dependencies: + '@ant-design/fast-color': 2.0.6 + + '@ant-design/cssinjs-utils@1.1.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@ant-design/cssinjs': 1.24.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@babel/runtime': 7.29.2 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@ant-design/cssinjs@1.24.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.29.2 + '@emotion/hash': 0.8.0 + '@emotion/unitless': 0.7.5 + classnames: 2.5.1 + csstype: 3.2.3 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + stylis: 4.4.0 + + '@ant-design/fast-color@2.0.6': + dependencies: + '@babel/runtime': 7.29.2 + + '@ant-design/icons-svg@4.4.2': {} + + '@ant-design/icons@5.6.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@ant-design/colors': 7.2.1 + '@ant-design/icons-svg': 4.4.2 + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@ant-design/react-slick@1.1.2(react@18.3.1)': + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + json2mq: 0.2.0 + react: 18.3.1 + resize-observer-polyfill: 1.5.1 + throttle-debounce: 5.0.2 + + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.0': {} + + '@babel/core@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.2 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-plugin-utils@7.28.6': {} + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.29.2': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + + '@babel/parser@7.29.2': + dependencies: + '@babel/types': 7.29.0 + + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/runtime@7.29.2': {} + + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@emotion/hash@0.8.0': {} + + '@emotion/unitless@0.7.5': {} + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@parcel/watcher-android-arm64@2.5.6': + optional: true + + '@parcel/watcher-darwin-arm64@2.5.6': + optional: true + + '@parcel/watcher-darwin-x64@2.5.6': + optional: true + + '@parcel/watcher-freebsd-x64@2.5.6': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-arm-musl@2.5.6': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.5.6': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-x64-musl@2.5.6': + optional: true + + '@parcel/watcher-win32-arm64@2.5.6': + optional: true + + '@parcel/watcher-win32-ia32@2.5.6': + optional: true + + '@parcel/watcher-win32-x64@2.5.6': + optional: true + + '@parcel/watcher@2.5.6': + dependencies: + detect-libc: 2.1.2 + is-glob: 4.0.3 + node-addon-api: 7.1.1 + picomatch: 4.0.4 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.5.6 + '@parcel/watcher-darwin-arm64': 2.5.6 + '@parcel/watcher-darwin-x64': 2.5.6 + '@parcel/watcher-freebsd-x64': 2.5.6 + '@parcel/watcher-linux-arm-glibc': 2.5.6 + '@parcel/watcher-linux-arm-musl': 2.5.6 + '@parcel/watcher-linux-arm64-glibc': 2.5.6 + '@parcel/watcher-linux-arm64-musl': 2.5.6 + '@parcel/watcher-linux-x64-glibc': 2.5.6 + '@parcel/watcher-linux-x64-musl': 2.5.6 + '@parcel/watcher-win32-arm64': 2.5.6 + '@parcel/watcher-win32-ia32': 2.5.6 + '@parcel/watcher-win32-x64': 2.5.6 + optional: true + + '@rc-component/async-validator@5.1.0': + dependencies: + '@babel/runtime': 7.29.2 + + '@rc-component/color-picker@2.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@ant-design/fast-color': 2.0.6 + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@rc-component/context@1.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.29.2 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@rc-component/mini-decimal@1.1.3': + dependencies: + '@babel/runtime': 7.29.2 + + '@rc-component/mutate-observer@1.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@rc-component/portal@1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@rc-component/qrcode@1.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.29.2 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@rc-component/tour@1.15.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.29.2 + '@rc-component/portal': 1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@rc-component/trigger@2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.29.2 + '@rc-component/portal': 1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@remix-run/router@1.23.2': {} + + '@rolldown/pluginutils@1.0.0-beta.27': {} + + '@rollup/rollup-android-arm-eabi@4.60.2': + optional: true + + '@rollup/rollup-android-arm64@4.60.2': + optional: true + + '@rollup/rollup-darwin-arm64@4.60.2': + optional: true + + '@rollup/rollup-darwin-x64@4.60.2': + optional: true + + '@rollup/rollup-freebsd-arm64@4.60.2': + optional: true + + '@rollup/rollup-freebsd-x64@4.60.2': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.60.2': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.60.2': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.60.2': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.60.2': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.60.2': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.60.2': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-x64-musl@4.60.2': + optional: true + + '@rollup/rollup-openbsd-x64@4.60.2': + optional: true + + '@rollup/rollup-openharmony-arm64@4.60.2': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.60.2': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.60.2': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.60.2': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.60.2': + optional: true + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.29.0 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + + '@types/babel__traverse@7.28.0': + dependencies: + '@babel/types': 7.29.0 + + '@types/estree@1.0.8': {} + + '@types/file-saver@2.0.7': {} + + '@types/node@20.19.39': + dependencies: + undici-types: 6.21.0 + + '@types/prop-types@15.7.15': {} + + '@types/react-dom@18.3.7(@types/react@18.3.28)': + dependencies: + '@types/react': 18.3.28 + + '@types/react@18.3.28': + dependencies: + '@types/prop-types': 15.7.15 + csstype: 3.2.3 + + '@types/stats.js@0.17.4': {} + + '@types/three@0.160.0': + dependencies: + '@types/stats.js': 0.17.4 + '@types/webxr': 0.5.24 + fflate: 0.6.10 + meshoptimizer: 0.18.1 + + '@types/webxr@0.5.24': {} + + '@vitejs/plugin-react@4.7.0(vite@5.4.21(@types/node@20.19.39)(sass@1.99.0))': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0) + '@rolldown/pluginutils': 1.0.0-beta.27 + '@types/babel__core': 7.20.5 + react-refresh: 0.17.0 + vite: 5.4.21(@types/node@20.19.39)(sass@1.99.0) + transitivePeerDependencies: + - supports-color + + '@xmldom/xmldom@0.9.10': {} + + adler-32@1.3.1: {} + + antd@5.29.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@ant-design/colors': 7.2.1 + '@ant-design/cssinjs': 1.24.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@ant-design/cssinjs-utils': 1.1.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@ant-design/fast-color': 2.0.6 + '@ant-design/icons': 5.6.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@ant-design/react-slick': 1.1.2(react@18.3.1) + '@babel/runtime': 7.29.2 + '@rc-component/color-picker': 2.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rc-component/mutate-observer': 1.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rc-component/qrcode': 1.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rc-component/tour': 1.15.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + copy-to-clipboard: 3.3.3 + dayjs: 1.11.20 + rc-cascader: 3.34.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-checkbox: 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-collapse: 3.9.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-dialog: 9.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-drawer: 7.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-dropdown: 4.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-field-form: 2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-image: 7.12.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-input: 1.8.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-input-number: 9.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-mentions: 2.20.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-menu: 9.16.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-notification: 5.6.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-pagination: 5.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-picker: 4.11.3(dayjs@1.11.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-progress: 4.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-rate: 2.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-segmented: 2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-select: 14.16.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-slider: 11.1.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-steps: 6.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-switch: 4.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-table: 7.54.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-tabs: 15.7.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-textarea: 1.10.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-tooltip: 6.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-tree: 5.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-tree-select: 5.27.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-upload: 4.11.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + scroll-into-view-if-needed: 3.1.0 + throttle-debounce: 5.0.2 + transitivePeerDependencies: + - date-fns + - luxon + - moment + + asynckit@0.4.0: {} + + axios@1.15.1: + dependencies: + follow-redirects: 1.16.0 + form-data: 4.0.5 + proxy-from-env: 2.1.0 + transitivePeerDependencies: + - debug + + baseline-browser-mapping@2.10.20: {} + + browserslist@4.28.2: + dependencies: + baseline-browser-mapping: 2.10.20 + caniuse-lite: 1.0.30001788 + electron-to-chromium: 1.5.340 + node-releases: 2.0.37 + update-browserslist-db: 1.2.3(browserslist@4.28.2) + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + caniuse-lite@1.0.30001788: {} + + cfb@1.2.2: + dependencies: + adler-32: 1.3.1 + crc-32: 1.2.2 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + classnames@2.5.1: {} + + codepage@1.15.0: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + compute-scroll-into-view@3.1.1: {} + + convert-source-map@2.0.0: {} + + copy-to-clipboard@3.3.3: + dependencies: + toggle-selection: 1.0.6 + + core-util-is@1.0.3: {} + + crc-32@1.2.2: {} + + csstype@3.2.3: {} + + dayjs@1.11.20: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + delayed-stream@1.0.0: {} + + detect-libc@2.1.2: + optional: true + + docx-preview@0.1.22: + dependencies: + jszip: 3.10.1 + + docxtemplater@3.68.5: + dependencies: + '@xmldom/xmldom': 0.9.10 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + echarts@5.6.0: + dependencies: + tslib: 2.3.0 + zrender: 5.6.1 + + electron-to-chromium@1.5.340: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.3 + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + escalade@3.2.0: {} + + fflate@0.6.10: {} + + file-saver@2.0.5: {} + + follow-redirects@1.16.0: {} + + form-data@4.0.5: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.3 + mime-types: 2.1.35 + + frac@1.1.2: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gensync@1.0.0-beta.2: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.3 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + gopd@1.2.0: {} + + gsap@3.15.0: {} + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.3: + dependencies: + function-bind: 1.1.2 + + immediate@3.0.6: {} + + immutable@5.1.5: {} + + inherits@2.0.4: {} + + is-extglob@2.1.1: + optional: true + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + optional: true + + isarray@1.0.0: {} + + js-tokens@4.0.0: {} + + jsesc@3.1.0: {} + + json2mq@0.2.0: + dependencies: + string-convert: 0.2.1 + + json5@2.2.3: {} + + jszip-utils@0.1.0: {} + + jszip@3.10.1: + dependencies: + lie: 3.3.0 + pako: 1.0.11 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + + lie@3.3.0: + dependencies: + immediate: 3.0.6 + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + math-intrinsics@1.1.0: {} + + meshoptimizer@0.18.1: {} + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + node-addon-api@7.1.1: + optional: true + + node-releases@2.0.37: {} + + pako@1.0.11: {} + + pako@2.1.0: {} + + picocolors@1.1.1: {} + + picomatch@4.0.4: + optional: true + + pizzip@3.2.0: + dependencies: + pako: 2.1.0 + + postcss@8.5.10: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + process-nextick-args@2.0.1: {} + + proxy-from-env@2.1.0: {} + + rc-cascader@3.34.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-select: 14.16.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-tree: 5.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-checkbox@3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-collapse@3.9.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-dialog@9.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + '@rc-component/portal': 1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-drawer@7.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + '@rc-component/portal': 1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-dropdown@4.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + '@rc-component/async-validator': 5.1.0 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-image@7.12.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + '@rc-component/portal': 1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-dialog: 9.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-input-number@9.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + '@rc-component/mini-decimal': 1.1.3 + classnames: 2.5.1 + rc-input: 1.8.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-input@1.8.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-mentions@2.20.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-input: 1.8.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-menu: 9.16.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-textarea: 1.10.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-menu@9.16.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-overflow: 1.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-motion@2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-notification@5.6.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-overflow@1.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-pagination@5.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-picker@4.11.3(dayjs@1.11.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-overflow: 1.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + dayjs: 1.11.20 + + rc-progress@4.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-rate@2.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-resize-observer@1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + resize-observer-polyfill: 1.5.1 + + rc-segmented@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-select@14.16.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-overflow: 1.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-virtual-list: 3.19.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-slider@11.1.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-steps@6.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-switch@4.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-table@7.54.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + '@rc-component/context': 1.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-virtual-list: 3.19.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-tabs@15.7.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-dropdown: 4.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-menu: 9.16.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-textarea@1.10.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-input: 1.8.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-tooltip@6.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + '@rc-component/trigger': 2.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-tree-select@5.27.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-select: 14.16.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-tree: 5.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-tree@5.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-virtual-list: 3.19.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-upload@4.11.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-util@5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-is: 18.3.1 + + rc-virtual-list@3.19.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + classnames: 2.5.1 + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react-is@18.3.1: {} + + react-refresh@0.17.0: {} + + react-router-dom@6.30.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@remix-run/router': 1.23.2 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-router: 6.30.3(react@18.3.1) + + react-router@6.30.3(react@18.3.1): + dependencies: + '@remix-run/router': 1.23.2 + react: 18.3.1 + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readdirp@4.1.2: {} + + resize-observer-polyfill@1.5.1: {} + + rollup@4.60.2: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.60.2 + '@rollup/rollup-android-arm64': 4.60.2 + '@rollup/rollup-darwin-arm64': 4.60.2 + '@rollup/rollup-darwin-x64': 4.60.2 + '@rollup/rollup-freebsd-arm64': 4.60.2 + '@rollup/rollup-freebsd-x64': 4.60.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.60.2 + '@rollup/rollup-linux-arm-musleabihf': 4.60.2 + '@rollup/rollup-linux-arm64-gnu': 4.60.2 + '@rollup/rollup-linux-arm64-musl': 4.60.2 + '@rollup/rollup-linux-loong64-gnu': 4.60.2 + '@rollup/rollup-linux-loong64-musl': 4.60.2 + '@rollup/rollup-linux-ppc64-gnu': 4.60.2 + '@rollup/rollup-linux-ppc64-musl': 4.60.2 + '@rollup/rollup-linux-riscv64-gnu': 4.60.2 + '@rollup/rollup-linux-riscv64-musl': 4.60.2 + '@rollup/rollup-linux-s390x-gnu': 4.60.2 + '@rollup/rollup-linux-x64-gnu': 4.60.2 + '@rollup/rollup-linux-x64-musl': 4.60.2 + '@rollup/rollup-openbsd-x64': 4.60.2 + '@rollup/rollup-openharmony-arm64': 4.60.2 + '@rollup/rollup-win32-arm64-msvc': 4.60.2 + '@rollup/rollup-win32-ia32-msvc': 4.60.2 + '@rollup/rollup-win32-x64-gnu': 4.60.2 + '@rollup/rollup-win32-x64-msvc': 4.60.2 + fsevents: 2.3.3 + + safe-buffer@5.1.2: {} + + sass@1.99.0: + dependencies: + chokidar: 4.0.3 + immutable: 5.1.5 + source-map-js: 1.2.1 + optionalDependencies: + '@parcel/watcher': 2.5.6 + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + scroll-into-view-if-needed@3.1.0: + dependencies: + compute-scroll-into-view: 3.1.1 + + semver@6.3.1: {} + + setimmediate@1.0.5: {} + + source-map-js@1.2.1: {} + + ssf@0.11.2: + dependencies: + frac: 1.1.2 + + string-convert@0.2.1: {} + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + stylis@4.4.0: {} + + three.meshline@1.4.0: {} + + three@0.160.1: {} + + throttle-debounce@5.0.2: {} + + toggle-selection@1.0.6: {} + + tslib@2.3.0: {} + + typescript@5.9.3: {} + + undici-types@6.21.0: {} + + update-browserslist-db@1.2.3(browserslist@4.28.2): + dependencies: + browserslist: 4.28.2 + escalade: 3.2.0 + picocolors: 1.1.1 + + util-deprecate@1.0.2: {} + + vite@5.4.21(@types/node@20.19.39)(sass@1.99.0): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.10 + rollup: 4.60.2 + optionalDependencies: + '@types/node': 20.19.39 + fsevents: 2.3.3 + sass: 1.99.0 + + wmf@1.0.2: {} + + word@0.3.0: {} + + xlsx@0.18.5: + dependencies: + adler-32: 1.3.1 + cfb: 1.2.2 + codepage: 1.15.0 + crc-32: 1.2.2 + ssf: 0.11.2 + wmf: 1.0.2 + word: 0.3.0 + + yallist@3.1.1: {} + + zrender@5.6.1: + dependencies: + tslib: 2.3.0 diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..c15c91b --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,24 @@ +import React from 'react' +import { BrowserRouter, Routes, Route } from 'react-router-dom' +import HomeView from './views/HomeView' +import { ConfigProvider } from 'antd' + +const App: React.FC = () => { + return ( + + + + } /> + + + + ) +} + +export default App diff --git a/src/App.vue b/src/App.vue deleted file mode 100644 index 98240ae..0000000 --- a/src/App.vue +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/src/api/http.ts b/src/api/http.ts index a4d5620..c0f1438 100644 --- a/src/api/http.ts +++ b/src/api/http.ts @@ -1,28 +1,29 @@ -import axios from "axios"; -//创建请求 -function createServe(config: any) { - let serve = axios.create({ - timeout: 5000 //超时 - }); - //请求拦截器 - serve.interceptors.request.use( - config => { - return config; - }, - error => { - return Promise.reject(error) - } - ) - //响应拦截器 - serve.interceptors.response.use( - response => { - return response; - }, - error => { - return Promise.reject(error) - } - ) - return serve(config); -} - -export default createServe; \ No newline at end of file +import axios, { AxiosRequestConfig } from 'axios' + +function createServe(config: AxiosRequestConfig) { + const serve = axios.create({ + timeout: 5000, + }) + + serve.interceptors.request.use( + (config) => { + return config + }, + (error) => { + return Promise.reject(error) + } + ) + + serve.interceptors.response.use( + (response) => { + return response + }, + (error) => { + return Promise.reject(error) + } + ) + + return serve(config) +} + +export default createServe diff --git a/src/api/request.ts b/src/api/request.ts index 8d68457..fd71e7f 100644 --- a/src/api/request.ts +++ b/src/api/request.ts @@ -1,28 +1,26 @@ -import createServe from "./http" - -//获取疫情数据1 -export function dataSource1(params = {}) { - return createServe({ - method: "GET", - url: '/dataSource1', - params - }) -} - -//获取疫情数据2 -export function dataSource2(params = {}) { - return createServe({ - method: "GET", - url: '/dataSource2', - params - }) -} - -//获取ip信息 -export function getIpMsg(params = {}) { - return createServe({ - method: "GET", - url: '/getIpMsg', - params - }) -} \ No newline at end of file +import createServe from './http' +import { AxiosRequestConfig } from 'axios' + +export function dataSource1(params: Record = {}) { + return createServe({ + method: 'GET', + url: '/dataSource1', + params, + }) +} + +export function dataSource2(params: Record = {}) { + return createServe({ + method: 'GET', + url: '/dataSource2', + params, + }) +} + +export function getIpMsg(params: Record = {}) { + return createServe({ + method: 'GET', + url: '/getIpMsg', + params, + }) +} diff --git a/src/components/AddNumber.scss b/src/components/AddNumber.scss new file mode 100644 index 0000000..ea6473a --- /dev/null +++ b/src/components/AddNumber.scss @@ -0,0 +1,3 @@ +.num-span { + transform: translateZ(0); +} diff --git a/src/components/AddNumber.tsx b/src/components/AddNumber.tsx new file mode 100644 index 0000000..dc8c822 --- /dev/null +++ b/src/components/AddNumber.tsx @@ -0,0 +1,63 @@ +import React, { useState, useEffect, useRef } from 'react' +import './addNumber.scss' + +interface AddNumberProps { + value: number + time?: number + thousandSign?: boolean +} + +const AddNumber: React.FC = ({ value, time = 2, thousandSign = false }) => { + const [displayValue, setDisplayValue] = useState(0) + const oldValueRef = useRef(0) + const intervalRef = useRef(null) + + useEffect(() => { + if (intervalRef.current) { + clearInterval(intervalRef.current) + } + + const targetValue = value - oldValueRef.current + const step = (targetValue * 10) / (time * 100) + let current = 0 + let start = oldValueRef.current + + intervalRef.current = setInterval(() => { + start += step + if (start > value) { + if (intervalRef.current) { + clearInterval(intervalRef.current) + } + start = value + intervalRef.current = null + } + if (current === start) { + return + } + current = Math.floor(start) + oldValueRef.current = current + setDisplayValue(current) + }, 10) + + return () => { + if (intervalRef.current) { + clearInterval(intervalRef.current) + } + } + }, [value, time]) + + const formatValue = (val: number): string => { + if (thousandSign) { + return val.toString().replace(/(\d)(?=(?:\d{3}[+]?)+$)/g, '$1,') + } + return val.toString() + } + + return ( + + {formatValue(displayValue)} + + ) +} + +export default AddNumber diff --git a/src/components/PointMsg.scss b/src/components/PointMsg.scss new file mode 100644 index 0000000..06811fc --- /dev/null +++ b/src/components/PointMsg.scss @@ -0,0 +1,29 @@ +.tag-div { + padding: 5px 20px; + background-color: rgba(0, 0, 0, 0.5); + color: #fff; + position: absolute; + border: 2px solid #aaa; + font-size: 15px; + font-weight: 900; + z-index: 100; +} + +.tag-div .name { + font-size: 25px; + color: #ff6a6a; + margin: 0px 0px 10px 0px; +} + +.tag-div .die, +.tag-div .cure, +.tag-div .all { + margin: 0px 0px 5px 0px; + color: #ccc; +} + +.tag-div .die span, +.tag-div .cure span, +.tag-div .all span { + color: #fff; +} diff --git a/src/components/PointMsg.tsx b/src/components/PointMsg.tsx new file mode 100644 index 0000000..811c66b --- /dev/null +++ b/src/components/PointMsg.tsx @@ -0,0 +1,45 @@ +import React from 'react' +import './PointMsg.scss' + +interface PointMsgProps { + dvColor: string[] + position: { x: string; y: string } + currentPointData: { + name?: string + value?: number + cureNum?: number + deathNum?: number + } +} + +const PointMsg: React.FC = ({ dvColor, position, currentPointData }) => { + if (!currentPointData.name) { + return null + } + + return ( +
+
+ {currentPointData.name} +
+
+ 累计数:{currentPointData.value} +
+
+ 治愈数:{currentPointData.cureNum} +
+
+ 死亡数:{currentPointData.deathNum} +
+
+ ) +} + +export default PointMsg diff --git a/src/components/PointMsg.vue b/src/components/PointMsg.vue deleted file mode 100644 index 0efe6d6..0000000 --- a/src/components/PointMsg.vue +++ /dev/null @@ -1,66 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/components/RiskDetails.scss b/src/components/RiskDetails.scss new file mode 100644 index 0000000..4dd6fef --- /dev/null +++ b/src/components/RiskDetails.scss @@ -0,0 +1,57 @@ +.RiskDetails-div { + height: 100%; + width: 100%; + color: #fff; +} + +.RiskDetails-div .places-div { + background-color: #333; + width: 100%; + display: flex; +} + +.RiskDetails-div .places-div .h-p, +.RiskDetails-div .places-div .m-p { + color: #ff6a6a; + width: 50%; +} + +.RiskDetails-div .places-div .h-p p, +.RiskDetails-div .places-div .m-p p { + text-align: center; + margin: 5px 0; +} + +.RiskDetails-div .places-div .m-p { + color: #ffd889; +} + +.RiskDetails-div .tag-tex { + margin: 2px !important; + width: 96% !important; + overflow: hidden !important; + padding: 0 10px !important; + justify-content: left !important; +} + +.RiskDetails-div .ant-table { + background-color: rgba(0, 0, 0, 0.8) !important; +} + +.RiskDetails-div .ant-table-thead > tr > th { + background-color: #333 !important; + color: #fff !important; +} + +.RiskDetails-div .ant-table-tbody > tr > td { + color: #fff !important; + border-bottom: 1px solid #333 !important; +} + +.RiskDetails-div .ant-table-tbody > tr:hover > td { + background-color: #333 !important; +} + +.RiskDetails-div .ant-table-expanded-row { + background-color: #333333 !important; +} diff --git a/src/components/RiskDetails.tsx b/src/components/RiskDetails.tsx new file mode 100644 index 0000000..283821d --- /dev/null +++ b/src/components/RiskDetails.tsx @@ -0,0 +1,177 @@ +import React, { useState, useEffect } from 'react' +import { Drawer, Table, Tag, Button, Tooltip } from 'antd' +import './RiskDetails.scss' +import xlsxImg from '@/assets/img/xlsx.png' +import downloadXlsx from '@/utils/xlsxUtils' + +interface RiskArea { + city: string + high_num: number + middle_num: number + city_total: number + high_areas: string[] + middle_areas: string[] +} + +interface RiskDetailsProps { + dvColor: string[] + isRiskDetails: boolean + currentDetails: { + province?: string + province_total?: number + province_high_num?: number + province_middle_num?: number + list?: RiskArea[] + } + onClose: () => void +} + +const RiskDetails: React.FC = ({ dvColor, isRiskDetails, currentDetails, onClose }) => { + const [visible, setVisible] = useState(false) + + useEffect(() => { + if (isRiskDetails) { + setVisible(true) + } + }, [isRiskDetails]) + + const handleClose = () => { + setVisible(false) + onClose() + } + + const clickXlsxBtn = () => { + const tabObj = { + fileName: (currentDetails.province || '风险地') + '风险地数据', + tabHead: ['城市', '高风险数', '中风险数', '总数', '高风险地', '中风险地'], + keyList: ['city', 'high_num', 'middle_num', 'city_total', 'high_areas', 'middle_areas'], + tabData: currentDetails.list || [], + } + if (window.confirm('确认下载' + (currentDetails.province || '风险地') + '风险地数据?')) { + downloadXlsx(tabObj) + } + } + + const expandedRowRender = (record: RiskArea) => ( +
+
+

高风险地区

+ {record.high_areas && + record.high_areas.map((item, index) => ( + + + {item} + + + ))} +
+
+

中风险地区

+ {record.middle_areas && + record.middle_areas.map((item, index) => ( + + + {item} + + + ))} +
+
+ ) + + const columns = [ + { title: '序号', key: 'index', render: (_: any, __: any, index: number) => index + 1, width: 80 }, + { title: '城市', dataIndex: 'city', key: 'city' }, + { + title: '高风险', + dataIndex: 'high_num', + key: 'high_num', + sorter: (a: RiskArea, b: RiskArea) => a.high_num - b.high_num, + style: { color: '#f00' }, + }, + { + title: '中风险', + dataIndex: 'middle_num', + key: 'middle_num', + sorter: (a: RiskArea, b: RiskArea) => a.middle_num - b.middle_num, + }, + { + title: '总数', + dataIndex: 'city_total', + key: 'city_total', + sorter: (a: RiskArea, b: RiskArea) => a.city_total - b.city_total, + }, + ] + + return ( +
+ +
+ {currentDetails.province}({currentDetails.province_total}个) +
+
+
+ 高风险地区{currentDetails.province_high_num}个 +
+
+ 中风险地区{currentDetails.province_middle_num}个 +
+ +
+ + + + ) +} + +export default RiskDetails diff --git a/src/components/RiskDetails.vue b/src/components/RiskDetails.vue deleted file mode 100644 index 77d28b8..0000000 --- a/src/components/RiskDetails.vue +++ /dev/null @@ -1,192 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/components/SetDrawer.scss b/src/components/SetDrawer.scss new file mode 100644 index 0000000..e3bf3f6 --- /dev/null +++ b/src/components/SetDrawer.scss @@ -0,0 +1,73 @@ +.set-drawer { + --el-bg-color: rgba(0, 0, 0, 0.8); + padding: 0px; + + .drawer-div { + height: 100%; + overflow-y: auto; + } + + .ant-form-item-label > label { + color: #fff !important; + font-weight: 900; + } + + .ant-btn { + margin-right: 10px; + border-radius: 0 !important; + font-weight: 900; + font-size: 15px; + } + + .ant-radio-button-wrapper { + border-radius: 0 !important; + border-color: #555; + background-color: transparent; + color: #fff; + } + + .ant-radio-button-wrapper:not(:first-child)::before { + background-color: #555; + } + + .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled) { + border-color: #555555 !important; + background-color: #555555 !important; + color: #fff !important; + } + + .ant-switch-checked { + background-color: #555555 !important; + } + + .ant-slider-rail { + background-color: #333; + } + + .ant-slider-track { + background-color: #555555 !important; + } + + .ant-slider:hover .ant-slider-track { + background-color: #555555 !important; + } + + .ant-slider-handle::after { + box-shadow: 0 0 0 2px #555555 !important; + } + + .ant-slider:hover .ant-slider-handle::after { + box-shadow: 0 0 0 2px #555555 !important; + } + + .ant-popover-inner { + background-color: #333 !important; + } + + .color-div { + &:hover { + margin: 5px 2px; + cursor: pointer; + } + } +} diff --git a/src/components/SetDrawer.tsx b/src/components/SetDrawer.tsx new file mode 100644 index 0000000..5518aef --- /dev/null +++ b/src/components/SetDrawer.tsx @@ -0,0 +1,341 @@ +import React, { useState, useEffect, useRef } from 'react' +import { Drawer, Form, Switch, Radio, Slider, Button, Popover } from 'antd' +import { ReloadOutlined } from '@ant-design/icons' +import './SetDrawer.scss' + +import onImg from '@/assets/img/on.png' +import offImg from '@/assets/img/off.png' +import lzImg from '@/assets/img/lz.png' +import hyImg from '@/assets/img/hy.png' +import bzImg from '@/assets/img/bz.png' +import PK from '@/../package.json' + +interface SetData { + sphereType: string + isDrag: boolean + isZoom: boolean + isTag: boolean + autoRotate: boolean + rotateSpeed: number + sysVer: string + dataType: string + sysColor: string[] +} + +interface SetDrawerProps { + isDrawer: boolean + onClose: () => void + onChangeSetData: (type: string, setData: SetData) => void +} + +const SetDrawer: React.FC = ({ isDrawer, onClose, onChangeSetData }) => { + const [visible, setVisible] = useState(false) + const [setData, setSetData] = useState({ + sphereType: '粒子', + isDrag: true, + isZoom: true, + isTag: true, + autoRotate: true, + rotateSpeed: 10, + sysVer: '', + dataType: '', + sysColor: ['#7b52f7', '#c5b2ff'], + }) + const colorInputRef = useRef(null) + const [colorType, setColorType] = useState(0) + + const sphereTypeList = ['粒子', '黑夜', '白昼'] + const dataTypeList = ['离线', '在线'] + const colorList = [ + ['#7b52f7', '#c5b2ff'], + ['#414a89', '#b9c1ff'], + ['#295eb5', '#a4c5fb'], + ] + + useEffect(() => { + if (isDrawer) { + setVisible(true) + sysConfig() + } + }, [isDrawer]) + + const sysConfig = () => { + const currentVer = PK.version + setData((prev) => ({ ...prev, sysVer: currentVer, dataType: dataTypeList[0] })) + + const ss = sessionStorage.getItem('config') + if (ss) { + const ssVer = JSON.parse(ss).sysVer + if (currentVer !== ssVer) { + sessionStorage.removeItem('config') + sessionStorage.setItem('config', JSON.stringify({ + ...setData, + sysVer: currentVer, + dataType: dataTypeList[0], + })) + } else { + setSetData(JSON.parse(ss)) + } + } else { + sessionStorage.setItem('config', JSON.stringify({ + ...setData, + sysVer: currentVer, + dataType: dataTypeList[0], + })) + } + } + + const handleClose = () => { + setVisible(false) + onClose() + } + + const changeSetData = (type: string) => { + sessionStorage.setItem('config', JSON.stringify(setData)) + onChangeSetData(type, setData) + } + + const changeColor = (type: number) => { + setColorType(type) + if (colorInputRef.current) { + colorInputRef.current.value = setData.sysColor[type] + colorInputRef.current.click() + } + } + + const updateColorVal = (e: React.ChangeEvent) => { + setData((prev) => { + const newColor = [...prev.sysColor] + newColor[colorType] = e.target.value + return { ...prev, sysColor: newColor } + }) + } + + const presetsColor = (item: string[]) => { + if (window.confirm('确认使用该预设主题?')) { + setData((prev) => ({ ...prev, sysColor: item })) + sureColor() + } + } + + const sureColor = () => { + sessionStorage.setItem('config', JSON.stringify(setData)) + window.location.reload() + } + + const refreshPage = () => { + if (window.confirm('确认重置所有设置?')) { + sessionStorage.removeItem('config') + window.location.reload() + } + } + + const colorPopoverContent = ( +
+ {colorList.map((item, index) => ( +
presetsColor(item)} + style={{ display: 'flex', margin: '5px 0', cursor: 'pointer' }} + > +
+ 主色 +
+
+ 副色 +
+
+ ))} +
+ ) + + return ( +
+ +
+

系统设置

+
+ + { + setData((prev) => ({ ...prev, autoRotate: checked })) + changeSetData('autoRotate') + }} + /> + + + { + setData((prev) => ({ ...prev, isDrag: checked })) + changeSetData('isDrag') + }} + /> + + + { + setData((prev) => ({ ...prev, isZoom: checked })) + changeSetData('isZoom') + }} + /> + + + { + setData((prev) => ({ ...prev, isTag: checked })) + }} + /> + + + { + setData((prev) => ({ ...prev, dataType: e.target.value })) + changeSetData('dataType') + }} + > + {dataTypeList.map((item) => ( + +
+ {item === '在线' && 在线} + {item === '离线' && 离线} +
{item}
+
+
+ ))} +
+
+ + { + setData((prev) => ({ ...prev, sphereType: e.target.value })) + changeSetData('sphereType') + }} + > + {sphereTypeList.map((item) => ( + +
+ {item === '粒子' && 粒子} + {item === '黑夜' && 黑夜} + {item === '白昼' && 白昼} +
{item}
+
+
+ ))} +
+
+ {setData.autoRotate && ( + + { + setData((prev) => ({ ...prev, rotateSpeed: value })) + changeSetData('rotateSpeed') + }} + /> + + )} + + + + + + + + + + + + + +
+ 版本号:v{setData.sysVer} +
+
+
+
+ ) +} + +export default SetDrawer diff --git a/src/components/SetDrawer.vue b/src/components/SetDrawer.vue deleted file mode 100644 index 009d012..0000000 --- a/src/components/SetDrawer.vue +++ /dev/null @@ -1,317 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/components/addNumber.vue b/src/components/addNumber.vue deleted file mode 100644 index 75055d8..0000000 --- a/src/components/addNumber.vue +++ /dev/null @@ -1,71 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/main.tsx b/src/main.tsx new file mode 100644 index 0000000..22f30e7 --- /dev/null +++ b/src/main.tsx @@ -0,0 +1,10 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import App from './App' +import './styles/global.scss' + +ReactDOM.createRoot(document.getElementById('root')!).render( + + + , +) diff --git a/src/router/index.ts b/src/router/index.ts deleted file mode 100644 index 5020f94..0000000 --- a/src/router/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router' -import HomeView from '../views/HomeView.vue' - -const routes: Array = [ - { - path: '/', - name: 'home', - component: HomeView - } -] - -const router = createRouter({ - history: createWebHashHistory(), - routes -}) - -export default router diff --git a/src/shims-vue.d.ts b/src/shims-vue.d.ts deleted file mode 100644 index 8648ed2..0000000 --- a/src/shims-vue.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* eslint禁用 */ -declare module '*.vue' { - import type { DefineComponent } from 'vue' - const component: DefineComponent<{}, {}, any> - export default component -} -declare module 'three'//防止import导入报错 -declare module 'three.meshline' -declare module 'gsap' -declare module 'three/examples/jsm/controls/OrbitControls' -declare module 'echarts' -declare module '@iamzzg/data-view/dist/vue3/datav.map.vue.esm' -declare module 'file-saver' -declare module "*.png" -declare module "*.jpg" -declare module "*.js" -declare module "*.json" diff --git a/src/styles/global.scss b/src/styles/global.scss new file mode 100644 index 0000000..dd709e9 --- /dev/null +++ b/src/styles/global.scss @@ -0,0 +1,125 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html, body, #root { + height: 100%; + width: 100%; + color: #fff; + background-color: #000; + overflow: hidden; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; +} + +::-webkit-scrollbar { + width: 5px; +} + +::-webkit-scrollbar-track { + background-color: rgba(255, 255, 255, 0.2); +} + +::-webkit-scrollbar-thumb { + background-color: rgba(255, 255, 255, 0.5); +} + +::-webkit-scrollbar-thumb:hover { + background-color: rgba(255, 255, 255, 1); +} + +.ant-drawer-body { + padding: 0 !important; +} + +.ant-drawer-content { + background-color: rgba(0, 0, 0, 0.8) !important; +} + +.ant-table { + background-color: rgba(0, 0, 0, 0.8) !important; +} + +.ant-table-thead > tr > th { + background-color: #333 !important; + color: #fff !important; +} + +.ant-table-tbody > tr > td { + color: #fff !important; + border-bottom: 1px solid #333 !important; +} + +.ant-table-tbody > tr:hover > td { + background-color: #333 !important; +} + +.ant-btn { + border-radius: 0 !important; +} + +.ant-input { + border-radius: 0 !important; +} + +.ant-switch-checked { + background-color: #555555 !important; +} + +.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled) { + border-color: #555555 !important; + background-color: #555555 !important; +} + +.ant-slider-track { + background-color: #555555 !important; +} + +.ant-slider:hover .ant-slider-track { + background-color: #555555 !important; +} + +.ant-slider-handle::after { + box-shadow: 0 0 0 2px #555555 !important; +} + +.ant-slider:hover .ant-slider-handle::after { + box-shadow: 0 0 0 2px #555555 !important; +} + +.ant-popover { + padding: 0; +} + +.ant-popover-inner { + background-color: #333 !important; +} + +.ant-tag { + margin: 2px !important; + width: 96% !important; + overflow: hidden !important; + padding: 0 10px !important; + justify-content: left !important; +} + +.ant-tooltip { + max-width: 400px !important; +} + +.ant-tooltip-inner { + background-color: rgba(0, 0, 0, 0.8) !important; +} + +.ant-drawer-mask { + background-color: rgba(0, 0, 0, 0.45) !important; +} + +.ant-table-row-expand-icon-cell { + background-color: transparent !important; +} + +.ant-table-expanded-row { + background-color: #333333 !important; +} diff --git a/src/utils/addVersion.js b/src/utils/addVersion.js deleted file mode 100644 index ef9221c..0000000 --- a/src/utils/addVersion.js +++ /dev/null @@ -1,20 +0,0 @@ -//npm run build打包前执行此段代码 -let fs = require('fs'); - -//返回package的json数据 -function getPackageJson() { - let data = fs.readFileSync('./package.json');//fs读取文件 - return JSON.parse(data);//转换为json对象 -} - -let packageData = getPackageJson();//获取package的json -let arr = packageData.version.split('.');//切割后的版本号数组 -arr[2] = parseInt(arr[2]) + 1; -packageData.version = arr.join('.');//转换为以"."分割的字符串 -//用packageData覆盖package.json内容 -fs.writeFile( - './package.json', - JSON.stringify(packageData, null, "\t" - ), - (err) => { } -); diff --git a/src/utils/echartsAutoTooltip.js b/src/utils/echartsAutoTooltip.js deleted file mode 100644 index ef6364f..0000000 --- a/src/utils/echartsAutoTooltip.js +++ /dev/null @@ -1,200 +0,0 @@ -/** - * echarts tooltip 自动轮播 - * @param chart - * @param chartOption - * @param options - * { - * interval 轮播时间间隔,单位毫秒,默认为2000 - * loopSeries boolean类型,默认为false。 - * true表示循环所有series的tooltip,false则显示指定seriesIndex的tooltip - * seriesIndex 默认为0,指定某个系列(option中的series索引)循环显示tooltip, - * 当loopSeries为true时,从seriesIndex系列开始执行. - * } - * @returns {{clearLoop: clearLoop}} - */ - -export const autoToolTip = (chart, chartOption, options) => { - var defaultOptions = { - interval: 2000, - loopSeries: false, - seriesIndex: 0, - updateData: null, - }; - - if (!chart || !chartOption) { - return {}; - } - - var dataIndex = 0; // 数据索引,初始化为-1,是为了判断是否是第一次执行 - var seriesIndex = 0; // 系列索引 - var timeTicket = 0; - var seriesLen = chartOption.series.length; // 系列个数 - var dataLen = 0; // 某个系列数据个数 - var chartType; // 系列类型 - var first = true; - - // 不循环series时seriesIndex指定显示tooltip的系列,不指定默认为0,指定多个则默认为第一个 - // 循环series时seriesIndex指定循环的series,不指定则从0开始循环所有series,指定单个则相当于不循环,指定多个 - // 要不要添加开始series索引和开始的data索引? - - if (options) { - options.interval = options.interval || defaultOptions.interval; - options.loopSeries = options.loopSeries || defaultOptions.loopSeries; - options.seriesIndex = options.seriesIndex || defaultOptions.seriesIndex; - options.updateData = options.updateData || defaultOptions.updateData; - } else { - options = defaultOptions; - } - - // 如果设置的seriesIndex无效,则默认为0 - if (options.seriesIndex < 0 || options.seriesIndex >= seriesLen) { - seriesIndex = 0; - } else { - seriesIndex = options.seriesIndex; - } - - function autoShowTip() { - function showTip() { - // 判断是否更新数据 - if ( - dataIndex === 0 && - !first && - typeof options.updateData === "function" - ) { - options.updateData(); - chart.setOption(chartOption); - } - - var series = chartOption.series; - chartType = series[seriesIndex].type; // 系列类型 - dataLen = series[seriesIndex].data.length; // 某个系列的数据个数 - - var tipParams = { seriesIndex: seriesIndex }; - switch (chartType) { - case "map": - case "pie": - case "chord": - tipParams.name = series[seriesIndex].data[dataIndex].name; - break; - case "radar": // 雷达图 - tipParams.seriesIndex = seriesIndex; - tipParams.dataIndex = dataIndex; - break; - default: - tipParams.dataIndex = dataIndex; - break; - } - - if ( - chartType === "pie" ||//饼图 - chartType === "radar" || - chartType === "map" || - chartType === "scatter" || - chartType === "line" ||//折线图 - chartType === "bar" ||//柱状图 - chartType === "graph" - ) { - // 取消之前高亮的图形 - chart.dispatchAction({ - type: "downplay", - seriesIndex: options.loopSeries - ? seriesIndex === 0 - ? seriesLen - 1 - : seriesIndex - 1 - : seriesIndex, - dataIndex: dataIndex === 0 ? dataLen - 1 : dataIndex - 1, - }); - - // 高亮当前图形 - chart.dispatchAction({ - type: "highlight", - seriesIndex: seriesIndex, - dataIndex: dataIndex, - }); - } - - // 显示 tooltip - tipParams.type = "showTip"; - chart.dispatchAction(tipParams); - - dataIndex = (dataIndex + 1) % dataLen; - if (options.loopSeries && dataIndex === 0 && !first) { - // 数据索引归0表示当前系列数据已经循环完 - seriesIndex = (seriesIndex + 1) % seriesLen; - } - - first = false; - } - - showTip(); - timeTicket = setInterval(showTip, options.interval); - } - - // 关闭轮播 - function stopAutoShow() { - if (timeTicket) { - clearInterval(timeTicket); - timeTicket = 0; - - if ( - chartType === "pie" || - chartType === "radar" || - chartType === "map" || - chartType === "scatter" || - chartType === "line" || - chartType === "bar" || - chartType === "graph" - ) { - // 取消高亮的图形 - chart.dispatchAction({ - type: "downplay", - seriesIndex: options.loopSeries - ? seriesIndex === 0 - ? seriesLen - 1 - : seriesIndex - 1 - : seriesIndex, - dataIndex: dataIndex === 0 ? dataLen - 1 : dataIndex - 1, - }); - } - } - } - - var zRender = chart.getZr(); - - function zRenderMouseMove(param) { - if (param.event) { - // 阻止canvas上的鼠标移动事件冒泡 - param.event.cancelBubble = true; - } - - stopAutoShow(); - } - - // 离开echarts图时恢复自动轮播 - function zRenderGlobalOut() { - if (!timeTicket) { - autoShowTip(); - } - } - - // 鼠标在echarts图上时停止轮播 - chart.on("mousemove", stopAutoShow); - zRender.on("mousemove", zRenderMouseMove); - zRender.on("globalout", zRenderGlobalOut); - - autoShowTip(); - - return { - clearLoop: function () { - if (timeTicket) { - clearInterval(timeTicket); - timeTicket = 0; - } - - chart.off("mousemove", stopAutoShow); - zRender.off("mousemove", zRenderMouseMove); - zRender.off("globalout", zRenderGlobalOut); - }, - }; -}; - diff --git a/src/utils/echartsAutoTooltip.ts b/src/utils/echartsAutoTooltip.ts new file mode 100644 index 0000000..c325c3b --- /dev/null +++ b/src/utils/echartsAutoTooltip.ts @@ -0,0 +1,180 @@ +import * as echarts from 'echarts' + +interface AutoToolTipOptions { + interval?: number + loopSeries?: boolean + seriesIndex?: number + updateData?: (() => void) | null +} + +export const autoToolTip = ( + chart: echarts.ECharts, + chartOption: echarts.EChartsOption, + options: AutoToolTipOptions +) => { + const defaultOptions: Required = { + interval: 2000, + loopSeries: false, + seriesIndex: 0, + updateData: null, + } + + if (!chart || !chartOption) { + return { clearLoop: () => {} } + } + + let dataIndex = 0 + let seriesIndex = 0 + let timeTicket: number | null = 0 + const seriesLen = (chartOption.series as any[]).length + let dataLen = 0 + let chartType: string = '' + let first = true + + if (options) { + options.interval = options.interval || defaultOptions.interval + options.loopSeries = options.loopSeries || defaultOptions.loopSeries + options.seriesIndex = options.seriesIndex ?? defaultOptions.seriesIndex + options.updateData = options.updateData || defaultOptions.updateData + } else { + options = defaultOptions + } + + if (options.seriesIndex < 0 || options.seriesIndex >= seriesLen) { + seriesIndex = 0 + } else { + seriesIndex = options.seriesIndex + } + + function showTip() { + if ( + dataIndex === 0 && + !first && + typeof options.updateData === 'function' + ) { + options.updateData() + chart.setOption(chartOption) + } + + const series = chartOption.series as any[] + chartType = series[seriesIndex].type + dataLen = series[seriesIndex].data.length + + const tipParams: any = { seriesIndex: seriesIndex } + switch (chartType) { + case 'map': + case 'pie': + case 'chord': + tipParams.name = series[seriesIndex].data[dataIndex].name + break + case 'radar': + tipParams.seriesIndex = seriesIndex + tipParams.dataIndex = dataIndex + break + default: + tipParams.dataIndex = dataIndex + break + } + + if ( + chartType === 'pie' || + chartType === 'radar' || + chartType === 'map' || + chartType === 'scatter' || + chartType === 'line' || + chartType === 'bar' || + chartType === 'graph' + ) { + chart.dispatchAction({ + type: 'downplay', + seriesIndex: options.loopSeries + ? seriesIndex === 0 + ? seriesLen - 1 + : seriesIndex - 1 + : seriesIndex, + dataIndex: dataIndex === 0 ? dataLen - 1 : dataIndex - 1, + }) + + chart.dispatchAction({ + type: 'highlight', + seriesIndex: seriesIndex, + dataIndex: dataIndex, + }) + } + + tipParams.type = 'showTip' + chart.dispatchAction(tipParams) + + dataIndex = (dataIndex + 1) % dataLen + if (options.loopSeries && dataIndex === 0 && !first) { + seriesIndex = (seriesIndex + 1) % seriesLen + } + + first = false + } + + function autoShowTip() { + showTip() + timeTicket = window.setInterval(showTip, options.interval!) + } + + function stopAutoShow() { + if (timeTicket) { + clearInterval(timeTicket) + timeTicket = 0 + + if ( + chartType === 'pie' || + chartType === 'radar' || + chartType === 'map' || + chartType === 'scatter' || + chartType === 'line' || + chartType === 'bar' || + chartType === 'graph' + ) { + chart.dispatchAction({ + type: 'downplay', + seriesIndex: options.loopSeries + ? seriesIndex === 0 + ? seriesLen - 1 + : seriesIndex - 1 + : seriesIndex, + dataIndex: dataIndex === 0 ? dataLen - 1 : dataIndex - 1, + }) + } + } + } + + const zRender = chart.getZr() + + function zRenderMouseMove(param: any) { + if (param.event) { + param.event.cancelBubble = true + } + stopAutoShow() + } + + function zRenderGlobalOut() { + if (!timeTicket) { + autoShowTip() + } + } + + chart.on('mousemove', stopAutoShow) + zRender.on('mousemove', zRenderMouseMove) + zRender.on('globalout', zRenderGlobalOut) + + autoShowTip() + + return { + clearLoop: () => { + if (timeTicket) { + clearInterval(timeTicket) + timeTicket = 0 + } + chart.off('mousemove', stopAutoShow) + zRender.off('mousemove', zRenderMouseMove) + zRender.off('globalout', zRenderGlobalOut) + }, + } +} diff --git a/src/utils/getWordBlob.js b/src/utils/getWordBlob.js deleted file mode 100644 index 39befe2..0000000 --- a/src/utils/getWordBlob.js +++ /dev/null @@ -1,22 +0,0 @@ -import docxtemplater from 'docxtemplater' -import PizZip from 'pizzip' -import JSZipUtils from 'jszip-utils' - -export function getWordBlob(tempDocxPath, wordData) { - return new Promise((resolve, reject) => { - JSZipUtils.getBinaryContent(tempDocxPath, (error, content) => { - let zip = new PizZip(content);// 创建一个PizZip实例,内容为模板的内容 - // 创建并加载docxtemplater实例对象 - let doc = new docxtemplater(); - doc.loadZip(zip);//加载zip - doc.setData(wordData);//设置数据 - doc.render();// 用模板变量的值替换所有模板变量 - // 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示) - let out = doc.getZip().generate({ - type: "blob", - mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" - }); - resolve(out);//成功后返回blob数据 - }) - }) -} \ No newline at end of file diff --git a/src/utils/getWordBlob.ts b/src/utils/getWordBlob.ts new file mode 100644 index 0000000..0be4588 --- /dev/null +++ b/src/utils/getWordBlob.ts @@ -0,0 +1,25 @@ +import docxtemplater from 'docxtemplater' +import PizZip from 'pizzip' +import JSZipUtils from 'jszip-utils' + +export function getWordBlob(tempDocxPath: string, wordData: any) { + return new Promise((resolve, reject) => { + JSZipUtils.getBinaryContent(tempDocxPath, (error: any, content: any) => { + if (error) { + reject(error) + return + } + const zip = new PizZip(content) + const doc = new docxtemplater() + doc.loadZip(zip) + doc.setData(wordData) + doc.render() + + const out = doc.getZip().generate({ + type: 'blob', + mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + }) + resolve(out) + }) + }) +} diff --git a/src/utils/jsonpUtils.ts b/src/utils/jsonpUtils.ts index 46d5bb1..42e2646 100644 --- a/src/utils/jsonpUtils.ts +++ b/src/utils/jsonpUtils.ts @@ -1,8 +1,7 @@ -//获取世界数据与使用者ip信息 -export default function jsonp(url: string, callback: any, callBackName: any = "val") { - let script = document.createElement('script'); - url += '?callback=' + callBackName; - script.setAttribute('src', url);//添加script的src属性 - document.head.appendChild(script); - window[callBackName] = callback; -}; \ No newline at end of file +export default function jsonp(url: string, callback: any, callBackName: string = 'val') { + const script = document.createElement('script') + const urlWithCallback = url + '?callback=' + callBackName + script.setAttribute('src', urlWithCallback) + document.head.appendChild(script) + ;(window as any)[callBackName] = callback +} diff --git a/src/utils/jsonpUtils1.ts b/src/utils/jsonpUtils1.ts deleted file mode 100644 index d282bdb..0000000 --- a/src/utils/jsonpUtils1.ts +++ /dev/null @@ -1,8 +0,0 @@ -//获取当前省的数据 -export default function jsonp(url: any, callback: any, callBackName: any = "val1", sendData: string) { - let script = document.createElement('script'); - url += '?callback=' + callBackName + "&" + sendData; - script.setAttribute('src', url);//添加script的src属性 - document.head.appendChild(script); - window[callBackName] = callback; -}; \ No newline at end of file diff --git a/src/utils/xlsxUtils.ts b/src/utils/xlsxUtils.ts index 8f43433..4edd4cd 100644 --- a/src/utils/xlsxUtils.ts +++ b/src/utils/xlsxUtils.ts @@ -1,64 +1,57 @@ -import * as XLSX from "xlsx"; -import { saveAs } from 'file-saver' - -//入参示例 -let eg = { - fileName: "测试",//文件名 - tabHead: ["国家", "人口", "测试"],//表头列表 - keyList: ["name", "population", "test"],//表头对应的属性名,顺序必须与表头对应 - tabData: [ - { name: "中国", population: "11", test: "t1" }, - { name: "美国", population: "22", test: "t2" }, - { name: "日本", population: "35", test: "t3" } - ]//对象数组 -} - -function workbook2blob(workbook: any) { - // 生成excel的配置项 - let wopts: any = { - // 要生成的文件类型 - bookType: "xlsx", - // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性 - bookSST: false, - type: "binary" - }; - var wbout = XLSX.write(workbook, wopts); - // 将字符串转ArrayBuffer - function s2ab(s: any) { - var buf = new ArrayBuffer(s.length); - var view = new Uint8Array(buf); - for (var i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xff; - return buf; - } - let buf = s2ab(wbout); - var blob = new Blob([buf], { - type: "application/octet-stream" - }); - return blob; -}; - -//导出数据表格 -export default async function downloadXlsx(tabObj: any) { - let aoaList: any = []; - aoaList[0] = tabObj.tabHead; //赋值表头列表 - tabObj.tabData.forEach((tabItem: any, tabIndex: number) => { - aoaList[tabIndex + 1] = [];//该二维度数组必须多加一个元素,因为表头占第一个元素 - tabObj.keyList.forEach((keyItem: any, keyIndex: number) => { - let val = tabItem[keyItem];//获取表格属性的值 - ((typeof val == "undefined") || (val == "")) ? - (aoaList[tabIndex + 1][keyIndex] = "-") ://数据未定义或者为空则用"-"代替 - (aoaList[tabIndex + 1][keyIndex] = val + "");//添加空字符串,防类型为非字符串 - }) - }); - let workSheet = null; - workSheet = XLSX.utils.aoa_to_sheet(aoaList); //将列表数据添加到工作表 - let workBook = XLSX.utils.book_new(); //创建一个工作薄 - XLSX.utils.book_append_sheet(workBook, workSheet, "1"); //将工作表添加到工作薄中 - //下载方式一:用XLSX的writeFile,写入文件,下载工作薄 - // await XLSX.writeFile(workBook, tabObj.fileName + ".xlsx"); - //下载方式二:利用file-saver的saveAs下载Blob - saveAs( - new Blob([workbook2blob(workBook)], { type: "application/octet-stream" }), - tabObj.fileName + ".xlsx" - ); -}; \ No newline at end of file +import * as XLSX from 'xlsx' +import { saveAs } from 'file-saver' + +interface TabObj { + fileName: string + tabHead: string[] + keyList: string[] + tabData: Record[] +} + +function workbook2blob(workbook: any) { + const wopts: any = { + bookType: 'xlsx', + bookSST: false, + type: 'binary', + } + const wbout = XLSX.write(workbook, wopts) + + function s2ab(s: any) { + const buf = new ArrayBuffer(s.length) + const view = new Uint8Array(buf) + for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xff + return buf + } + + const buf = s2ab(wbout) + const blob = new Blob([buf], { + type: 'application/octet-stream', + }) + return blob +} + +export default async function downloadXlsx(tabObj: TabObj) { + const aoaList: any = [] + aoaList[0] = tabObj.tabHead + + tabObj.tabData.forEach((tabItem, tabIndex) => { + aoaList[tabIndex + 1] = [] + tabObj.keyList.forEach((keyItem, keyIndex) => { + const val = tabItem[keyItem] + if (typeof val === 'undefined' || val === '') { + aoaList[tabIndex + 1][keyIndex] = '-' + } else { + aoaList[tabIndex + 1][keyIndex] = val + '' + } + }) + }) + + const workSheet = XLSX.utils.aoa_to_sheet(aoaList) + const workBook = XLSX.utils.book_new() + XLSX.utils.book_append_sheet(workBook, workSheet, '1') + + saveAs( + new Blob([workbook2blob(workBook)], { type: 'application/octet-stream' }), + tabObj.fileName + '.xlsx' + ) +} diff --git a/src/views/ChinaEchartDrawer.scss b/src/views/ChinaEchartDrawer.scss new file mode 100644 index 0000000..4e93361 --- /dev/null +++ b/src/views/ChinaEchartDrawer.scss @@ -0,0 +1,128 @@ +.chinaEchart-drawer { + height: 100vh; + background-color: rgba(0, 0, 0, 0.8); + color: #fff; +} + +.chinaEchart-drawer .my-header { + z-index: 5; + position: absolute; + top: 0; + width: 100%; + background-color: rgba(0, 0, 0, 0.8); + display: flex; + justify-content: space-between; + align-items: center; +} + +.chinaEchart-drawer .my-header .header-title { + font-size: 20px; + font-weight: 900; + display: flex; + justify-content: center; + align-items: center; +} + +.chinaEchart-drawer .my-header .header-title .anticon { + margin-right: 10px; + color: #1890ff; +} + +.chinaEchart-drawer .my-header .header-num div { + width: 100%; + display: flex; + justify-content: flex-end; + align-items: center; +} + +.chinaEchart-drawer .my-header .header-num div span { + color: #ffd889; + font-size: 18px; + margin: 0 5px; + font-weight: 900; +} + +.chinaEchart-drawer .my-header .header-num div span:nth-child(3) { + color: #66f68f; +} + +.chinaEchart-drawer .my-header .header-num div span:nth-child(5) { + color: #ff6a6a; +} + +.chinaEchart-drawer .my-content { + height: 100%; + width: 100%; + background-color: #000; +} + +.chinaEchart-drawer .my-content .left-div, +.chinaEchart-drawer .my-content .center-div, +.chinaEchart-drawer .my-content .right-div { + position: absolute; + top: 0; + padding: 70px 0 10px 0; + height: 100%; + overflow: auto; + border: 2px solid rgba(255, 255, 255, 0.2); +} + +.chinaEchart-drawer .my-content .left-div .item-div, +.chinaEchart-drawer .my-content .center-div .item-div, +.chinaEchart-drawer .my-content .right-div .item-div { + height: 33%; + margin: auto 0; + text-align: center; + color: #fff; + font-weight: 900; + padding: 10px; +} + +.chinaEchart-drawer .my-content .left-div .item-div .tit, +.chinaEchart-drawer .my-content .center-div .item-div .tit, +.chinaEchart-drawer .my-content .right-div .item-div .tit { + font-size: 18px; +} + +.chinaEchart-drawer .my-content .left-div { + width: 20%; + left: 5px; +} + +.chinaEchart-drawer .my-content .center-div { + width: 45%; + left: 23%; +} + +.chinaEchart-drawer .my-content .center-div .china-map-div { + height: 45%; + padding: 10px; +} + +.chinaEchart-drawer .my-content .center-div .china-map-div .china-map { + height: 100%; + width: 100%; +} + +.chinaEchart-drawer .my-content .center-div .history-line-div { + height: 55%; + padding: 10px; +} + +.chinaEchart-drawer .my-content .center-div .history-line-div .history-line { + height: 100%; + width: 100%; +} + +.chinaEchart-drawer .my-content .right-div { + width: 28%; + right: 5px; +} + +.chinaEchart-drawer .my-content .right-div .item-div:nth-child(1) { + border-top-left-radius: 30px; +} + +.chinaEchart-drawer .my-content .right-div .item-div:nth-child(3) { + border-bottom-left-radius: 30px; +} diff --git a/src/views/ChinaEchartDrawer.tsx b/src/views/ChinaEchartDrawer.tsx new file mode 100644 index 0000000..1eb4a36 --- /dev/null +++ b/src/views/ChinaEchartDrawer.tsx @@ -0,0 +1,719 @@ +import React, { useState, useEffect, useRef } from 'react' +import { Drawer } from 'antd' +import { CloseOutlined } from '@ant-design/icons' +import * as echarts from 'echarts' +import AddNumber from '@/components/AddNumber' +import { autoToolTip } from '@/utils/echartsAutoTooltip' +import './ChinaEchartDrawer.scss' + +interface ProvinceData { + name: string + value: number + econNum: number + deathNum: number + cureNum: number + conadd: number + jwsrNum: number +} + +interface SphereDataItem { + name: string + value: number + deathNum: number + cureNum: number + position?: number[] +} + +interface DailyData { + addcon_new?: number + addcure_new?: number + adddeath_new?: number +} + +interface HistoryListItem { + ymd: string + cn_conNum: number + cn_cureNum: number + cn_deathNum: number + cn_jwsrNum: number +} + +interface AllData { + gntotal: number + curetotal: number + deathtotal: number + list: ProvinceData[] + add_daily: DailyData + jwsrTop: { name: string; jwsrNum: number }[] + historylist: HistoryListItem[] + locIncrProTop: { name: string; locIncrNum: number }[] +} + +interface ChinaEchartDrawerProps { + dvColor: string[] + sphereData: SphereDataItem[] + daily: DailyData + jwsrTop: { name: string; jwsrNum: number }[] + historylist: HistoryListItem[] + isEchart: boolean + allData: AllData + onClose: () => void +} + +const ChinaEchartDrawer: React.FC = ({ + dvColor, + daily, + historylist, + isEchart, + allData, + onClose, +}) => { + const [visible, setVisible] = useState(false) + const [addcon, setAddcon] = useState(0) + const [addcure, setAddcure] = useState(0) + const [addDie, setAddDie] = useState(0) + + const chinaMapRef = useRef(null) + const diagnosedChartRef = useRef(null) + const dieChartRef = useRef(null) + const dayAddChartRef = useRef(null) + const cureChartRef = useRef(null) + const locIncrProTopChartRef = useRef(null) + const jwsrTopChartRef = useRef(null) + const historyLineDivRef = useRef(null) + + const chartsRef = useRef<{ [key: string]: echarts.ECharts | null }>({}) + const sliceNum = 10 + + useEffect(() => { + if (isEchart) { + setVisible(true) + setTimeout(() => { + initChart() + }, 100) + window.addEventListener('resize', initChart) + } else { + setAddcon(0) + setAddcure(0) + setAddDie(0) + } + return () => { + window.removeEventListener('resize', initChart) + Object.values(chartsRef.current).forEach((chart) => { + if (chart) chart.dispose() + }) + } + }, [isEchart]) + + const handleClose = () => { + setVisible(false) + onClose() + } + + const sortFun = (arr: { name: string; value: number }[]) => { + return [...arr].sort((a, b) => b.value - a.value) + } + + const getDiagnosedList10 = () => { + const tempList: { name: string; value: number }[] = [] + allData.list?.forEach((l) => { + tempList.push({ + name: l.name, + value: Number(l.value), + }) + }) + return sortFun(tempList).slice(0, sliceNum) + } + + const getDieList10 = () => { + const tempList: { name: string; value: number }[] = [] + allData.list?.forEach((l) => { + tempList.push({ + name: l.name, + value: Number(l.deathNum), + }) + }) + return sortFun(tempList).slice(0, sliceNum) + } + + const getDayAddList10 = () => { + const tempList: { name: string; value: number }[] = [] + allData.list?.forEach((l) => { + tempList.push({ + name: l.name, + value: isNaN(Number(l.conadd)) ? 0 : Number(l.conadd), + }) + }) + return sortFun(tempList).slice(0, sliceNum) + } + + const getCureList = () => { + const tempList: { name: string; value: number }[] = [] + allData.list?.forEach((l) => { + tempList.push({ + name: l.name, + value: Number(l.cureNum), + }) + }) + return sortFun(tempList).slice(0, sliceNum) + } + + const getLocIncrProTop = () => { + const tempList: { name: string; value: number }[] = [] + allData.locIncrProTop?.forEach((l) => { + tempList.push({ + name: l.name, + value: Number(l.locIncrNum), + }) + }) + return sortFun(tempList).slice(0, sliceNum) + } + + const getJwsrTop = () => { + const tempList: { name: string; value: number }[] = [] + allData.jwsrTop?.forEach((l) => { + tempList.push({ + name: l.name, + value: Number(l.jwsrNum), + }) + }) + return sortFun(tempList).slice(0, sliceNum) + } + + const histogramOption = (list: { name: string; value: number }[], titName: string) => { + const option: echarts.EChartsOption = { + title: { + text: titName + sliceNum, + left: 'center', + textStyle: { + color: '#fff', + }, + }, + tooltip: { + backgroundColor: 'rgba(0,0,0,.5)', + borderWidth: 0, + trigger: 'axis', + textStyle: { + color: '#fff', + fontWeight: 'bolder', + }, + }, + grid: { + top: '10%', + left: '10%', + right: '10%', + bottom: '0%', + }, + xAxis: { + type: 'value', + show: false, + }, + yAxis: { + type: 'category', + axisLabel: { + color: '#fff', + }, + data: [], + }, + series: [ + { + data: [], + type: 'bar', + animationDuration: 2000, + animationEasing: 'cubicInOut', + showBackground: true, + backgroundStyle: { + color: 'rgba(180, 180, 180, 0.2)', + }, + itemStyle: { + color: new echarts.graphic.LinearGradient(0, 1, 1, 1, [ + { + offset: 0, + color: dvColor[0], + }, + { + offset: 1, + color: '#555', + }, + ]), + }, + label: { + color: '#fff', + fontWeight: 'bolder', + show: true, + align: 'left', + formatter: '{c}', + }, + }, + ], + } + + const yData: string[] = [] + const sData: number[] = [] + list.forEach((l) => { + yData.push(l.name) + sData.push(l.value) + }) + yData.reverse() + sData.reverse() + ;(option.yAxis as any).data = yData + ;(option.series as any)[0].data = sData + + return option + } + + const initHistogram = () => { + if (diagnosedChartRef.current) { + if (chartsRef.current.diagnosedChart) chartsRef.current.diagnosedChart.dispose() + chartsRef.current.diagnosedChart = echarts.init(diagnosedChartRef.current) + chartsRef.current.diagnosedChart.setOption(histogramOption(getDiagnosedList10(), '确诊数前')) + } + + if (dieChartRef.current) { + if (chartsRef.current.dieChart) chartsRef.current.dieChart.dispose() + chartsRef.current.dieChart = echarts.init(dieChartRef.current) + chartsRef.current.dieChart.setOption(histogramOption(getDieList10(), '死亡数前')) + } + + if (dayAddChartRef.current) { + if (chartsRef.current.dayAddChart) chartsRef.current.dayAddChart.dispose() + chartsRef.current.dayAddChart = echarts.init(dayAddChartRef.current) + chartsRef.current.dayAddChart.setOption(histogramOption(getDayAddList10(), '当日新增前')) + } + + if (cureChartRef.current) { + if (chartsRef.current.cureChart) chartsRef.current.cureChart.dispose() + chartsRef.current.cureChart = echarts.init(cureChartRef.current) + chartsRef.current.cureChart.setOption(histogramOption(getCureList(), '治愈数前')) + } + + if (locIncrProTopChartRef.current) { + if (chartsRef.current.locIncrProTopChart) chartsRef.current.locIncrProTopChart.dispose() + chartsRef.current.locIncrProTopChart = echarts.init(locIncrProTopChartRef.current) + chartsRef.current.locIncrProTopChart.setOption(histogramOption(getLocIncrProTop(), '本地新增前')) + } + + if (jwsrTopChartRef.current) { + if (chartsRef.current.jwsrTopChart) chartsRef.current.jwsrTopChart.dispose() + chartsRef.current.jwsrTopChart = echarts.init(jwsrTopChartRef.current) + chartsRef.current.jwsrTopChart.setOption(histogramOption(getJwsrTop(), '境外输入前')) + } + } + + const chinaMapInit = () => { + if (!chinaMapRef.current || !allData.list) return + + const list = JSON.parse(JSON.stringify(allData.list)) + const echartData: any[] = [] + list.forEach((l: any) => { + echartData.push({ + name: l.name, + value: l.econNum, + allNum: l.value, + deathNum: l.deathNum, + cureNum: l.cureNum, + conadd: isNaN(Number(l.conadd)) ? 0 : Number(l.conadd), + jwsrNum: l.jwsrNum, + }) + }) + + if (chartsRef.current.chinaMapChart) chartsRef.current.chinaMapChart.dispose() + chartsRef.current.chinaMapChart = echarts.init(chinaMapRef.current) + + const option: echarts.EChartsOption = { + title: { + text: '国内各省现存分布', + left: 'center', + top: '1%', + textStyle: { + color: '#fff', + }, + }, + visualMap: { + min: 0, + max: 500, + left: '5%', + bottom: '5%', + text: ['高', '低'], + textStyle: { + color: '#fff', + }, + calculable: true, + inRange: { + color: ['#fff', '#f00'], + }, + }, + tooltip: { + padding: 10, + enterable: true, + transitionDuration: 1, + backgroundColor: 'rgb(0,0,0,.8)', + borderRadius: 0, + textStyle: { + color: '#fff', + }, + formatter: (params: any) => { + let tipString = '' + if (params.data && params.data.value) { + tipString = + "
" + + params.data.name + + '
' + + "
现存:" + + params.data.value + + '
' + + "
累计:" + + params.data.allNum + + '
' + + "
死亡:" + + params.data.deathNum + + '
' + + "
治愈:" + + params.data.cureNum + + '
' + + "
较昨日新增:" + + params.data.conadd + + '
' + + "
境外输入:" + + params.data.jwsrNum + + '
' + } + return tipString + }, + }, + grid: { + top: '15%', + left: '10%', + right: '10%', + bottom: '15%', + }, + xAxis: { + type: 'category', + data: echartData.slice(0, 20).map((d) => d.name), + axisLabel: { + color: '#fff', + rotate: 45, + }, + }, + yAxis: { + type: 'value', + axisLabel: { + color: '#fff', + }, + }, + series: [ + { + type: 'bar', + data: echartData.slice(0, 20).map((d) => d.value), + itemStyle: { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { offset: 0, color: '#ff6a6a' }, + { offset: 1, color: '#ffd889' }, + ]), + }, + label: { + show: true, + position: 'top', + color: '#fff', + }, + }, + ], + } + + chartsRef.current.chinaMapChart.setOption(option) + } + + const historyLineChartFun = (list: HistoryListItem[]) => { + if (!historyLineDivRef.current || !list) return + + const lineData = JSON.parse(JSON.stringify(list)) + lineData.reverse() + + if (chartsRef.current.historyLineChart) chartsRef.current.historyLineChart.dispose() + chartsRef.current.historyLineChart = echarts.init(historyLineDivRef.current) + + const option: echarts.EChartsOption = { + grid: { + left: '8%', + }, + title: { + text: '国内历史数据', + left: 'center', + top: '5%', + textStyle: { + color: '#fff', + }, + }, + tooltip: { + backgroundColor: 'rgba(0,0,0,.5)', + borderWidth: 0, + trigger: 'axis', + textStyle: { + color: '#fff', + fontWeight: 'bolder', + }, + axisPointer: { + type: 'cross', + }, + }, + legend: { + icon: 'rect', + data: ['确诊数', '治愈数', '死亡数', '境外输入'], + textStyle: { + color: '#fff', + }, + orient: 'vertical', + top: '15%', + right: '2%', + }, + xAxis: { + data: lineData.map((item: any) => item.ymd), + axisLabel: { + color: '#fff', + }, + }, + yAxis: { + axisLabel: { + color: '#fff', + }, + }, + dataZoom: [ + { + startValue: '', + }, + { + type: 'inside', + }, + ], + series: [ + { + name: '确诊数', + type: 'line', + animationDuration: 2000, + animationEasing: 'cubicInOut', + lineStyle: { + color: '#f4c25e', + }, + itemStyle: { + color: '#f4c25e', + }, + data: lineData.map((item: any) => item.cn_conNum), + }, + { + name: '治愈数', + type: 'line', + lineStyle: { + color: '#48c56b', + }, + itemStyle: { + color: '#48c56b', + }, + data: lineData.map((item: any) => item.cn_cureNum), + }, + { + name: '死亡数', + type: 'line', + lineStyle: { + color: '#ff6a6a', + }, + itemStyle: { + color: '#ff6a6a', + }, + data: lineData.map((item: any) => item.cn_deathNum), + }, + { + name: '境外输入', + type: 'line', + lineStyle: { + color: '#9574fb', + }, + itemStyle: { + color: '#9574fb', + }, + data: lineData.map((item: any) => item.cn_jwsrNum), + }, + ], + } + + chartsRef.current.historyLineChart.setOption(option) + } + + const initChart = () => { + if (allData) { + setAddcon(Number(allData.gntotal)) + setAddcure(Number(allData.curetotal)) + setAddDie(Number(allData.deathtotal)) + } + chinaMapInit() + initHistogram() + historyLineChartFun(historylist) + } + + return ( +
+ +
+ 国内分析 + +
+
+
+
+
+

国内确诊数

+
+ +
+

+ 今日{daily.addcon_new} +

+
+
+

国内治愈数

+
+ +
+

今日{daily.addcure_new}

+
+
+

国内死亡数

+
+ +
+

今日{daily.adddeath_new}

+
+
+
+
+
+
+ +
+ {[ + { ref: diagnosedChartRef, id: 'diagnosedChart' }, + { ref: dieChartRef, id: 'dieChart' }, + { ref: dayAddChartRef, id: 'dayAddChart' }, + { ref: cureChartRef, id: 'cureChart' }, + { ref: locIncrProTopChartRef, id: 'locIncrProTopChart' }, + { ref: jwsrTopChartRef, id: 'jwsrTopChart' }, + ].map((item) => ( +
+
+
+ ))} +
+ +
+
+
+
+ +
+ ) +} + +export default ChinaEchartDrawer diff --git a/src/views/ChinaEchartDrawer.vue b/src/views/ChinaEchartDrawer.vue deleted file mode 100644 index d1ec8cd..0000000 --- a/src/views/ChinaEchartDrawer.vue +++ /dev/null @@ -1,743 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/views/ChinaTabDrawer.scss b/src/views/ChinaTabDrawer.scss new file mode 100644 index 0000000..5d92aba --- /dev/null +++ b/src/views/ChinaTabDrawer.scss @@ -0,0 +1,30 @@ +.chinaTab-drawer { + --el-bg-color: rgba(0, 0, 0, 0); +} + +.chinaTab-drawer .ant-table { + background-color: rgba(0, 0, 0, 0.8) !important; +} + +.chinaTab-drawer .ant-table-thead > tr > th { + background-color: #333 !important; + color: #fff !important; +} + +.chinaTab-drawer .ant-table-tbody > tr > td { + color: #fff !important; + border-bottom: 1px solid #333 !important; +} + +.chinaTab-drawer .ant-table-tbody > tr:hover > td { + background-color: #333 !important; +} + +.chinaTab-drawer .ant-table-expanded-row { + background-color: #333333 !important; +} + +.chinaTab-drawer .close-icon:hover { + color: #fff !important; + transform: rotateZ(180deg); +} diff --git a/src/views/ChinaTabDrawer.tsx b/src/views/ChinaTabDrawer.tsx new file mode 100644 index 0000000..429c8cb --- /dev/null +++ b/src/views/ChinaTabDrawer.tsx @@ -0,0 +1,334 @@ +import React, { useState, useEffect } from 'react' +import { Drawer, Table, Input, Button } from 'antd' +import { CloseOutlined } from '@ant-design/icons' +import './ChinaTabDrawer.scss' +import xlsxImg from '@/assets/img/xlsx.png' +import downloadXlsx from '@/utils/xlsxUtils' +import RiskDetails from '@/components/RiskDetails' + +interface CityData { + name: string + conNum: number + econNum: number + deathNum: number + cureNum: number + conadd: number + zerodays: number + asymNum?: number +} + +interface HighMiddleData { + province: string + province_total: number + province_high_num: number + province_middle_num: number + list: any[] +} + +interface ProvinceData { + name: string + value: number + econNum: number + deathNum: number + cureNum: number + conadd: number + jwsrNum: number + asymNum?: number + city: CityData[] + isHM?: boolean + highAndMiddle?: HighMiddleData +} + +interface AllData { + list: ProvinceData[] + highAndMiddle: HighMiddleData[] +} + +interface ChinaTabDrawerProps { + dvColor: string[] + allData: AllData + isChina: boolean + list: ProvinceData[] + onClose: () => void +} + +const ChinaTabDrawer: React.FC = ({ dvColor, allData, isChina, list, onClose }) => { + const [visible, setVisible] = useState(false) + const [tabData, setTabData] = useState([]) + const [nameValue, setNameValue] = useState('') + const [isRiskDetails, setIsRiskDetails] = useState(false) + const [currentDetails, setCurrentDetails] = useState({} as HighMiddleData) + + useEffect(() => { + if (isChina) { + setVisible(true) + processList() + } + }, [isChina, list, allData]) + + const processList = () => { + const temp = list.map((l) => ({ + ...l, + value: Number(l.value), + econNum: Number(l.econNum), + deathNum: Number(l.deathNum), + cureNum: Number(l.cureNum), + jwsrNum: Number(l.jwsrNum), + asymNum: l.asymNum ? Number(l.asymNum) : 0, + conadd: isNaN(Number(l.conadd)) ? 0 : Number(l.conadd), + city: l.city.map((c) => ({ + ...c, + conNum: Number(c.conNum), + econNum: Number(c.econNum), + deathNum: Number(c.deathNum), + cureNum: Number(c.cureNum), + asymNum: c.asymNum ? Number(c.asymNum) : 0, + conadd: isNaN(Number(c.conadd)) ? 0 : Number(c.conadd), + zerodays: Number(c.zerodays), + })), + })) + + temp.forEach((t) => { + allData.highAndMiddle?.forEach((h) => { + if (h.province && t.name.includes(h.province.slice(0, 2))) { + t.isHM = true + t.highAndMiddle = h + } + }) + }) + + setTabData(temp) + } + + const handleClose = () => { + setVisible(false) + onClose() + } + + const enterSearch = (e: React.KeyboardEvent) => { + if (e.key === 'Enter') { + const matchStr = nameValue + if (matchStr === '') { + processList() + return + } + const filtered = tabData.filter((s) => s.name.includes(matchStr)) + setTabData(filtered) + } + } + + const clickXlsxBtn = (type: string, name: string, data: any) => { + let tabObj = {} + if (type === 'province') { + tabObj = { + fileName: '国内疫情数据', + tabHead: ['省份', '累计数', '现存确诊', '死亡数', '治愈数', '较昨日新增数', '境外输入'], + keyList: ['name', 'value', 'econNum', 'deathNum', 'cureNum', 'conadd', 'jwsrNum'], + tabData: tabData, + } + } + if (type === 'city') { + tabObj = { + fileName: name + '疫情数据', + tabHead: ['市/区', '累计数', '现存确诊', '死亡数', '治愈数', '较昨日新增数', '0增天数'], + keyList: ['name', 'conNum', 'econNum', 'deathNum', 'cureNum', 'conadd', 'zerodays'], + tabData: data, + } + } + if (window.confirm('确认下载疫情表格?')) { + downloadXlsx(tabObj as any) + } + } + + const clickMore = (moreData: HighMiddleData) => { + setIsRiskDetails(true) + setCurrentDetails(moreData) + } + + const expandedRowRender = (record: ProvinceData) => ( +
+ +
+ + ) + + const cityColumns = [ + { title: '序号', key: 'index', render: (_: any, __: any, index: number) => index + 1, width: 100 }, + { title: '市/区', dataIndex: 'name', key: 'name' }, + { title: '累计数', dataIndex: 'conNum', key: 'conNum', sorter: (a: CityData, b: CityData) => a.conNum - b.conNum }, + { title: '现存确诊', dataIndex: 'econNum', key: 'econNum', sorter: (a: CityData, b: CityData) => a.econNum - b.econNum }, + { title: '死亡数', dataIndex: 'deathNum', key: 'deathNum', sorter: (a: CityData, b: CityData) => a.deathNum - b.deathNum }, + { title: '治愈数', dataIndex: 'cureNum', key: 'cureNum', sorter: (a: CityData, b: CityData) => a.cureNum - b.cureNum }, + { title: '较昨日新增数', dataIndex: 'conadd', key: 'conadd', sorter: (a: CityData, b: CityData) => a.conadd - b.conadd }, + { title: '0增天数', dataIndex: 'zerodays', key: 'zerodays', sorter: (a: CityData, b: CityData) => a.zerodays - b.zerodays }, + ] + + const columns = [ + { title: '序号', key: 'index', render: (_: any, __: any, index: number) => index + 1, width: 100 }, + { title: '省份', dataIndex: 'name', key: 'name' }, + { + title: '累计数', + dataIndex: 'value', + key: 'value', + sorter: (a: ProvinceData, b: ProvinceData) => a.value - b.value, + }, + { + title: '现存确诊', + dataIndex: 'econNum', + key: 'econNum', + sorter: (a: ProvinceData, b: ProvinceData) => a.econNum - b.econNum, + }, + { + title: '死亡数', + dataIndex: 'deathNum', + key: 'deathNum', + sorter: (a: ProvinceData, b: ProvinceData) => a.deathNum - b.deathNum, + }, + { + title: '治愈数', + dataIndex: 'cureNum', + key: 'cureNum', + sorter: (a: ProvinceData, b: ProvinceData) => a.cureNum - b.cureNum, + }, + { + title: '较昨日新增数', + dataIndex: 'conadd', + key: 'conadd', + sorter: (a: ProvinceData, b: ProvinceData) => a.conadd - b.conadd, + }, + { + title: '境外输入', + dataIndex: 'jwsrNum', + key: 'jwsrNum', + sorter: (a: ProvinceData, b: ProvinceData) => a.jwsrNum - b.jwsrNum, + }, + { + title: '风险地', + key: 'risk', + render: (_: any, record: ProvinceData) => { + if (record.isHM && record.highAndMiddle) { + return ( + + {record.highAndMiddle.province_total}个 + + + ) + } + return 0个或未公布 + }, + }, + ] + + return ( +
+ +
+
+
+ setNameValue(e.target.value)} + onKeyUp={enterSearch} + size="small" + placeholder="输入省名回车检索" + /> +
+ +
+ +
+
+ + setIsRiskDetails(false)} + /> + + ) +} + +export default ChinaTabDrawer diff --git a/src/views/ChinaTabDrawer.vue b/src/views/ChinaTabDrawer.vue deleted file mode 100644 index 0abe803..0000000 --- a/src/views/ChinaTabDrawer.vue +++ /dev/null @@ -1,293 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/views/HomeView.scss b/src/views/HomeView.scss new file mode 100644 index 0000000..3e16b0a --- /dev/null +++ b/src/views/HomeView.scss @@ -0,0 +1,22 @@ +.home { + height: 100vh; + width: 100vw; + color: #fff; + background-color: #000; +} + +.home ::-webkit-scrollbar { + width: 5px; +} + +.home ::-webkit-scrollbar-track { + background-color: rgba(255, 255, 255, 0.2); +} + +.home ::-webkit-scrollbar-thumb { + background-color: rgba(255, 255, 255, 0.5); +} + +.home ::-webkit-scrollbar-thumb:hover { + background-color: rgba(255, 255, 255, 1); +} diff --git a/src/views/HomeView.tsx b/src/views/HomeView.tsx new file mode 100644 index 0000000..77bbc2c --- /dev/null +++ b/src/views/HomeView.tsx @@ -0,0 +1,13 @@ +import React from 'react' +import Sphere from './Sphere' +import './HomeView.scss' + +const HomeView: React.FC = () => { + return ( +
+ +
+ ) +} + +export default HomeView diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue deleted file mode 100644 index d3915be..0000000 --- a/src/views/HomeView.vue +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/views/ProvinceEchartDrawer.scss b/src/views/ProvinceEchartDrawer.scss new file mode 100644 index 0000000..a6035e9 --- /dev/null +++ b/src/views/ProvinceEchartDrawer.scss @@ -0,0 +1,142 @@ +.province-echart-drawer { + height: 100vh; + background-color: rgba(0, 0, 0, 0.8); + color: #fff; +} + +.province-echart-drawer .my-header { + z-index: 5; + position: absolute; + top: 0; + width: 100%; + background-color: rgba(0, 0, 0, 0.8); + display: flex; + justify-content: space-between; + align-items: center; +} + +.province-echart-drawer .my-header .header-title { + font-size: 20px; + font-weight: 900; + display: flex; + justify-content: center; + align-items: center; +} + +.province-echart-drawer .my-header .header-title .anticon { + margin-right: 10px; + color: #1890ff; +} + +.province-echart-drawer .my-header .header-num div { + width: 100%; + display: flex; + justify-content: flex-end; + align-items: center; +} + +.province-echart-drawer .my-header .header-num div span { + color: #ffd889; + font-size: 18px; + margin: 0 5px; + font-weight: 900; +} + +.province-echart-drawer .my-header .header-num div span:nth-child(3) { + color: #66f68f; +} + +.province-echart-drawer .my-header .header-num div span:nth-child(5) { + color: #ff6a6a; +} + +.province-echart-drawer .my-content { + height: 100%; + width: 100%; + background-color: #000; +} + +.province-echart-drawer .my-content .btn-div { + position: absolute; + top: 55px; + z-index: 5; + width: 45%; + margin: 0 28%; + height: auto; + text-align: center; +} + +.province-echart-drawer .my-content .btn-div .btn { + color: #fff; + margin: 10px; + border-radius: 0; +} + +.province-echart-drawer .my-content .btn-div .btn img { + height: 20px; + margin-right: 10px; +} + +.province-echart-drawer .my-content .left-div, +.province-echart-drawer .my-content .right-div { + position: absolute; + top: 0; + padding: 70px 0 10px 0; + height: 100%; + overflow: auto; + border: 2px solid rgba(255, 255, 255, 0.2); +} + +.province-echart-drawer .my-content .left-div { + width: 25%; + left: 5px; +} + +.province-echart-drawer .my-content .right-div { + width: 70%; + right: 5px; +} + +.province-echart-drawer .my-content .right-div .echart-div, +.province-echart-drawer .my-content .right-div .table-div { + height: 100%; + width: 100%; + padding: 20px; +} + +.province-echart-drawer .my-content .right-div .echart-div .pro-his-echart { + height: 100%; + width: 100%; +} + +.province-echart-drawer .my-content .right-div .table-div .ant-table-thead > tr > th { + background-color: rgba(0, 0, 0, 0.6); + color: #fff; + border-bottom: 1px solid #303030; +} + +.province-echart-drawer .my-content .right-div .table-div .ant-table-tbody > tr > td { + border-bottom: 1px solid #303030; +} + +.province-echart-drawer .my-content .right-div .table-div .ant-table-tbody > tr:hover > td { + background: rgba(0, 0, 0, 0.6); +} + +.province-echart-drawer .my-content .right-div .table-div .ant-table { + background-color: transparent; + color: #fff; +} + +.province-echart-drawer .my-content .right-div .table-div .ant-table::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +.province-echart-drawer .my-content .right-div .table-div .ant-table::-webkit-scrollbar-track { + background-color: rgba(255, 255, 255, 0.2); +} + +.province-echart-drawer .my-content .right-div .table-div .ant-table::-webkit-scrollbar-thumb { + background-color: rgba(255, 255, 255, 0.5); +} diff --git a/src/views/ProvinceEchartDrawer.tsx b/src/views/ProvinceEchartDrawer.tsx new file mode 100644 index 0000000..e0f24ed --- /dev/null +++ b/src/views/ProvinceEchartDrawer.tsx @@ -0,0 +1,716 @@ +import React, { useState, useEffect, useRef } from 'react' +import { Drawer, Table, Button } from 'antd' +import { CloseOutlined, BarChartOutlined, UnorderedListOutlined } from '@ant-design/icons' +import * as echarts from 'echarts' +import AddNumber from '@/components/AddNumber' +import { autoToolTip } from '@/utils/echartsAutoTooltip' +import './ProvinceEchartDrawer.scss' + +interface CityData { + name: string + conNum: number + econNum: number + deathNum: number + cureNum: number + conadd: number + zerodays: number + asymNum?: number +} + +interface HistoryListItem { + ymd: string + conNum: number + econNum: number + deathNum: number + cureNum: number + conadd: number +} + +interface AddDaily { + econadd?: number + cureadd?: number + conadd?: number + conadd_n?: number +} + +interface ProvinceData { + province?: string + contotal?: number + econNum?: number + curetotal?: number + deathtotal?: number + locIncrNum?: number + asymptomtotal?: number + adddaily?: AddDaily + city?: CityData[] + historylist?: HistoryListItem[] +} + +interface ProvinceEchartDrawerProps { + dvColor: string[] + isProvinceEchartDrawer: boolean + currentProvinceData: ProvinceData + onClose: () => void +} + +const ProvinceEchartDrawer: React.FC = ({ + dvColor, + isProvinceEchartDrawer, + currentProvinceData, + onClose, +}) => { + const [visible, setVisible] = useState(false) + const [isProHisEchart, setIsProHisEchart] = useState(true) + const [provinceBaseData, setProvinceBaseData] = useState({}) + const [provinceData, setProvinceData] = useState([]) + + const rightEchartRef = useRef(null) + const historyEchartRef = useRef(null) + const chartsRef = useRef<{ proHisEchart?: echarts.ECharts; historyEchart?: echarts.ECharts }>({}) + + useEffect(() => { + if (isProvinceEchartDrawer) { + setVisible(true) + processData() + setTimeout(() => { + initEchart() + }, 100) + window.addEventListener('resize', initEchart) + } else { + setProvinceBaseData({ + contotal: 0, + econNum: 0, + curetotal: 0, + deathtotal: 0, + }) + } + return () => { + window.removeEventListener('resize', initEchart) + if (chartsRef.current.proHisEchart) chartsRef.current.proHisEchart.dispose() + if (chartsRef.current.historyEchart) chartsRef.current.historyEchart.dispose() + } + }, [isProvinceEchartDrawer]) + + const handleClose = () => { + setVisible(false) + onClose() + } + + const processData = () => { + const data = currentProvinceData + setProvinceBaseData({ + province: data.province, + contotal: Number(data.contotal), + econNum: Number(data.econNum), + curetotal: Number(data.curetotal), + deathtotal: Number(data.deathtotal), + locIncrNum: Number(data.locIncrNum), + asymptomtotal: Number(data.asymptomtotal), + econadd: data.adddaily?.econadd, + cureadd: data.adddaily?.cureadd, + conadd: data.adddaily?.conadd, + conadd_n: data.adddaily?.conadd_n, + }) + + if (data.city) { + const processed = data.city.map((c) => ({ + ...c, + conNum: Number(c.conNum), + econNum: Number(c.econNum), + deathNum: Number(c.deathNum), + cureNum: Number(c.cureNum), + conadd: isNaN(Number(c.conadd)) ? 0 : Number(c.conadd), + })) + setProvinceData(processed) + } + } + + const clickEchartBtn = () => { + setIsProHisEchart(true) + proHisEchartFun() + } + + const initEchart = () => { + setIsProHisEchart(true) + proHisEchartFun() + historyEchartFun() + } + + const proHisEchartFun = () => { + if (!rightEchartRef.current || !provinceData.length) return + + const echartData: any = { + cityName: [], + conNum: [], + econNum: [], + deathNum: [], + cureNum: [], + conadd: [], + } + + provinceData.forEach((p) => { + echartData.cityName.push(p.name) + echartData.conNum.push(p.conNum) + echartData.econNum.push(p.econNum) + echartData.deathNum.push(p.deathNum) + echartData.cureNum.push(p.cureNum) + echartData.conadd.push(p.conadd) + }) + + if (chartsRef.current.proHisEchart) chartsRef.current.proHisEchart.dispose() + chartsRef.current.proHisEchart = echarts.init(rightEchartRef.current) + + const option: echarts.EChartsOption = { + title: { + text: provinceBaseData.province + '各地数据', + left: 'center', + top: '5%', + textStyle: { + color: '#fff', + }, + }, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'shadow', + }, + }, + dataZoom: [ + { + type: 'inside', + }, + { + show: true, + yAxisIndex: 0, + filterMode: 'empty', + width: 25, + height: '70%', + showDataShadow: false, + left: '3%', + top: 'center', + }, + ], + legend: { + icon: 'rect', + data: ['累计数', '治愈数', '确诊数', '较昨日新增', '死亡数'], + orient: 'vertical', + top: '15%', + right: '2%', + textStyle: { + color: '#fff', + }, + }, + grid: { + left: '3%', + right: '15%', + bottom: '10%', + containLabel: true, + }, + xAxis: { + type: 'category', + data: echartData.cityName, + axisLabel: { + interval: 0, + rotate: 50, + color: '#fff', + }, + }, + yAxis: { + type: 'value', + axisLabel: { + color: '#fff', + }, + }, + series: [ + { + name: '累计数', + type: 'bar', + animationDuration: 2000, + animationEasing: 'cubicInOut', + emphasis: { + focus: 'series', + }, + itemStyle: { + color: '#f59158', + }, + data: echartData.conNum, + }, + { + name: '治愈数', + type: 'bar', + animationDuration: 2000, + animationEasing: 'cubicInOut', + emphasis: { + focus: 'series', + }, + itemStyle: { + color: '#48c56b', + }, + data: echartData.cureNum, + }, + { + name: '确诊数', + type: 'bar', + stack: 'total', + animationDuration: 2000, + animationEasing: 'cubicInOut', + emphasis: { + focus: 'series', + }, + itemStyle: { + color: '#ffd889', + }, + data: echartData.econNum, + }, + { + name: '较昨日新增', + type: 'bar', + stack: 'total', + animationDuration: 2000, + animationEasing: 'cubicInOut', + emphasis: { + focus: 'series', + }, + itemStyle: { + color: '#9574fb', + }, + data: echartData.conadd, + }, + { + name: '死亡数', + type: 'bar', + stack: 'total', + animationDuration: 2000, + animationEasing: 'cubicInOut', + emphasis: { + focus: 'series', + }, + itemStyle: { + color: '#ff6a6a', + }, + data: echartData.deathNum, + }, + ], + } + + chartsRef.current.proHisEchart.setOption(option) + + autoToolTip(chartsRef.current.proHisEchart, option, { + interval: 1000, + loopSeries: true, + seriesIndex: 0, + }) + } + + const historyEchartFun = () => { + if (!historyEchartRef.current || !currentProvinceData.historylist) return + + const histData = JSON.parse(JSON.stringify(currentProvinceData.historylist)) + histData.reverse() + + if (chartsRef.current.historyEchart) chartsRef.current.historyEchart.dispose() + chartsRef.current.historyEchart = echarts.init(historyEchartRef.current) + + const echartData: any = { + time: [], + conNum: [], + econNum: [], + deathNum: [], + cureNum: [], + conadd: [], + } + + histData.forEach((h: any) => { + echartData.time.push(h.ymd) + echartData.conNum.push(h.conNum) + echartData.econNum.push(h.econNum) + echartData.deathNum.push(h.deathNum) + echartData.cureNum.push(h.cureNum) + echartData.conadd.push(h.conadd) + }) + + const option: echarts.EChartsOption = { + title: { + text: provinceBaseData.province + '历史数据', + left: 'center', + top: '5%', + textStyle: { + color: '#fff', + }, + }, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'cross', + label: { + backgroundColor: '#6a7985', + }, + }, + }, + legend: { + icon: 'rect', + data: ['累计数', '确诊数', '较昨日新增', '治愈数', '死亡数'], + orient: 'vertical', + top: '15%', + right: '2%', + textStyle: { + color: '#fff', + }, + }, + grid: { + left: '8%', + }, + xAxis: [ + { + type: 'category', + boundaryGap: false, + axisLabel: { + color: '#fff', + }, + data: echartData.time, + }, + ], + yAxis: [ + { + type: 'value', + axisLabel: { + color: '#fff', + }, + }, + ], + dataZoom: [ + { + startValue: '', + }, + { + type: 'inside', + }, + ], + series: [ + { + name: '累计数', + type: 'line', + animationDuration: 2000, + animationEasing: 'cubicInOut', + stack: 'Total', + smooth: true, + lineStyle: { + width: 1, + }, + showSymbol: false, + areaStyle: { + opacity: 0.8, + color: new echarts.graphic.LinearGradient(1, 0, 1, 1, [ + { offset: 0, color: '#f59158' }, + { offset: 1, color: '#ffffff' }, + ]), + }, + emphasis: { + focus: 'series', + }, + itemStyle: { + color: '#f59158', + }, + data: echartData.conNum, + }, + { + name: '确诊数', + type: 'line', + animationDuration: 2000, + animationEasing: 'cubicInOut', + stack: 'Total', + smooth: true, + lineStyle: { + width: 1, + }, + showSymbol: false, + areaStyle: { + opacity: 0.8, + color: new echarts.graphic.LinearGradient(1, 0, 1, 1, [ + { offset: 0, color: '#ffd889' }, + { offset: 1, color: '#ffffff' }, + ]), + }, + itemStyle: { + color: '#ffd889', + }, + emphasis: { + focus: 'series', + }, + data: echartData.econNum, + }, + { + name: '较昨日新增', + type: 'line', + animationDuration: 2000, + animationEasing: 'cubicInOut', + stack: 'Total', + smooth: true, + lineStyle: { + width: 1, + }, + showSymbol: false, + label: { + show: true, + position: 'top', + }, + areaStyle: { + opacity: 0.8, + color: new echarts.graphic.LinearGradient(1, 0, 1, 1, [ + { offset: 0, color: '#9574fb' }, + { offset: 1, color: '#ffffff' }, + ]), + }, + itemStyle: { + color: '#794ebd', + }, + emphasis: { + focus: 'series', + }, + data: echartData.conadd, + }, + { + name: '治愈数', + type: 'line', + animationDuration: 2000, + animationEasing: 'cubicInOut', + stack: 'Total', + smooth: true, + lineStyle: { + width: 1, + }, + showSymbol: false, + areaStyle: { + opacity: 0.8, + color: new echarts.graphic.LinearGradient(1, 0, 1, 1, [ + { offset: 0, color: '#48c56b' }, + { offset: 1, color: '#ffffff' }, + ]), + }, + itemStyle: { + color: '#48c56b', + }, + emphasis: { + focus: 'series', + }, + data: echartData.cureNum, + }, + { + name: '死亡数', + type: 'line', + animationDuration: 2000, + animationEasing: 'cubicInOut', + stack: 'Total', + smooth: true, + lineStyle: { + width: 1, + }, + showSymbol: false, + areaStyle: { + opacity: 0.8, + color: new echarts.graphic.LinearGradient(1, 0, 1, 1, [ + { offset: 0, color: '#ff6a6a' }, + { offset: 1, color: '#ffffff' }, + ]), + }, + itemStyle: { + color: '#ff6a6a', + }, + emphasis: { + focus: 'series', + }, + data: echartData.deathNum, + }, + ], + } + + chartsRef.current.historyEchart.setOption(option) + } + + const columns = [ + { title: '序号', key: 'index', render: (_: any, __: any, index: number) => index + 1, width: 100 }, + { title: '市/区', dataIndex: 'name', key: 'name' }, + { title: '累计数', dataIndex: 'conNum', key: 'conNum', sorter: (a: CityData, b: CityData) => a.conNum - b.conNum }, + { title: '确诊数', dataIndex: 'econNum', key: 'econNum', sorter: (a: CityData, b: CityData) => a.econNum - b.econNum }, + { title: '死亡数', dataIndex: 'deathNum', key: 'deathNum', sorter: (a: CityData, b: CityData) => a.deathNum - b.deathNum }, + { title: '治愈数', dataIndex: 'cureNum', key: 'cureNum', sorter: (a: CityData, b: CityData) => a.cureNum - b.cureNum }, + { title: '较昨日新增', dataIndex: 'conadd', key: 'conadd', sorter: (a: CityData, b: CityData) => a.conadd - b.conadd }, + ] + + return ( +
+ +
+ 省内分析 + +
+
+
+
+
+
+

{provinceBaseData.province}

+
+
+

+ 累计: + + (今日{provinceBaseData.conadd}) +

+

+ 现存: + + (今日{provinceBaseData.econadd}) +

+

+ 治愈: + + (今日{provinceBaseData.cureadd}) +

+

+ 较昨日新增: + {!isNaN(Number(provinceBaseData.conadd_n)) && provinceBaseData.conadd_n !== undefined ? ( + + ) : ( + provinceBaseData.conadd_n + )} +

+

+ 死亡: + +

+
+
+
+ +
+ {isProHisEchart ? ( +
+ ) : ( +
+

{provinceBaseData.province}各地数据

+
+ + )} +
+ + +
+ + + +
+
+
+
+ + + ) +} + +export default ProvinceEchartDrawer diff --git a/src/views/ProvinceEchartDrawer.vue b/src/views/ProvinceEchartDrawer.vue deleted file mode 100644 index 9f7e2a8..0000000 --- a/src/views/ProvinceEchartDrawer.vue +++ /dev/null @@ -1,715 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/views/ReportDrawer.scss b/src/views/ReportDrawer.scss new file mode 100644 index 0000000..e4b16ae --- /dev/null +++ b/src/views/ReportDrawer.scss @@ -0,0 +1,26 @@ +.reportDrawer-div { + --el-bg-color: rgba(0, 0, 0, 0.8); + padding: 0; + text-align: center; + user-select: none; +} + +.reportDrawer-div ::-webkit-scrollbar { + width: 15px !important; +} + +.reportDrawer-div ::-webkit-scrollbar-track { + background-color: rgba(0, 0, 0, 0.2) !important; +} + +.reportDrawer-div ::-webkit-scrollbar-thumb { + background-color: rgba(0, 0, 0, 0.5) !important; +} + +.reportDrawer-div .docx-dv { + background-color: transparent; +} + +.reportDrawer-div #docx-con { + background-color: #fff; +} diff --git a/src/views/ReportDrawer.tsx b/src/views/ReportDrawer.tsx new file mode 100644 index 0000000..af0ef73 --- /dev/null +++ b/src/views/ReportDrawer.tsx @@ -0,0 +1,115 @@ +import React, { useState, useEffect, useRef } from 'react' +import { Drawer, Button } from 'antd' +import { DownloadOutlined } from '@ant-design/icons' +import { saveAs } from 'file-saver' +import { renderAsync } from 'docx-preview' +import './ReportDrawer.scss' + +interface ReportData { + blobData: Blob | null + fileName: string | null +} + +interface ReportDrawerProps { + dvColor: string[] + isReport: boolean + reportData: ReportData + onClose: () => void +} + +const ReportDrawer: React.FC = ({ dvColor, isReport, reportData, onClose }) => { + const [visible, setVisible] = useState(false) + const docxRef = useRef(null) + + useEffect(() => { + if (isReport) { + setVisible(true) + setTimeout(() => { + previewReport() + }, 0) + } else { + if (docxRef.current) { + docxRef.current.innerHTML = '' + } + } + }, [isReport, reportData]) + + const handleClose = () => { + setVisible(false) + onClose() + } + + const previewReport = () => { + if (reportData.blobData && docxRef.current) { + docxRef.current.innerHTML = '' + renderAsync(reportData.blobData, docxRef.current, undefined, { + className: 'docx', + inWrapper: false, + ignoreWidth: false, + ignoreHeight: false, + }) + } + } + + const downloadReport = () => { + if (window.confirm('确认生成并下载当地疫情报告?')) { + if (reportData.blobData && reportData.fileName) { + saveAs(reportData.blobData, reportData.fileName) + } + } + } + + return ( +
+ +
+
+
+
+ +
+ +
+ ) +} + +export default ReportDrawer diff --git a/src/views/ReportDrawer.vue b/src/views/ReportDrawer.vue deleted file mode 100644 index 318ae6f..0000000 --- a/src/views/ReportDrawer.vue +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/views/Sphere.scss b/src/views/Sphere.scss new file mode 100644 index 0000000..2de3f0c --- /dev/null +++ b/src/views/Sphere.scss @@ -0,0 +1,208 @@ +.sphere-container { + height: 100%; + width: 100%; + color: #fff; + background-color: #000; + position: relative; +} + +.sphere-container .top-div { + pointer-events: none; + width: 98%; + margin: 0 1%; + position: absolute; + right: 0; + z-index: 5; + color: #fff; +} + +.sphere-container .top-div .name-div { + margin: 15px 0 0 0; + display: flex; + justify-content: center; + align-items: center; +} + +.sphere-container .top-div .name-div .sys-name { + height: 60px; + width: 250px; + font-size: 25px; + font-weight: 900; + margin: 0 10vw; + display: flex; + justify-content: center; + align-items: center; +} + +.sphere-container .top-div .sys-msg { + height: 100%; + font-weight: 900; + margin: 0 auto; + text-align: center; + padding: 10px; +} + +.sphere-container .top-div .sys-msg span { + margin: 0 20px; +} + +.sphere-container #sphereDiv { + position: absolute; + top: 15px; + margin: 0 1%; + height: calc(100% - 25px); + width: 98%; + cursor: move; +} + +.sphere-container .sphereDataDiv { + text-align: center; + pointer-events: none; + position: absolute; + z-index: 5; + height: 74vh; + min-width: 250px; + width: 25vw; + margin: 15vh 0 0 5px; + border: 2px solid rgba(255, 255, 255, 0.2); +} + +.sphere-container .sphereDataDiv p { + font-size: 20px; + font-weight: 900; + margin-top: 10px; + margin-bottom: 30px; +} + +.sphere-container .sphereDataDiv .histogramDivDiv { + height: calc(100% - 100px); + width: 100%; + overflow: auto; + pointer-events: auto; +} + +.sphere-container .sphereDataDiv #histogramDiv { + height: 1500px; + width: 100%; +} + +.sphere-container .set-div { + position: absolute; + bottom: 0; + z-index: 5; + margin: 30px; +} + +.sphere-container .set-div .anticon { + transition: all 0.3s linear; +} + +.sphere-container .set-div .anticon:hover { + transform: rotateZ(180deg); + color: #fff; +} + +.sphere-container .numDiv { + pointer-events: none; + position: absolute; + right: 10px; + z-index: 5; + min-width: 300px; + width: 20vw; + height: 74vh; + margin: 15vh 0 0 0; + display: flex; + padding-left: 20px; + border: 2px solid rgba(255, 255, 255, 0.2); +} + +.sphere-container .numDiv .addconDiv, +.sphere-container .numDiv .addcureDiv, +.sphere-container .numDiv .addDieDiv { + height: 31%; + margin: auto 0; + text-align: center; + color: #fff; + font-weight: 900; +} + +.sphere-container .numDiv .addconDiv .tit, +.sphere-container .numDiv .addcureDiv .tit, +.sphere-container .numDiv .addDieDiv .tit { + font-size: 20px; +} + +.sphere-container .numDiv .addconDiv .day-tit, +.sphere-container .numDiv .addcureDiv .day-tit, +.sphere-container .numDiv .addDieDiv .day-tit { + font-size: 20px; +} + +.sphere-container .numDiv .addconDiv { + border-top-left-radius: 30px; + display: flex; + flex-direction: column; + padding-top: 5vh; +} + +.sphere-container .numDiv .addconDiv .tit, +.sphere-container .numDiv .addconDiv .day-tit { + margin: 5px 20px; + padding-right: 10px; + color: #ffd889; +} + +.sphere-container .numDiv .addDieDiv { + border-bottom-left-radius: 30px; + display: flex; + flex-direction: column; +} + +.sphere-container .numDiv .addDieDiv .tit, +.sphere-container .numDiv .addDieDiv .day-tit { + margin: 5px 20px; + padding-right: 10px; + color: #ff6a6a; +} + +.sphere-container .numDiv .addcureDiv { + display: flex; + flex-direction: column; +} + +.sphere-container .numDiv .addcureDiv .tit, +.sphere-container .numDiv .addcureDiv .day-tit { + margin: 5px 20px; + padding-right: 10px; + color: #66f68f; +} + +.sphere-container .btn-div { + position: absolute; + bottom: 10px; + z-index: 5; + width: 50%; + height: auto; + text-align: center; + margin: 0 25%; + border: 2px solid rgba(255, 255, 255, 0.2); +} + +.sphere-container .btn-div .btn { + color: #fff; + margin: 10px; + border-radius: 0; +} + +.sphere-container .btn-div .btn img { + height: 20px; + margin-right: 10px; +} + +.sphere-container .ant-spin-container { + height: 100%; +} + +.sphere-container .ant-spin-nested-loading { + height: 100%; +} diff --git a/src/views/Sphere.tsx b/src/views/Sphere.tsx new file mode 100644 index 0000000..c0d827d --- /dev/null +++ b/src/views/Sphere.tsx @@ -0,0 +1,1289 @@ +import React, { useState, useEffect, useRef, useCallback } from 'react' +import { Button, Spin } from 'antd' +import { + UnorderedListOutlined, + BarChartOutlined, + SettingOutlined, +} from '@ant-design/icons' +import * as THREE from 'three' +import { MeshLine, MeshLineMaterial } from 'three.meshline' +import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' +import gsap from 'gsap' +import * as echarts from 'echarts' + +import AddNumber from '@/components/AddNumber' +import PointMsg from '@/components/PointMsg' +import SetDrawer from '@/components/SetDrawer' +import SphereTabDrawer from '@/views/SphereTabDrawer' +import ChinaTabDrawer from '@/views/ChinaTabDrawer' +import ChinaEchartDrawer from '@/views/ChinaEchartDrawer' +import ProvinceEchartDrawer from '@/views/ProvinceEchartDrawer' +import ReportDrawer from '@/views/ReportDrawer' + +import { dataSource1 } from '@/api/request' +import jsonp from '@/utils/jsonpUtils' +import { getWordBlob } from '@/utils/getWordBlob' +import countryPosition from '@/assets/json/countryPosition.json' +import tempData from '@/assets/json/tempWorldData.json' +import tempProvinceData from '@/assets/json/tempProvinceData.json' +import tempIpData from '@/assets/json/tempIpData.json' +import PK from '@/../package.json' + +import universeImg from '@/assets/img/universe.jpg' +import starImg from '@/assets/img/star.jpg' +import earthImg from '@/assets/img/earth.jpg' +import earthNightImg from '@/assets/img/earthNight.jpg' +import ringImg from '@/assets/img/ring_explosion.jpg' +import earthGlowImg from '@/assets/img/earth-glow.jpg' +import normalImg from '@/assets/img/earthNormal.jpg' +import virusImg from '@/assets/img/virus1.png' +import earthGrayscale from '@/assets/img/map_inverted.png' +import wordImg from '@/assets/img/word.png' + +import './Sphere.scss' + +interface CountryData { + name: string + value: number + deathNum: number + cureNum: number + citycode?: string + position?: number[] +} + +interface OtherTotal { + certain?: number + recure?: number + die?: number + certain_inc?: number + recure_inc?: number + die_inc?: number +} + +interface AllData { + mtime?: string + othertotal?: OtherTotal + worldlist?: CountryData[] + list?: any[] + add_daily?: any + jwsrTop?: any[] + historylist?: any[] + highAndMiddle?: any[] + locIncrProTop?: any[] + times?: number + gntotal?: number + curetotal?: number + deathtotal?: number +} + +interface ReportData { + blobData: Blob | null + fileName: string | null +} + +interface SetData { + sphereType: string + isDrag: boolean + isZoom: boolean + isTag: boolean + autoRotate: boolean + rotateSpeed: number + sysVer: string + dataType: string + sysColor: string[] +} + +const Sphere: React.FC = () => { + const [isLoading, setIsLoading] = useState(false) + const [isDrawer, setIsDrawer] = useState(false) + const [isSphere, setIsSphere] = useState(false) + const [isChina, setIsChina] = useState(false) + const [isEchart, setIsEchart] = useState(false) + const [isReport, setIsReport] = useState(false) + const [isProvinceEchartDrawer, setIsProvinceEchartDrawer] = useState(false) + + const [allData, setAllData] = useState({}) + const [sphereData, setSphereData] = useState([]) + const [othertotal, setOthertotal] = useState({}) + const [currentPointData, setCurrentPointData] = useState({}) + const [position, setPosition] = useState({ x: '', y: '' }) + const [dvColor, setDvColor] = useState([]) + const [dataType, setDataType] = useState(null) + + const [certain, setCertain] = useState(0) + const [addcure, setAddcure] = useState(0) + const [addDie, setAddDie] = useState(0) + + const [userMsg, setUserMsg] = useState({}) + const [currentProvinceData, setCurrentProvinceData] = useState({}) + const [reportData, setReportData] = useState({ blobData: null, fileName: null }) + + const sphereDivRef = useRef(null) + const histogramDivRef = useRef(null) + + const sceneRef = useRef(null) + const cameraRef = useRef(null) + const rendererRef = useRef(null) + const orbitControlsRef = useRef(null) + const earthGroupRef = useRef(null) + const animationIdRef = useRef(0) + const histogramChartRef = useRef(null) + + const dotLineRingMeshRef = useRef(null) + const flylineMeshRef = useRef(null) + const expandRingMeshRef = useRef(null) + + const mouse = useRef(new THREE.Vector2()) + const raycaster = useRef(new THREE.Raycaster()) + const earthSize = 100 + const sliceNum = 50 + const sysBackgroundColor = 'rgb(255, 255, 255, .1)' + + const configRef = useRef(null) + + const sysConfig = useCallback(() => { + let setData: SetData = { + sphereType: '粒子', + isDrag: true, + isZoom: true, + isTag: true, + autoRotate: true, + rotateSpeed: 10, + sysVer: PK.version, + dataType: '离线', + sysColor: ['#7b52f7', '#c5b2ff'], + } + + const ss = sessionStorage.getItem('config') + if (ss) { + const savedConfig = JSON.parse(ss) + if (savedConfig.sysVer === PK.version) { + setData = savedConfig + } else { + sessionStorage.setItem('config', JSON.stringify(setData)) + } + } else { + sessionStorage.setItem('config', JSON.stringify(setData)) + } + + configRef.current = setData + setDvColor(setData.sysColor) + return setData + }, []) + + const judgeDevice = useCallback(() => { + const isMobile = navigator.userAgent.match( + /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i + ) + if (isMobile) { + alert('当前项目暂未适配移动端,请在PC端打开!') + } else { + const config = sysConfig() + setDataType(config.dataType) + getCOVID19Data() + } + }, [sysConfig]) + + const decodingStr = (str: string) => { + const repStr = str.replace(/\\/g, '%') + const str1 = repStr.split('jsoncallback(')[1] + const str2 = str1.split(');')[0] + const unStr = decodeURIComponent(str2) + return JSON.parse(unStr) + } + + const getCOVID19Data = useCallback(() => { + setIsLoading(true) + const config = configRef.current + if (config?.dataType === '在线') { + dataSource1() + .then((res) => { + console.log('vue代理dataSource1获取数据') + const decodingObj = decodingStr(res.data) + setAllData(decodingObj.data) + structureData(decodingObj.data) + setIsLoading(false) + }) + .catch(() => { + jsonpGetData() + }) + } else { + console.log('使用tempData数据') + setAllData(tempData.data) + structureData(tempData.data) + setIsLoading(false) + } + }, []) + + const jsonpGetData = () => { + const jsonpUrl = import.meta.env.VITE_APP_1 || '' + const callBackName = 'jsoncallback' + jsonp( + jsonpUrl, + (res: any) => { + if (res.status.msg === 'success') { + console.log('jsonp获取数据') + setAllData(res.data) + structureData(res.data) + } else { + console.log('使用tempData数据') + setAllData(tempData.data) + structureData(tempData.data) + } + setIsLoading(false) + }, + callBackName + ) + } + + const structureData = (COVID19Data: AllData) => { + const worldlist = JSON.parse(JSON.stringify(COVID19Data.worldlist || [])) + worldlist.forEach((w: any) => { + for (const key in countryPosition) { + if (w.name === key) { + w.position = (countryPosition as any)[key] + } + } + w.value = Number(w.value) + w.deathNum = Number(w.deathNum) + w.cureNum = Number(w.cureNum) + }) + setSphereData(worldlist) + if (COVID19Data.othertotal) { + setOthertotal(COVID19Data.othertotal) + } + + if (COVID19Data.list) { + COVID19Data.list.forEach((l: any) => { + l.value = Number(l.value) + l.econNum = Number(l.econNum) + l.deathNum = Number(l.deathNum) + l.cureNum = Number(l.cureNum) + l.jwsrNum = Number(l.jwsrNum) + l.asymptomNum = Number(l.asymptomNum) + if (l.city?.length !== 0) { + l.city?.forEach((c: any) => { + c.conNum = Number(c.conNum) + c.econNum = Number(c.econNum) + c.deathNum = Number(c.deathNum) + c.cureNum = Number(c.cureNum) + c.asymptomNum = Number(c.asymptomNum) + c.zerodays = Number(c.zerodays) + }) + } + }) + } + + init(worldlist) + setTimeout(() => { + initEchart(worldlist, COVID19Data) + }, 500) + } + + const latLongToVector3 = (e: number, a: number, t: number, o: number) => { + const r = (e * Math.PI) / 180 + const i = ((a - 180) * Math.PI) / 180 + const n = -(t + o) * Math.cos(r) * Math.cos(i) + const s = (t + o) * Math.sin(r) + const l = (t + o) * Math.cos(r) * Math.sin(i) + return new THREE.Vector3(n, s, l) + } + + const init = (data: CountryData[]) => { + if (!sphereDivRef.current) return + + const dom = sphereDivRef.current + const width = dom.clientWidth + const height = dom.clientHeight + + const scene = new THREE.Scene() + sceneRef.current = scene + + const camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000) + camera.position.set(0, 50, 350) + camera.lookAt(0, 0, 0) + cameraRef.current = camera + + const renderer = new THREE.WebGLRenderer({ + antialias: true, + alpha: true, + }) + renderer.setClearColor(0x000000, 0.1) + renderer.setSize(width, height) + dom.appendChild(renderer.domElement) + rendererRef.current = renderer + + const earthGroup = new THREE.Group() + earthGroupRef.current = earthGroup + earthGroup.name = '地球组' + + createUniverse(scene) + createStars(scene) + createLight(scene) + createSphere(scene, earthGroup, data) + createOrbitControls(camera, renderer) + render(scene, camera, renderer) + + window.addEventListener('resize', onWindowResize) + } + + const createUniverse = (scene: THREE.Scene) => { + const universeGeometry = new THREE.SphereGeometry(500, 100, 100) + const universeMaterial = new THREE.MeshLambertMaterial({ + map: new THREE.TextureLoader().load(universeImg), + side: THREE.DoubleSide, + }) + const universeMesh = new THREE.Mesh(universeGeometry, universeMaterial) + universeMesh.name = '宇宙' + scene.add(universeMesh) + } + + const createStars = (scene: THREE.Scene) => { + const positions: number[] = [] + const colors: number[] = [] + const starsGeometry = new THREE.BufferGeometry() + + for (let i = 0; i < 1000; i++) { + const vertex = new THREE.Vector3() + vertex.x = Math.random() * 2 - 1 + vertex.y = Math.random() * 2 - 1 + vertex.z = Math.random() * 2 - 1 + positions.push(vertex.x, vertex.y, vertex.z) + const color = new THREE.Color() + color.setRGB(255, 255, 255) + colors.push(color.r, color.g, color.b) + } + + starsGeometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3)) + starsGeometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3)) + + const starsMaterial = new THREE.PointsMaterial({ + map: new THREE.TextureLoader().load(starImg), + size: 4, + blending: THREE.AdditiveBlending, + fog: true, + depthTest: false, + }) + + const starsMesh = new THREE.Points(starsGeometry, starsMaterial) + starsMesh.scale.set(1000, 1000, 1000) + starsMesh.name = '星辰' + scene.add(starsMesh) + } + + const createLight = (scene: THREE.Scene) => { + const lightColor = new THREE.Color(0xffffff) + const ambient = new THREE.AmbientLight(lightColor) + ambient.name = '环境光' + scene.add(ambient) + + const directions = [ + [0, 0, 1000], + [0, 0, -1000], + [1000, 0, 0], + [-1000, 0, 0], + [0, 1000, 0], + [0, -1000, 0], + ] + + directions.forEach((dir) => { + const directionalLight = new THREE.DirectionalLight(lightColor) + directionalLight.position.set(dir[0], dir[1], dir[2]) + scene.add(directionalLight) + }) + } + + const createSphere = (scene: THREE.Scene, earthGroup: THREE.Group, data: CountryData[]) => { + const config = configRef.current + const sphereType = config?.sphereType || '粒子' + + if (sphereType === '粒子') { + createSpotSphere(earthGroup) + } else { + createWBSphere(earthGroup, sphereType) + } + + createVirus(earthGroup, data) + scene.add(earthGroup) + earthGroup.translateY(-8) + } + + const createWBSphere = (earthGroup: THREE.Group, sphereType: string) => { + const earthGeometry = new THREE.SphereGeometry(earthSize, 100, 100) + const nightColor = new THREE.Color(0x999999) + const dayColor = new THREE.Color(0x444444) + + const earthMaterial = new THREE.MeshPhongMaterial({ + map: new THREE.TextureLoader().load(sphereType === '白昼' ? earthImg : earthNightImg), + color: sphereType === '白昼' ? dayColor : nightColor, + normalScale: new THREE.Vector2(0, 5), + normalMap: new THREE.TextureLoader().load(normalImg), + }) + + const earthMesh = new THREE.Mesh(earthGeometry, earthMaterial) + earthMesh.name = '地球' + earthGroup.add(earthMesh) + } + + const createSpotSphere = (earthGroup: THREE.Group) => { + const config = configRef.current + const globeBufferGeometry = new THREE.SphereGeometry(earthSize - 3, 50, 50) + const globeInnerMaterial = new THREE.MeshBasicMaterial({ + color: new THREE.Color(config?.sysColor[0] || '#7b52f7'), + transparent: true, + opacity: 0.4, + fog: new THREE.Fog(0x050505, 2000, 3500), + }) + + const globeInnerMesh = new THREE.Mesh(globeBufferGeometry, globeInnerMaterial) + earthGroup.add(globeInnerMesh) + createSpot(earthGroup) + } + + const createSpot = (earthGroup: THREE.Group) => { + const config = configRef.current + const img = new Image() + img.src = earthGrayscale + + img.onload = () => { + const canvas = document.createElement('canvas') + canvas.width = img.width + canvas.height = img.height + const ctx = canvas.getContext('2d') + if (!ctx) return + + ctx.drawImage(img, 0, 0, img.width, img.height) + const canData = ctx.getImageData(0, 0, canvas.width, canvas.height) + const globeCloudBufferGeometry = new THREE.BufferGeometry() + const globeCloudVerticesArray: THREE.Vector3[] = [] + + for (let o = 0; o < canData.data.length; o += 4) { + const r = (o / 4) % canvas.width + const i = (o / 4 - r) / canvas.width + if ((o / 4) % 2 === 1 && i % 2 === 1) { + if (0 === canData.data[o]) { + const n = r + const longitude = (i / (canvas.height / 180) - 90) / -1 + const latitude = n / (canvas.width / 360) - 180 + const s = latLongToVector3(longitude, latitude, earthSize, 0.1) + globeCloudVerticesArray.push(s) + } + } + } + + const l = new Float32Array(3 * globeCloudVerticesArray.length) + for (let o = 0; o < globeCloudVerticesArray.length; o++) { + l[3 * o] = globeCloudVerticesArray[o].x + l[3 * o + 1] = globeCloudVerticesArray[o].y + l[3 * o + 2] = globeCloudVerticesArray[o].z + } + + const positionVal = new THREE.BufferAttribute(l, 3) + globeCloudBufferGeometry.setAttribute('position', positionVal) + + const globeCloudMaterial = new THREE.PointsMaterial({ + color: new THREE.Color(config?.sysColor[1] || '#c5b2ff'), + fog: true, + size: 1.5, + transparent: false, + }) + + const d = new Float32Array(3 * globeCloudVerticesArray.length) + const c: THREE.Color[] = [] + for (let o = 0; o < globeCloudVerticesArray.length; o++) { + c[o] = new THREE.Color(config?.sysColor[1] || '#c5b2ff') + d[3 * o] = c[o].r + d[3 * o + 1] = c[o].g + d[3 * o + 2] = c[o].b + } + + const color_val = new THREE.BufferAttribute(d, 3) + globeCloudBufferGeometry.setAttribute('color', color_val) + + const globeCloud = new THREE.Points(globeCloudBufferGeometry, globeCloudMaterial) + globeCloud.name = 'globeCloud' + earthGroup.add(globeCloud) + } + } + + const createVirus = (earthGroup: THREE.Group, data: CountryData[]) => { + const colors = [ + new THREE.Color(0xf9b8b8), + new THREE.Color(0xfe4242), + new THREE.Color(0xff0000), + ] + const virSize = 4 + + const list = JSON.parse(JSON.stringify(data)) + list.forEach((e: any) => { + e.value >= 10000000 && (e.color = colors[2]) + e.value >= 500000 && e.value < 10000000 && (e.color = colors[1]) + e.value < 500000 && (e.color = colors[0]) + + if (e.position) { + const virusMaterial = new THREE.SpriteMaterial({ + color: e.color, + map: new THREE.TextureLoader().load(virusImg), + transparent: true, + depthWrite: true, + fog: true, + }) + const Sprite = new THREE.Sprite(virusMaterial) + Sprite.scale.set(virSize, virSize, 1) + + const lat = e.position[1] + const lon = e.position[0] + const s = latLongToVector3(lat, lon, earthSize, 1) + Sprite.position.set(s.x, s.y, s.z) + ;(Sprite as any).dotData = e + Sprite.name = '病毒' + earthGroup.add(Sprite) + } + }) + + createRings(earthGroup) + } + + const createRings = (earthGroup: THREE.Group) => { + const config = configRef.current + const color = config?.sysColor[0] || '#7b52f7' + + createEquatorSolidRing(earthGroup, earthSize + 20, color) + createEquatorFlyline(earthGroup, earthSize + 30, color) + createEquatorDottedLineRing(earthGroup, earthSize + 35) + createSpikes(earthGroup, earthSize + 40, color) + createUpDownRing(earthGroup, earthSize - 50, earthSize - 40, color) + createExpandRing(earthGroup, color) + createSphereGlow(earthGroup, color) + } + + const createEquatorSolidRing = (earthGroup: THREE.Group, r: number, color: string) => { + const ringGeometry = new THREE.RingGeometry(r - 2, r + 2, 100) + const ringMaterial = new THREE.MeshBasicMaterial({ + color: new THREE.Color(color), + opacity: 0.3, + side: THREE.DoubleSide, + fog: true, + depthWrite: false, + blending: THREE.AdditiveBlending, + transparent: true, + }) + const ringMesh = new THREE.Mesh(ringGeometry, ringMaterial) + ringMesh.rotation.x = 90 * Math.PI / 180 + earthGroup.add(ringMesh) + } + + const createEquatorFlyline = (earthGroup: THREE.Group, r: number, color: string) => { + const geometry = new THREE.BufferGeometry() + const path = new THREE.Path() + path.arc(0, 0, r, 0, Math.PI * 2) + const points = path.getPoints(100) + geometry.setFromPoints(points) + + const line = new MeshLine() + line.setGeometry(geometry) + + const material = new MeshLineMaterial({ + color: new THREE.Color(color), + lineWidth: 1, + dashArray: 0.5, + dashRatio: 0.5, + transparent: true, + }) + + const flylineMesh = new THREE.Mesh(line.geometry, material) + flylineMesh.rotation.x = 90 * Math.PI / 180 + flylineMeshRef.current = flylineMesh + earthGroup.add(flylineMesh) + } + + const createEquatorDottedLineRing = (earthGroup: THREE.Group, r: number) => { + const positions: number[] = [] + const ringPointGeometry = new THREE.BufferGeometry() + const pointNum = 50 + const ringPointAngle = (2 * Math.PI) / pointNum + + for (let o = 0; o < 500; o++) { + const n = new THREE.Vector3() + n.x = r * Math.cos(ringPointAngle * o) + n.y = 0 + n.z = r * Math.sin(ringPointAngle * o) + positions.push(n.x, n.y, n.z) + } + + ringPointGeometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3)) + + const config = configRef.current + const ringPointMaterial = new THREE.PointsMaterial({ + size: 3, + transparent: false, + blending: THREE.AdditiveBlending, + side: THREE.DoubleSide, + depthWrite: false, + }) + + const dotLineRingMesh = new THREE.Points(ringPointGeometry, ringPointMaterial) + dotLineRingMesh.name = '赤道虚线' + dotLineRingMeshRef.current = dotLineRingMesh + earthGroup.add(dotLineRingMesh) + } + + const createSpikes = (earthGroup: THREE.Group, spikeRadius: number, color: string) => { + const spikesVerticesArray: THREE.Vector3[] = [] + const spikesObject = new THREE.Group() + spikesObject.name = '赤道尖刺' + earthGroup.add(spikesObject) + + const spikeNum = 400 + const o = (2 * Math.PI) / spikeNum + + for (let s = 0; s < spikeNum; s++) { + const r = new THREE.Vector3() + r.x = spikeRadius * Math.cos(o * s) + r.y = 0 + r.z = spikeRadius * Math.sin(o * s) + r.normalize() + r.multiplyScalar(spikeRadius) + + const i = r.clone() + if (s % 10 === 1) { + i.multiplyScalar(1.1) + } else { + i.multiplyScalar(1.05) + } + + spikesVerticesArray.push(r) + spikesVerticesArray.push(i) + } + + const n = new Float32Array(3 * spikesVerticesArray.length) + for (let s = 0; s < spikesVerticesArray.length; s++) { + n[3 * s] = spikesVerticesArray[s].x + n[3 * s + 1] = spikesVerticesArray[s].y + n[3 * s + 2] = spikesVerticesArray[s].z + } + + const spikesMaterial = new THREE.LineBasicMaterial({ + color: new THREE.Color(color), + transparent: true, + opacity: 0.5, + }) + + const spikesBufferGeometry = new THREE.BufferGeometry() + spikesBufferGeometry.setAttribute('position', new THREE.BufferAttribute(n, 3)) + + const spikesMesh = new THREE.LineSegments(spikesBufferGeometry, spikesMaterial) + spikesObject.add(spikesMesh) + } + + const createUpDownRing = (earthGroup: THREE.Group, r1: number, r2: number, color: string) => { + const ringsObject = new THREE.Group() + ringsObject.name = '南北极环' + earthGroup.add(ringsObject) + + const a = new THREE.RingGeometry(r1, r1 - 2, 100) + const ringsOuterMaterial = new THREE.MeshBasicMaterial({ + color: new THREE.Color(color), + transparent: true, + opacity: 0.3, + side: THREE.DoubleSide, + fog: true, + depthWrite: false, + blending: THREE.AdditiveBlending, + }) + + const o = new THREE.Mesh(a, ringsOuterMaterial) + o.rotation.x = 90 * Math.PI / 180 + const r = o.clone() + o.position.y = 95 + r.position.y = -95 + ringsObject.add(o) + ringsObject.add(r) + + const t = new THREE.RingGeometry(r2, r2 - 2, 100) + const ringsInnerMaterial = new THREE.MeshBasicMaterial({ + color: new THREE.Color(color), + transparent: true, + opacity: 0.3, + side: THREE.DoubleSide, + fog: true, + depthWrite: false, + blending: THREE.AdditiveBlending, + }) + + const i = new THREE.Mesh(t, ringsInnerMaterial) + i.rotation.x = 90 * Math.PI / 180 + const n = i.clone() + i.position.y = 100 + n.position.y = -100 + ringsObject.add(i) + ringsObject.add(n) + } + + const createExpandRing = (earthGroup: THREE.Group, color: string) => { + const ringMaterial = new THREE.MeshBasicMaterial({ + map: new THREE.TextureLoader().load(ringImg), + color: new THREE.Color(color), + transparent: true, + opacity: 1, + side: THREE.DoubleSide, + fog: true, + depthWrite: false, + blending: THREE.AdditiveBlending, + }) + + const ringGeometry = new THREE.PlaneGeometry(earthSize * 2, earthSize * 2, 10, 10) + const expandRingMesh = new THREE.Mesh(ringGeometry, ringMaterial) + expandRingMesh.name = '放大环' + expandRingMesh.rotation.x = 90 * Math.PI / 180 + expandRingMeshRef.current = expandRingMesh + earthGroup.add(expandRingMesh) + } + + const createSphereGlow = (earthGroup: THREE.Group, color: string) => { + const glowMaterial = new THREE.SpriteMaterial({ + map: new THREE.TextureLoader().load(earthGlowImg), + color: new THREE.Color(color), + transparent: true, + opacity: 1, + side: THREE.DoubleSide, + fog: true, + depthWrite: false, + blending: THREE.AdditiveBlending, + }) + + const glowSprite = new THREE.Sprite(glowMaterial) + glowSprite.scale.set(earthSize * 3.2, earthSize * 3.2, 1) + earthGroup.add(glowSprite) + } + + const createOrbitControls = (camera: THREE.Camera, renderer: THREE.WebGLRenderer) => { + const config = configRef.current + const orbitControls = new OrbitControls(camera, renderer.domElement) + orbitControls.autoRotate = config?.autoRotate || true + orbitControls.enableRotate = config?.isDrag !== false + orbitControls.enableZoom = config?.isZoom !== false + orbitControls.autoRotateSpeed = (config?.rotateSpeed || 10) / 10 + orbitControls.enablePan = false + orbitControls.enableDamping = true + orbitControls.dampingFactor = 0.05 + orbitControls.minDistance = 250 + orbitControls.maxDistance = 400 + orbitControlsRef.current = orbitControls + } + + const createExpandRingAnimation = () => { + if (!expandRingMeshRef.current) return + + if (!gsap.isTweening(expandRingMeshRef.current.scale)) { + gsap.fromTo( + expandRingMeshRef.current.scale, + { x: 1, y: 1 }, + { x: 2.7, y: 2.7, duration: 1.5 } + ) + gsap.fromTo( + expandRingMeshRef.current.material, + { opacity: 1 }, + { opacity: 0, duration: 1.5 } + ) + } + } + + const render = (scene: THREE.Scene, camera: THREE.Camera, renderer: THREE.WebGLRenderer) => { + const animate = () => { + animationIdRef.current = requestAnimationFrame(animate) + + if (sphereDivRef.current) { + sphereDivRef.current.addEventListener('mousemove', onMousemove, false) + } + + if (orbitControlsRef.current) { + orbitControlsRef.current.update() + } + + if (dotLineRingMeshRef.current) { + dotLineRingMeshRef.current.rotation.y += 5 + } + if (flylineMeshRef.current) { + flylineMeshRef.current.rotation.z -= 0.15 + } + + createExpandRingAnimation() + renderer.render(scene, camera) + } + + animate() + } + + const onMousemove = (e: MouseEvent) => { + if (!sphereDivRef.current || !cameraRef.current || !sceneRef.current) return + + const dom = sphereDivRef.current + const width = dom.clientWidth + const height = dom.clientHeight + + mouse.current.x = (e.offsetX / width) * 2 - 1 + mouse.current.y = -(e.offsetY / height) * 2 + 1 + + raycaster.current.setFromCamera(mouse.current, cameraRef.current) + const intersects = raycaster.current.intersectObjects(sceneRef.current.children, true) + + const config = configRef.current + if (intersects.length !== 0 && intersects[0].object.name === '病毒') { + if (config?.isTag) { + setCurrentPointData((intersects[0].object as any).dotData || {}) + } + dom.style.cursor = 'pointer' + setPosition({ + x: e.pageX + 20 + 'px', + y: e.pageY + 'px', + }) + } else { + setCurrentPointData({}) + dom.style.cursor = 'move' + } + } + + const onWindowResize = () => { + if (!cameraRef.current || !rendererRef.current || !sphereDivRef.current) return + + cameraRef.current.aspect = window.innerWidth / window.innerHeight + cameraRef.current.updateProjectionMatrix() + rendererRef.current.setSize(window.innerWidth, window.innerHeight) + initEchart(sphereData, allData) + } + + const sortFun = (arr: any[]) => { + return [...arr].sort((a, b) => Number(b.value) - Number(a.value)) + } + + const initEchart = (data: CountryData[], allDataVal: AllData) => { + const sortList = sortFun(data) + histogramChartFun(sortList.slice(0, sliceNum)) + + if (allDataVal.othertotal) { + setCertain(Number(allDataVal.othertotal.certain || 0)) + setAddcure(Number(allDataVal.othertotal.recure || 0)) + setAddDie(Number(allDataVal.othertotal.die || 0)) + } + } + + const histogramChartFun = (list: any[]) => { + if (!histogramDivRef.current) return + + if (histogramChartRef.current) { + histogramChartRef.current.dispose() + } + + histogramChartRef.current = echarts.init(histogramDivRef.current) + + const option: echarts.EChartsOption = { + backgroundColor: '', + title: { + text: `累计确诊前${sliceNum}国家`, + left: 'center', + top: '3%', + textStyle: { + color: '#fff', + }, + }, + grid: { + top: '0%', + left: '25%', + right: '5%', + bottom: '0%', + }, + xAxis: { + type: 'value', + show: false, + }, + yAxis: { + type: 'category', + axisLabel: { + color: '#fff', + }, + data: [], + }, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'shadow', + }, + backgroundColor: 'rgba(0,0,0,.5)', + textStyle: { + color: '#fff', + fontWeight: 'bolder', + }, + borderWidth: 0, + }, + series: [ + { + data: [], + type: 'bar', + animationDuration: 2000, + animationEasing: 'cubicInOut', + showBackground: true, + backgroundStyle: { + color: sysBackgroundColor, + }, + itemStyle: { + color: new echarts.graphic.LinearGradient(0, 1, 1, 1, [ + { + offset: 0, + color: dvColor[0] || '#7b52f7', + }, + { + offset: 1, + color: '#555', + }, + ]), + }, + label: { + color: '#fff', + fontWeight: 'bolder', + show: true, + align: 'left', + formatter: '{c}', + }, + }, + ], + } + + const yData: string[] = [] + const sData: number[] = [] + list.forEach((l) => { + yData.push(l.name) + sData.push(l.value) + }) + yData.reverse() + sData.reverse() + ;(option.yAxis as any).data = yData + ;(option.series as any)[0].data = sData + + histogramChartRef.current.setOption(option) + } + + const getLocationMsg = () => { + if (dataType === '在线') { + const jsonpUrl = import.meta.env.VITE_APP_3 || '' + jsonp(jsonpUrl, (res: any) => { + setUserMsg(res) + getProvinceData() + }) + } else { + setUserMsg(tempIpData) + getProvinceData() + } + } + + const getProvinceData = () => { + const pro = userMsg.pro + let ePro = '' + + if (dataType === '在线') { + allData.list?.forEach((l: any) => { + if (pro.search(l.name) >= 0) { + ePro = l.ename + } + }) + + jsonp( + import.meta.env.VITE_APP_5 || '', + (res: any) => { + setCurrentProvinceData(res.data) + }, + 'val1', + `mod=province&province=${ePro}` + ) + } else { + setCurrentProvinceData(tempProvinceData.data) + } + } + + const provinceAnalyze = () => { + setIsProvinceEchartDrawer(true) + } + + const openPreview = async () => { + setIsLoading(true) + + const tempData = JSON.parse(JSON.stringify(currentProvinceData)) + const currentDate = currentProvinceData.cachetime?.split(' ')[0] || '' + + const wordData: any = { + wordName: '', + hasCityData: true, + currentDate: currentDate, + version: PK.version, + currentCityData: {}, + overviewData: { + name: tempData.province, + contotal: tempData.contotal, + econNum: tempData.econNum, + curetotal: tempData.curetotal, + deathtotal: tempData.deathtotal, + conadd: tempData.conadd ? tempData.conadd : 0, + }, + tabData: [], + sourceUrl: window.location.href, + } + + tempData.city?.forEach((c: any, index: number) => { + c.index = index + 1 + wordData.tabData.push(c) + if (userMsg.city?.search(c.name) !== -1) { + wordData.hasCityData = true + wordData.currentCityData = c + wordData.wordName = c.name + } + }) + + if (!wordData.wordName) { + wordData.hasCityData = false + wordData.wordName = wordData.overviewData.name + } + + try { + const res = await getWordBlob('docx/word.docx', wordData) + setIsLoading(false) + setReportData({ + fileName: wordData.wordName + '疫情报告.docx', + blobData: res as Blob, + }) + setIsReport(true) + } catch (error) { + setIsLoading(false) + console.error('生成报告失败:', error) + } + } + + const changeSetData = (type: string, setData: SetData) => { + if (type === 'sphereType') { + destroyScene() + init(sphereData) + } else if (type === 'autoRotate' && orbitControlsRef.current) { + orbitControlsRef.current.autoRotate = setData.autoRotate + } else if (type === 'isDrag' && orbitControlsRef.current) { + orbitControlsRef.current.enableRotate = setData.isDrag + } else if (type === 'isZoom' && orbitControlsRef.current) { + orbitControlsRef.current.enableZoom = setData.isZoom + } else if (type === 'rotateSpeed' && orbitControlsRef.current) { + orbitControlsRef.current.autoRotateSpeed = setData.rotateSpeed / 10 + } else if (type === 'dataType') { + window.location.reload() + } + } + + const destroyScene = () => { + if (earthGroupRef.current) { + earthGroupRef.current.translateY(8) + clearGroup(earthGroupRef.current) + } + if (animationIdRef.current) { + cancelAnimationFrame(animationIdRef.current) + } + if (rendererRef.current) { + rendererRef.current.forceContextLoss() + rendererRef.current.dispose() + } + if (sceneRef.current) { + sceneRef.current.clear() + } + if (sphereDivRef.current) { + sphereDivRef.current.innerHTML = '' + } + + sceneRef.current = null + cameraRef.current = null + orbitControlsRef.current = null + rendererRef.current = null + } + + const clearGroup = (group: THREE.Group) => { + const clearCache = (item: any) => { + item.geometry?.dispose() + item.material?.dispose() + } + + const removeObj = (obj: any) => { + const arr = obj.children?.filter((x: any) => x) || [] + arr.forEach((item: any) => { + if (item.children?.length) { + removeObj(item) + } else { + clearCache(item) + item.clear?.() + } + }) + obj.clear?.() + } + + removeObj(group) + } + + useEffect(() => { + judgeDevice() + + return () => { + destroyScene() + if (histogramChartRef.current) { + histogramChartRef.current.dispose() + } + window.removeEventListener('resize', onWindowResize) + } + }, [judgeDevice]) + + useEffect(() => { + if (allData.times) { + getLocationMsg() + } + }, [allData]) + + return ( +
+ +
+
+
疫情可视化
+
+
+ + {dataType}数据截止{allData.mtime} + +
+
+ +
+ +
+

累计确诊前{sliceNum}国家

+
+
+
+
+ +
+ setIsDrawer(true)} + /> +
+ +
+
+
全球现存确诊
+ +
今日{othertotal.certain_inc}
+
+
+
全球累计治愈
+ +
今日{othertotal.recure_inc}
+
+
+
全球累计死亡
+ +
今日{othertotal.die_inc}
+
+
+ +
+ + + + + +
+ + + + setIsDrawer(false)} + onChangeSetData={changeSetData} + /> + + setIsSphere(false)} + /> + + setIsChina(false)} + /> + + setIsEchart(false)} + /> + + setIsProvinceEchartDrawer(false)} + /> + + setIsReport(false)} + /> + +
+ ) +} + +export default Sphere diff --git a/src/views/Sphere.vue b/src/views/Sphere.vue deleted file mode 100644 index 991b594..0000000 --- a/src/views/Sphere.vue +++ /dev/null @@ -1,1351 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/views/SphereTabDrawer.scss b/src/views/SphereTabDrawer.scss new file mode 100644 index 0000000..dbcfaa7 --- /dev/null +++ b/src/views/SphereTabDrawer.scss @@ -0,0 +1,26 @@ +.sphereTab-drawer { + --el-bg-color: rgba(0, 0, 0, 0); +} + +.sphereTab-drawer .ant-table { + background-color: rgba(0, 0, 0, 0.8) !important; +} + +.sphereTab-drawer .ant-table-thead > tr > th { + background-color: #333 !important; + color: #fff !important; +} + +.sphereTab-drawer .ant-table-tbody > tr > td { + color: #fff !important; + border-bottom: 1px solid #333 !important; +} + +.sphereTab-drawer .ant-table-tbody > tr:hover > td { + background-color: #333 !important; +} + +.sphereTab-drawer .close-icon:hover { + color: #fff !important; + transform: rotateZ(180deg); +} diff --git a/src/views/SphereTabDrawer.tsx b/src/views/SphereTabDrawer.tsx new file mode 100644 index 0000000..c7b367c --- /dev/null +++ b/src/views/SphereTabDrawer.tsx @@ -0,0 +1,152 @@ +import React, { useState, useEffect } from 'react' +import { Drawer, Table, Input, Button } from 'antd' +import { CloseOutlined } from '@ant-design/icons' +import './SphereTabDrawer.scss' +import xlsxImg from '@/assets/img/xlsx.png' +import downloadXlsx from '@/utils/xlsxUtils' + +interface CountryData { + name: string + value: number + deathNum: number + cureNum: number + citycode?: string + position?: number[] +} + +interface SphereTabDrawerProps { + dvColor: string[] + isSphere: boolean + sphereData: CountryData[] + onClose: () => void +} + +const SphereTabDrawer: React.FC = ({ dvColor, isSphere, sphereData, onClose }) => { + const [visible, setVisible] = useState(false) + const [tabData, setTabData] = useState([]) + const [nameValue, setNameValue] = useState('') + + useEffect(() => { + if (isSphere) { + setVisible(true) + setTabData(sphereData) + } + }, [isSphere, sphereData]) + + const handleClose = () => { + setVisible(false) + onClose() + } + + const enterSearch = (e: React.KeyboardEvent) => { + if (e.key === 'Enter') { + const matchStr = nameValue + if (matchStr === '') { + setTabData(sphereData) + return + } + const filtered = sphereData.filter((s) => s.name.includes(matchStr)) + setTabData(filtered) + } + } + + const clickXlsxBtn = () => { + const tabObj = { + fileName: '各国疫情数据', + tabHead: ['国家', '累计数', '死亡数', '治愈数', '地区代码', '坐标'], + keyList: ['name', 'value', 'deathNum', 'cureNum', 'citycode', 'position'], + tabData: tabData, + } + if (window.confirm('确认下载全球疫情数据?')) { + downloadXlsx(tabObj) + } + } + + const columns = [ + { title: '序号', key: 'index', render: (_: any, __: any, index: number) => index + 1, width: 100 }, + { title: '国家', dataIndex: 'name', key: 'name' }, + { title: '累计数', dataIndex: 'value', key: 'value', sorter: (a: CountryData, b: CountryData) => a.value - b.value }, + { title: '死亡数', dataIndex: 'deathNum', key: 'deathNum', sorter: (a: CountryData, b: CountryData) => a.deathNum - b.deathNum }, + { title: '治愈数', dataIndex: 'cureNum', key: 'cureNum', sorter: (a: CountryData, b: CountryData) => a.cureNum - b.cureNum }, + { title: '地区代码', dataIndex: 'citycode', key: 'citycode' }, + { + title: '坐标', + key: 'position', + render: (_: any, record: CountryData) => (record.position ? record.position : '-'), + }, + ] + + return ( +
+ +
+
+
+ setNameValue(e.target.value)} + onKeyUp={enterSearch} + size="small" + placeholder="输入国家回车检索" + /> +
+ +
+ +
+
+ + + ) +} + +export default SphereTabDrawer diff --git a/src/views/SphereTabDrawer.vue b/src/views/SphereTabDrawer.vue deleted file mode 100644 index 2d0aaf6..0000000 --- a/src/views/SphereTabDrawer.vue +++ /dev/null @@ -1,165 +0,0 @@ - - - - - \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 9140c60..a103236 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,42 +1,27 @@ { "compilerOptions": { - "target": "esnext", - "module": "esnext", - "strict": true, - "jsx": "preserve", - "moduleResolution": "node", - "experimentalDecorators": true, - "skipLibCheck": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, + "target": "ES2020", "useDefineForClassFields": true, - "sourceMap": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + "strict": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "noFallthroughCasesInSwitch": true, "baseUrl": ".", - "types": [ - "webpack-env", - "element-plus/global" - ], "paths": { - "@/*": [ - "src/*" - ] + "@/*": ["src/*"] }, - "lib": [ - "esnext", - "dom", - "dom.iterable", - "scripthost" - ] + "esModuleInterop": true, + "allowSyntheticDefaultImports": true }, - "include": [ - "src/**/*.ts", - "src/**/*.tsx", - "src/**/*.vue", - "tests/**/*.ts", - "tests/**/*.tsx" - ], - "exclude": [ - "node_modules" - ] -} \ No newline at end of file + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 0000000..42872c5 --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..5dddba8 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,43 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' +import path from 'path' + +export default defineConfig({ + plugins: [react()], + resolve: { + alias: { + '@': path.resolve(__dirname, './src'), + }, + }, + base: './', + server: { + port: 8080, + open: false, + proxy: { + '/dataSource1': { + target: 'https://c.m.163.com/ug/api/wuhan/app/data/list-total', + ws: true, + changeOrigin: true, + pathRewrite: { + '^/dataSource1': '', + }, + }, + '/dataSource2': { + target: 'https://view.inews.qq.com/g2/getOnsInfo', + ws: true, + changeOrigin: true, + pathRewrite: { + '^/dataSource2': '', + }, + }, + '/getIpMsg': { + target: 'https://apis.map.qq.com/ws/location/v1/ip', + ws: true, + changeOrigin: true, + pathRewrite: { + '^/getIpMsg': '', + }, + }, + }, + }, +}) diff --git a/vue.config.js b/vue.config.js deleted file mode 100644 index 1b29b8c..0000000 --- a/vue.config.js +++ /dev/null @@ -1,41 +0,0 @@ -let devProxy = { - //获取疫情数据1 - '/dataSource1': { - target: process.env.VUE_APP_1, - ws: true, - changeOrigin: true, - pathRewrite: { - '/dataSource1': '' - }, - }, - - //获取疫情数据2 - '/dataSource2': { - target: process.env.VUE_APP_2, - ws: true, - changeOrigin: true, - pathRewrite: { - '/dataSource2': '' - }, - }, - - //获取ip信息 - '/getIpMsg': { - target: process.env.VUE_APP_3, - ws: true, - changeOrigin: true, - pathRewrite: { - '/getIpMsg': '' - }, - }, -}; -const { defineConfig } = require('@vue/cli-service') -module.exports = defineConfig({ - transpileDependencies: true, - publicPath: './', - devServer: { - port: 8080,//端口 - open: false,//项目启动后是否在浏览器自动打开 - proxy: devProxy//代理服务器 - }, -}) From d29964ec62ae53ebd603caaaa2255b977e827e2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E4=BD=B3=E5=AE=9D?= <1197995518@qq.com> Date: Mon, 20 Apr 2026 15:34:13 +0800 Subject: [PATCH 3/3] =?UTF-8?q?fix(Sphere):=20=E4=BF=AE=E5=A4=8D=E7=AA=97?= =?UTF-8?q?=E5=8F=A3=E5=A4=A7=E5=B0=8F=E5=8F=98=E5=8C=96=E6=97=B6=E7=9A=84?= =?UTF-8?q?=E5=93=8D=E5=BA=94=E5=BC=8F=E5=B8=83=E5=B1=80=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 调整窗口大小变化时的处理逻辑,确保相机、渲染器和图表正确更新。同时优化移动端样式,添加背景色和响应式媒体查询,提升不同屏幕尺寸下的显示效果。 --- src/views/Sphere.scss | 117 +++++++++++++++++++++++++++++++++++++++++- src/views/Sphere.tsx | 19 +++++-- 2 files changed, 129 insertions(+), 7 deletions(-) diff --git a/src/views/Sphere.scss b/src/views/Sphere.scss index 2de3f0c..87d135d 100644 --- a/src/views/Sphere.scss +++ b/src/views/Sphere.scss @@ -59,12 +59,15 @@ text-align: center; pointer-events: none; position: absolute; + left: 5px; z-index: 5; height: 74vh; min-width: 250px; width: 25vw; - margin: 15vh 0 0 5px; + margin-top: 15vh; border: 2px solid rgba(255, 255, 255, 0.2); + background-color: rgba(0, 0, 0, 0.6); + box-sizing: border-box; } .sphere-container .sphereDataDiv p { @@ -110,10 +113,12 @@ min-width: 300px; width: 20vw; height: 74vh; - margin: 15vh 0 0 0; + margin-top: 15vh; display: flex; padding-left: 20px; border: 2px solid rgba(255, 255, 255, 0.2); + background-color: rgba(0, 0, 0, 0.6); + box-sizing: border-box; } .sphere-container .numDiv .addconDiv, @@ -206,3 +211,111 @@ .sphere-container .ant-spin-nested-loading { height: 100%; } + +@media screen and (max-width: 1200px) { + .sphere-container .sphereDataDiv { + width: 30vw; + min-width: 200px; + } + + .sphere-container .numDiv { + width: 25vw; + min-width: 250px; + } +} + +@media screen and (max-width: 900px) { + .sphere-container .sphereDataDiv { + width: 35vw; + min-width: 180px; + margin-top: 12vh; + height: 50vh; + } + + .sphere-container .numDiv { + width: 35vw; + min-width: 200px; + margin-top: 12vh; + height: 50vh; + padding-left: 10px; + } + + .sphere-container .numDiv .addconDiv, + .sphere-container .numDiv .addcureDiv, + .sphere-container .numDiv .addDieDiv { + height: 30%; + } + + .sphere-container .numDiv .addconDiv .tit, + .sphere-container .numDiv .addcureDiv .tit, + .sphere-container .numDiv .addDieDiv .tit, + .sphere-container .numDiv .addconDiv .day-tit, + .sphere-container .numDiv .addcureDiv .day-tit, + .sphere-container .numDiv .addDieDiv .day-tit { + font-size: 14px; + } + + .sphere-container .sphereDataDiv p { + font-size: 16px; + margin-top: 5px; + margin-bottom: 15px; + } + + .sphere-container .btn-div { + width: 80%; + margin: 0 10%; + } + + .sphere-container .btn-div .btn { + margin: 5px; + font-size: 12px; + } +} + +@media screen and (max-width: 600px) { + .sphere-container .sphereDataDiv { + width: 45vw; + min-width: 150px; + margin-top: 10vh; + height: 45vh; + } + + .sphere-container .numDiv { + width: 45vw; + min-width: 150px; + margin-top: 10vh; + height: 45vh; + padding-left: 5px; + } + + .sphere-container .numDiv .addconDiv .tit, + .sphere-container .numDiv .addcureDiv .tit, + .sphere-container .numDiv .addDieDiv .tit, + .sphere-container .numDiv .addconDiv .day-tit, + .sphere-container .numDiv .addcureDiv .day-tit, + .sphere-container .numDiv .addDieDiv .day-tit { + font-size: 12px; + margin: 2px 5px; + } + + .sphere-container .sphereDataDiv p { + font-size: 14px; + margin-top: 3px; + margin-bottom: 10px; + } + + .sphere-container .sphereDataDiv .histogramDivDiv { + height: calc(100% - 60px); + } + + .sphere-container .btn-div { + width: 95%; + margin: 0 2.5%; + } + + .sphere-container .btn-div .btn { + margin: 3px; + font-size: 11px; + padding: 4px 8px; + } +} diff --git a/src/views/Sphere.tsx b/src/views/Sphere.tsx index c0d827d..e30048e 100644 --- a/src/views/Sphere.tsx +++ b/src/views/Sphere.tsx @@ -845,12 +845,21 @@ const Sphere: React.FC = () => { } const onWindowResize = () => { - if (!cameraRef.current || !rendererRef.current || !sphereDivRef.current) return + if (cameraRef.current && rendererRef.current && sphereDivRef.current) { + cameraRef.current.aspect = window.innerWidth / window.innerHeight + cameraRef.current.updateProjectionMatrix() + rendererRef.current.setSize(window.innerWidth, window.innerHeight) + } + + if (sphereData.length > 0) { + initEchart(sphereData, allData) + } - cameraRef.current.aspect = window.innerWidth / window.innerHeight - cameraRef.current.updateProjectionMatrix() - rendererRef.current.setSize(window.innerWidth, window.innerHeight) - initEchart(sphereData, allData) + if (histogramChartRef.current) { + setTimeout(() => { + histogramChartRef.current?.resize() + }, 100) + } } const sortFun = (arr: any[]) => {