From 4b64175e5843cc428ed5d50597f5db56723dbe07 Mon Sep 17 00:00:00 2001 From: IHIRINA <2582067027@qq.com> Date: Tue, 27 May 2025 15:48:34 +0800 Subject: [PATCH 01/11] aichat --- package-lock.json | 376 +++++++++++++++++++++++++++++++++-- package.json | 3 +- src/api/interface/type.ts | 7 +- src/api/user/type.ts | 3 + src/stores/counter.ts | 12 -- src/stores/index.ts | 8 + src/stores/modules/user.ts | 123 ++++++++++++ src/views/ask/chatAi.vue | 44 ++-- src/views/login/index.vue | 2 +- src/views/register/index.vue | 2 +- 10 files changed, 524 insertions(+), 56 deletions(-) delete mode 100644 src/stores/counter.ts create mode 100644 src/stores/index.ts create mode 100644 src/stores/modules/user.ts diff --git a/package-lock.json b/package-lock.json index 74aebc9..f3903f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "echarts": "^5.6.0", "element-plus": "^2.9.9", "pinia": "^3.0.1", + "pinia-plugin-persistedstate": "^4.3.0", "vue": "^3.5.13", "vue-router": "^4.5.0" }, @@ -1022,6 +1023,85 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@nuxt/kit": { + "version": "3.17.4", + "resolved": "https://registry.npmmirror.com/@nuxt/kit/-/kit-3.17.4.tgz", + "integrity": "sha512-l+hY8sy2XFfg3PigZj+PTu6+KIJzmbACTRimn1ew/gtCz+F38f6KTF4sMRTN5CUxiB8TRENgEonASmkAWfpO9Q==", + "license": "MIT", + "dependencies": { + "c12": "^3.0.4", + "consola": "^3.4.2", + "defu": "^6.1.4", + "destr": "^2.0.5", + "errx": "^0.1.0", + "exsolve": "^1.0.5", + "ignore": "^7.0.4", + "jiti": "^2.4.2", + "klona": "^2.0.6", + "knitwork": "^1.2.0", + "mlly": "^1.7.4", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "pkg-types": "^2.1.0", + "scule": "^1.3.0", + "semver": "^7.7.2", + "std-env": "^3.9.0", + "tinyglobby": "^0.2.13", + "ufo": "^1.6.1", + "unctx": "^2.4.1", + "unimport": "^5.0.1", + "untyped": "^2.0.0" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/@nuxt/kit/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/@nuxt/kit/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@nuxt/kit/node_modules/unimport": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/unimport/-/unimport-5.0.1.tgz", + "integrity": "sha512-1YWzPj6wYhtwHE+9LxRlyqP4DiRrhGfJxdtH475im8ktyZXO3jHj/3PZ97zDdvkYoovFdi0K4SKl3a7l92v3sQ==", + "license": "MIT", + "dependencies": { + "acorn": "^8.14.1", + "escape-string-regexp": "^5.0.0", + "estree-walker": "^3.0.3", + "local-pkg": "^1.1.1", + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "pkg-types": "^2.1.0", + "scule": "^1.3.0", + "strip-literal": "^3.0.0", + "tinyglobby": "^0.2.13", + "unplugin": "^2.3.2", + "unplugin-utils": "^0.2.4" + }, + "engines": { + "node": ">=18.12.0" + } + }, "node_modules/@polka/url": { "version": "1.0.0-next.29", "resolved": "https://registry.npmmirror.com/@polka/url/-/url-1.0.0-next.29.tgz", @@ -1391,7 +1471,6 @@ "version": "1.0.7", "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.7.tgz", "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", - "dev": true, "license": "MIT" }, "node_modules/@types/lodash": { @@ -1845,7 +1924,6 @@ "version": "8.14.1", "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.14.1.tgz", "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", - "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -2025,6 +2103,62 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/c12": { + "version": "3.0.4", + "resolved": "https://registry.npmmirror.com/c12/-/c12-3.0.4.tgz", + "integrity": "sha512-t5FaZTYbbCtvxuZq9xxIruYydrAGsJ+8UdP0pZzMiK2xl/gNiSOy0OxhLzHUEEb0m1QXYqfzfvyIFEmz/g9lqg==", + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.3", + "confbox": "^0.2.2", + "defu": "^6.1.4", + "dotenv": "^16.5.0", + "exsolve": "^1.0.5", + "giget": "^2.0.0", + "jiti": "^2.4.2", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "perfect-debounce": "^1.0.0", + "pkg-types": "^2.1.0", + "rc9": "^2.1.2" + }, + "peerDependencies": { + "magicast": "^0.3.5" + }, + "peerDependenciesMeta": { + "magicast": { + "optional": true + } + } + }, + "node_modules/c12/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/c12/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -2084,6 +2218,15 @@ "fsevents": "~2.3.2" } }, + "node_modules/citty": { + "version": "0.1.6", + "resolved": "https://registry.npmmirror.com/citty/-/citty-0.1.6.tgz", + "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==", + "license": "MIT", + "dependencies": { + "consola": "^3.2.3" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz", @@ -2100,9 +2243,17 @@ "version": "0.2.2", "resolved": "https://registry.npmmirror.com/confbox/-/confbox-0.2.2.tgz", "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", - "dev": true, "license": "MIT" }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmmirror.com/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -2200,6 +2351,12 @@ } } }, + "node_modules/deep-pick-omit": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/deep-pick-omit/-/deep-pick-omit-1.2.1.tgz", + "integrity": "sha512-2J6Kc/m3irCeqVG42T+SaUMesaK7oGWaedGnQQK/+O0gYc+2SP5bKh/KKTE7d7SJ+GCA9UUE1GRzh6oDe0EnGw==", + "license": "MIT" + }, "node_modules/default-browser": { "version": "5.2.1", "resolved": "https://registry.npmmirror.com/default-browser/-/default-browser-5.2.1.tgz", @@ -2243,6 +2400,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmmirror.com/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "license": "MIT" + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -2252,6 +2415,24 @@ "node": ">=0.4.0" } }, + "node_modules/destr": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/destr/-/destr-2.0.5.tgz", + "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", + "license": "MIT" + }, + "node_modules/dotenv": { + "version": "16.5.0", + "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.5.0.tgz", + "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -2351,6 +2532,12 @@ "url": "https://github.com/sponsors/antfu" } }, + "node_modules/errx": { + "version": "0.1.0", + "resolved": "https://registry.npmmirror.com/errx/-/errx-0.1.0.tgz", + "integrity": "sha512-fZmsRiDNv07K6s2KkKFTiD2aIvECa7++PKyD5NC32tpRw46qZA3sOz+aM+/V9V0GDHxVTKLziveV4JhzBHDp9Q==", + "license": "MIT" + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz", @@ -2457,7 +2644,6 @@ "version": "5.0.0", "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -2503,14 +2689,12 @@ "version": "1.0.5", "resolved": "https://registry.npmmirror.com/exsolve/-/exsolve-1.0.5.tgz", "integrity": "sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==", - "dev": true, "license": "MIT" }, "node_modules/fdir": { "version": "6.4.4", "resolved": "https://registry.npmmirror.com/fdir/-/fdir-6.4.4.tgz", "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", - "dev": true, "license": "MIT", "peerDependencies": { "picomatch": "^3 || ^4" @@ -2688,6 +2872,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/giget": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/giget/-/giget-2.0.0.tgz", + "integrity": "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==", + "license": "MIT", + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.4.0", + "defu": "^6.1.4", + "node-fetch-native": "^1.6.6", + "nypm": "^0.6.0", + "pathe": "^2.0.3" + }, + "bin": { + "giget": "dist/cli.mjs" + } + }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", @@ -2809,6 +3010,15 @@ "node": ">=0.10.0" } }, + "node_modules/ignore": { + "version": "7.0.4", + "resolved": "https://registry.npmmirror.com/ignore/-/ignore-7.0.4.tgz", + "integrity": "sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/image-size": { "version": "0.5.5", "resolved": "https://registry.npmmirror.com/image-size/-/image-size-0.5.5.tgz", @@ -2981,6 +3191,15 @@ "node": ">=16" } }, + "node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmmirror.com/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz", @@ -3037,6 +3256,21 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/klona": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/knitwork": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/knitwork/-/knitwork-1.2.0.tgz", + "integrity": "sha512-xYSH7AvuQ6nXkq42x0v5S8/Iry+cfulBz/DJQzhIyESdLD7425jXsPy4vn5cCXU+HhRN2kVw51Vd1K6/By4BQg==", + "license": "MIT" + }, "node_modules/kolorist": { "version": "1.8.0", "resolved": "https://registry.npmmirror.com/kolorist/-/kolorist-1.8.0.tgz", @@ -3095,7 +3329,6 @@ "version": "1.1.1", "resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-1.1.1.tgz", "integrity": "sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==", - "dev": true, "license": "MIT", "dependencies": { "mlly": "^1.7.4", @@ -3262,7 +3495,6 @@ "version": "1.7.4", "resolved": "https://registry.npmmirror.com/mlly/-/mlly-1.7.4.tgz", "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", - "dev": true, "license": "MIT", "dependencies": { "acorn": "^8.14.0", @@ -3275,14 +3507,12 @@ "version": "0.1.8", "resolved": "https://registry.npmmirror.com/confbox/-/confbox-0.1.8.tgz", "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", - "dev": true, "license": "MIT" }, "node_modules/mlly/node_modules/pkg-types": { "version": "1.3.1", "resolved": "https://registry.npmmirror.com/pkg-types/-/pkg-types-1.3.1.tgz", "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", - "dev": true, "license": "MIT", "dependencies": { "confbox": "^0.1.8", @@ -3350,6 +3580,12 @@ "node": ">= 4.4.x" } }, + "node_modules/node-fetch-native": { + "version": "1.6.6", + "resolved": "https://registry.npmmirror.com/node-fetch-native/-/node-fetch-native-1.6.6.tgz", + "integrity": "sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==", + "license": "MIT" + }, "node_modules/node-releases": { "version": "2.0.19", "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.19.tgz", @@ -3440,6 +3676,31 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/nypm": { + "version": "0.6.0", + "resolved": "https://registry.npmmirror.com/nypm/-/nypm-0.6.0.tgz", + "integrity": "sha512-mn8wBFV9G9+UFHIrq+pZ2r2zL4aPau/by3kJb3cM7+5tQHMt6HGQB8FDIeKFYp8o0D2pnH6nVsO88N4AmUxIWg==", + "license": "MIT", + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.4.0", + "pathe": "^2.0.3", + "pkg-types": "^2.0.0", + "tinyexec": "^0.3.2" + }, + "bin": { + "nypm": "dist/cli.mjs" + }, + "engines": { + "node": "^14.16.0 || >=16.10.0" + } + }, + "node_modules/ohash": { + "version": "2.0.11", + "resolved": "https://registry.npmmirror.com/ohash/-/ohash-2.0.11.tgz", + "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", + "license": "MIT" + }, "node_modules/open": { "version": "10.1.2", "resolved": "https://registry.npmmirror.com/open/-/open-10.1.2.tgz", @@ -3503,7 +3764,6 @@ "version": "2.0.3", "resolved": "https://registry.npmmirror.com/pathe/-/pathe-2.0.3.tgz", "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, "license": "MIT" }, "node_modules/perfect-debounce": { @@ -3522,7 +3782,6 @@ "version": "4.0.2", "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.2.tgz", "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -3576,11 +3835,34 @@ } } }, + "node_modules/pinia-plugin-persistedstate": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/pinia-plugin-persistedstate/-/pinia-plugin-persistedstate-4.3.0.tgz", + "integrity": "sha512-x9wxpHj6iFDj5ITQJ3rj6+KesEqyRk/vqcE3WE+VGfetleV9Zufqwa9qJ6AkA5wmRSQEp7BTA1us/MDVTRHFFw==", + "license": "MIT", + "dependencies": { + "@nuxt/kit": "^3.17.2", + "deep-pick-omit": "^1.2.1", + "defu": "^6.1.4", + "destr": "^2.0.5" + }, + "peerDependencies": { + "@pinia/nuxt": ">=0.10.0", + "pinia": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@pinia/nuxt": { + "optional": true + }, + "pinia": { + "optional": true + } + } + }, "node_modules/pkg-types": { "version": "2.1.0", "resolved": "https://registry.npmmirror.com/pkg-types/-/pkg-types-2.1.0.tgz", "integrity": "sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==", - "dev": true, "license": "MIT", "dependencies": { "confbox": "^0.2.1", @@ -3650,7 +3932,6 @@ "version": "0.2.10", "resolved": "https://registry.npmmirror.com/quansync/-/quansync-0.2.10.tgz", "integrity": "sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==", - "dev": true, "funding": [ { "type": "individual", @@ -3663,6 +3944,16 @@ ], "license": "MIT" }, + "node_modules/rc9": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/rc9/-/rc9-2.1.2.tgz", + "integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==", + "license": "MIT", + "dependencies": { + "defu": "^6.1.4", + "destr": "^2.0.3" + } + }, "node_modules/read-package-json-fast": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/read-package-json-fast/-/read-package-json-fast-4.0.0.tgz", @@ -3782,7 +4073,6 @@ "version": "1.3.0", "resolved": "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz", "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==", - "dev": true, "license": "MIT" }, "node_modules/semver": { @@ -3888,6 +4178,12 @@ "node": ">=0.10.0" } }, + "node_modules/std-env": { + "version": "3.9.0", + "resolved": "https://registry.npmmirror.com/std-env/-/std-env-3.9.0.tgz", + "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", + "license": "MIT" + }, "node_modules/strip-final-newline": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-4.0.0.tgz", @@ -3905,7 +4201,6 @@ "version": "3.0.0", "resolved": "https://registry.npmmirror.com/strip-literal/-/strip-literal-3.0.0.tgz", "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==", - "dev": true, "license": "MIT", "dependencies": { "js-tokens": "^9.0.1" @@ -3918,7 +4213,6 @@ "version": "9.0.1", "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-9.0.1.tgz", "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", - "dev": true, "license": "MIT" }, "node_modules/superjson": { @@ -3933,11 +4227,16 @@ "node": ">=16" } }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmmirror.com/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "license": "MIT" + }, "node_modules/tinyglobby": { "version": "0.2.13", "resolved": "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.13.tgz", "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", - "dev": true, "license": "MIT", "dependencies": { "fdir": "^6.4.4", @@ -3998,9 +4297,29 @@ "version": "1.6.1", "resolved": "https://registry.npmmirror.com/ufo/-/ufo-1.6.1.tgz", "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", - "dev": true, "license": "MIT" }, + "node_modules/unctx": { + "version": "2.4.1", + "resolved": "https://registry.npmmirror.com/unctx/-/unctx-2.4.1.tgz", + "integrity": "sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg==", + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17", + "unplugin": "^2.1.0" + } + }, + "node_modules/unctx/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, "node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.21.0.tgz", @@ -4071,7 +4390,6 @@ "version": "2.3.2", "resolved": "https://registry.npmmirror.com/unplugin/-/unplugin-2.3.2.tgz", "integrity": "sha512-3n7YA46rROb3zSj8fFxtxC/PqoyvYQ0llwz9wtUPUutr9ig09C8gGo5CWCwHrUzlqC1LLR43kxp5vEIyH1ac1w==", - "dev": true, "license": "MIT", "dependencies": { "acorn": "^8.14.1", @@ -4119,7 +4437,6 @@ "version": "0.2.4", "resolved": "https://registry.npmmirror.com/unplugin-utils/-/unplugin-utils-0.2.4.tgz", "integrity": "sha512-8U/MtpkPkkk3Atewj1+RcKIjb5WBimZ/WSLhhR3w6SsIj8XJuKTacSP8g+2JhfSGw0Cb125Y+2zA/IzJZDVbhA==", - "dev": true, "license": "MIT", "dependencies": { "pathe": "^2.0.2", @@ -4168,6 +4485,22 @@ } } }, + "node_modules/untyped": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/untyped/-/untyped-2.0.0.tgz", + "integrity": "sha512-nwNCjxJTjNuLCgFr42fEak5OcLuB3ecca+9ksPFNvtfYSLpjf+iJqSIaSnIile6ZPbKYxI5k2AfXqeopGudK/g==", + "license": "MIT", + "dependencies": { + "citty": "^0.1.6", + "defu": "^6.1.4", + "jiti": "^2.4.2", + "knitwork": "^1.2.0", + "scule": "^1.3.0" + }, + "bin": { + "untyped": "dist/cli.mjs" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.3", "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", @@ -4432,7 +4765,6 @@ "version": "0.6.2", "resolved": "https://registry.npmmirror.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", - "dev": true, "license": "MIT" }, "node_modules/which": { diff --git a/package.json b/package.json index 5423c0e..88e4215 100644 --- a/package.json +++ b/package.json @@ -16,13 +16,14 @@ "echarts": "^5.6.0", "element-plus": "^2.9.9", "pinia": "^3.0.1", + "pinia-plugin-persistedstate": "^4.3.0", "vue": "^3.5.13", "vue-router": "^4.5.0" }, "devDependencies": { "@tsconfig/node22": "^22.0.1", "@types/axios": "^0.9.36", - "@types/echarts": "^4.9.22", + "@types/echarts": "^4.9.22", "@types/node": "^22.14.0", "@vitejs/plugin-vue": "^5.2.3", "@vue/tsconfig": "^0.7.0", diff --git a/src/api/interface/type.ts b/src/api/interface/type.ts index 4a09cf2..c2d61ef 100644 --- a/src/api/interface/type.ts +++ b/src/api/interface/type.ts @@ -1,9 +1,10 @@ //AI接口参数 export interface aiChatForm { - answer: string; + question: string, + userId: number } export interface aiResponseData { - code:number, - Respond:string + code: number, + Respond: string } \ No newline at end of file diff --git a/src/api/user/type.ts b/src/api/user/type.ts index 6fc5e77..06bda70 100644 --- a/src/api/user/type.ts +++ b/src/api/user/type.ts @@ -9,4 +9,7 @@ export interface loginForm{ export interface userResponseData { code:number, msg:string + data: { + userId: number, + } } \ No newline at end of file diff --git a/src/stores/counter.ts b/src/stores/counter.ts deleted file mode 100644 index b6757ba..0000000 --- a/src/stores/counter.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ref, computed } from 'vue' -import { defineStore } from 'pinia' - -export const useCounterStore = defineStore('counter', () => { - const count = ref(0) - const doubleCount = computed(() => count.value * 2) - function increment() { - count.value++ - } - - return { count, doubleCount, increment } -}) diff --git a/src/stores/index.ts b/src/stores/index.ts new file mode 100644 index 0000000..0c7dfda --- /dev/null +++ b/src/stores/index.ts @@ -0,0 +1,8 @@ +import { createPinia } from "pinia"; +import piniaPluginPersistedstate from "pinia-plugin-persistedstate"; + +// pinia persist +const pinia = createPinia(); +pinia.use(piniaPluginPersistedstate); + +export default pinia; diff --git a/src/stores/modules/user.ts b/src/stores/modules/user.ts new file mode 100644 index 0000000..2bfe252 --- /dev/null +++ b/src/stores/modules/user.ts @@ -0,0 +1,123 @@ +import { defineStore } from 'pinia' +import { reqLogin, reqRegiter } from '@/api/user' +import { type loginForm, type userResponseData } from '@/api/user/type' +import { useRouter } from 'vue-router' +import { ElNotification } from 'element-plus' +import { ref } from 'vue' + +// 定义用户状态类型 +interface UserState { + userId: number | null + token: string | null + username: string | null + email: string | null +} + +// 创建用户小仓库 +export const useUserStore = defineStore('user', { + // 小仓库数据 + state: (): UserState => ({ + userId: null, + token: null, + username: null, + email: null + }), + + actions: { + // 用户登录方法 + async userLogin(data: loginForm) { + try { + const result: userResponseData = await reqLogin(data) + console.log('Login response:', result) + + if (result.code === 200) { + // 存储用户信息到状态 + this.userId = result.data.userId + this.email = data.email + + // 存储到本地存储,确保刷新后数据不丢失 + localStorage.setItem('userId', result.data.userId.toString()) + + + const router = useRouter() + router.push({ name: 'home' }) + /* + ElNotification({ + title: '登录成功', + message: `欢迎回来,${this.username}`, + type: 'success', + duration: 3000 + })*/ + } else { + ElNotification({ + title: '登录失败', + message: result.msg || '用户不存在或密码错误', + type: 'error', + duration: 3000 + }) + } + } catch (error: any) { + console.error('Login request failed:', error) + ElNotification({ + title: '登录异常', + message: error.response?.data?.message || '登录请求失败,请稍后再试', + type: 'error', + duration: 3000 + }) + } + }, + + // 用户注册方法 + async userRegister(data: loginForm) { + try { + const result = await reqRegiter(data) + console.log('Register response:', result) + + if (result.code === 200) { + ElNotification({ + title: '注册成功', + message: '请登录后使用完整功能', + type: 'success', + duration: 3000 + }) + + const router = useRouter() + router.push({ name: 'login' }) + } else { + ElNotification({ + title: '注册失败', + message: result.msg || '用户已存在', + type: 'error', + duration: 3000 + }) + } + } catch (error: any) { + console.error('Register request failed:', error) + ElNotification({ + title: '注册异常', + message: error.response?.data?.message || '注册请求失败,请稍后再试', + type: 'error', + duration: 3000 + }) + } + }, + + /* + // 从本地存储初始化用户状态 + initUserState() { + const userId = localStorage.getItem('userId') + const token = localStorage.getItem('token') + if (userId && token) { + this.userId = parseInt(userId) + this.token = token + } + }*/ + }, + + getters: { + /* 判断用户是否已登录 + isLoggedIn(): boolean { + return this.userId !== null && this.token !== null + }*/ + } +}) \ No newline at end of file diff --git a/src/views/ask/chatAi.vue b/src/views/ask/chatAi.vue index 4e1c891..93997ca 100644 --- a/src/views/ask/chatAi.vue +++ b/src/views/ask/chatAi.vue @@ -120,8 +120,12 @@ import { ElMessage } from 'element-plus' import router from '@/router' import axios from 'axios' import { reqAiChat } from '@/api/interface' +import { useUserStore } from '@/stores/modules/user' + +// 获取用户状态 +const userStore = useUserStore() +const userId = ref(userStore.userId) -const baseURL = '' //侧边栏开合 const isCollapse = ref(false) @@ -156,22 +160,26 @@ const handleEnter = (event: KeyboardEvent) => { const backThing = ref() const userThing = ref() watch(userThing, async (newValue) => { - if (newValue.trim()) { + if (newValue && newValue.question.trim() && newValue.userId !== null) { backThing.value = '思考中...' - backThing.value = await reqAiChat(newValue.trim()) - .then((res) => { - if (res.code === 200) { - return res.Respond - } else { - ElMessage.error('请求失败,请稍后再试') - return '请求失败,请稍后再试' - } - }) - .catch((error) => { - console.error('请求错误:', error) - ElMessage.error('请求错误,请稍后再试') - return '请求错误,请稍后再试' + try { + // 发送包含userId和问题的请求 + const res = await reqAiChat({ + question: newValue.question, + userId: newValue.userId }) + + if (res.code === 200) { + backThing.value = res.Respond + } else { + ElMessage.error('请求失败,请稍后再试') + backThing.value = '请求失败,请稍后再试' + } + } catch (error) { + console.error('请求错误:', error) + ElMessage.error('请求错误,请稍后再试') + backThing.value = '请求错误,请稍后再试' + } } }) const submitClick = (): void => { @@ -181,7 +189,11 @@ const submitClick = (): void => { return } - userThing.value = inputValue + // 构造包含userId的请求数据 + userThing.value = { + question: inputValue, + userId: userId.value + } text.value = '' isShow.value = true } diff --git a/src/views/login/index.vue b/src/views/login/index.vue index 50a6d63..fd4a0e8 100644 --- a/src/views/login/index.vue +++ b/src/views/login/index.vue @@ -125,7 +125,7 @@ const loginHandler = async () => { if (response.code === 200) { // 验证验证码 router.push('/') - console.log(response.message) + console.log(response.msg) } else { alert('用户名或密码错误'); } diff --git a/src/views/register/index.vue b/src/views/register/index.vue index cb35886..10ca039 100644 --- a/src/views/register/index.vue +++ b/src/views/register/index.vue @@ -117,7 +117,7 @@ const registerHandler = async () => { alert('注册成功,请登录'); router.push('/login'); } else { - alert(response.message); + alert(response.msg); } } else { console.error('未收到有效的响应'); From debb7519cfa920d680248f0ad5ffb525e71e0047 Mon Sep 17 00:00:00 2001 From: IHIRINA <2582067027@qq.com> Date: Tue, 3 Jun 2025 15:15:58 +0800 Subject: [PATCH 02/11] =?UTF-8?q?=E8=BF=99=E6=8A=8A=E6=98=AF=E7=9C=9F?= =?UTF-8?q?=E7=9A=84=E5=86=99=E5=AE=8C=E4=BA=86chat=E7=9A=84=E9=83=A8?= =?UTF-8?q?=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/interface/index.ts | 8 ++- src/api/interface/type.ts | 16 ++++- src/api/user/index.ts | 16 ----- src/api/user/login/index.ts | 8 +++ src/api/user/login/type.ts | 16 +++++ src/api/user/register/index.ts | 12 ++++ src/api/user/register/type.ts | 13 ++++ src/api/user/type.ts | 15 ----- src/main.ts | 4 +- src/stores/modules/user.ts | 107 +++++++++++++++++---------------- src/views/ask/chatAi.vue | 33 ++++++---- src/views/ask/musicAi.vue | 7 ++- src/views/ask/tableAi.vue | 25 +++----- src/views/home.vue | 7 ++- src/views/login/index.vue | 10 ++- src/views/myself/my.vue | 7 ++- src/views/myself/used.vue | 5 ++ src/views/register/index.vue | 29 ++++----- src/views/table/index.vue | 6 +- 19 files changed, 200 insertions(+), 144 deletions(-) create mode 100644 src/api/user/login/index.ts create mode 100644 src/api/user/login/type.ts create mode 100644 src/api/user/register/index.ts create mode 100644 src/api/user/register/type.ts diff --git a/src/api/interface/index.ts b/src/api/interface/index.ts index 9486dbf..c7a5001 100644 --- a/src/api/interface/index.ts +++ b/src/api/interface/index.ts @@ -1,9 +1,11 @@ import request from "@/utils/request" -import { type aiChatForm , type aiResponseData} from '@/api/interface/type' +import { type aiChatForm , type aiTableForm, type aiResponseData} from '@/api/interface/type' enum API { - AICHAT_URL = "/questionSimple" + AICHAT_URL = "/user/questionSimple", + AIPICTURE_URL = "/user/picture" } //对外暴露请求函数 -export const reqAiChat = (data: aiChatForm) => request.post(API.AICHAT_URL, data) as Promise; \ No newline at end of file +export const reqAiChat = (data: aiChatForm) => request.post(API.AICHAT_URL, data) as Promise; +export const reqAitable = (data: aiTableForm) => request.post(API.AIPICTURE_URL, data) as Promise \ No newline at end of file diff --git a/src/api/interface/type.ts b/src/api/interface/type.ts index c2d61ef..5db48f2 100644 --- a/src/api/interface/type.ts +++ b/src/api/interface/type.ts @@ -4,7 +4,19 @@ export interface aiChatForm { userId: number } +export interface aiTableForm { + picture: string + userId: string +} + export interface aiResponseData { - code: number, - Respond: string + code: number + msg: string + data: { + Respond: string + } +} + +export interface aiResponsePictureData { + } \ No newline at end of file diff --git a/src/api/user/index.ts b/src/api/user/index.ts index 034336c..e69de29 100644 --- a/src/api/user/index.ts +++ b/src/api/user/index.ts @@ -1,16 +0,0 @@ -//用户相关接口 -import request from "@/utils/request"; -import { type loginForm ,type userResponseData} from '@/api/user/type'; - -//统一管理接口 -enum API{ - LOGIN_URL = "/login", - REGISTER_URL = "/user/register" -} -//对外暴露请求函数 - -//登录接口方法 -export const reqLogin = (data: loginForm) => request.post(API.LOGIN_URL, data) as Promise; - -//注册用户信息接口方法 -export const reqRegiter = (data: loginForm) => request.post(API.REGISTER_URL, data) as Promise; \ No newline at end of file diff --git a/src/api/user/login/index.ts b/src/api/user/login/index.ts new file mode 100644 index 0000000..d542bb6 --- /dev/null +++ b/src/api/user/login/index.ts @@ -0,0 +1,8 @@ +import request from "@/utils/request" +import { type loginForm, type userLoginResponseData } from "./type" + + +const LOGIN_URL = "/user/login" + + +export const reqLogin = (data: loginForm) => request.post(LOGIN_URL,data) as Promise \ No newline at end of file diff --git a/src/api/user/login/type.ts b/src/api/user/login/type.ts new file mode 100644 index 0000000..18613e2 --- /dev/null +++ b/src/api/user/login/type.ts @@ -0,0 +1,16 @@ +export interface loginForm { + username:string, + password:string + email: string, +} + +export interface userLoginResponseData { + code:number + msg:string + data:{ + id:number + username:string + email:string + token:string + } +} \ No newline at end of file diff --git a/src/api/user/register/index.ts b/src/api/user/register/index.ts new file mode 100644 index 0000000..202678d --- /dev/null +++ b/src/api/user/register/index.ts @@ -0,0 +1,12 @@ +//用户相关接口 +import request from "@/utils/request"; +import { type registerForm ,type userRegisterResponseData} from '@/api/user/register/type'; + +//统一管理接口 +enum API{ + REGISTER_URL = "/user/register" +} +//对外暴露请求函数 + +//注册用户信息接口方法 +export const reqRegiter = (data: registerForm) => request.post(API.REGISTER_URL, data) as Promise; \ No newline at end of file diff --git a/src/api/user/register/type.ts b/src/api/user/register/type.ts new file mode 100644 index 0000000..79df6b4 --- /dev/null +++ b/src/api/user/register/type.ts @@ -0,0 +1,13 @@ +//登录接口参数 +export interface registerForm{ + username:string, + password:string + email: string, +} + +//登录,注册返回数据类型 +export interface userRegisterResponseData { + code:number, + msg:string + data: string +} \ No newline at end of file diff --git a/src/api/user/type.ts b/src/api/user/type.ts index 06bda70..e69de29 100644 --- a/src/api/user/type.ts +++ b/src/api/user/type.ts @@ -1,15 +0,0 @@ -//登录接口参数 -export interface loginForm{ - username:string, - password:string - email: string, -} - -//登录,注册返回数据类型 -export interface userResponseData { - code:number, - msg:string - data: { - userId: number, - } -} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 6158c08..4c51d67 100644 --- a/src/main.ts +++ b/src/main.ts @@ -15,7 +15,9 @@ const app = createApp(App) for (const [key, component] of Object.entries(ElementPlusIconsVue)) { app.component(key, component) } -app.use(createPinia()) +const pinia = createPinia() + +app.use(pinia) app.use(router) app.mount('#app') diff --git a/src/stores/modules/user.ts b/src/stores/modules/user.ts index 2bfe252..98cd07b 100644 --- a/src/stores/modules/user.ts +++ b/src/stores/modules/user.ts @@ -1,108 +1,112 @@ import { defineStore } from 'pinia' -import { reqLogin, reqRegiter } from '@/api/user' -import { type loginForm, type userResponseData } from '@/api/user/type' +import { reqRegiter } from '@/api/user/register' +import { reqLogin } from '@/api/user/login' +import { type registerForm, type userRegisterResponseData } from '@/api/user/register/type' +import { type loginForm, type userLoginResponseData } from '@/api/user/login/type' import { useRouter } from 'vue-router' import { ElNotification } from 'element-plus' -import { ref } from 'vue' + // 定义用户状态类型 interface UserState { - userId: number | null - token: string | null - username: string | null - email: string | null + userId: number + token: string + username: string + email: string } // 创建用户小仓库 export const useUserStore = defineStore('user', { // 小仓库数据 state: (): UserState => ({ - userId: null, - token: null, - username: null, - email: null + userId: 0, + token: '', + username: '', + email: '' }), actions: { - // 用户登录方法 - async userLogin(data: loginForm) { + // 用户注册方法 + async userRegister(data: registerForm) { try { - const result: userResponseData = await reqLogin(data) - console.log('Login response:', result) + const result:userRegisterResponseData = await reqRegiter(data) + console.log('Register response:', result) //code,msg,注册成功请登录 if (result.code === 200) { - // 存储用户信息到状态 - this.userId = result.data.userId - this.email = data.email - - // 存储到本地存储,确保刷新后数据不丢失 - localStorage.setItem('userId', result.data.userId.toString()) - - - const router = useRouter() - router.push({ name: 'home' }) - /* ElNotification({ - title: '登录成功', - message: `欢迎回来,${this.username}`, + title: '注册成功', + message: '请登录后使用完整功能', type: 'success', duration: 3000 - })*/ + }) + + const router = useRouter() + router.push('/login') + } else { ElNotification({ - title: '登录失败', - message: result.msg || '用户不存在或密码错误', + title: '注册失败', + message: result.msg, type: 'error', duration: 3000 }) } } catch (error: any) { - console.error('Login request failed:', error) + console.error('Register request failed:', error) ElNotification({ - title: '登录异常', - message: error.response?.data?.message || '登录请求失败,请稍后再试', + title: '注册异常', + message: error.response?.data?.message || '注册请求失败,请稍后再试', type: 'error', duration: 3000 }) } }, - // 用户注册方法 - async userRegister(data: loginForm) { + // 用户登录方法 + async userLogin(data: loginForm) { try { - const result = await reqRegiter(data) - console.log('Register response:', result) + const result: userLoginResponseData = await reqLogin(data) + console.log('Login response:', result) if (result.code === 200) { + // 存储用户信息到状态 + this.userId = result.data.id + this.email = result.data.email + this.username = result.data.username + + // 存储到本地存储,确保刷新后数据不丢失 + localStorage.setItem('userId', result.data.id.toString()) + + const router = useRouter() + router.push('/') + ElNotification({ - title: '注册成功', - message: '请登录后使用完整功能', + title: '登录成功', + message: `欢迎回来,${this.username}`, type: 'success', duration: 3000 }) - const router = useRouter() - router.push({ name: 'login' }) } else { ElNotification({ - title: '注册失败', - message: result.msg || '用户已存在', + title: '登录失败', + message: result.msg || '用户不存在或密码错误', type: 'error', duration: 3000 }) } } catch (error: any) { - console.error('Register request failed:', error) + console.error('Login request failed:', error) ElNotification({ - title: '注册异常', - message: error.response?.data?.message || '注册请求失败,请稍后再试', + title: '登录异常', + message: error.response?.data?.message || '登录请求失败,请稍后再试', type: 'error', duration: 3000 }) } }, - /* + // 从本地存储初始化用户状态 initUserState() { const userId = localStorage.getItem('userId') @@ -111,13 +115,14 @@ export const useUserStore = defineStore('user', { this.userId = parseInt(userId) this.token = token } - }*/ + } }, + //getters计算属性 getters: { - /* 判断用户是否已登录 + //判断用户是否已登录 isLoggedIn(): boolean { return this.userId !== null && this.token !== null - }*/ + } } }) \ No newline at end of file diff --git a/src/views/ask/chatAi.vue b/src/views/ask/chatAi.vue index 93997ca..74be02e 100644 --- a/src/views/ask/chatAi.vue +++ b/src/views/ask/chatAi.vue @@ -57,7 +57,7 @@ - + user @@ -71,7 +71,7 @@
-

{{ userThing }}

+

{{ userThing.question }}

user
@@ -117,14 +117,9 @@ import { onMounted, ref, watch } from 'vue' import { getTimeState } from '@/utils/index' import { ElMessage } from 'element-plus' -import router from '@/router' -import axios from 'axios' import { reqAiChat } from '@/api/interface' import { useUserStore } from '@/stores/modules/user' - -// 获取用户状态 -const userStore = useUserStore() -const userId = ref(userStore.userId) +import { type aiChatForm } from '@/api/interface/type' //侧边栏开合 @@ -144,6 +139,11 @@ onMounted(() => { console.log(thisTimeState.value) }) + /*网页全屏*/ +const handleFullscreen = () => { + document.documentElement.requestFullscreen() +} + /*对话框写入部分*/ const text = ref() const isShow = ref(false) @@ -157,20 +157,28 @@ const handleEnter = (event: KeyboardEvent) => { } /*对话框交互部分*/ +// 获取用户状态 +const userStore = useUserStore() +const userId = userStore.userId + const backThing = ref() -const userThing = ref() +const userThing = ref({ + question: text.value ?? '', + userId: userId ?? 1 // 默认用1或默认userId +}) + watch(userThing, async (newValue) => { if (newValue && newValue.question.trim() && newValue.userId !== null) { backThing.value = '思考中...' try { - // 发送包含userId和问题的请求 + // 请求 const res = await reqAiChat({ question: newValue.question, userId: newValue.userId }) if (res.code === 200) { - backThing.value = res.Respond + backThing.value = res.data.Respond } else { ElMessage.error('请求失败,请稍后再试') backThing.value = '请求失败,请稍后再试' @@ -182,6 +190,7 @@ watch(userThing, async (newValue) => { } } }) + const submitClick = (): void => { const inputValue = text.value.trim() if (!inputValue) { @@ -192,7 +201,7 @@ const submitClick = (): void => { // 构造包含userId的请求数据 userThing.value = { question: inputValue, - userId: userId.value + userId: userId ?? 1 // 保证userId为number类型 } text.value = '' isShow.value = true diff --git a/src/views/ask/musicAi.vue b/src/views/ask/musicAi.vue index fd0ceb7..f27d7e8 100644 --- a/src/views/ask/musicAi.vue +++ b/src/views/ask/musicAi.vue @@ -57,7 +57,7 @@ - + user @@ -114,6 +114,11 @@ onMounted(() => { console.log(thisTimeState.value) }) + /*网页全屏*/ +const handleFullscreen = () => { + document.documentElement.requestFullscreen() +} + const text = ref() const handleEnter = (event: KeyboardEvent) => { // 如果按下Shift+Enter则插入换行 diff --git a/src/views/ask/tableAi.vue b/src/views/ask/tableAi.vue index 7689a8b..c09cef8 100644 --- a/src/views/ask/tableAi.vue +++ b/src/views/ask/tableAi.vue @@ -56,8 +56,8 @@ {{ thisTimeState }} - - + + user @@ -67,6 +67,9 @@
+ + + { console.log(key, keyPath) @@ -129,18 +134,8 @@ const handleEnter = (event: KeyboardEvent) => { } const submitClick = () => { - if(text.value.trim() == 0) { - ElMessage.warning("请输入东西哦亲") - }else{ - - } - - - - - ElMessage.success("正在为您生成计划") -} - + +} diff --git a/src/views/home.vue b/src/views/home.vue index 5b45a5a..68f92db 100644 --- a/src/views/home.vue +++ b/src/views/home.vue @@ -57,7 +57,7 @@ - + user @@ -106,6 +106,11 @@ onMounted(() => { console.log(thisTimeState.value) }) + /*网页全屏*/ +const handleFullscreen = () => { + document.documentElement.requestFullscreen() +} + const item = [ ['在蓝心小V里你可以问问AI该怎么制定计划'], ["如果你不开心,你也可以在AI原子能力里面和AI聊天"], diff --git a/src/views/login/index.vue b/src/views/login/index.vue index fd4a0e8..6179cea 100644 --- a/src/views/login/index.vue +++ b/src/views/login/index.vue @@ -47,10 +47,8 @@ import { reactive, ref, type Component } from 'vue' import { RowAlign, type FormInstance, type FormRules } from 'element-plus' import ValidCodeComponent from '@/components/validCode.vue' import { useRouter } from 'vue-router' -import axios from 'axios' -import request from '@/utils/request' -import type { loginForm, userResponseData } from '@/api/user/type' -import { reqLogin } from '@/api/user' +import type { loginForm, userLoginResponseData } from '@/api/user/login/type' +import { reqLogin } from '@/api/user/login' interface RuleForm { @@ -114,6 +112,7 @@ const loginHandler = async () => { } }) + //注册申请 const loginData: loginForm = { username: ruleForm.name, password: ruleForm.password, @@ -121,9 +120,8 @@ const loginHandler = async () => { } try { - const response: userResponseData = await reqLogin(loginData); + const response: userLoginResponseData = await reqLogin(loginData); if (response.code === 200) { - // 验证验证码 router.push('/') console.log(response.msg) } else { diff --git a/src/views/myself/my.vue b/src/views/myself/my.vue index 9dab16b..4f3c656 100644 --- a/src/views/myself/my.vue +++ b/src/views/myself/my.vue @@ -57,7 +57,7 @@ - + user @@ -98,7 +98,10 @@ onMounted(() => { console.log(thisTimeState.value) }) - + /*网页全屏*/ +const handleFullscreen = () => { + document.documentElement.requestFullscreen() +} diff --git a/src/views/myself/used.vue b/src/views/myself/used.vue index 365a84c..475fd6b 100644 --- a/src/views/myself/used.vue +++ b/src/views/myself/used.vue @@ -98,6 +98,11 @@ onMounted(() => { console.log(thisTimeState.value) }) + /*网页全屏*/ +const handleFullscreen = () => { + document.documentElement.requestFullscreen() +} + diff --git a/src/views/register/index.vue b/src/views/register/index.vue index 10ca039..f2a7f10 100644 --- a/src/views/register/index.vue +++ b/src/views/register/index.vue @@ -41,10 +41,8 @@ import { reactive, ref } from 'vue' import { RowAlign, type FormInstance, type FormRules } from 'element-plus' import { useRouter } from 'vue-router' -import axios from 'axios' -import request from '@/utils/request' -import type { loginForm, userResponseData } from '@/api/user/type' -import { reqRegiter } from '@/api/user' +import type { registerForm, userRegisterResponseData } from '@/api/user/register/type' +import { reqRegiter } from '@/api/user/register' interface RuleForm { name: string @@ -105,28 +103,23 @@ const registerHandler = async () => { }) // 提交注册请求 - const registerData: loginForm = { + const registerData: registerForm = { username: ruleForm.name, password: ruleForm.password, email: ruleForm.email, } try { - const response: userResponseData = await reqRegiter(registerData); - if (response) { - if (response.code === 200) { - alert('注册成功,请登录'); - router.push('/login'); - } else { - alert(response.msg); - } - } else { - console.error('未收到有效的响应'); - alert('注册失败,请重试'); - } + const response: userRegisterResponseData = await reqRegiter(registerData); + if (response.code === 200) { + alert('注册成功,请登录'); + router.push('/login'); + } else { + alert(response.msg); + } } catch (error) { console.error('注册失败:', error); alert('注册失败,请重试'); - } + } } diff --git a/src/views/table/index.vue b/src/views/table/index.vue index 184f539..c86dd43 100644 --- a/src/views/table/index.vue +++ b/src/views/table/index.vue @@ -57,7 +57,7 @@ - + user @@ -96,6 +96,10 @@ onMounted(() => { console.log(thisTimeState.value) }) + /*网页全屏*/ +const handleFullscreen = () => { + document.documentElement.requestFullscreen() +} const chartRef = ref(null); From 3aea5964b7459695b631be3888ec270e28368da4 Mon Sep 17 00:00:00 2001 From: IHIRINA <2582067027@qq.com> Date: Mon, 30 Jun 2025 20:54:48 +0800 Subject: [PATCH 03/11] hahaha --- auto-imports.d.ts | 1 + components.d.ts | 12 + index.html | 2 + package-lock.json | 440 ++++++++++++++++++++++++++++++++- package.json | 8 +- public/5.png | Bin 0 -> 77678 bytes src/api/interface/index.ts | 7 +- src/api/interface/type.ts | 13 +- src/api/user/login/index.ts | 12 +- src/api/user/login/type.ts | 18 ++ src/api/user/register/index.ts | 2 +- src/api/user/register/type.ts | 4 +- src/api/user/show/index.ts | 12 + src/api/user/show/type.ts | 21 ++ src/assets/fonts/DFKTL1B.TTF | Bin 0 -> 42436 bytes src/assets/fonts/blomster.ttf | Bin 0 -> 44628 bytes src/assets/fonts/theFonts.css | 4 + src/main.ts | 8 +- src/stores/modules/user.ts | 209 +++++++++++++--- src/types/amap.d.ts | 71 ++++++ src/utils/request.ts | 2 +- src/views/ask/chatAi.vue | 71 +++--- src/views/ask/musicAi.vue | 216 ++++++++++++++-- src/views/ask/tableAi.vue | 80 +++++- src/views/home.vue | 140 +++++++++-- src/views/login/index.vue | 358 ++++++++++++++++++++------- src/views/myself/my.vue | 411 +++++++++++++++++++++++++++--- src/views/myself/used.vue | 214 +++++++++------- src/views/register/index.vue | 304 ++++++++++++++++++----- src/views/table/index.vue | 194 ++++++++------- 30 files changed, 2321 insertions(+), 513 deletions(-) create mode 100644 public/5.png create mode 100644 src/api/user/show/index.ts create mode 100644 src/api/user/show/type.ts create mode 100644 src/assets/fonts/DFKTL1B.TTF create mode 100644 src/assets/fonts/blomster.ttf create mode 100644 src/assets/fonts/theFonts.css create mode 100644 src/types/amap.d.ts diff --git a/auto-imports.d.ts b/auto-imports.d.ts index bc57d8c..b60e825 100644 --- a/auto-imports.d.ts +++ b/auto-imports.d.ts @@ -8,4 +8,5 @@ export {} declare global { const ElMenu: typeof import('element-plus/es')['ElMenu'] const ElMenuItem: typeof import('element-plus/es')['ElMenuItem'] + const ElMessage: typeof import('element-plus/es')['ElMessage'] } diff --git a/components.d.ts b/components.d.ts index 73ded34..2bfc728 100644 --- a/components.d.ts +++ b/components.d.ts @@ -9,6 +9,7 @@ export {} declare module 'vue' { export interface GlobalComponents { Charts: typeof import('./src/components/charts.vue')['default'] + ElAlert: typeof import('element-plus/es')['ElAlert'] ElAside: typeof import('element-plus/es')['ElAside'] ElAvatar: typeof import('element-plus/es')['ElAvatar'] ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb'] @@ -22,14 +23,19 @@ declare module 'vue' { ElCol: typeof import('element-plus/es')['ElCol'] ElContainer: typeof import('element-plus/es')['ElContainer'] ElDatePicker: typeof import('element-plus/es')['ElDatePicker'] + ElDescriptions: typeof import('element-plus/es')['ElDescriptions'] + ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem'] ElDropdown: typeof import('element-plus/es')['ElDropdown'] ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem'] ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu'] + ElEmpty: typeof import('element-plus/es')['ElEmpty'] ElForm: typeof import('element-plus/es')['ElForm'] ElFormItem: typeof import('element-plus/es')['ElFormItem'] ElHeader: typeof import('element-plus/es')['ElHeader'] ElIcon: typeof import('element-plus/es')['ElIcon'] + ElImage: typeof import('element-plus/es')['ElImage'] ElInput: typeof import('element-plus/es')['ElInput'] + ElLoading: typeof import('element-plus/es')['ElLoading'] ElMain: typeof import('element-plus/es')['ElMain'] ElMenu: typeof import('element-plus/es')['ElMenu'] ElMenuItem: typeof import('element-plus/es')['ElMenuItem'] @@ -47,14 +53,17 @@ declare module 'vue' { ElSwitch: typeof import('element-plus/es')['ElSwitch'] ElTable: typeof import('element-plus/es')['ElTable'] ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] + ElTag: typeof import('element-plus/es')['ElTag'] ElText: typeof import('element-plus/es')['ElText'] ElTimePicker: typeof import('element-plus/es')['ElTimePicker'] + ElTooltip: typeof import('element-plus/es')['ElTooltip'] HelloWorld: typeof import('./src/components/HelloWorld.vue')['default'] IconCommunity: typeof import('./src/components/icons/IconCommunity.vue')['default'] IconDocumentation: typeof import('./src/components/icons/IconDocumentation.vue')['default'] IconEcosystem: typeof import('./src/components/icons/IconEcosystem.vue')['default'] IconSupport: typeof import('./src/components/icons/IconSupport.vue')['default'] IconTooling: typeof import('./src/components/icons/IconTooling.vue')['default'] + Main: typeof import('./src/components/main.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] TheWelcome: typeof import('./src/components/TheWelcome.vue')['default'] @@ -62,4 +71,7 @@ declare module 'vue' { ValidCode: typeof import('./src/components/validCode.vue')['default'] WelcomeItem: typeof import('./src/components/WelcomeItem.vue')['default'] } + export interface ComponentCustomProperties { + vLoading: typeof import('element-plus/es')['ElLoadingDirective'] + } } diff --git a/index.html b/index.html index 872ab31..4d45f34 100644 --- a/index.html +++ b/index.html @@ -11,3 +11,5 @@ + + diff --git a/package-lock.json b/package-lock.json index f3903f4..f7dd675 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,23 +9,27 @@ "version": "0.0.0", "dependencies": { "@element-plus/icons-vue": "^2.3.1", - "axios": "^1.9.0", + "axios": "^1.10.0", "echarts": "^5.6.0", "element-plus": "^2.9.9", "pinia": "^3.0.1", "pinia-plugin-persistedstate": "^4.3.0", + "recordrtc": "^5.6.2", "vue": "^3.5.13", - "vue-router": "^4.5.0" + "vue-router": "^4.5.0", + "weixin-js-sdk": "^1.6.5" }, "devDependencies": { "@tsconfig/node22": "^22.0.1", "@types/axios": "^0.9.36", "@types/echarts": "^4.9.22", "@types/node": "^22.14.0", + "@types/recordrtc": "^5.6.14", "@vitejs/plugin-vue": "^5.2.3", "@vue/tsconfig": "^0.7.0", "less": "^4.3.0", "npm-run-all2": "^7.0.2", + "sass-embedded": "^1.89.2", "typescript": "~5.8.0", "unplugin-auto-import": "^19.1.2", "unplugin-vue-components": "^28.5.0", @@ -503,6 +507,13 @@ "node": ">=6.9.0" } }, + "node_modules/@bufbuild/protobuf": { + "version": "2.5.2", + "resolved": "https://registry.npmmirror.com/@bufbuild/protobuf/-/protobuf-2.5.2.tgz", + "integrity": "sha512-foZ7qr0IsUBjzWIq+SuBLfdQCpJ1j8cTuNNT4owngTHoN5KsJb8L9t65fzz7SCeSWzescoOil/0ldqiL041ABg==", + "dev": true, + "license": "(Apache-2.0 AND BSD-3-Clause)" + }, "node_modules/@ctrl/tinycolor": { "version": "3.6.1", "resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz", @@ -1498,6 +1509,13 @@ "undici-types": "~6.21.0" } }, + "node_modules/@types/recordrtc": { + "version": "5.6.14", + "resolved": "https://registry.npmmirror.com/@types/recordrtc/-/recordrtc-5.6.14.tgz", + "integrity": "sha512-Reiy1sl11xP0r6w8DW3iQjc1BgXFyNC7aDuutysIjpFoqyftbQps9xPA2FoBkfVXpJM61betgYPNt+v65zvMhA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/web-bluetooth": { "version": "0.0.16", "resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz", @@ -1992,9 +2010,9 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.9.0", - "resolved": "https://registry.npmmirror.com/axios/-/axios-1.9.0.tgz", - "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", + "version": "1.10.0", + "resolved": "https://registry.npmmirror.com/axios/-/axios-1.10.0.tgz", + "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", @@ -2087,6 +2105,13 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/buffer-builder": { + "version": "0.2.0", + "resolved": "https://registry.npmmirror.com/buffer-builder/-/buffer-builder-0.2.0.tgz", + "integrity": "sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg==", + "dev": true, + "license": "MIT/X11" + }, "node_modules/bundle-name": { "version": "4.1.0", "resolved": "https://registry.npmmirror.com/bundle-name/-/bundle-name-4.1.0.tgz", @@ -2227,6 +2252,13 @@ "consola": "^3.2.3" } }, + "node_modules/colorjs.io": { + "version": "0.5.2", + "resolved": "https://registry.npmmirror.com/colorjs.io/-/colorjs.io-0.5.2.tgz", + "integrity": "sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==", + "dev": true, + "license": "MIT" + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz", @@ -2931,6 +2963,16 @@ "dev": true, "license": "ISC" }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz", @@ -3033,6 +3075,13 @@ "node": ">=0.10.0" } }, + "node_modules/immutable": { + "version": "5.1.3", + "resolved": "https://registry.npmmirror.com/immutable/-/immutable-5.1.3.tgz", + "integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==", + "dev": true, + "license": "MIT" + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -3994,6 +4043,12 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/recordrtc": { + "version": "5.6.2", + "resolved": "https://registry.npmmirror.com/recordrtc/-/recordrtc-5.6.2.tgz", + "integrity": "sha512-1QNKKNtl7+KcwD1lyOgP3ZlbiJ1d0HtXnypUy7yq49xEERxk31PHvE9RCciDrulPCY7WJ+oz0R9hpNxgsIurGQ==", + "license": "MIT" + }, "node_modules/rfdc": { "version": "1.4.1", "resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.4.1.tgz", @@ -4053,6 +4108,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmmirror.com/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -4061,6 +4126,319 @@ "license": "MIT", "optional": true }, + "node_modules/sass-embedded": { + "version": "1.89.2", + "resolved": "https://registry.npmmirror.com/sass-embedded/-/sass-embedded-1.89.2.tgz", + "integrity": "sha512-Ack2K8rc57kCFcYlf3HXpZEJFNUX8xd8DILldksREmYXQkRHI879yy8q4mRDJgrojkySMZqmmmW1NxrFxMsYaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bufbuild/protobuf": "^2.5.0", + "buffer-builder": "^0.2.0", + "colorjs.io": "^0.5.0", + "immutable": "^5.0.2", + "rxjs": "^7.4.0", + "supports-color": "^8.1.1", + "sync-child-process": "^1.0.2", + "varint": "^6.0.0" + }, + "bin": { + "sass": "dist/bin/sass.js" + }, + "engines": { + "node": ">=16.0.0" + }, + "optionalDependencies": { + "sass-embedded-android-arm": "1.89.2", + "sass-embedded-android-arm64": "1.89.2", + "sass-embedded-android-riscv64": "1.89.2", + "sass-embedded-android-x64": "1.89.2", + "sass-embedded-darwin-arm64": "1.89.2", + "sass-embedded-darwin-x64": "1.89.2", + "sass-embedded-linux-arm": "1.89.2", + "sass-embedded-linux-arm64": "1.89.2", + "sass-embedded-linux-musl-arm": "1.89.2", + "sass-embedded-linux-musl-arm64": "1.89.2", + "sass-embedded-linux-musl-riscv64": "1.89.2", + "sass-embedded-linux-musl-x64": "1.89.2", + "sass-embedded-linux-riscv64": "1.89.2", + "sass-embedded-linux-x64": "1.89.2", + "sass-embedded-win32-arm64": "1.89.2", + "sass-embedded-win32-x64": "1.89.2" + } + }, + "node_modules/sass-embedded-android-arm": { + "version": "1.89.2", + "resolved": "https://registry.npmmirror.com/sass-embedded-android-arm/-/sass-embedded-android-arm-1.89.2.tgz", + "integrity": "sha512-oHAPTboBHRZlDBhyRB6dvDKh4KvFs+DZibDHXbkSI6dBZxMTT+Yb2ivocHnctVGucKTLQeT7+OM5DjWHyynL/A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-arm64": { + "version": "1.89.2", + "resolved": "https://registry.npmmirror.com/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.89.2.tgz", + "integrity": "sha512-+pq7a7AUpItNyPu61sRlP6G2A8pSPpyazASb+8AK2pVlFayCSPAEgpwpCE9A2/Xj86xJZeMizzKUHxM2CBCUxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-riscv64": { + "version": "1.89.2", + "resolved": "https://registry.npmmirror.com/sass-embedded-android-riscv64/-/sass-embedded-android-riscv64-1.89.2.tgz", + "integrity": "sha512-HfJJWp/S6XSYvlGAqNdakeEMPOdhBkj2s2lN6SHnON54rahKem+z9pUbCriUJfM65Z90lakdGuOfidY61R9TYg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-x64": { + "version": "1.89.2", + "resolved": "https://registry.npmmirror.com/sass-embedded-android-x64/-/sass-embedded-android-x64-1.89.2.tgz", + "integrity": "sha512-BGPzq53VH5z5HN8de6jfMqJjnRe1E6sfnCWFd4pK+CAiuM7iw5Fx6BQZu3ikfI1l2GY0y6pRXzsVLdp/j4EKEA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-darwin-arm64": { + "version": "1.89.2", + "resolved": "https://registry.npmmirror.com/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.89.2.tgz", + "integrity": "sha512-UCm3RL/tzMpG7DsubARsvGUNXC5pgfQvP+RRFJo9XPIi6elopY5B6H4m9dRYDpHA+scjVthdiDwkPYr9+S/KGw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-darwin-x64": { + "version": "1.89.2", + "resolved": "https://registry.npmmirror.com/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.89.2.tgz", + "integrity": "sha512-D9WxtDY5VYtMApXRuhQK9VkPHB8R79NIIR6xxVlN2MIdEid/TZWi1MHNweieETXhWGrKhRKglwnHxxyKdJYMnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-arm": { + "version": "1.89.2", + "resolved": "https://registry.npmmirror.com/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.89.2.tgz", + "integrity": "sha512-leP0t5U4r95dc90o8TCWfxNXwMAsQhpWxTkdtySDpngoqtTy3miMd7EYNYd1znI0FN1CBaUvbdCMbnbPwygDlA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-arm64": { + "version": "1.89.2", + "resolved": "https://registry.npmmirror.com/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.89.2.tgz", + "integrity": "sha512-2N4WW5LLsbtrWUJ7iTpjvhajGIbmDR18ZzYRywHdMLpfdPApuHPMDF5CYzHbS+LLx2UAx7CFKBnj5LLjY6eFgQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-arm": { + "version": "1.89.2", + "resolved": "https://registry.npmmirror.com/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.89.2.tgz", + "integrity": "sha512-Z6gG2FiVEEdxYHRi2sS5VIYBmp17351bWtOCUZ/thBM66+e70yiN6Eyqjz80DjL8haRUegNQgy9ZJqsLAAmr9g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-arm64": { + "version": "1.89.2", + "resolved": "https://registry.npmmirror.com/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.89.2.tgz", + "integrity": "sha512-nTyuaBX6U1A/cG7WJh0pKD1gY8hbg1m2SnzsyoFG+exQ0lBX/lwTLHq3nyhF+0atv7YYhYKbmfz+sjPP8CZ9lw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-riscv64": { + "version": "1.89.2", + "resolved": "https://registry.npmmirror.com/sass-embedded-linux-musl-riscv64/-/sass-embedded-linux-musl-riscv64-1.89.2.tgz", + "integrity": "sha512-N6oul+qALO0SwGY8JW7H/Vs0oZIMrRMBM4GqX3AjM/6y8JsJRxkAwnfd0fDyK+aICMFarDqQonQNIx99gdTZqw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-x64": { + "version": "1.89.2", + "resolved": "https://registry.npmmirror.com/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.89.2.tgz", + "integrity": "sha512-K+FmWcdj/uyP8GiG9foxOCPfb5OAZG0uSVq80DKgVSC0U44AdGjvAvVZkrgFEcZ6cCqlNC2JfYmslB5iqdL7tg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-riscv64": { + "version": "1.89.2", + "resolved": "https://registry.npmmirror.com/sass-embedded-linux-riscv64/-/sass-embedded-linux-riscv64-1.89.2.tgz", + "integrity": "sha512-g9nTbnD/3yhOaskeqeBQETbtfDQWRgsjHok6bn7DdAuwBsyrR3JlSFyqKc46pn9Xxd9SQQZU8AzM4IR+sY0A0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-x64": { + "version": "1.89.2", + "resolved": "https://registry.npmmirror.com/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.89.2.tgz", + "integrity": "sha512-Ax7dKvzncyQzIl4r7012KCMBvJzOz4uwSNoyoM5IV6y5I1f5hEwI25+U4WfuTqdkv42taCMgpjZbh9ERr6JVMQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-win32-arm64": { + "version": "1.89.2", + "resolved": "https://registry.npmmirror.com/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.89.2.tgz", + "integrity": "sha512-j96iJni50ZUsfD6tRxDQE2QSYQ2WrfHxeiyAXf41Kw0V4w5KYR/Sf6rCZQLMTUOHnD16qTMVpQi20LQSqf4WGg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-win32-x64": { + "version": "1.89.2", + "resolved": "https://registry.npmmirror.com/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.89.2.tgz", + "integrity": "sha512-cS2j5ljdkQsb4PaORiClaVYynE9OAPZG/XjbOMxpQmjRIf7UroY4PEIH+Waf+y47PfXFX9SyxhYuw2NIKGbEng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/sax": { "version": "1.4.1", "resolved": "https://registry.npmmirror.com/sax/-/sax-1.4.1.tgz", @@ -4227,6 +4605,45 @@ "node": ">=16" } }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/sync-child-process": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/sync-child-process/-/sync-child-process-1.0.2.tgz", + "integrity": "sha512-8lD+t2KrrScJ/7KXCSyfhT3/hRq78rC0wBFqNJXv3mZyn6hW2ypM05JmlSvtqRbeq6jqA94oHbxAr2vYsJ8vDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "sync-message-port": "^1.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/sync-message-port": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/sync-message-port/-/sync-message-port-1.1.3.tgz", + "integrity": "sha512-GTt8rSKje5FilG+wEdfCkOcLL7LWqpMlr2c3LRuKt/YXxcJ52aGSbGBAdI4L3aaqfrBt6y711El53ItyH1NWzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/tinyexec": { "version": "0.3.2", "resolved": "https://registry.npmmirror.com/tinyexec/-/tinyexec-0.3.2.tgz", @@ -4532,6 +4949,13 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/varint": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/varint/-/varint-6.0.0.tgz", + "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==", + "dev": true, + "license": "MIT" + }, "node_modules/vite": { "version": "6.3.4", "resolved": "https://registry.npmmirror.com/vite/-/vite-6.3.4.tgz", @@ -4767,6 +5191,12 @@ "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", "license": "MIT" }, + "node_modules/weixin-js-sdk": { + "version": "1.6.5", + "resolved": "https://registry.npmmirror.com/weixin-js-sdk/-/weixin-js-sdk-1.6.5.tgz", + "integrity": "sha512-Gph1WAWB2YN/lMOFB/ymb+hbU/wYazzJgu6PMMktCy9cSCeW5wA6Zwt0dpahJbJ+RJEwtTv2x9iIu0U4enuVSQ==", + "license": "MIT" + }, "node_modules/which": { "version": "5.0.0", "resolved": "https://registry.npmmirror.com/which/-/which-5.0.0.tgz", diff --git a/package.json b/package.json index 88e4215..46efefb 100644 --- a/package.json +++ b/package.json @@ -12,23 +12,27 @@ }, "dependencies": { "@element-plus/icons-vue": "^2.3.1", - "axios": "^1.9.0", + "axios": "^1.10.0", "echarts": "^5.6.0", "element-plus": "^2.9.9", "pinia": "^3.0.1", "pinia-plugin-persistedstate": "^4.3.0", + "recordrtc": "^5.6.2", "vue": "^3.5.13", - "vue-router": "^4.5.0" + "vue-router": "^4.5.0", + "weixin-js-sdk": "^1.6.5" }, "devDependencies": { "@tsconfig/node22": "^22.0.1", "@types/axios": "^0.9.36", "@types/echarts": "^4.9.22", "@types/node": "^22.14.0", + "@types/recordrtc": "^5.6.14", "@vitejs/plugin-vue": "^5.2.3", "@vue/tsconfig": "^0.7.0", "less": "^4.3.0", "npm-run-all2": "^7.0.2", + "sass-embedded": "^1.89.2", "typescript": "~5.8.0", "unplugin-auto-import": "^19.1.2", "unplugin-vue-components": "^28.5.0", diff --git a/public/5.png b/public/5.png new file mode 100644 index 0000000000000000000000000000000000000000..c123c5ea7da121d5f4b2eca12f533ec76703b4bc GIT binary patch literal 77678 zcmeEu_dnJBAGhsfuk7qNnJ3BKn`9+>CnQTzA-oX>l_UeEO^TvJ_%5RVoQ4GoP@MOj`O4GsN0{E9iG8yJ&B8m4h@Y7O+{Wt$K&mvCIeTxRZq#+J~(I1Bxpwu^W{|%B?wD6Ys5!>?p=Sf@m5e`^S;K2YlHI3pRT>(BOOMRVwHIlWj74spYRCW zilcCkn8za%LwzyFIlEdsSvhNGD^QL=Msyq*ulZ95Q}=uC`)=CXF4O1U6X#3lCBO+{LTDEYWDPq0_0+O=Knk8>A(6g!^0jaEeVnvUUOiD`Z%0LG z7YCPzUCpeK=T9VN&oXwh`y2CW6poOEci0PZQQ(Eh#;LLQUVXPsSv-^;fGL>PE zp#m42JX~C~b2KUNu;bTRDPz3?DTIh&_XTnFlau;Zc0I&N5aL(o`*-f#ajEwX+04tX zy9wu@@)}b@uVtmaVET)Onds=~d-v{1olOq9)En1t<`FSWFE>5Dtd zql{e?`oEtU)+?b`wIE(LC$`thu3D5fTJmt>Q3|ig-q{6Nc(4U^^5Z+H1jn~W5C8Wb znw&`?vNF6Wc~~D{qiCc1Rz$szcXoE1xGCj)H4C(1b7gZXtQFn_T4KY8s>4K@;JP2O zl8n9A;mlk$NQSRx9d~g2`t>WYHQShX(7KACec46iI9%t<|9_tfR#Fq0ul*!PbI4Xe ze6VojNvMUrppl$hdq)QrXA8;`uk&iISDlBclkmU&^_R^->lI1pb)vVaow|;vz@9*= zuzS3_Bqt{~US<-6iA?F+KM}9?q7cG-fBaEFn!&@W*^1wQCC*=5hd;G{b)PcwWfJ zs3yEh7#1FWotC7M?9OCxeFbQ*W1+9$*A>`R(<*uoY)4`sh>!`riK;8d$H(6?#7M8Y zEGt)59w+qX>u|O&RP z_Vx1mTwYF`4Aqx1&Tecq#C9#mmR+GSoR# zSuQRv-~v8xm_eq;qN~*YeSxguv|Vw(hps??WM++jOs$xs*U3W?WQAkcJ^t9+5u}QjJhRbR{XaK9toyfh_1NQYZvPvDJtT}6R1LLlziD7 z)3dVlIFpLZ5rHHz-Fd^v!F^OFAhCh{?^4^OVF9c{6B$mDA#%%?@ zT76Vzv#d58vpc{f7T>wp_G>9GhicTj;*!wImeMzvCB=u3eg6E;o9`ugj)o_t`kMQ- z1!#VRIgIC$MQHlmlv)(e>))D|!yCIbG?kQW^u)1NRaH^(8td!pE3+pUme#y`r%2K1 zAx<<*5s$^zoX><HLFs8)UFyQsMTJuio4mTuWK~tdQr)+2>J2lO z-^8~69vy8@*Y7`KJfq%=af&S-D{+F4&Fe3RKEj&NtEquj@+hN?m!3QsqYL|m#yQ`q zMchw0njC#@uO`!mnP#7}!~NC4mZRC11=`mryKMz1@vsy9;~3%1k$4I34ACCqdsp8b z#M7l_96%A+(L(XG7knx}o1q?dhpii(wJ;|Ky#+2>4;l-OS%wufU7|2dz3Y5Yic2|i zVPz%_H9lun`Ceb4 zdPYR|QbtAwJYy>QkiQc$b2UlzX5UAss)=cPT)LMxES&W6G0f@5#Wh?u^sKa=xPR>m zOqTqCUG$}`np7d~*ng!N({nZBV*2i_7b|bY-V*qh>u`Ezrl=Mu=2aFHbXr$k3q(ms zG*whUIpm>?9JZA|3uZ#h69me2L)$>XQbU!rt4^!-cemu`J24hc3dWU-!vCq&L(_KN zy3yE5PfU;di`uUfr3Nd`nWSAZh7*L2QRLM$YcEJg5E>8=kdwn)tYZfU4F{7yzgR~V zT6+T4sIyL%b7sd-kPP8L>6oc$y`HjfI8}am=v%>E`r@P70B8Xw(r+cjO^Ujbt6pvY zv}I^3HQJ?ntH_=JMaF{&TV}^Y+@ZGN^XIfx&#b|ez7=S94+v&)>Qox3hS$8}+{U{);&9 zS)2UB-j13MPkv?(S|%#Hyguw&Pa_+EaV|zC*!GdBB~;KT`Ej)3qx<&>)xJ+pzlB5$9q0?W zZQP54CcG(Ao8PRf+S}WAJ-nggS2&noW%p6XN!A-MZ6!wDA}M2$ByBMxeV-8A9)a`? z@hSY}m?!<*Zv#6~lIbB!M6O{eyGGyX-Kn`RdGdjbgBCfOJu5EI`qBq-u>$tEq7)>v z^h(BNW@aYs1xXOu?<2Vv4n7`?_j#83?&IAJzV4~rR?6&$L41m1mip%U8!3H_lCd<^ z0zf0jvqfG(flIDXLp>ipOq#Uc+TLcQp)t_cUt3$7sC8uQ`?%{t@8c546w6@I(OBW! zvC#S0c;JHlmv2b4(LSE0J$KQG5nt@(WQkrmdqVHU*%52?r=P!PWLWFoe&6Jomk@l>mgFE@^qcNk!z)}JpzXes`PR~bx<;i_3(6ZUJ*%Kx= z-DHXQDDVW+@0X0RlZ6}ej?c}RaZ`$kiFsy1xAAIXa7*y+wiirSV}DdhJ-FX#8Mh>y zx#~>2QW(J(s7L|mam=puSVoc*hjdxV?o5z=^!!4Kl47gn z$~Ureug~m~pEjB{x(fiaJWH!H{da9Ean>kqefD6_NN;ja|C}IMm)}f7tp=Kzm?dAUY<7DzdXZjCiT#eMt%Pdu0JjY#FrY75dzZiyH@CpA3l!389Xyudl3SXlI9m%XSkA7#RuiWXl9Cc+IqrCKi)PJ-Z9%*ns-JfeeLY*EH1tU zHFt28nfB{P?!J%EqZne83P)rHDCY3BsP|5HgtUn3gT|j%jS2vU>9nkz+RR11j*bqI zWe%5bbACH!H(*^=Z>(ObTU%2jdk5!zU|r|1ErkS6-TWHAd^nI{^Ku|Lz>^8u0ly{m zS_!54iRHGGZZezVNZrG4*Skv7LSkgyuLoF~4VZ#tT7@H+T? z)O^%bnC1I(#f7;ub8z**O9E+aSektN=2f#wagO*IZ=7;`Z@y`{QVlN&0xPH$IH3-w zTu!WPj`VUTDr&~TT{HvvCvZ4fz0d-wqKnUh>{!B_IqJd=dx`7*wGlp`3<-7U`r4Yg zfgojMT(a03lneqY*0~FpXSBG_B>%!FF`wa`0$}))4`8O zzUHFwjatXKOW;GY?|L0-_r+s4NE}#iYwvsmXv19H`Wx6{eSN(S=k>@==v}~^S&HFg z)znbB6avpE)n&~Lnd?Ro@LMXg#?#(R)7IRmyFF}mPnI`j!&TH?)}eOF9QCCrM>_ak zFqL8+DIJ@yK&qNPPaxA<(HCD=Tyh>bSy(Wq^ySzEXLQ+BGYC7OrBKz*<8c0a1=D}0lc*$MkI0g@%)>=}RR&^62&c0oFQ=?}3woFVQJxv!{@a-eRA&=Uc< z4UHYJ2GX#0Qu6*itOsQzb_id!;f-iTE}m8|;=r^PVstvm2m;$F=}{F`MxiG+VppI? zAOwdo)H1OWdR^zg1nlna*3S8!`CYF1>2Qv{z9IIxp&>mjElTl`Xhv7+yeGNB?cJyH zdBe(V@oMbAgaKO{mI6eArnc@H&#bg^Zb1;nHcF!AB`2gWGFjJHmCN6`ZGIFk7Da&8 zjtZ9#H0F(+*i}zl0vJ-}3E#HjQsE=!_NS=0nEB2_#C=*((Va8?)F`N<+%%y)1nX6U zl4k>szR&YC9xVlw3MZ*r)L|v^1K8`eGS`}aCS-QlxfHyLW%Bq{ka;{Djo&T6o&uzq zXro~ly~{J9_@zrIBb|M$g(lz9%^o0f~ImeS(llPamRJ1B*JACcOFj#5Cs z10|7*w9LYN5cP=*^sSoAQr>X6 zg@|;zkB{A_P)3%lWMXpTM-VIkl494xI7gEyCg3qzd)SLM6am?dl|Yk~mk;aTF!i3W z5MmrP!qTxVa(@65~)n6}(Gib0Uq-JIk;RG!>y;=2q#Y`971^uFm`)So=lww}{!n`mM@tC3+Pejs} zD2hLB0OCOxgE${fXGcHFEa#zT(-bU8yUP-SYxIskoKMG1pmF+{;{M}%>A zy&RPk6@hB*ctk}jV2X|}KG|)kW z>}Ixot`4Wj>vqWql}y_{^a7mkBcNi@6SXHjC>f*g4ryP2PO6DyLtqR?wH8?}ivmN3 zO1P-ao1(-*+A%u6yXN}YL!5yqOiWbtgKmiqC-y*srYGq0Mwn1){dTGRoKN;v{H~7t zwl_E7^einc+4}Bzh$9$ZGe|_R8-!XQ$a5RlBOV(Ram0Nh{kXJ-PJ)GAFPLaHX7}RJ zqeqU8vj&2MQ_g$JQbbc$}Wf@M!#-^h1hP~ z|F+VX64?nN6N)z4HocRGI1ezT^qH(3C_ci_uG)u(hAQgnKyap`rTt{c)AzAwF^-xe zRZTVsi|?y5t4@oE9RkN#wAu&I@~HcIU@mm5J>^JJwh>$`tW$u z(J%e+BsqtA&&pnEDox>th?Laa$jFjg!~V%RfKXxj&?gD11-l+^S3TjnP`zXyy<~4TqoZdWYJoY!Eg4zYOkpCshITj5 zopJn*-^3uu=P`cgk6PxgMjvRTs<9`2Yg=$aQUHC2bKu*;crnkOa4Vsg>GDOrG2pX} z14|Dy>uV&B?a4kXvXItJWvH=Z27F24(qn4s{AjPIr|07%!9sxeok&coa2r?mdioKL zN&QQF;22ng`+%GBhM^8>T4cW5s)q+p;Lu=UP+?C{<_wd~QDa{^I*W^6@|2{E%$eng zuoR~6ns-toZBNb|u!epI2!WH%uKK5CWt}mvPJjvTzxQH4$c_!{C(UF`d;>RXE$VJ5 z!`%>fTzEEE1ls7YD|;h_8XEWS8*nEV6x{seH#$1XmY^aV9QYR;0=N>Ck(~=p<|<4= zVdDJpUMsf@Sz51t7&!uGSXi(~ANaNF0gd0Hb}CwtH5vC;vj4}R8b%h~P^p%OZ3DX4 z0~bCBWzKZ9ck(O&w?sNEcOPV(j_wai`JMh%Gxa>i( zx0*{|th}o7tXFk%9;n+Yv0&in% z({1UEes$6BT!E-~`X9FJ3E|yK6-homKA4!82?+_HF|B3D7NWbXzEP~P%x2-4aX@5u z%i*}l9_jF=m^FF5u(u}|cy;5(4NwN)EyIt&q3CHPy|8JcXH&Q{eP6cHRHB49_>HS* z)5{}=lCcO{L&>Zdd6qckFw9ZL69Tmy+_^ng+aC4^>T>jjVj!XqKq)R9Jq9dLvz6 zQ19VG=pSSEpD=pwpugummhc*_5Y-wrlBkKcl+%>tVZeU}s-tX9TwL6?&-P1zpm(xP z)J#lf-~=$@g-BkV4Ay@7Bp@gV5HS}gIC@7{it4XDPyzv309+(YL8hz-SpnLEvkRaL zuughq#&N0zy;dI^8UV$P{`m1@d>s1e8`<2Apl^?@3`vT=AQN6^^Vpw3rN2h@BJdrq z*PV8hZ%a!~POD`l0Rh3^!$V+TfFzDDd{g?We>wMHaOzRBTfN!~uT&oK=WT%H%g5KU z{b4IGWT$kPR?*voV2Fsucw6l)Ni556%FWFUhT@wVOk5%YV&Xinsj;!gmHN_jLw41# zIKQAZJ*-~6u6QSX0KB(%5`7;D2?+rh!VC5d*q8~F#nt`t=F|7Xw&I?9`G8^u(7I?3 zY~{s=Z4)i1BRd1Vg#_)FjlS-O8W9`q8_fs~spk*dnx|*eJmjW)Av%N0=uLtb@>YEn zihRp%wBz|OxTMhfJT?tw}J?HLt;)Sy;4^Uq(rxa;Cw=j`+YrM|5z z1tvp0PeR3g=A&q`3b2*RezpeTdS+57?DnVL+4VRtt)2B+FGvCI+i2?e;K2hE6BDRB zi?&UspjRyI3g?){jooA4)Y{i0MNt#vR}r?!gP;23$@=fHlC|njhNayxj4f`PhA3+A zJcLHX3?%UhZ!lRk^N1smx-yE_o~e~9yh;6E7NFN^FG30Qb~ zdgG&`e`BtWV}K>Mqw+k&)!)%F$A2kRvUk3hg`Yt^WT`xWg^l+{?>H&HmyA#uT=G1| z3uM=wf&P9t_UFqSQlwa|8wYN#u1q|ycIYLT<-hvPl+85-mR=D$UR(RBSu&QYX6@tz zpyAY8az`2X*w##g7DY*MF?fh;TaCBB+L-742$;advW}Ng!tru&*n(Y9DbR*9&Yx<3 zb$J1{&LZPbyo>K0vYxRezd-G%~nS0++pX^nt3GJRB5_PQW@m^{FXkw^&go30ILpX2Grg+Z%D8#JUk}WU4PnxUvL-@N6d*<)B`^x@fRH< zAzzPxLz^sG9`-XZDer-F?dtlewzl^Ddpm1uYcNEbnl2W?7`vuW_5^=W@&fJ~UYZ{W z1-M!G=%W>>C@D`*PZxLVrZ#<#7s3kPy<6P%0I{*8Zql9-E5P-S`ITH@_cLz+dqzCl zil-}gmaZv;+CI$XTW>Ot!=?FqEE#EpKf&$WAYzKAs)57hL|SHCPlgu)$|7JQ{?va$9Z2FhRV>KR z+nkhh!w90Iv==r$ENS!NF-;*txoxyJ|Z9U7{hri`DHc z=Dua`=*WR#oWG5Dc!QrDAT{#j(F%b$r#*c*NuocpXrgtCzcRXlkXDuOFI zjdv}D6`ccF;HiwNd^H-v|1txL5!0){Sr8g;5QR-`Iy`w2V9pnRm&8`?mCWCbzST$5 z;uV_aqfmzn3k&bk!nKTILeO_xpjUtTL@(_0Wx**{UPI)^rnc5JMy#Lo6y#l?+riay zsC@~655AW3k8|7Z!u0jV4sLEgmUc;ey7ovG)K!va2z34Mx@K*v43vv*QQ#%1g2zcq zOA9WxcJbSc3?K|XD@l4F9)pYa^XJc3(`;}2!F#i=ii^9p!x>96CtuSXg*%*F*ARUBjko5`Y9;gk9<8Pa8pdhNN{d+Z@{7O&ZGn4c_c7pCT z{2|m1a zV?<#29+a5D&I$+!yisHCcjuF$We6U)e&XP>A7;(e(E>bznjj(<%!FU7t8vFgB_&mc zrLcH)Bk~T2(|&4YWe1LH9yyJ=v%}5_Ur1wxfDl4sfvyCyF6QI81*bo=O;ff4>PjJMU95xm_Wqt;$wS)hOL+-z7ETW8Su`14 ztQwpk=2SJ7J4GYwqGDp;k;V5egQl*bF*rSKtfUmyYxTakc-O0Gh|_F%vA$mS7p0Kj zP*k9_CQBSOBO{0uYvM}20}izuWY=_potKy!qfB!>#G7HeMMa@ot?qhIhu$g_om0F+ zq8p{d39JiB3-A-xLGp0<`}YSH+QR@d%7AsK{wKnv`P~{v1%-r!#Kqq#vw`dOpZ-f5%^s%=Y*5CPiY%$) zM+Gz=>zK23C&t$-bhT2xdtEj=A1U=S|`--_%zUL86@^QgbNJR7sS zI~$cYyIGG-7c$_STpMjG5OJ9~ISKi=MYjf#*W?PM*DVq&V{uG#@^CM5As7~?3_lCZ zS)G*OTPi>9i&WO1KaYFP%}9kWT|(A)uFvhZ{{5z!udSow_V3@aKMORG5Q7q+y;l4i zCv}g|FP4*X?G9vs)C>2Al^8+20^TLrl`46@18}x|zQMT3>n>UNTVZEQIF)bIpVUri zjkDZ$>1*do2;^VYG?OWog=gy$lY7-O8vhl-r%Y2BPy9p zc*naX5C66I)>aufusKh_3*te)ubTeYz`=PRya*c`o0OE411}%&gLqnFpgUn)iyw^6^cePm^4e=aeBi_m%Rn zz$Iq*P+Z))-J2ac@G(S}Nwt7X*az|xcGcEZlNvt1AAs59b8#>Z)>gs2l+T|(LzF~~ zePeCS7;O8Inhm z*gzVM00)!3+Vb^%z#Gq=Wu&Ej1=as(Yi!*$d)S`$+APnde}EELw|y(`OG_UjDYEZc z=(449MEhwG$%&l;g#BOxQ4(u{c)}Lr%{?zBdo=pDJIT!1F_cB%+L<(ai=_0uaCetF zo(~!u8xxkGm@l$%=VN7vf$H6;Sk&Nm<+~g*+~Bj&h8@(Jty|J^+{yPkD(bD6`|HP( z5EbcW^rIif^xz=DlP|>5r4k%J*s8qgz{D>C8ZxoeIVxTj5so4Y{va27$Nb}=m-o%1(aZ`1LFmLRCY<(kMpb1jU7@kLI|+xQ%jqwCiuvE{UUB+Zye zoJ2D~OV~JI!BP|?nG$9mFykA?cOe*F{lee2gX`LOo8XS9=;y{p`%3+vQ&Vt-M(yqn z|7NmOHL4!-u9C|e_9vDCI(qQ?VgFcu)+vrR7nAEO#NW*0Pyj@$<^RxtXP zK_>H8lSWaGuDcS2$rX;=S6BZwIQX(@7N3fj9^3%P1o<6@`5i;N$Zx9V*@^e%MCBte zeJ$fA!c}UyCm-ldHH&#%%1dJA1-I;k@WF->u?qBMNH!9V5XvA}pHA5ej{o?X)cnbg^mCRo_<0F2#pRW z^RsLn&bV~e**U_m=R0R8T}29oKLt)S@>&!Mpr3($^a?*fS|eGEW~DORZCDj^aoSZh zdh9WZT0hyu)RYJdL%aAdC>8o5u~V-)ErFAK3Ba6x36fKanXjjv9bRMr7OuR!dB_-R z{-PLyB`s@kb-;QbWZ}cDnW^z{At|XCG(e!x01ZeRSg6 z`ZHO^xcm=X`<@>wW_5{TJfi~_I!^h^*X*yM>rdAf{S%OJ%AnZ!`AKy z8czWgIFS0+!)y?PC0s7pGoE_mXDK z10M?`C@4sLP)I;PnErKZE0~HpW@dAs;c_Mc{#|tyjbW79I`Dd4KMftI-+CXSt&5Af zV|IigvTFiDscQ36tToc^Ctg&iGN+I=F6xwt+nKI^&Y5Hf`}=C6wLk1n5))$24D-HY z9pczb?L$`&tqh6oJ@M(PiN#jFA~ku-R~FPrkvtpn4T4s_e()|{$+Hl&o5wPJZ?f`Z z|N2Y*<6kc#TGb||W^?Dk!NEsQv7;{`#t6DwD=y=ot*siv(v^JAMI47*Ji~$j!~h=; zj|ly1sBmiRRgI1GG2H-Okr7#E)2l#qm=L@v_eikhiJ=?)KGBfP1vfH`!3*K_IlFTnJwQ$=S>W0OKwRCR1$vN-rtQZJveUe+t2 zEfCn-dt6@lUUhWH^QHikEiNtPp}>QPGMxP|q8k|Ds*r9`V-K|mY@LTfOE8cr@e(}A zi3#d%XVBjvG6aarHecbCV3z#jSVj7TL$9Mpri}q*lL|sa#kAp^KqX(+a&=E3WGy(B z9NI`b3NEhy=@XEK!P=oFfb1Y`G+Afb7(SVa8hpLPYowsG)?;hi>x(w#HstqO=CTH? zL2~^5{kzZ6OyT&3g4VJp!$(Txh1O3wt3vcdV7AzbCaKCiL@~r9@XkQ^@FUQv?R$Jp z!S$fMo~;|_YKQm=B_Qy(o$*q$RQJrg*?ra%w^v?<1QAE+zqE%*1e^x!>r1MTylj;yA(c5vz{3h6l>%09|( zGJ0hv_t?lLIAk7z;STHzs4Qf9zL` zlkD2)G~9tF)uC_^ONCbM5mswSGq0w zvuBAmb3H>@vNaTc;pOV$^0Bk@D*Co>qz)bA^+9SW(1w5?x0i6Cyeq>y zlIMJVVIRtlc}uYWhOdae_?;-5Gtu-?C=u^=iqAdXKD@hr%Fq1Udr?pnJkK_3FML~I zU|>D~SM!^aHfHJTAupNj3hiR78R8OhJepUk(l#eQYMbv03%@d)z$6wQnw*>*9wx;L zG3V;d9|wc(J*=u}E911+hW$Rq*u-At9Bj3ln;Xb7fDGZubRW66xY*kRa)Vd+8!~SC$mR@s( zeOMq1gCFK7tEx$ep=csOz5OQwW{80p2H(v>+T*+0TY)yaQCfSso^`q2NoD2@n*+Q?jh*}}q;I*?2M+)Km9D`YtAcX9cF*ke zJAA54?>!ah!n+>Q&2s*bWgJcl-ori-&96^zb^cIc+iUfGPr zNgT%x_wf!crIm5+gf7)VhA2GzT1wvmP$Rh}vXbD(li-z#iJgsPUAn@{%L|A%C@Xml z4Rl_y$|yOqgFlm1d`*AJ82rJuxdIu%R#-+%2aXktpA2&nccCpN-ZfIHnH6kMk$GRV zJSUrjx_kHTojXCTit;-?PEJnN);Oox9r|B7NbXX}HzPnqQV^gGu}fBC#}AQhYHETw zl$oI+EhD3&qhmJ_jA8JaHN(R}BnoiOe~HWe{e4J>UY)gEz5LamN@ePiQ(Noq>&tMR z3_+f~Et@yIBi<7DUN$Y|YhUy7SuQS(oTKmQNY>BILoi0n?PijVlZ{4-t`wPULki%~ z!PU2x%$lpRAr^kCECQSqgpb`_XQ=jlDm6J8&SA%Dq?U=8n7O z=jTDX%hz6?yO^2F07C+r3AB9n1fUasAhUMxLjGNkn-V;H;n#GGjKpE>scOIA_6Yl& z{{8+veq?>R`e{n{Qt^MnH}%hudXp7AdwEA3vuG#v7osNO3=nV!PLc)kGlYVGi^5B2 zi|7L%=jeIdE3_sDs5?u-G2NKA13~y#F9eEA_o4%``M(TFptY7GR1BZHeN=b?@nS zBR!>9BqGX|$9pH@%e0_tsux0t0C}4CCz2E!@*nI8olDMY{%rkXY@VbvB%O}&!M#@e z^xYC?f2uSj4n~)k!GIBm(VC-{E1ysc0D57|{A@p=i-OT1nEuSxR(fu?_(5T#>Gqc| z(gL(i;A8NoHhS#l_F4sA7xVfH5=(FaTu@;fHg6_mcmQ6}Wk8jJei-A~MEB)^*;O?t z(ACw~CAsY-w3H2{OxhYkp|<*~7QjTt-06>6{bUK}MJ&?hE69X(b#*yCfH5HV&7U_T z7NN$F=LcAf?wy>&TLUUM*>^LT zqiQ`<)Ni8E(x7njyX>kanJ`};`kuc7?Dp;*P8DOH4RfgzvmPU(^w8-MSf_KBhqZ7D zD54kUxB_#igFNB0(|Fh9Uyd|@AIAT-IIfg6gEBvwktadM5Bn3p3t*d03V;@gKH=qL^Kj*za@a`Qu zmLhF*=qt8TC62urrI25jv4r8BmQa5rBqV5~e^q5&aCbX{Jt&#w=RO^xcrsgojB|JpggYKLof7u?11R@z$;f*amQJ0bqcsW>pL#7;UU{(f4&%%E-sC zA%Nb%E`zA9LoK-J#=JuCEFhWgpTzfCaVDi@WPl{l^TmHr^;0Ry4XQ|mu=Yw&*-)sR ze$G8+x+w1i5iFm0Ht>H z^#!*sYj7N7fS7Jj!Je;tO>!0Wfu<4Tz06vmT?`9NO%SLFgCvb6p%!4pL&yV;sbBY! zbKyw%H+70~3pb&~%xM*!qNA`1J(A#YGd~{y6QHC+&!;B}YhQqNT2@xZk>&mI-Mi2w zVKpgXzsqx&MYOS51wR!O`f|{4L0o7uotvIMFV^sZG$91(!`cHBk&&G&5sNTL)zJ|Q zps4QevJ~0q`Aij(>VP@wv06PF29MLg&?QJf(&WrOD=R_2_3lIuKM$v2 zI{u)~t!re|hw3+SY=U?@@Wo$8XHX+S={(w;f|N+%uq_TQE=XQRMsx^&piX2Dm3!lU znT;mOn88FAXvL+ar4Sx1hO>GXGBs<}3lwhxIu{NdEES9h z!aP%^L^=qgm8l(BMIagnhJo7_cxKQ zi4DG=ww(Eb>U`@AtTJiT2+o;?3P~tfNkUJ!Z1Bq_3E7iWmv%h_(-oFzb#7tHR2Y^r z#Mm5d%|P_2vhv>?CL|aNQcO=fI3#oaeVV86<70gP=0O;mLCRPBpWks4GNsD&%m^%m zc_8z5^f6O`8}6>I;s8>>Ri111Y3N>pfF)n!PFuQTvnOKSvH0 z2Zk;473^LZx6o+i{L+9NS>7<90Q6sc^hA$-`~;+J_w=cAOl2+WKEI?S5$TtOg#}II z=;Y){2f4=R*qDVm)3nN8-yLx&ett5dFfgtlMo&H3Gi=@?ck)Tj?rh81oG|f79g??M zAB=6$ZabbtDG93z{lJ&Lm8{baVb5NxHY?r`+2Of4z9dzcVgqCXjUyVs1Pn5ijAcss z`8qrAt_|ne#<$xrJ9JhM*;dPxK|*ap$@bKmp9Y2*9(aIVJoe*WXmG<1 z4M~E9=DbH%_aWLXLjrEfYep$kGcye`3FNE{e@S_{1_@TRVKfqRfmpZ*BHpFV`963Y za-M!i-1BpB!YO}Dvkyom1QPiw9^`7pQ|HlXILIxD{N{M$k7xQ9co`fuNX{@Y9D0Z& zA5Yi|mg+{b-vj~*18PnC-^3vO@6`lD8{k^zwi5X=YOO%t2Jxk}!g^LB`F~je7#PZ4 z1T97WU-<Qic1`lUAmykt;bbf%wiYqwTvwFCE{^R7=J;gdX^XWb$?!(scj9*Yw_O1OI9; z0D@(dx%*6;ysDd<85+rRu}ig!rJH;~REGWj7kG)4m1b19)+WHl`Tn>`G4B>*0T%14 z+rfsVl+kDmG2N^CU>ic19oj8qk9*mkB(;m!qceYqK=}n%hO|+3JA+4tb9?1E2sq*7 z9OnM9e^|M$+s(f*pWi13Vs+kj&m z193M3I(cHg$&$)?=9Zv8*FH-|DYDk>RqDflU}Ua7l7iQ`4(<9HjAH<#u~OVwm;X7> z+wWLVS2a=8O?OtN!ztl3{{@mUL;uo1sfZTh8>!S3N7X>TPFA!0w(3`#!MBrJ#VezE zQ`i!h{&5kXtV^M32aP;G@gCIcsAZu5wj2Pb}6;ePGsSS>}c~47e6hlmED# zjW-|OjaCfulG+=}7t8poz;Xx&4@8&dvn{Ada!vssNCH#1^vcvUG*ww12KVMg8b7|HA(^;h=#z#ey1hE5d2s)U zfdE2mPH;kx^K@yZIA?G!vTd|2vV%PM+aHhs zo@ltj`$L%by;WG*()w>>T#MU-KL6*By*R^M^;13YpT_J$0x9D@vz^Maq4AY7Xloi1 zBgEqz$Q3}EA|fJ!VQeT_S%XIaOzkZ!7KU=oINxdmA9vByKc@{J-%s*eR|wc=iNFU2~NDv*AaotWcqKFQ$7I&3WgpassJ9tzk=^{5$^xEJ{O(&ba;C12Tt4r(*UEUr3qmz8?^45 zamwe5R4r>;TV*i4jT00gZ4Rjr=p{_oE%zz0ataGqfiX!FyLh5rCj26;FRk_Wqe}3+pi^N>MRyw|+G< zp>G8&{}}PTR|D2(-`ty@{~iUP)ryK5u$G%6?RJLDMk7}dd6@&MW%dheuAQ9fmlY0U zN%7!Do2v3vs4cpA=b=ewmO{;OJLkj6z%(GO0}8fo$ukEBH_;4|Hntnt@;EM?s}2ES z=j!OaSUSPV8l9B$aSP|YQD2RDQ(z28*I|7t;RAl9FsL%VzLE?vFyjhxHo##K5xCCa z3wdTLoohiXg_{!k>StwT{ilo!?guhK!F^l>6=^VDCbY!e(lCT|;`A4>e#W0Vn!*_WWgl>@0Wo@J zLP!M4%KbF9Z#*1wr3kJc3u4bK6ZMvJG-~gT2E{QcreSBy+j=%e%aMNNtn`OaDI6ux zPJ6Ai3rBn|Hq5$T^?|7I_wQer2m*Z!qN8xc;Ar#m@i|7{`&?E;vF{#~^Gyh|qXsg% zkWw))H3cX=Tk|X(#9;}lO=lR!Km>91bD2b9$z#Vv(cQ#oOQ$W0SI8Td%>f6}V%kxT z@{=(qP6|L{z^Y1&K03uZ&0ulEY_VmfH)JOi$XE4RPRC#r=U;FXgm{qaRoTd(zpxp9%zD>aT! zo!Um$;V)KDl;ee8LMP{>ZwAI1D7WawyOV7qQiP9ch)_)Hbxrebv5D2XcXG!Rac@ z97R&`N$&UG@ol*ZlR976KL5522Kyo;xIjIJ2#91BU!3x%>gv+o%d=;{hmEcoS@c~z zb4qx*1VKL>9oc$~ykQgp<}apoG>-49Txs51o}MPe`2|qIVGQTw|L-y`M{-oh;3gfIL(AmELSj#9Lvz&mofAaT#; zyRnxXo7_RmbA;Yk?01xXL*9}6347C1|D`ClC;tr`fJsQA4^AZ8HH3BlJG8C;L(_GK zW7)rbn`GQ1D+vi9D@pbyNl1295+xyzBzuJHBo*0(B$0~jO%fs_gd`*)gfiaG-S2q& z=Q)n&DDL~ZzT-SU>%8LUS7lK+KRXMmGGoL}yD}y_p_R>&vK8tbi=uuIaaL#;fm)qX z-Yos6GQlwd%jhY7X5B}>a1bFa$JyE0%ZrtgkoS3_)j;^r=!(c7rwKmnaUOH^#;pt= zWl71*j~CICaxqZT(C75u*4yS2xN?>KH$ zM{}{ueHZGA0ybyif1`PtG&*{+RQ4wsQLFrvQ7;BEe<*Kphyw3MbNA#4?XVBufl!|V zT=zYEHXTVJ-Kz8K_a*(H5cpUOxHDvLgEyR{PChasxLO>F^%Dn){7}|iO*lzRObm)@ zv)ZBGTk-5oFM}^db9Mu7j%xY>;WcVUH@CE@)gOaPZ$*ki8|-2yKr@VPbd37WUrpbC zS@2HCO97(!VnO;gD|)?hpt-MyMu3&P7;Ifu%d$84Oi+6Rod9h}!x`7IfNX;gR~YMk z&|{T(f=mf!5^ev!;)BNE!-eajzCV#2ff6I%SnkM?-3;NTt%IY?5*L^+zZy8-eTic4 z>7xD{i(i^NDK#B0)r&-kpDV+P zk&>cjRQd2>BojfJQD=+rB8ARGg9N=J(6zNWFb7m~9H$BmQCpL{HYF0zSU)Uf$O2u^ zhYv>5oQGa>rd*N-Wy{ra?4iErmi_nn%icv1g3sRplKH1q-7ebxQ`FR?87+ps&r<4s z>VpSxS`IwN$$z!nDj=Yy$sR>4ivRn1_*lEiUkM2ZuX*fgom#@{gZ;~zpBXI{XiVUY zZbm%UNX=D@kD;dd@PXMWaKPfq^ZNOhf*g_S_!V?-NkgW@^v3w}70cd1AL8#{Z6E|p zL5Cl-vEfk_WB(zB-Vy2tiXUc{hljatH;Mdtdu7XD?Tb*|L6%#9Fap+-19pTraL47o zdGqPwOE3edLZKc&d5JU`*yG%Xf$B5tQ;N>iY<>2HwrF9?Rg~oPu?)+)@W81<1R6bk zeXQ+5lcCR_pY_ZDoZ|R?GeGi8ftl!IqkJ5{;6#MHug*OKHa1ZPcu9>j`*eoN}UmbNxBU+n5#8&aCj*0P_8?m>dYKQ{?s zZ?@u%-<3G;VST&vR4p^`{v_-QQ`ciBB;vTJb0mL07|`qdK0?ZQ1APRboqu#Xcyd|_ zGTbJ)fi2v$Gu z+CI|ib*l?6p`)`?FtH5^HHzCQBBlp!WeME^&!EuRa9>lS=5u;f0qs8OT`oH=85Q++ zzI&H(o@{HUzKf>OFY6O8zW9QFMZ8hD)jyP6FU^X{|1({L%z34Bl-)$57m5Kz?l>MA zjaatJHK-J9?Z@}yq)yWl075kAB5?oohofqt#-^(|qnG-Z<}*Ax_AQD&_gP2*MT7JX z4ZiMApDa+)>gS?dBI=7HHI~7y7HOXejo?HkkHm?(fNJ^kJ@Pa$T8VlB;7x051BGtU z^vwr1gb5mC8Z0Qp^?*s6y#5)5b4)WlS!rm06dK9ql|=r&B0UE_8xde-;sm9#j}tV( zfqH!HB{QBdqo-5JGaJ!hr+$PqW;Hf8R!me>BinF+6qF2{<2_{5e$i7`GNWzkPSgqI=NKcxlKpR#+OVWT18O+}MSKIt%^*tfd1#p7oxXv(ct&yQ~NqG7yrwPseEtRog!cxZ6X-Nn{;+ zZgezZeZRDpL(ihq2xZzs9va;ESndO%zt$^pD_9ibx56v;^5x2hM<=*i4kqcwXuXK! zKIfF7x_aK(x$Wnw`s$=fT!?(|SE&e5!Bc6&fIDt()NdfF2|F1uG|D6UVw#7P#yY4J z+s(yU`qjf8D3grbS@?tiyyaz_e^5z489>x#;)z3{l=Gt7DO6Aj$}2g!TL);^1kyWi zC~(&YSWEJbb5pMkIdKcIMg{ZS*$D|Yg(^D-N4eX0Jv5|v&heoT(5*x2N8}ygu(UP5 zy|cnRP_hf)Wr9xQ)Dp_sp{~CnJKIV`*QkhElTc{UK>UkA*m1a4LQg6ETDcXFex4Km zVl*smY?S5Yk#=z<`>T<2p63$vQHdm7$i*o_R3QKz9GqENm-ya0>2b!?6a~XgJ4D== z6d>iM>(fW@z)6tF<1Po{ofYHz0`LTkNe)txw;8soc7C=|fUVl8jV>9*S5N z+9sIO+e?HfqOu~|uFv`@U899MF@?I6Q8rec{YF8H>ZN05p-$I!hBr*FYYrrIIA+!b zwfflE@v=toE=A-QW+)bQz8;nX(yDFzq|4+OpcJY&D={`23JB$K%MH4G27hKzc+;?U z-~lKssr$&y$ax3DjMNbt-lGrSIKY9o?n~Feqt2KaUU79x!vKeg?GHojS=~opi0;gz z8v#H3u6YhmCcV-+EnUUd5iOm~apXkFA@h>qNirD$22ye=)>cRI9p((YK|f0PQ@%Q| zy|)XBkEe1s(^1=zDG(U4Xa4S?Hj|e=9RHo{UslTQ_6<;&s<;pvvtrjG6TALdS@uz z`zKf?Ix0;*CQe;!Yf)CLR3uY*FWTdGBZefQRXP4UIk_?R1AeKKG*0WWTh`OF;9yG# z$YN077AMd^$)uFtiPSgh_Z=NrHz=7=!EUu?`0oFe0l~w~m8%0x8MVDgJmZSBb4oDPKDuCq{Zy3D(%3tEcq!vu>m$CWg3e zn{$z!jN#JW!heG`J zB;UP|HCsqAe0)&!!oxc)A7t9~-o$rRt0f5=)8-!V&SA@z(5A8CvgPQ?36{6^DD=rr7>}HBOb(HU|LH+|*7-1qB5wDk|WiTP#@% zry$KtrY|TJ`R}ZF|DWKS%4^!FcW}6>@Q@Tda*{@ZX8YT>NE&>_W5g@ez>|ed0e5k+ zS+vZqSCla&&1CMRSAz^&;}fRNpJk48xOnmHxEn0Hd|$e@4`iF@-WhOtg+xCBbu!uL zyhnh(nTsSl9oEFG#5A=ju6SI4dJHP!rVp&;9(F4zowW$1#PmM2B7ETgA%}>2J2iYigSg z74`3-p#b#`o~qskfLF=+cDQSj+hbZLJax01BvJO$P#`t}7Wg`ZlGUj;8BFDB=(V^m@e0Qh^%=E9exU=Vc ztWa}7<8|=13J)4C*rB=Ovgb~GGxU6tXtT#ax$M>1`JYE*WKc)Ev^d0{zDCy@ttF#t zK91D#^{L(N)3EG1?{rPa4@j>+v%56f~fYMT2r%CaJTQWt;$F`)+smoQ~sfTZ=melVnWv+o)!7P_n;^h5?lAy zK35;{q?CRo%lOn}7D|rMpVS&h6civa2f$`s6i%INER3Vd@cjAn;Oio)RTd5F5tN8# zB%HM`2$#g9hhMb@$Adq7tWm1G>`0;#NOaq&&7jG^FjbLx=T#y-{4&F+iV+J@ZiSrU z1RXcoR1H2}7FsaK#E_zrl9J+LNd(h0TtJfsdAyhWc+TKY@au?;GE~ZDu5ZSX2YCkg zaM#!J+;QrJ!H*w_R&rYjbd;pjXWPnYlK;c<83hUrXHNg@A#w51=XUCvnqfxyjn(|) zoOAaKguZ%|qjraojU#PDD#R`6gUHwY-XwX7WVzEK3sr>uM)@p09c#SRER&fzE-!}W zAQ%L}f?!N`y0t+HvLF!^-#TijiEBS`&{4fiK>|xkht}^0I{es$sQ#`Ln~iPVc}Q-Q zPFfTh`>Mln4;NQu*SQI!L-nj(*@UPjfy5n5MAE}M*J{Ogua{Ka`}s^XhQLB}AHg6? zI%mh?!Vg*59TT+pa#eW3}1`VoIrv$RGw8C$L>j{XU^Gd}w%toRl-Dv^W{NaRZpLiP;{ zZEx;?B%uJn3k+?G-dI#!+?uX5BV;l{F>5>qH-Cxe2t#&q@uk{65AzyR1#XmP|MuWS zQN%Y;*uzX4yVDOdN9sKKkd?(3eIVq*8x20FPilR{M%64-ot=e~ZtL*-D(xc&_SOLL zu-kFS^uKkaY%k|3Lsm3hOL*wMNUA~L1Wv!d9==7AYeoO-?V?= z`7ob-ne@t511=nbl5gBlr6%Z%_0|4R5h5m1iF{4Sb1w)dk?AW! z1d^ZqE$}W;%>qZfi_FyIB%)yRjUOZ?EZnI)^lfk^a!_o4U3&)$KjHpb( ztLx%Z=WR@#*RnbMyrpKQbR0?ocJVA;(4H;+2>+E<_F%Q&4OP`3SXU^>7T#s3CJ(f9 z9fEKbfg`gc*qy*S8N%J~?Rx)Eafq#AA2H4k6)n$`hDNpcAFWNH)d!hMO7iz~$prBP zH}0xAReM!|Tl)ogZJ7R0RqbYFtrs9U1@j=;dAfyT)?84+1s)4xB3ny^#3R!nIyM%*P%!?VWf?K1HpSz9np zJVfiC)jxZ~#|IIxv^#h5GLg%vsx(gi_R^M$+K8&NeQH+x1ANg(yrk>Gjx!6sF0+Ff=UJ@JmT4NGDm)XdK#IOIF>7z`foie?{@M9tBC9r zLsevZ0OZ^dyDVdAXlSUas*29f+?+#+`O6W%gn;F5KhJP((Nrn5Kl^=Jd{uLpJW2PA zv2keb&SR9jpW}8xP0(t-P~AV{Nw9^V0-Y&q6t208c25kZ)%o+GUi z`);c7f*kmG@x_ePpdQVqMPPFgetGf>U-_AL)ZS^-!x?~<))_H(!FrTh8##ASU3*I* z7t1GLEmHT9S{eMHP5h^XQx6_*!&{)C0BL_Gqb9&moH>s0o-xy4U}&fSiJ7yrlOF4U zw{IVS<1GSur)SUn7n|6qsi-nu*EL~#$p&>P)D`e9&CSjtZ-xCjshbo02F#a{ zQ9HG?xW0i$etEQ7F+m6MJxJAjX#r+p2Ny{*byB89Vf9qnjZih-xEA#+-1mq`Irfg~ zkl6og0kXTx&b1(h#@NIJvXU2Pvx{P4sS69xWxS20S$;Rh7)o!`cqnLZ3Lb?QIUl9_ z)9IDPg$k=@#Jyces!muYOVXvJ+u1>X@tO)LS)c%C%s>!*KP!O_kY)db!W=NyQz?(&9gR2ciA1oKg}=CENk?EJZkq`2Gk z@&5N|uTz}nB&BOyG8!>q{%k;%pbzR6akh{X>Jro2;-aH%?~-U;Bhr_EwuOa-kwsWG z<{(N-zhnO4pbNwUEAURDyd1ODark*+Wt`2-b0Xr;lvl+|i#bG`|5xkAb3QwCO01qb zQ?+rQo2#=lXOIe!#aCkNz3cem7=ea`jV%Ba%O+%eA9{OBT}R#o2M4S0xIr3obx#=< zIok$!ZSuf)9e$N@Ikzzt;3G4SQ*gPNiE7Qp)y7{E-8frSF0!{*V=~wK8f(fb-(4Mk zfO`X{%o?eiKR>GavidjwRg+3I07|6w#PjTU_rc{nC9e2InpVo=XnABoL- z_da^>;+4Xe!mK)MYAohmneZdSFDMs?E(9IW4I*e+>V9BU&;#UtjoU`}a1=#%zd@PA z#eg_F-)pzF${1Jl^o0)TFeh0oxY&+SW1< zbZ$-X8>(?fHL1lw%?E#ANX~!QDCAK9NPqMC(U;1X^y7ReIiSjK4yX?qAn)!UJWxq< z=umlz!S^6SBHG(O!8Fuf6-b6fa#q*DHQ(x?IqrX&8Ml?%W2se#B2t-XD1hz21xaMq z9cb>sNM_~JY5b?YT#U1tHcaCE5n@jL@h1UHw`)7es!#(Wy3_5FiuL`Jl!n}< z8@x&CM`ENY#5H3cLZ0yx!~~~zYFkZ<91aiEh#yGB1rKmc zP*5Atnyg!3BX=*E(rkMAqZ8^}0C;UBu+of$HJ8HS;#N|1b$wQ68#sb|uc(#@6tGBt zfm(Kg1Dpi_D;`2dvgQc=yzrQU2Ji;d3fKnpM~BhYE%Z&rR=<()sWwZ$y7o7kf|8(( za|YWKVzoJLBXO%n%L!g>lO)ADsT;WHR5)X(at=Y?49%TV`k>3rRVq->3xz)E7P`CIjy)ozb8%I=KlPVhZopI z-cBt+DUFpR%8J97{OV;due%+NqgOi>@$DZyqP)fQg&E}q;$l9_#kJrq-~t|ZLqX2B zp_y&yai;8Pl!cwF3uN#Js?y57)c17e`}emv@@c~cN#2_WidQixQm(xl_&)X-deEpQ z`=b7#zCO%~fXEGg$#@EU*+~zayb$vM^H$(yOzC)*m#0#<^Wsj)&&7-f_iKf;Bf+KW zGhzi(eb=u1E`8U@*Z-H=!t~1T3w&-XF}>om zXuaHy8W|Y3kR8@K4W;0P8Bop!LMY=gv|>HOHbkv4_&v{#`T-X&erDu`pkR1p#8kw` zPM4)Z^#wUW$Ow)6cCv2s_EQ%{@~VR&bwVN{J$R!jhqxFJiCQs|ro*qn$MoGCqXUfc zxBm3kKsh@s4>x~|R`=65t!$0c;vypI^fYrzyDy#oVqq8^XpT(L!lELiWCi| z&CusnJ@MP-tQcFu&kr-D0O>r+;i<7_<{}25CAJ|C0Q~`yY1niYAZ~e_c7csc$2g(? z+%}wAu%CXsSe(4jXT0O=jijGv_Tpf;h0A}=3mLGy1!^|wUQ3!PzgV_PHr2)|B7YH- zHQY&ysT11}po7e_&Z&^#cE=Ye03B3HC)$=vU%WUB!G;hE>+apC-4?uO_P%(O|5bxR zfuWA=hO49FzwKjB=8eLSa1PSx>c_ruP6#;`yisp-Na+;nJ$FS7Qi23}>)`5H3Tek@z6p zM;~5Z>PP01{>hU;4@DAmx;RwEsou*pGh%)YRxG6c0AVFODSJg(tRn6<+DepKT!wWY zFfC9iq4908K+W5NfM)polRBr=snrocnO2D7=RN;3GDOZfLKWwyv`^mUhi%dU;Q&&zpu{g&Jz;frn9`iIk+n|`0R?!z#;1A zlAlbLeszI~TzNumx$&?42~sI_Q&J{=&KN}I5S9jAUpJ@$GK3nCWDRl^x2vQzL2vc} z+eXL=Qe^V-A}ErUlkz)NaySsJK%j~L5$}Gta|*5r>I3)M9H79>2(Kkw3`cB)VHS0v zynlGa)^sV4UdU@2XNpjY>4J!->;{WzG<^0Il8$UiIeY83-@5uD zOk|)Gm1UK6Tp?vD!zqH8Gn5WETit$rJua3URmm-X2<_^RAR3)gYNRJEt=CpJ4x)SP zUe1tvs58>9w`1ejg@CdPttM{!QPcjCcj2i88vw=x5FtESTP!YjojI2u{ZVL@UVMNY zkw(-Z!2qYc&!8MyZc?e!o<>hAq@c>^D8UZVAPmJIXdI+6cNQ-g9``@F@L7fLF*H6h zU<`hsj0*UB-oyKWQ1ea;U}G*o2_l_ z&($K!*9`i!YY%qTh`+yF*1mvAL+jUbZjc3KKw#A9!Z%s>@f=8ccoRAtQD-@X4-|Ul zp;6^Lz#Xa4WufY6S?MkLfmYhg(2-B5wojQr1MT1k|62FMK>8H8A-(sMW9k#HZ{0a; zd+QZTYdj;;^L+gu>f;Llmp$HxtaHH0e^zD#mb3TamLyrSFJ`AW*JbZ^(7yOyoh@X* zYkdYQHuFC8s|nK-T|8L@S7AWBDw_%d5^cr$NlzDtsp!G~4m@{81Xfvr{Z zZo@cG_aFzzO+3H0CcvYxSI!f(XCY*BP~8tz-FQ9X+M>c0nsh?8lf{8D`t)-%QC!q{ zc|aD(0@Y_?9#9%R!O=*v;Kr@J8w@Q-e*VNZT(;xK!;ekxG`2)?_S6!JjJl8H<_oX{ zeEg?m{k60N`ZQ2^S`0)Q6b0wbW$W+@BfB?>+*#^ms!EoHfdK#nG`jcn9s_$mjhc(< zYNKb6~ACugfE2Gn{nyF222~rucjM=}Iy07S)Olf07rP2I7pejGO*JJJQN< z)59BxvzMQlDXOXUXo9qR`S6fy1+wRr*1sl3L>gSf->(>neMO>M`Q^)(Lzb@~4TUBb zZ3|iX*8Js?uB^vgFo>n4-5e9;juW@3w)!W2LqbgHNay!QX@7V5oaEY_XV;xTewb^L z$)9=;N&hZ3ED9H(Kl0Ri0=-7P9T~<<`z-kq?%cggcAvLzrvp+yZu!N|UN!NHrzDi{ zH`d|&1p28Ki4H5|PJFxt!g>sZ;-d)NW#;L^kH@+{KvENX1NL6fkG^wO3v^6^P-m8;2!*> zurfh&0L(PGo%f7ZW~c@tmFpu2X>CB`R~Q=SxEONF%Aim-+NREuEW3rM%73Ax;uyE_ zw2>)nfcihqs3ypv_pr0)6&2M?&+4UhwyGqE@P1B$mv40y0gCAQZFfRnJ-#O^Ofb#+ zizPf?ZHa>8J81g$+{17!H=Nb5;PE9u-g^7?ZE)odQr9P9j#|&F8ZVy>ylYR!#CaZ2 z*}nh@=oNvGG`1|wQ5(&S74^pMq7Bn=1c{t5#T*>{RqVc=JtK(_u7(2#4ousO2XqfJ zzF}G;mt_QoRejf6IKeD+a<})P!cOJC>Q_TVe}jmqvvtCu;o`!@$@#XuT|`vWxZor5 z*wD4(1C^GtbdntTA#SJ5oNqv!lEeolKrFez#`KX9M~oJtLMmb`9)VlNG!lwnGf}h# zV4j&y;wKqiLN9|hE9}57omKn|z`gv;s+|l&(#p#FKKSXSgp8BXfEn}|dGjAhrJGC! zTQnChb0nhkyv?(%f_1!neSIP9QvVS_9wbB4e9Vpz3PZ-lmw=jI3UcpGJ-%j(W25Jj zSe6o58!JKhIt_r`Wd~a)I(m@PB^HG^B!$*-6TOww4KUq{dTDQCgbftc)#% z&L3S}U9un*Q`6)Q#|pB+eRdat@y&PwvahAV%{uq#Wf$icOL5zPl*>1QHmOFSg6D>L(ZE!h($tT*c+mwC zg7~wFc{x3K2MKlv^WbeoUE$`o0PQgTu}_uK(CXxe*jK8zk@*f@1j-EQ6hNIY1+f~b z%pQNv0eND3JN$W|PS7>?&t67!Qh38285fn}n-(j`XoUS~lPrDLjbu+37nzExDn*>O zQ&Z~KBKrij%8+~mJ94e>sEdqxZ`kR*pZ@E8;$Jg5wFKA|9+IWKv{Fhy#3RrtYw zospr!&pghgmQK+p)#Z};F$4Q=2*T~GR1K;i4f67VwKZAyMzLkNY{I!>v#vRi1h0pH zRZ1u*AVv?D^|fn9I~Ycw7Bv=z0zky%DM{327`%weDQJC?Yc|d&=)iLcE7U%pY2G}m zu1I?ccC?MDj?JlAeW13o?Q zLtYilQFZAHK=2`;1qR(Eob){%zV3;|HOwO@JKxSq6#{6Jh(3>9R4ER$ z#0!VswQpo(^Y7^P7R2|;?{!JqbSHie9Jw&6-FpwE2R}2MvBhSrhb$=WW##A3VEl@} ziQ=o<#}-qWNEcVSgQ@GRk;zoA_kwEtvF6=a&#=V+cZ;t359c~a1LKq=>eIp0aPFZE zbLwh2Qm*uR;acC#?ENA`Mms2(YE1!UFh`CrQ>Q&`X4dK;g%HhST>3X|R6tbl^eM$PYTLUe1#>@splL#MfF5nDRdTe>aj^&g z+{bV%3$Y-E0U6w^Y;vub>yVqPEyR*lAb;ctVr?YSg$Ojnyel~3@~S62j#X|;&~zhP zr|ApWUrf?6*v9@u+?4^x4hk|jQeO{g@*#jwNS1)-inI=xnGq!LyT(amfa|AzPZ^9SC3hSKNlTivqXD0pStCXYg9F{?La$6#(9x zt5{*R`QtCeAyXH%frD~f3>31dgU@>@<8SH9$r)xy$M^K-R?FspS#Tn0f%yOvqS_o# zpsDX$06Mwg>poUF-Jb{bYD*EbeiWhGtD30-O*D!SErzb`|-`_ zqsc$##f=I0A}%uW=wuRUgGYaG@m3r+H8MiI!&~bq%SA_Z4oU2TA@~jIQ2TZ`iinA& zrKI4rftIu;QigIyu5BE;=l^_txgOBx4T2h8^YusgD4yzI7^enR)xXe2 zDM70U|wpI-xfiyxI9s-JV_oIlnfbcriz4d2Get{uCBnxSfj>eDX4h_1*ruXKstlc;*LvBN_u$gDxyj) z3ODvVmW)%9`<>z~4h9*LR?J$nHikgRRe9X#Z^DsP+TwmPx4!*xo|89Dm?i zO(R1?5mSgApg0T`oAD%0_aHptoyJ{UZWY@I>8a1hCui9I5+XI=y0*SPiF-;)Qj&D9 z86vIlWTBlvVL#_p(J&rJ`59rs*lbrS7n`wB=I7^O(b|I49g$gRkAOZiJb)SJBs*&q zCKEx6wK37UBY~eHkjHki6#P)>a~+{zlmC7vKYGiMotWvIU48=Lo~Tbi844%e(#WFU zBLmSHWb!PuN3VRgGB%c0R0IZ)-nwUmR6X{*Ff(&_t5YimUR>_;c*dz_q+8ej@>5<`c> zYj#J6KZ^Ab%IJP10k~q4OJ^CcYF(68HWvdbH#|;*r(#(X+NU~>@C=mk&kEBA@XtId zKkv4vDYEcX$8$%6jnw_nqpFx;a0P+@$L;#^T{KhQz7ai_T*ss&Brp&Knm+H ztRuKjpf3(M;vo!9SC^NO9an=pban+{ z4@tV3tgpHno|`>AQ(!VTS`&clv804q@#F^+o9V2dn#~kw5+@cNUdXFwB9#)eQwD1S zwoyfDYq#7zWC?6vhy`Nu%DGoVtTc9OwiMfT3gpeHU=3JuJ%8JDZEbG{iQhQ;Xguzg zwr(#%!|oAkzrA>|e8OA1XJ#4QmIOP}06fYok>WYD_~q$0TX)(-lG!&*=N&D)^$jBXf51)Z9jieSS89b;o-inqud=t6_H zf)!sk=hZNXVJ^r}M)&R}Ymf@C43?6eVfALBudXkBL!tut#O&N06bjuBj$BgU?j%ls zg3-|cp%wO$zo<3r;4Y%xjzbcE<4LuIh1C9!AK~}wpIQpKd?HmU!@rC{DAf6zprZ`9 z4AHjyeMW}bd-g*Zes#`SBVM_7$?7t#TJP9Q2_(&&gl|m zEvTv4XElw(9LdL{sJ;-5HMKN1_#*e|Q$W~&Hqp&O#W;`u^ZfY&c*pDb3D_(po--ft z?9H6(DF~w&MT@5RDddrG_wt?gX~ibQP-^r~SFUImP*c%M&r=T)?8?>vS^bANKv?rp zXFyoX#emE$ymunL55xy)cmFa;iu!?;{u7~oMIs(CbQAJ>gw0`Cud4FBWZ2NR-W~4b z*@9vTVs2vOP|DFO@YS}y&%1;lTVvO76LC5L2x*AdBPlAQvEI|2(pJT^aNu*8LLNX~ zJvv6%0vhPZZ$jG#c}$jO6s!LwzG=wea4!x#td9$cuL~=#+i@5l3v~eiq-`aD z<9OuNe66*?vKn!P7z^4kC_p?64HVz|vE7cE=tR_>lM_vdH(@LOZ>`$RCVSK?n1@r& zeb3LsIV$<7& zzYFH=u)KUh&&)J$u5c0ZwXm}A_#s-awhk1HFxR4s))PQY?+bV*TRV>L42nbM$ge@v z++`SH1s(*SGqXy4SlRE7Cyp1i=U6`OvlyAtIYmxaKe34DZ1_ad(pV!kP)5Twza$>8 zj=LA|3wC|zg2vfoPr0*(hQ(MgA=Hd8;==5{;LcPj^C?k-zuAx4HPEzyE(WS4*mDUq zW6igA92RB0gcGtmOLJ!ptYy+P=k5AM+i(;TZ5*c_E$hCQu#>>)Wb1qF+A6{%K-*z35(*$8 zp#jJX54|2H?)Shw27I_&0YM?9bm8H(&p((KC;wjyfIP^ue`3k!;t-sm25x;gz5!Vu zbT}ZI;moh9ff__z8IFI1RaWM-p1R57hHb3V)Q$ZnA0XF zbahd%xW1Wrj0y}Jo|XDuGz|x;7U&RBmq5(*zDhccX^>A;5YQm*1`~t8l z^Rd9RX6;K9azEs9S{6>L_^R&uMvQyvE3}l{CS5m`<-+LBE6&bfJ`g)I=>a4os&_Bi zRjf5=r2h>Gz?=v~fwG%qj|H2OeG&ye<0S2)zzt!{O@UNnaIaVqP&47i@cI@zOUL~V z;y?=_NU% zM)WTvmQ^Fq36)qEJrWi$CfnW5ZxhE63Da$(0}u7D3_Ks7dp$b;Z`>~gpPEyvr>C?7 zE;eg~!6MUiOgoajL-(7TEEXA!nXFD9Rtz$2P|=|e0-if~h2|<|t`V4}>yEeFY~*+~ zE>TZ*TWtsFhK<@PZnB3KZHj>VUIAq9R&ySJlpEI zODb(8%6!*y6pOrBSp^->*4y$ zP_hH|?od$ob8&Mc76fjovG_A4Ce^5PSfeJ3Teur|s4GSo(s{EE7^JDjPNE9Y?K*W< z=imZO;MaiNv6|ZueP8VC=2jatv$2WexCfF!j70jt#AzGq-FzE5cg4=i9X`AS!~{b^ z9Kt-O?Pfvyf-6Tz83MplV`N`5UCgu#PQ2>wE_v%DyppLpV#%Q5Q1BO8zP6vTlMw-~ zRq*lkXP;SMEw^w5MMZ(;gt$pK2?;q!u|*9DV&YzEDh9Zq+wQY;+RL|y4hqL4fd))& z8O~p5O}?s{<;F*Q;&lu*b<9%eIi*~6WmJh>nx}pL(a?>J4Hce19}}@;wD)0Z zi(eB@%?}js7ZjYjp!|0bydneB35fhSi0Q|(eTAUg^O7Tl-`Psw;`lr~TzT#1XB78# z?@s?-t9`M&ePP7?7enpS1JQgzThtovzUL84am`v!8-&l%&)yR-&R&Ar!Ppq0NMv%L zC?a91UQdF+xJm)2PBf;kW#MAmvE z?Ht)HsA@2|FdZY`h9*50*L_2OxXFqlJHlVtvyuIB&<}E{3k=~eoO=XtSZq7wyF)*4u$so~XkQx7UKSnz5SeiLY+#r@DrXGZK*= z5A;)FMXkx_Zs4^bnuzOrbsFQP8YH;pju>yk1Y=B^-ii4|@uDFd4EYn-Biie|8lyRK#o_ zR|e^y^g_b+R+!{K1jl6SIyB`)9_j-)LiK=_W{UXvgqQPQulcU-Wyhclh_q?LvJn3K zPOvcy?q1J5!7+&Bp$!|e?j9H@`!@#cX}1$`AOiFSQnEa}Ke03hr2k}lH3Y+<$gNeA_^@O6e)Hi+(3 zxNJKsE%NP&g-zE&cvnaX%}_+3%yYXP@sIl&bE_Ey{BigEn+%Ie<_~H-H*atDGrXas z#$tB;S)BDDs^YOe9pi4b+KdJ)?=2z0@s90qgvS>o<%J2N2?H8;nDMmC!HVId`9W(6 zcgDha0~$ikm@hVUB0JXi53{0|DZQloNQyw?GV70^>81moj^P8LdnkOcwrZBn=2~+AH3`|YKiR(Z6Kuo=Ep$ROk*_RU1)3qVGl2@DI)yJ;x}_{K6| z43bXVsV)!fO93%{%F579O1e^RiV?^OP7>=B$3=P**|#v{!JXNrtMaVx7;Mug-xDJv z?HZ`YxKXR4*8#tW=|6~sv6Z?HMNwWJ%_3)x4u*BC9A&<+{I=E7F6h}gVCDJ7K$~#+ z6xIOgNzyHPMdKY4UbA%8RYIRI;wGQZ9_or|ero2$&-3Ywps&g@$_GUS1a#kxAH|r% z$IrRY-EifDqo&=?eDb8`Mej<;#?UrKlDxU);2-ihx6OfAHwGR+C4-BCca85VOH>mY zkGkBb1l|9IDNmWGqAlq~G6v3kPY}4{%Qay%hfY&Jr`0dEDDg8niad z0mFbY#>OyP=3f*ndGPKxe%+))rkD$DvhZ2**#-%bVm=|MJ<5pJbVpEzkK-m96C{D7Pm375K$;JBaj zf^Z+kgoD*T%}&y~;{8Q(+-E=`OBHwu8lEKQ-=f-g!MRI54d;Ey1Q%@DX6jxet&l zR!-iv?0aesj)unL7n~Cqw!Afkrnw#A>s&V{7Rz+_>my{#2C^BW^lfChwDebzUS|6v zRx2A0IJbD<91yLLP~&P^X|aojiye`)Gktv~DhjplVE}zQggWX$$2aU2icfazJVJ)D0--7y z7UfCGo5qsjAq2kO>$nL~3~--&n#`HZ`ACm5gDQJtLqSW`akS@Z__On!=bHek1ID(Y zcXe5?2h8L88m#MHv2t{7odFW;ERh-@$S~0oUjiwZ*l+L}&3H1;?&2^(ZQC=0tp4Uu zJ-T(Wdx39{u5Lf;WZufyIFZ{EuN-``{8GQz*r$d0-H{r;N&)uvYW&P~(I9D{uv0|F z8{$@Qxnf$P@_O4T#MM%h^6}Zq{M;M{(z1e7sviJ9KpnfiuoA0@NH9yjadu*G-(sAb zQiwyKzrr--qBmE^jXM&{LPmE>B~H#fJ$S;cBSewZhJ}6ZIml;uh{3bR*-STktf!!PJAjG07im?9#Jr)Gl2hP%hjf z#rC*#w=={7^Hyhi#i zQPP2S?%>*sEVY(RHLgrYxtnt18oYb14O6m4tsoiv6g2m0-odvRTC87LhiUN;=mYC) zmseKGN9IxBK?!F|(Z^DMwE4E}?}O6HYk6`H=K&IV0}YgymxrJvxGrPFRa{t@>^E5; z-CRCGB7=j;Ak&D$A zgdc$YgM&!X>xY>HJ4iB&(Ey20oIZu0!76SY9TjcvV|zZcB`mrAG&J9@NRIceP2Ye=ESiyspqxB9 zVr*%-vxPL@_!HXCK`IhiI?VK`Glq`u(X_k242^@`pz4%oD(@166c61@;1sz&EvkrR3!{nnm6m>xB@ z`%Aj*)5Ep?Drcv^;;bxX5K30SaRDevLNn^lWqvU=8_L!qWZiMbV7|)Wa_$3H(dTZo zx3jpGN^l7bx-{SWro)dJOE1&|z&xVg^|^7wy%6$h9>SQLtXD-9I1g|WbfnMoN%`vH zcjuD`7{JLvQb(b37Rt*u9q*vSuP<-CG5#W-CJIV_YzsE z#zWw_Od8+f_ySRVpGHToNOMBAo93pFm1j0ycL6r=SeO8SbIr`o%K!JhcX=5u11g$` zTG~#ZctfXq{A={U`-lK2>Lnlc&e~Ix#L#ybck0;cQtIg^v4kL>oLbuacC@ChvI;XK zv&Xy@KBM6f-9nyTgu`X9cnLZVfPrxNU_=p;Pi${s*tV(l^)P85OH?Ynw_W3n8|~fk z6i{0uIUG)G8P{RiW5?EE!8*)ByYl;YmI`8IX=v}%J=__T@KE?93+Yi!h<0ltgArEJ z?oa|?3+Dpyb6y+y4+1DSgGp5%EWCU%yh!*4aRke)Y5V<>p~p3@Uq9wZ2m6Zbv~8L= zp~_RPu-i%I@~36oTnU|1xTRKq|Av$GoV_^BxGmYiq_>C&MrI*|aPm@I##6hpL{$cw z#rT>uA!(xxgEbXJH8ii;-CT-3ET6pa?RsV)h}%Sk0U!g@V1XJT^R*5MCB8~fr@KZE zSlpuvp{A{kFc3l^VT=O^AKSEIMC_lpM=V44(HpX>cf~!=PK?Lp9dar@FaH#?URPFE zM}b6)WuxQc)b&%nWLG_4zVnpvt7e`ds*7N|p%f`D?w<21_;~S-H_aeGw7@x@*8`xh zkUiaGPpW>;mvxLZj1BoQPH!?LzAkzb8;k5XrCaMKt;ALVsS?v{kqM7TT*T6KKUX&- zC$C0|S}E=rcGg?=%TMhp^*stOAI!S2eNxVM4TBgqh?NSyVSRl)W|ks8WpgnuKx1TY zTuXuzWD*No5Nz9h0fpOpaV3ON>0d`^`~+#;e?e6tN&{^iVq{xIx*OVDThed5?4%6< zqjR{9(=~!+_~5ctw}Y$Y3HN|dKEBIq^$b?e@H}!?7QC%Er9abMU4-;bn_~Mgwai*yW@wum#?;b_+TT1|T%c|e-+8$X`02yCeP2&b&%OnvOy!H93_pJ~e_h*`4US#lDMAe-%m@ zLX5KRSrR#&D|HMo&QMzEB+;aIii?W+A_M33U+{~`-GCN3`V!`;VjJeS_j`;QTTjUjyxg)>N8GFDX`NriMo-f3!LQ{h6! zt3BrTNBY4rol&@IqMC>U&hFnw zz@*PfAKM8`ADmcqe**)^>0Et!28Q4vsBOUKG5#57DIpT=(fum{xG4BfEA zUvYK4xrm_5XAR>>R9Fyd@>HxXL*fVW4>EQ^Y`cY%1I98UOoRy{3xjLEN)q%EhHzV` zWv&@NU3y`#t>cHldf*fIAuv~RUjr#Co$se)gSi$0FSATd&Ys=;5+(j6eb~KaFV+rw zeRvk875j{i?XZ8+8yB!~F1!Jjd5F|-#6b0NIi4Y{;Nsc8lAhCy{?j#`hk9O=Kd zp)xdRCy61d5HMKdf1{PrI?A{VV3-c}T#zqh=`isjcjOkkg`A#KeE;yra3@_s-VVkIL9PNVQ|+!Q>z@d@zkIn64!5iQWQFCFS^`Wqf~-;abjZVt z)Ie3lN>TyjkVuBtIjIV=QBu?@(G_4U2r*Ks^7`Rk-7*FQ#r0Dc?)LO2dixI|u@2uc zh#@TShWo&uNo!O(KF7ppGb}c}PR6tdT(V2M9B9=7$-X z{3Vjl04ofdc;%b3vkZj5SR^D3gJ9xfn1Z+UA_ClWU7Q5LpQ8mrvyhFhk2dKchV86R zCfoHaEHp5Jfg|ROBYNfeb3)9I6xTO9$fL|f`*8cMC8lp+42b@zQ_3s7rxDq~+j>t$ zg10nSepfJ?0A~ojeoQu{LOw=|U^2{K8b1DRxTz7I1=0zydT#Co>>VKqchSs?j~xhq zYJem~HPvIf#U7F=FpJ3ClR0t(7b@@ho7AW9NgWmUTS7e3HJ4RGdM*N>BL=jH=m{*n zMxsbTQT3<3KGYMhM?BgOfxjv07q=)CVvZbpZ{6sxu1;4B>^&|v79f|2i3x@g;g5q9 zF_yj(3m2WB8#9D}SVc%?L#lpt^%el9t>l1pwi<|Pwzn{@67jBC>EtH`#TaDBZ-3eR zySj}E5l{r$QsPyjBNoi?d9?Fs+1J?z^Z|pe?;KVo9^hQ}`y03SPFCV) zOLkV0og@{KRCX$* z>(M^zqUcyJNIDvYHWK3n;XxK2p*T~V zr4b1@@lA=11k=PZNlDo4v@q1VFUJ;v?h{&{K@MWUyt%pAb8(-GIj=7Uu%$!RD4_9_ zK)nSczSn$C7{EJ{<+7w?r{hB3LWzvkI3$SodQfqRvnLL*_A^Vr&iMYV_=?h2KUqAf zcKZ18IFgZ6c$Lx(QStx6J&TCi8tm2?M8m>*U!Hm^@`H~0HpM;G6KfD0pEz*>T;#cD zvokXVZx^u#A1Kf0vLSiaI$SY4`tH z01g3Op(&vg``rzj9-S(}p$rQ`f0>A%=Cf!B1sl4|C6x{y92*!Y2R#5;5>31_i_l-W z%ywZt#_&n_#h$L%FTIA#vAuDGC>7!`5U>hJfj(XH+k}a{YN_gT0}1ta-jvOUR@5%G z`;Vq039?@~EN}&w320gzpZ|uo3hLVhK2i2@=VnHnP-w+u9|fEb8T!2Dp$5P+d>)8r zf(yihzZG9k=vR2Ui6ck6i#nDS7khZ3y#*3R-=4pIr?%vJ|E{&^2{DX@>F7clZHy#R z?kfG))!CVT?;Zt9W(K*H=tEROG1|KvjXbVRkox!-T>{NkshF1_M?Cll#03+MoKBCVEU6SL`YEd|8M02GYN=wUBlV zz`+J72lx?IrR}fOJZvuB=U-V>e1)Y`pKLhiqitOSO$Fe zDgm_4H^KZK{^9Zw3-pT^62d27lYIrZZw@1b*pY@02R3lj6YVJ>+AVgxRL*2n1ekrW z6gqiwN1{P;8=Mmd&khrmEDAnt?>vW#O(&DGS3kA;EyB4*=po>z+VORqn0Su^t1xEC907DI6}d-#1XR71$fgVEusY zysTQdo6br9^0(WUG9Kr3=Ga2cG9tT7dRN($7b}Fy2{APenl3swO+g zI>4;APh*niq2?r?4m8s8*N?TE%JmyP$Rq8PefUX zo*HGFHk#WdKVb2z3jnFOd4tUqR+FO0iS&B7?tLu!;iNWv z@^WMDZvFOJ>G>j(-P&%;$7&xo(v)<9JxnF`L=9>3=MzhxwHt z=!CMzMTIxV$N?271Z=2~xKh6U+9c-9TtdG?bdkvTuF|iYWl;86G*SA<35Ivi@<0Z- zdv{0*iNRT_AX}xoSYi0X>PO-AOYzFPEo7^QG9n@n4QK$Vg_c$$krt1%_M*4HQT;8V zaQY9z19w}f!X-JF85lZdUDP~gt{jVcqA^&*o`IUuh^7BRUg6UpXeQ1S=dM z_+he{dBGV0=tHvp=ua>g6&zGe^`<|t~EyKXruMXjOAA2s1$Q&bg z%O&f!ax(%8U=a#+Y_DvkQ$O_et$^K>wf}}*(cAlWgrjLUIM4ni;l5rnA?$xC8f>30 z%TThq;Fa|As~>X$zTux)3&lGY4)1lqANCIePPxp+IQg3LZ(E_ zy`@(LND?TE*M^rCPj$HG+{D%nG`qS+=)*C8>LO1SR#Un2p~lOEW<^WWHNi=cM>^Vvot0UYKF1dj zZY+R*c>W<$2R&?`2Z?y|WCs#4G+A(I)S@Q%(-yg6eP z*Z5uJVbjdd4=I=)WHsE~UU7G9awUv_bSwof2JGO70asd#w-KPz%2f`b>oo{JG`2Ao zL^{KWcXI~~MTx>0#v#(n zM&drm#mv(1vnnr%WJOR&5sUy<%5&&80f?ypN% z>s4t?vb)ymF9t=n$<$fB5X8Y{xlUYe;(~S`_u<^hRvF1YDOea>Vyj)jkb@*Ey1!(z z+Ty2S{ouCZyYX9!&+Z$`<#|rUpUpnQ&o1wXTn~{lfson@7iJ-YhT$Ay ztoCUEKHkWO^s0wXUv^&VGkG^WoCb)uNg;YBhlSM8@*K;m z`n#VK6BEc8!4d(Bu~mP8W0>j6aiz}7b7}Zbkt@zLkW;n^IJbS&`yN%;%JuM07SYv% zko7w3kuX?Ww^wApB<>Xz_6ZC1|M4N>lWfY&abyREYNLQFh#FqT^@}v6OP3xtPeKs| zWk&~DqZH*0&0@2YMT$!*ANw(&73!32bGx%AR@jR_Ss(s_H{E4U|j5^nMETx%C zLQsdX7xDMs^j09#brERHPfJfPEGTGbSzY@~w9Bw_a4<15Hy;VkqA_NvpTs6G5QT+Dip>y$Gx!HS z5khj*E%M4ix9Z*1cq~$M1p~bOkW)9l{dF9wLgazl3>vFuP*qcM@@BE0yC})=0Z&s` z==j#0^5vG#f&-0CdtnPJEieB*Ty`GQwsj~&nVI=>Up`rvOR)Ku1b7u?C`NoO6xzY@ zdGt?%)9KYlI~2TXKjJdpKI2)b^?0w0%<{ql2s?eslqE-m6QQrOrAKx->Sy@}hQQ0} zUllx6F|qmj^pPg9Z<~KEmfv!9Wq(4?!+F+P<5aEawEy>R@4+~bNwC#MTMlqWC~IoL zo}?Cz@UHOgk_FGeK`JAEa!iupS;O8>ON%s8%GsRb+J4Qyp^%oIEyf}r(gG<73GE~7 zic8Sr!j^fSU1EyXVRYb?HTyupZ&L1@$w}L|_JRI>5HND4$Zy9%n-QUlmqK>`!-5i) z?zqH=zR^(5`i_l#rwSX_@z2nevp7?719L9W6PZl8%6qbK5Un-3hrla_IRM||37J2g zb8*)lW-YZ{KMaVYHoW3EyEy4S@@ITdJgBccvgEw(H5DPI4!!Ntl9R(__}|2@=RT(W zTLiU@qvNBxI((8^k|eIAk`H%9bj#4S_KX7AA$Dh#}xt)>Jm*xY!o`iganG>=r|GJZ1wpIB;A5GXV)VTJnP1 z9A5?7wKVBEdr{dqKuy}GNE6n~6C;YzS9CPg^oXhPgeodc?u4X%eD4uE*b6ZJMtg=3 zREtVyEpc`x1_nY*IL}@K##Ik*50CW_PAdReG`T%z#M4A-g!XLhJs7F)FSr(Qd)Fxa zRT77AT~j9ER+?Zi;J)1YJX8v(uvMx1)vI4H^gs4+Aa7sWRUKVp8eav`EtnT_7y)TW zda6LfK>ymH?%ihfs9RVwC}O^7U?80%x_2;TYie$~;a|+Q!v#uOc+{Spm?~@Y=2-WC z6`-r^L~|NFB1|l)-HJRhD85W>{g>hFSL9)oU4oPl#big%<>&8-c}Vas22ruEU}LOF zzeD^9VMXqQKlhg1Ad@DL`(RusgOK5{d?#~gqf2?6E{#MQ#R|92>4GGn5n=dscI|Ml ze)mP?-F|EsQ<9UBUx|SkREGB2=?mS5aC~UnXy=;%VRG!QQh+gyY+y20x{Z&oo5qvS ziGK+sSAbIK*QTZP5Jt&vM_yvH^9`Q<3Du zO}b<3Ws3j}i%R6SK$WTL0Cva5nv- z8Na>4F=fm_7eXKh^&v)2$5rBi1gGjLh}aRYmu*r=paS5GbRGx9Q+%5rzILz(JP*zm zZML+O{gJ&~rlk1;EDK_mI-%0J*!e`eZJo@UTPSwBRniSHyA|jRpNzrZ(k&ZNG#;va z@axb`lN=*hX<&t!Z-rsfIK{t7VR5%bpSXXB^+_|cP|~kyT~psT-hcQ2z8uz$$R~fd z!$OK@817Ezt#!oKqRj*S9*!}yBG3WWHviyv#n(3bE9328i!dv-irJR!i+dtBZF~NW ztTC@x?`MOT8egmi+m8t`XjwIe2vVYN{krNw0)Ffp8(IIh@Bmr-SPQy^N+CwqX}-hy zQ&1zQG*7wl(|5T}W~n2u9<6@8>aMcYD0UY8F$^8RQWJ>_;f3(XV6B3XM@Sl5cI#)^ zmgd@C8yv4P{iNd^jy;QtQ`*Kc3U(e}3eL9+u9%XCX$!crlL*zV#$3Y_nDuw-Qvo0B zA`C^)sh*bbv8S0yC=cajRA8@LE52qM%SkCS#Jbk&H^0Xo?qq{}7hJmNXS8!x-~d8P zjxQVfC5L15A=*Q~-8v!{*M37~OFWoy-r+auJ{Ku7p`$8&CYtktIZ)xOS++;GZr#x5 zuZxS1-~)YjISGoH%|Bdv$M=L_Gz`ZT_T3m;B2pZ2 z5hGuJBA}z-%Oo4=iObP4Z=PbJ4{SY6<$5j2RKs%fC0!liQHAWCNz4Sch~pWmimIwS zOkub(WHVU`A;Alb3-#B5<(GxgLySWNKw)h37peyDMj4L4V*c zu^lI>7Pq&zA)!)Pca}2Fd@x3{9F)N_?i6r|@e zForUgC9LlBk76LqT{S9|cJqKeiJi{xTT&K|M}cEO`82jx(MNRELbOt89`{)Q24-}g zk^)aCc!5Ko-M;up`Em5!P6h=_rMrw`oTgk#cP-DJ1(XMo?Q1^OoNCYGptoF&CfH$dZ&FJW zYAFLP*gPA<7ttGHK87Xx{o2TjIoUfu{cNv0FutiXuq#cFSfgtEQBZA0{|rbqX$b$9 zn^2l^jWoX+mDymT>O8@|19qdBTTJ0k(ga=EpG%4Bhs^DlPOZkc-J!Jk8XZ*-&B5#? z>OcV#9I2&13OSM8JBC-U-vO>a1sK|8n}uq>%6%m zw+3Y>P07M_c%oJW|3RjgMqid=7AhkXSJhRreA{xtTJ}EYfBPU~&`n5XXCVo(xsG`- zyx=Vn^qEx8`v4*=Ia40m$KlTFnJk{8na*f%K|i|bt6kSGX^(Agp4uo2YUxxI6-bSj zPU-}{sO({&w`cxd9i8PTdkK@-L!SZABB^t5ZuzA=$$IwRJ1&?2c>`n}y5YpWCvxXr zD4(z?9bd){8R3psm8>hBb4p8>w>Ou23r6r+q1lHF^3EH~#LmRE2kCPCH`rlf`#rCP zF^M7iWMJ-ZVvZ~EQmXr&u?*`xN}p^mhLOFx-VXZygMcnTbgDv%L{%c*p8NMF%-cJN zX+GIIq`y-4%CaS**O||Cz`7}{*|T;VN{h{3%lv$N5YuL-kRAYezti5};Q)?alpk34 zulL9K3WITXJTU(H*qQfx$L2u^UK|A6aq!I>m>Lf9F+YD`ti|!%a^+3B<79Gc^M8j( zoD_J#dnn^?X3cdwxOldC2zeMV)O#K@k&Du&etm6v)3iiAvjS2aILW}p&x*}^@`?ZU zv**{FxXj;!I{p4VokGhC&kuCxEIU!Uc6WAyQD4xW+s>!!hAF7T-!EUjpl`%HH(}(= z(t)tUyo@PWM;BgyFA;I)@QGa%r8L_#DJ+z^0y7DR`G|2uc%jVA%#h5ADF!~^SqA{a zbOq7l1Em@(V4{XoT9fh&{Cmo*$7Ft)Q>m&SXJb4?u$^D~jZGG!m$2*NSNHZn&oD%x z>Iz|_yKeyEg4Az3-yXW@_=G9{cSixqZ`Q32Foj?V>24==q;76{vk=_D^IG$>m#N1@Z=ioP4)p@_f z_D4elF@}&5<6;P4A-{d|&>>2NjQICRy~gqoJ2u+wdk7;tonT zL?<+14qFai-071i&&#K0za)8i3l^xILh&96TULp^ULradxWD~KPJC#qCmx$Ck9Qy^ z_HADu3IFZ)3;m*vhRP-0Nf47i*Z|SYeY3f|i8!Q?wT@bEwT~3fKv8-`BW~0dTd?!_X zMN~k_@p8t-nWmEPcSl`)Fuasdw;z6^RI3%3EWF4j!aGuqc|{nE}@&69o>j-bDN`%Lyylil@PQ zB@*;)$jIG%E7igk(s#*t(>>Te+(sUwlJHd9P|N{LuHz5)vC!b8c?><6aVL`KvDOxk z$v(+)nBh*UIk|Y?_`O??S?=as&QkGvPfO^C-RmFCWyWKKK)J~`0^#S~>MwLCe#{mS zVqh>3O>)RZ68>#Eba^TaaZ56?9_Ki;=3~J@~NibtKFkr{v|aw%~T;bhaLsGPlvLE zn$9@fis$drRef+cezHKi;DzSmk-<|?ANKek;TG`t!;qg;(%E+ft4uk|3N%EZmVLL9 zrHb0n{Mht)rEt00P`7OMMK$|&AER~&bx8Wr;g8kXIXn3S#MZ=E&YxFb7gQlTMOpvS zz;1`H$L9ZQ0frcPZZKbB5(~Pkm&x-^*x6hCr`!SQG%@B`{Di7yggr9?-=y!$2)v+bdy&dnt4y-8Wbjb$y{H#9yveIV(AhRz z4X$OG7A_{8%QuhL_HO4=j68PycqWF~2!Y46V1k32d2zCq{K=fsGkm5F(hN6#|EHJt zf;Y6C=Sv?5XRpO{TfUbubRMZTEA0XM;1s` z&dukGB)0dgI$xu19%Be=#tHzSZfqPdH4b*q+wyL=4m)?jeb3ef8n3?P)DN4@9lC-U zc43F#N=~P|k|3SkmJb{+vfpnJ#(Hn^aFv1X=L;MqhR+_Sh_U>Y!=HbO{t~lW zd@-<4gQ@_d2Pz4x!Y4;pHOna} zh4LNfWA4nillEfxp~}>3Y<)nF%Yxi!{ z{Q;W(b%|s<_wgTQm44$k9~|O;p#RD0&L=eWyQJ*0tuQfdY;25;Wda@L*XB_1xv*_D zVG(_uziyueT4QvU*k~E;Z(eU27Lffz{aAGV%w(5lqbx@h{HAEVU}D*~Zve;#7`Cj_ z(%!;(vA`x z+kf;bz};;#-cOV-S0iC15L{+n>8?NL5uMb&i5(^uTSmFNncAU}+8LvF9YIdmuc(4v zy=M;*3!J1YsHGA*C8_&pb-~|ko|@zk_rsWSG-L7P4bJWky(|k*ZryZqyYCa&K3#0_ zGEt)b`@?r*W}$5|1toS@pMicgMenArzZ1iFd|YGniTCkLVOx_Xt+9W9xaW<>g7ulgTM5z&q2HkHeb`<=9#Q zF6>HK8%g;%L*K5z7S31XLCds5RO&J{^?=d*{P6?!a@=z5c4f(_srz(lKAhRlWO|I{ zr0iyls^-KoA!d@pfRUUp0j~*09?f8QpJD5Bqq(E%9~uwy8jT5Tj^I#1SV#1S;We!I ztur2QJEZ=CT(Da9n%1S2$uNGb8@OJhBf>Y+;E~NU?|nQ=R}dq0=;&r$jE_wIW+7dI z8wrXT%xj#SUSBN7Esxq5O}%TTjUMxlDY;y7@?nQQkZ|&jusSc542pC;=1lsjnmmEG z$g>2<(e?F8I3mv$qeQ@9flK`;>GD?wzqG0_D;J~69TCAMg(a{Rg&=< zNIxWudDTJ!g=I9@YmPUeDSp7y5Y!f;9UrAY^B@m2in_|mbCWzcpE81#gs9b6xG^i{aA ziQTS)0=9Yp2U66tq%~|gk1Owku~0&IxAyxb=Na;V2KZFfl$0QalNH*-#bEbH=IMPSu15t0vUhvp>01UZ zgP#FaN0VtJ5lAM4Fk6X~EY;#YSB7lQte@j(e(!Heo9GmNJ)Z1*`3Us6JTakfY=xgw z<&IQqzHwH8IbW9b>+d(V{>LRxhc&~afyMR+w4&&KJ=BO2&(ySXO96!Jt3zp*F?d88v3*u*!Ziq6~?9?fwQif=k0rUZNw^zczu>ABo!wdWqES+SN&OIE+`Ez^!)w>22ua?;DqAx|i zuzf9{6UfjBo+9u{nDP?yY~VX#3L`4#;mB_Oqm|-+cK5tdg}~3oK}W?HwqX9#W@bN| z=w+}$26_!jQ79;sS-2Ulo+pvdW703C-mm*=S726bNg6gcNP-|bPO1?bC;Z>L+kH=0 zDkMW&7$0#!iwW84m=jotR2X*1#xZKKB!$LY%a#Fb5Aw+EjKc7n#n~jh0j~}|EAKmB z4YV6}93VO4P`v5tYF_-V*JtU5XKiM|>p^B6k9G!^!ox8eUJrKB)H8cEU@(hKD^z6D zs~)#*Z9pN}o#&qYODK23>w~AC4HFSYUQywW)hupBgg})WnqY%5gLQ{cr%#u|XYx<=|X{oo>~`=wj>M)g!C6*PRMJ zlD&{U%yom$**p3v46%nI_hlTn25!&Wy9PaJ#_{FhGM%Egz+BEK1kk)n`z`9e`8w6$ zqT3F@;*mD2kndmgWz_>1E{IgI+B7SIG6AMMq?Sue6nrOq)!aIK=UwPyvfWu}CptVD zSnHf8weed4(m}?rz0Hc(U|%8kl9KQt-%v?QV_!2AlWg-S(( z=$x!xlPE96BdLzr=1xj;$X%RO)D#tO!uyHm0D~H+CXjB*?lwVf%ee2-vC$bZTde@9 z2X8p5WSmR?`1;|C_43+;71LmAV#)Z5QuM}hRD2SxT>n{e_iL`MgBQ!eZo-9vs0T>G z%FHn_6Av!PnRGiDd22)F&2ER0iC=f5gieJ8D?nat@V)(;)vVm7yLjb*)4}QrwvC*X z_0?%`Lcrh16=OMVAe`u-7CX9elj5-RDcro81n{@u4aIoKZ@rmc+Pcod$jEuBB?7!D zpz%otj5Qh^bUmKx{zsa{s_PIwcU}*aBE*s$z>ZJcH}2riG~^W)xa4W&{JD9>U43ew zyjQy1ZC_B0M@UvGASF1SsTN^1hd(apUNAe~Tjx^sD@WKihC3(NFb%+`3i~hQd{D5x zdGoDnZz%%<14c+J#qfN9V?Qe#<)dtOW_ejPhNoX^Q!|kNy7<73npJn?wJ*4yMYxuE z+5PJ311vOv%Ol!_gx|rH%Q(3|O6l*_PrJ%YCdO?gG9l*$F$qpo+=9f!+xPFQs;iB| zz{n7fCS)FB4`mnQ5cZAJ!GEEi<@W^-Wf;@36DQCK!%R?YS#w4GumQv!)@1QrM|IAyHV{I)^Cg4OMDQ4tOotq}u!<$pC<{kA)0zMau; z;JyY3Ec|;YS`cHui-$)x9)vfzjqibP3!NYw>ah}cdt%$Chdr;0r2Z8gBNi-Io=~>V zvohR&xVu&Tk?&|FN=l@_UtM>21VT4vX?A5Q04lQ6U4LouL?k@L<=8N(3E!gFym70b zZVW)3kN_c?^wcSAZd9>%`!Nsf6@D;KE=4>HWUVldL0Q}BRX?tQXhn$dfW-n^5;H&u zCxH%eR>3$#O;`87f_p5@bGIA#kKAnB{lNOZ`Sq2FMnICF5L8D_ZWj1HX7Gv^Wo-Jj z@xJ$3Yh&2j@b(pF$LqPcuz>I~Fg0Ko-b_DRtPY}}ySuxwF>48*=+B>@?JRF6mT&DF7*}h>fcto7|d!p(9;uNQh3NKYew3Q#e(;QCw z(zHiXSPj)yAr=9ft4UecdF*mxcOOuamk$(W1PnNlhX%vNB8;7X)&Ko7Gh+|FJ!}9_ zuwWtm>f-mUmkug70&RE*UPo&*9Or`gvElMjA19I|kx7bWnyc!6^6Bt-!XBYNdT`YJ zy;sQ~*?J)p;iD%ah3f0;i;Ee1>Y)IvA75@)giwiCDf?};``y#dqBa4F+f)Lo3!?&TG@#M^@WeLA zP*i6%S#B4ZYzvC^Y?XRIJ-n!1oO_szLKBs`L&(aEOC&p7pNaUKb*XA zAHD*g0hTtn`oQzfuf*u(4)aZX4XmOO?o#OmNE};T&aC8iGV*I%KdsKSlhGC$6n^DiM`U~QElV2UGtbm)i0O0^aa;c=W zG9fC5BMa7nA5eUL^90-PDR|KMW6X*W4A)SL0JI4g`I~eNI#utIgzMv)!C`c--^I`Zn{`Q7-x8hY z?iwkku%JxFlviP>>t>aol1Ic}x;1ZHRkf;$mt39@t{B`)^_2!|8lhGcn zDwiB95VE2_sQox3(CNo+q7!9)U(usSIMYFk0ColUDzK!H9**IP-wJ z6CPM>oGA9Njo6Q#$vDm#*Pe0w5=gvIrZtgOe5ifadAqvj>5BWQ(6G!w@qq;exfql>G`ELR<{mGqGn6q%I~mO|IaB!DIGod0azIZnc4&8A{%X6R1ph znXrv?IEP-X?VQ7EW5U-rpW)v9cvb1Vy~ukte?^psu!9ZrmDDj*1&4a+PNzTFn;pYb ze$r?T5Im8EN7$3!-!TG~2Rl2Y4A7X}H5Bz&>U*IrXh+++q_y+j-MeslDBV4lV+0=D zJuZvo|IsP;&ts2NF+z-%fX&+bNC%~51)0-3r_#~!uUEsjC&;H>w#cJ;C0+~86aJY@}`i_Zd zK9yVd*VKt#3Lc6e)5i|oOsmyFwP~uM%ydG3-&TQq)Bq&U`X{xIO7O%$8pn^P5;YC{ z$8bcN6g~sN6Mbh@6{>**0wwM5pxJVjyUUA=w@yX#V;7F^0ugVBPU>KDemRQyPlPVv z4lap)tP)|2^jurSAS6C3sZ-dgJ<+1#-_PzjsP5#?-PyOZtq{S76Y3YFYPhoD#zz>* z(m2t=gaO-|Waf!hSeg%sE7x7c4(iPb2?oz*D+W-CD7!RIjZd$VumC^u>&wWE zpI=7$`!RJs6V&(wT?Q78Q1Afe3cS3U`W){d{>jCV-&DOj4oUTO;32{xM;x@!P!RmX z)u!?FsW%;!sde4>b|K?9b=6J51d=gJU?*SS`u<_$Y2)%KZsCs0Ov-6K|1hCe|8!N* zX5dr#(TQ22FSzs%2T)}=z5xg>@m?HI43qQ`-@&>&%y%oVxcF;Ff)Ej1Fde61Woa4X zNwaS~V>!g~^V7zMByTz9nKNZ&$vPG7_4`?xc*nf_Nc!Fc}1oA39LY1$aeu_NP6oESbC%flVVbjJZ2%C0XObnDke!n03 zk#zwW;ri$ITA}G8kdAmYQ8hK%u(Sr`#~8t2ivB~K-L8CuCkBdrBt&{6T-9eGKh+o7 zgqgWHs7q(@KhxE^O>xMH#eZd)u>a%&2Ok~nLCr&<`|o}K{ph2zU0y^?H3z!S0L^RH zmiu!Lk2xu~#XQ2BqIVLRD8s|yFHQB0{QID+OB)rPQH`%N*WRgJ!|I^G<-bOB&BJ*F z0Y_-3J-FUMm%e`AK-~%jdrmIpU!DN$;<7YIrLUa6j3(d_gY9mL{o#U}@2`}i`D9>Z zEHi(MtHf?3`_VcG3|K-#ssWJ?vT%*POscFCTbu35Fl7Xg$88MA44iLBg>h9qk)gWw z^TRcqpzyXnHvQO99YhFJ;Y&&`?cI4^l>C8|VA_!MG;8g2AN zlO}#Wuc!bvZ)SE@EAK^py&u$}W<_iC*6Z4*PVMCVZ+<#S?d-dfx5N{*jonUrk*Kbj zUIj%#A?xKBmfk1No<%jo%&XEjFo4)eutbDYyBVo;2rTeN4hiT#U*D6UOX%f@D$W z^jMRm+2fNvya_gBDH9jvDeud9BSroXv}=Eeh!m_eRaE9(ULwQ-t|nAwL=d~9Bb1g% zKMG}6m$Xp3>Vm;X5^cer_&a;$A0$e9G@ZUIysTey{NIij#TcfrpnOV5BzDg_)PP9` zMiG|!W)dl&OMT$$S{mA98T)#h(YLfKjm(*Z9^`q*=i}P>Z_Ok?@;?c&G*KbVkcEI! zY*oUV^VPEM!fT`$kOsBa;1@k$rtao$>k4>h-L zpfvbc>(z6y{H-GbA>FDEveW%HT3Pn!kwI>M{JTAb1E2p`W?iVQFOu&YnNUq=iAP@X zNl#IuBnghi3rSkSnYeu#rRj0Wm(t0{?WE0Iaq;KF3hwl@Jm(2lKR2 zu82y}rbRU!R6pP=T%4e^md0lk6dc(xof zjSTIKm26WVHMl?^ZNNx|=Zm;c#jFqPw3bticp> z<5m12k~8p%Qjn20Njjf_`bT4XeHy^pqU!2hUtYqiQt_eKNPJ~P&TJG&u5Toc*}S=` zhOVym*9v7q5`BbCn3v-UWvdKVAgzbH8twM$ERA}%ukSH21a`*D!C{`r?0T>&KzU>~ zL*&*#b>F`$Xbsi3ar9%|QpkfKF2V1Ki32 zf2ejY!Z@aZ8o;*a`-XS<2+>`B6;x@Bzuz_TO%{NuB1-bh%rQB=ET4{2TQ9X=)0Q{> z5%-U2MX7I}9hh>T#M)OHB{V!SV#h(4&^)Q)GNUia0qq6C)Nma@xKv-C)jf-Ws1~mm z<}tG_0U<%}rMn)lvlq1Ho}tX5xvWbdL|V4oBBMJ`F4TW#c3(#q=tcjNFXt)+HtGKh zbjmBGWL$ha)3|nqW4ok_FdZwGV$O%0s{q8KBParRCIudAk4eN%{fm%T{&lYSovFmE zt7?p%kRwyKz|r&o-3VQ6!30eMKFiK|am^$hgs@7sP74)MueZajn7&BPKdzPH78_e$r|%oS%nb{5WLc zid!kSZ-c9eN6`zD4b{gWaB4|Uoq6?+&?!^!g5(mbwa!u2DNiG}&a|H|y+gAniMBNz zoghuZ{L<2GgM9Q~njitOpTOv+!7=zs&FH5a56=?6ZI*8~@szg@YCpu)nr{-p-*3}B z>p}$C;3uEe8+IfGbS8-uP?~CN(qFR_K%=C2BX>`8#|_&?qqULgRmhxgr>4U8hlPpG zVH6(4;7?$7f%4broc0C(!tN$ll619{y|e2jL1v5|WGT2RG%Xz+9Ee$Wo}PEQXAOke zMkzb`Hvjl`^ymq)Y6^!&-S5IW1l~QQwSV{ufe2+W^J_1#VdY&^?iq>Wrnyf{4rZVr zQ;}C`BjH3GoYc9M;nZEE|8fEl8VlO`r|%)n;M&#P_;lQr`i2TGG{p7lY!McPWnx#d z97l@WPEk!Vsu*=7G+O%`9f;h;We2`^UtYxMj&HO28ph>=CL@8jln1GeBtp&sB1qD* zp73J;Ee{l|z|Y}q!&nY`0dz*zu#dyG2?0H_qhL6s35YWsWNE59abeMN@2HS6wT+8v z2B=C-71TjmhQ~~b-tscRsY~MXI`iOO78==mJ1WSz2oc%YLh=oI+ zC+R_jqX^RK^T%up-*|2FFbSZ_s~%{3dp|YPYXY;{gU_5J>QKH(de7YFD$AjZnCI*v z#)V!RvMaM`+qHF_{qf|_kHOzx3Q2iQmb{Y}Zk=Q&3{j12B)0lxwzH=Zt6*x1aglgR7Y0}0uwu-hFPMO!PEdXjQ$)$= zW=fhZo~idIaPML2ho*ZBlJv6zq!KQgZv4L%fWkV_!IkFP5xdOpSu80(e*6f7uE!00 zk*#JP-sV5iq99tw)03yfT8&R^%t*oEcsuMwSQ)uZe@d z)zPsFoG7c>-$Y4YcXxC0PThHr_WYi!nz|+!e^K}J_Hst(rkR}h`bvB-{$q&Vx7st*#fM zb+dYv5yuBQEQUf<+X&bOocy@h+20safv2w&G$k{7&PAK_l4&2|0n;gCqg4W>-kc$` ziB}tI_;iz98Gy=i=cd68h|tT0?gm6E;*1B)bn4FQun;9m;F^b4F6h${Bc=0nUU;KF zpeEC4bA90OjkRDWNc0kbz8QNcci+j{HVw55Ez(a4m&@Kwt9VZ=tT~~377q`^X4pdw zV>XB!I;=qIx4P>)X5qg1hM_EiU1+K%`~c$Kf0D$k(o4KG`peD^Ft0BXr(*9poUx#365N$(|CM^{Pt#&Hf% zY5rF;({3zJ@4wgZ9 z0-%>8n$Dh}b+fJbfHf&FXq$J(xAY24k&X?hNsB)+Akkgq8q;7)^ih)lw=m4~pucBk z;tggo$IS+;BE{h&CY0h-5m(a3IzC$Wh}7%2>INR_{jJ1*XbYpSk=1WetZ&Iqr@ksJ$R}J3`-M~!EXqgJrRAu{TrvBF_7;d~A#as}P61Lbo=<& z`Js`xQ7TC+;RKz}`FkYy&yq=E1RvLK{GdUSiEvhhx9xC4eeYIQV>$V*gh(;r;&2AS zEU7IwjrPJm(fIzToQW8V08}p-Ad?xcB#|aD<)yA5O56EDlBEVp@{9Q*)rb7#ZtsK*K0j`YCeSe;_V-=Jy{eP9>}!_7lnlH@;)-vp1nqvr{PbCjrb`KO@M{) z+6NM4(sPyHoNXF4s2$$Wukbwj8K3a^@XFyuD(2m~GFaJV)0j0MDg$u47*fmDJx~*ImShF%WcPJmp-U&M~#`jH= zPnsu5M!3R*$nSsc{pxnIkll7-^e=b$t=pm{q-WCX+3n}k7WVnG21iAlIQ-~jfeV3} znvVXF0%5?2J(^*+4SOUB_%eynvMLYPMNW1`rhm)5#&V{)9kosk^ud!Gfj17%UgU9k zYWgen_)d{RS5+u2_Ss0&-%@rW-cHS3aeBEl*T6{wwHhQuR2o;6KA``=Br>Rx&?YZg zEWW>gUi0eD4R4fKwaAw}cn~B+60%pcIv-&!hKpHu3Vzg`Sbtppk+h$esl^jRIVP$g zXI1p9TZ+1=Ncb?_L{yo)XUiVj+YSpq=DhTf_Pxin`D&if`QLWobw?cUW^<&tW9+=g zN##^!{QL)zcg9Xm(#KOiCd(#tdJ0G|)FRlPDe*q23|OYGALNd->K>xbcs^TBeB7`o zil)%n!UW^05+bIt%;W-?f{%~NL~}Qf&-tU@>d;E0oe78yCr*E&qp{e=x&u`K1_(0~ z&|5*DA;NQv!5w|az)PAEX_EaHQFWxM7lv|jLc9Uj%{wnR6 zxz9cql0|90&2dpxVueaCI@U+2mFq!!u8fq>O1mVGPec1i{+{|)ig*~wNr}&>YWy35 z<%beS+aHge?QR<<+y~ zTA}Wxw-VUbB%*R&FT-$Mr_x|hO>}GWZnP05649Q^9gVtN^cBfnec`+asKSNVX;0If zpzvxUR(5v{1~1!8<4j@ezXeEe1h=C@)3N^ zaO(9nki^7`xN@Ud$m;zImjR?7$lJVk9GI^|*6cw% zO>`HlMe>ITN7Npn&@?8+0Bmx4wzCAt^*4OyF3WB<&n35#|2^da`=fLAryUee?S|K&l&FHzxpYa4Od1{26fd4}kAYI3uUEhU!Tag( z5DSAz=d?X3hHMNrLON1R_bzSe=j|ZSzvY%aLau22h{4F`cBcw?8&9lbSw7)QCVh_P`B8I6g?23P z+r%RgwIk+Kd6~>Yvb82t*e$nCUw4iJXra-@#w<8ZT4L5Db!PkG*STR!IzQd)Lrv&U zYqx)Y#s&m4mzo+RjB7(i8*;Wd(~m;!S2lGnj|Yb8sAlRYnPQW7&rvA#=&LIQv@r<$$A;@N&3IbfBztT0VX!N7M)@<@}-=* zLsIT2*73tBrFYY^ub~n-E&7rocIUT{(BGrliyiO#XG@>@ZJrj#HH4NkJ8&L5bu zmRAyg0T7nk9@IREw$ZR$=gp3)K9J2*>$md35?0MXZ-=Qy_BTy!j0?sd;1vJ8pC zv=$e0X&60`0^M=#K8g0eqlL#phF`C2XJ-KJvVn36e=JDR01QYfue^9pluG+5nd}dz z#zK(DlE(4}F)XqyH1n=ixHlM%-u*i<<@J~vn0Ne$tH(ZKl&=`nMP9zc<}$zMN&(V1 z74&6K(u$DTs9r9eGE9@Lu&HwNoeb=YFO2D$>5*d=VWBbd2-zf;)QpX$qaW;}+RZ6i zmd>;9hi7f`q)i=h61WL54AvPP*-y-a_gyzs03bMOT?0~~FwOie znDF4p2YD23CxA77Vuy`SUpypMA`=XxwEhl=(j^iCs}3|-)u@2Vg0&_<=ZT|(>% z_z!gaA%IzW9_8J}qI=_nnWLR$H{AcNx?}hUX|~laapVeVH1}uAS}T+XD9AsaIASto zWn10&WlI-o0>6$Y7dVz{q5*b;q6R-2*Lhb`R`~aGAaX)By{SDMs;?(upf(^#xGoo-&BBg~!;&-Rcz)>NcCCU2{!!A|+qw zCYjP-Bz^es6I5>CT`*GKH-Pcv>5tKrlOzc}QL${}UU zNpMrdbtPXt>3hc2jZ5mpPo;;)?I$*YyVt;hqoug6_-Qv-?>wNFT)0YA4cBFayQB)Y$LH5TVh@vQtN2+jeR;8%DUpm>S1-(5rRb<)P4aX6d%nj0cc;m``|%(?=*6OmzuN{7lEJfIM?)swh;Gz!&Ew8R%y;G&aN6std|v^(ng@bECC26S%1!j07z6*Ui{ zUVlUCLRK~G$P`aZ$dd%(FX@2I8mVv^HMJ3&bIf)SL~BGAAj_4%yRm;hgfXXg8l+1A zvw%x{gebt#y@S_ytlPdRaV4N#$;{o@3(N;1AA)K-|74gI*?_80`JvlaG6pEq3;b{K z(n+34B5&eqGw|TLs_+q?A41tElzshWiP5vrFwROfQPtsn7l|J*&rhBZX^yyH@8jS= z14klfZcYyR>$;~KQLTw-Ae>i1nTmh|BM}6r22%UEd3kqaGz5$SH8ZhiOOxB9SYS}6^N7Tqm&AECZZi0u*rabKwAa=0XA_Tfy{VDg@q%EH?k7u zMweQvx5omN*bEIdsOR?8@5&Tk+oV-2B&SuN4`pDKgfBuF)N16m{hR+`&32Xjq;|4uXq;q5Noml97-KF8Qia*90y zG##VT!S5@NYip6+;#TzWfZS$Bt)glQiUG`Q0Q(`ydKO45u=Vg>DD4wa%wvemr^#3=fAj&3@wVQq9J0N2r+}~ zJaOFrR|+0#%(bYE$P_LPbkc-dNoPH`Sp?w_7H;pih&^~I@Jed_RJ&+BIp zMF6)EPJ8iv<@1Rzhlve3@F@e5`5Prr!~_R0&bT7r_X<+xZNFbsN}}>oUcU?unHT?9 zsQbp1okw!;1TZB^O7VXgGIbR$mNMK1s24gLY9mh{*1(2BT60GcetN6Uz@U z9z?)xZ?2#`3ut^~ZxOben6Se(rXzqaf0%71g;ZfyKq~hVEU4&9+96Lg5SnV#_phnH z2ec!fa}g|ctbZO{1Lwhh2B%0*Ump``wE`Y{XkxI4V#sD`nFYf_=^!jS=mZ}~$*CUv6w_8eE&&dbG~G=pSE!Fy?K0l<$kgw$1+hDIq2XvpYl=oM13rAiht8;E-?f z@%Wviz{2cW=t_DxWpLNa-!6MyEwh<{v^0#lF!AqZ#xRHfpJ``->G`8QNdAot+CVhpXUXa~CIm;?Y zNkREWk1f!P!$63fIHCUV?qXz61KtuhC#RT*2*Qr&=ZU%bqyn2nSL%j}Il)ucP6pR* zy*J9s{pwheaR$NWz2sw4U~DYW^;tFm+MRU&`MFH#$2+HmbouwxON!;u+&a&QTC!Lu;C z_g@2^q>~*eQrK#N=xs9>U?f0VRjAahi22$RR9=JM5N(OtMb^ERaH^q2BaDL27=Uo2 zyJiqlV95j8$sfmAT;sqEfG-^24rOKTfgLNX==OoKt|Nep3pzX;#`Zro7FGRS`AB!5s~ zQ%PPP4mf;fdL#y7uh(0iM4r;Imr#l58KQ}3&orC;y^e(h7#w1V0hBDPvOQVGLeP!- zsYxl$hMUs77n51)68+kDzP;a4%C&24w?^Z{-W2hJ4}E3ZZYg#Vb(v3U7btv!)LVbF zwV>cc8fz=6l5K3ZfUkG^@N@uoxHb$CIY5C1hc{m}-ad-O@8A`f`|qYU^i z?KiYOejo+z&*j<3f3#UUD~Eh>KQU{B*#nh5{q6dn4sRnQ0ZkAu5j7WpZ$Iar>pr~I z;&jn+9{Z@(C!z%*|6t32y1FJz{ldbdH5UfaQqmXztpsT~M`;sF6lmLvKSirVd8C$E zKYv*_A)M}DtnJ`+X{pF%n!kj@X&T<-@Ree$*{dXkckBtszfF>7<(x%OFeX$nw})L5ob+N*sjLH<$=T zg**>Kk~1lEh91Y{aC;Cwfa?G_ySLaIn=1%b6uXk%(56VH=H!f_a~M~51ihC1c?J*5 z$e_^=UmivR?l5w?A0=#(#P#jN_b?l*H6P z(@$5xF_*xc)fVxJV3u`R{MXr+BI?xnG@Y~TV(o85W91k;U+H{K98qo62m)p8Gr^#S zyaZqCi|Jpbz_N1xTjEX%GCYt1PaHZ^UE7-(=;`5*e)8ziZZ4L$c}u6xnz!@Bg{i^% z2F#@DL((SU4*|F`IlUrQj)IVmpkG-VmQ|jfOoIa;nydaWAPSQjprL*tU8j=uL6J1h zmKo{k@GY(-2=#y2Fs`SUNy#ZuA6Fy(wqn`#+5LuRgvfT)C!J(VbZrl(!*2?CFKpa^ zz;WI$Fvii@vci0-p(-7>bW9w0I}GgkX9>oF6c0mNj@pr}5O$JG3iDloo8DONqPzRQ zFWmp+<>U@95*QbPoFbXIWEdUH#RzYu!#yR7MrqG5RO#Pm^|}7i-{QvpE1!RCox63} zV&ho$n8)?3>j%?%{+}1%k<=tFte;q{7h=wA@mV~FURq$h_SZj5jU-oz_F4c`4Kx&$ z84Ka)F3$n?3Meo?yuW)rLpHvVu1=Xg0wyi|oM7R{6LQxK^G=yf3V;L@C?&9JCTEpU9qI)h7rJP3MaszN(0?!zy^$0Z>Hd2wv1)af$!Qn+I5C0in zfBEQf6*j&MRga>rKQGcm{-G`NyrW|=U`Y%@c>~ys5fJ`{B?~WaR0`pL zdQy1LRK>(`)mhf-H_T26ozRjbDKW_Bn#=RxgR^amAViKU1%CL@wy-A={|y94_~Uqt zDCgUK+yzEuC@dXAtC?y0&dbY45DXbh!}Jyp-{w;*@R_;eSpU8zafH z7$)JT3iYKeraVHHqbW**58Zgh#ZyGWcXziAuKu_MVnPv&oi;B)n2*X~r+m!o1e^K{(>bXl*QP??mb_wLiDcnf2f;iMk)?m%rED5%_ZE zt~K8;O6Fr7YFB&|@rWv^eDUd9o-A+q-I z;{{Osn>H8PKgn|lz6rJvy)*Q^=ic6TEtvW=kN^8{<#p=^5_Jtm|A$73#rL-u{L+s+ zpcBd6cFtnoc9qK^>X$&J77;p}DiH>LQ$@on?s)FpfF8Bkh6x>6$|~wlzAS;!lGK!t z`+=vI)Ouec=~5aUrN`q8D zPuhRwk~L*V@}iulH&HE?wBQkd1ujg5s7cW|7-^113IMp;RptH58QIo zyU3DGEJP4!=*)4({>Jur?zptNG|BUyCsgTDim?t6%d~Oj0k%^(MA8~F8#XR4B5CwLfz{tH|P8r|xC@!|#!w$Rb52FOn;&&@i_QIKntdEl<+@n-es`1sfu z?rYnBe+D2Iyo8TIFpD|5;h^9}`E3!4g5@VVca@GF_4V|8_~5}MSp8~>0Y8R@i(ont z@>yAl-XGkFa*ebL6*UYz_V>Ja(KbO6t*60JID6WZ>8$5>w6$O+z5T0KqTu`;&Bpu* z?4nLG#{PD5@wYxNaW*hARYVr5r4N-!sRdCT;fnD$Tqevn)AZaJp|n5mu6aVpt=x)u z$`_`cQR#H^L8YY5*i z{{3Fftrdh1q1G|~g_m)__pDRo=P!bk%YNAEiL+4As`mQPThy%;NLXRh{v%f7itP8) z$_+3ck0_E?7#$$lA=vs)++65y6kB2&qn`_|({`h=F`z(3^=g2$l z_%WJ`usJtuk+AaCVXVn{txE3CnzfLVv#~)ck6`7d#RsPBlVgcXo)3L_!arfsYo`+P z-UF8k7OO%^&0{CFhG3icxPTV|DmiHR73RJeiy(uUn|ra=ijzJ9ww+lo0vkHbaVt7B zJ{hL&AZ)R2Ze{h%eY^<~OUMe5Le*j#|AqXicRWmESyvc*=7vkNyL^8IA$-sEo_=Zg9yP+Y>q5R@a7CR5+56(iiy>{&n z&S<)w7!yBkMO_9|BDlOPe9vZ*ne3A@fpt1lt?SF>DQ&o6pCUjG(E)wX>{JTf!#j2P z+iR5KJ|Cbp>%V97SWz&0!R}zfHb)SbMxEE8WbGYNO67wGmSl2TNSz%At0dPrxs1^> z`M%kHp4L*?h?BgTjVyfk%c-eiz|?PFyhVv=^1C7n{pFGKw=r?U{*2=R>{yUOv#C&e zfpS~;q%Jx;w-`ox69LF6*_78?yoh*Nc^IGwMv&|zXx;rDz(tCeg{U9^5g_RM~ z0K%r5f48wT-+oP*!sf=gwC)Ebljsdc?0?7aQ#kHCa+T*wUQQ6}USywirxnTGP7djDGJ^j8628<*{`Gv<8NOJ()zM#k|G^G64|AI;prhLeSi>bTZu!@CMLQs zogM*bAb(_6lu(*p>_Z@q@WkIzy#5P?OS_^R?d~C$Hh3n^pZ^v{!#Xh?mP6^xY1)sS6A?{R zj-yq)0i`I!ysMco?D>B_UgM_vk}|FFubM%=OVMK^hY}n+d3gW`AEP4=rz`}VfeA(g z&HmQz6D_z|?u{c}HX-Sl8$t8~2v8Ggrib^3WsG=76=FeCvA+;(psYvUIfx0XJ4v_~)yuPK(6mOSQff03!`2<*cBl%Id+AKu|Z zF}CvO?n9Gc4E0f5Sn@%0GMscn-#hBHXp9`H*_31~G$kQ@w^_)h-ed&dzpKYs#ESLU!=L#?X2@(l*og0DXo7SPc_9TpsYEp;mSc+d=i zbtF5qUB4%pdBG%H|D60o0Uk~ICLM2ITgS}^4ZhZVa;pc6(t$7OLL>Ly8v2f717g!6 zibefXsByD!Aa5IxWo22Knwp+D^AFQnh&Z8gW;amJ!TI=6LM@ z2g8{3oe<{zZH3%PbR@NxFSLs5JLW55zFP{uR zYZ3X+ER0@1ptulL-kn4F4Uw02ToTq1z(KYNBNU)d>{IDr{OUa?$<}hvc~k9z!6+x& z6UM&-q3lMa@(_Fg)8v;crVP^GLw%ibFnjIxf{^+B)mbWhT7G=}4TG1HKvTY&bJ+^{X=!P(;}1 zLIhg5VMT@sW}+B8o_^WrBrG4m16gmzIG^Z`r$t`mTKYef+om8URH#C(JYjw}60_i#h?|C+FfwAb&D zH0i$cl56bfi>?!>Qg`Pw5_od{Jy*ED%(`0G_%ZIhMlQYdvE^Ws0>pK2J=UKF<716nkWN8WviLWInDZM#DjoN8_0E#$DL*uC}mR zQWD9@=ffGg)f8f@ESkZNA;M>$IX0_p*<*QRhXwi>3dI6YEOz(Z9RA-`8M_mDe|Q77 zD71pj9ak(=5+Y!Sqfox<(&pa-DN*UH2wOf6f4Zmj0rkqEnyS{b!!ZIk_ONy4^FN;r zbK9+Y_|9W{@wfoq+ggnb=UO#wvZp=Qp+f3?hehT8-gKB)KFoj*z1J4=``+mr7$)Ee9ryVX2k0`<=p`2+N4T%h z^ON<^ef$9pZOJq-Y{aea)hifuAzS_HyVkUGL&bULvry&w*WVnDjhxU5=<(B5=9@F9 zGs&@Hmz_LLV)uggh_`H5?z%opQ~x7JCnxZi56H;;2Gzf(w^w~T#+kuBq{2<;LgZ$^89G$r9scrjr%0=AUU?J2&yVQaV!t*G z*I0a+^p0H(F30Gfup2l+c7!FTEWfo)$Dem0NOdPC1&3?Zy=gSkAjMzVv~dsV6+eNq z0S%7|v+s911v}KW%pRv*-VKk`ozha=VQ`>^ArLx*LTgIQCX{xu+dbKHo z30Mm8mHU#;8@oFR>nE(Zo*NA?4fPxEwcgafqqgf|VH)UDk zx*pXVkeRYUd%!3&!5l`Gg^!OJ#0&8kT1)Mj2`weslp-}^Z5@3fb-(#|_vIC;dR zj_xrzkM`p#lr9e^3zcj=4;0{PJC2KaVwUOcP%YyJRKr!V2RR9)h!HymF1O~NO3nW^dC_=!5fRC5hGz3?i-0B-f z@c~uOU%?4SKNE^gAkaBVLrO+fry*`jona)D3dK)`yHyQO-r%5i8Lqb3%9!delq2LQ zJvw!0ta{InR>r&57SD=(QYxriWV4}3VTj>ATGIn!UFx2_jTrubcF03$`J@x4^&3~= z=D(|BNDdVZKzw^{^R({*8RN=P1t%u*#3gPUdMQ7OE>82Wq|x?2S)8LLP7)u>HT6&* znhJ$FVPp-EVXPiNI~Npkg#EEwa>&)MrqC7Y`h*%ZgM3k{{C5`hPXj00$D;S~-riVq zYQY8(IZ&mpE}r2&@=)`xnbWy*IQ4@%*CeJRaBh+!gHLp{I-0fw)(K+x%e6Bt)-LF+ zy`8$JtcrAZxaWKe%TYCbFZJZZ-dp_FdpJg92g+G0>`KdwH3HE3N#$_m%5Mlbmt}aq z2`yWzUaVQ6s%^%kCMV~poLr~4UTLm|e3o1B0n)cRFc|?rLmQ6AG;yylgWXRK`9|4m zgd{tdS>SYzPn^rEDg2$SBzPd@0%&MYsZeErfQn8okJ@vZ)}DgJEWR7r7icI#VDZEA zJO_74kf#jUYQN5zFM=6gZV=xqtbJN~4BSehX?iAg>Tg5*SoEZ<5;JX*TCYhq<_|c7 z0fSq}(08zCKH;bYZ%X(*#^{izt2#S^sF})piyEKx7+OEB?tSnvzunIFV2xw)1Fbhl z9!cD`CCufxMMrbnzbhU4;dH1|Mn;D1Y?v~2872EoNw(*6OLmfkr3P!dl@?FM*ge|V3% zJ;s3FY(|n#PipTA>-+RZ#VVa?v@ykSoK{y?V=Pc{rkU&PsZh(u{uwQc2f> zU%6aPN(l)pV=`!NQS%CA_Ap^fo~P0oxFz&2EIsbyEo`F8m*j;_PkfQG|NQg6kAw#ux8;2M5TS%o9H(I>Gw^HG|O2Fy}FZ4()V|be9u>| zv$-UfgRjO9vvK5a@v2biNd!2O*#+yzTM#ykUF=>hTrR|8h!!0jgfZlhz~fR^cVwQS z?tNS!I=OAnW>UWFgffRSDA+Ma7oP59$(b67_*&WBk+)}jlEz>ge*^mstytiMi;GL* z^`!OvBl01X{7HldaE`>46E2fIeyU0l8!J6h=5py$yg%g|x*eeea)nz0@69TJ`=WZWULauI(+5GHeD4ZqDl&hLReGyS1eLcp9#smSoc?i+o06 zxPm8@ZLVcQa`m6ey2NE;zN8kP!rp1DIIti)8VprOfYt-u9E2QMbd{cqCo?LS9fVlTo_qBmE;9mU3@oH|XDr*?CJccjNVef640rAG6TSbZ1%NXxpg4krwtEAitp5U~vZ?PU~9BKyg&vo!7cX zM)5evjr}0r8P^)YxkF^^BZGG}$zAV7@h_jktubu7otX(g)-nIBHPm=auH2ZcPQQKo zby2fB1@YNVC278cY1VW3r;jhcifkBWak)7G^D<)5*swsbXr*35gguz2#gI%kDA!)6 zT#7QdPRQa2Z)GtF#rqEjuam_Ie~;`_i7(sWUw!W4;ZpTRN7>qxxne(4qwE^jqavQS zCptrw-&jlM-Z_^nF9+!PC)SSMc~{-_CcF5|!1KCBVn z{+7(O|9Z>ygDS4Q&aw+|{-8Ek86|0BV`GzlA}sRmMHlZU-SdV+ih>NVHQBv}l59YQ zjbV7P{;@DUns4VenRf5HfL;Q2r@+?>#Hj(RfUBF}rKsDAP&UOd+dozQ4$nbp={Hn| z-4573a-_&EkVH&bE?eE7PKl3&-<(v+J~GbG{oq)k8@->STn>mQ@Vkohsxks+AfD07 zyP$i0vG5>MdUDIr9=BS?)8gd4@1`BU=L|Q*7NWHP2Mb_EuA^DIKerLd)*{zjF|XB$P*kq#k?TIA3G2ZzZso z9&cpFA&ED;BYj!t7RBj{1|rLu&K=Zghg5|G6Os>H8oNmexx=)nE>p4%9S2Hv7KW!X zk`X`C^Y)RC{rveeTq}-C;DR7b1yfyZY__P*sePozs~vH zWL;Hj<)61m{9Txum6GC6Yjxo@b2-bi_;2Lb3#h^m@eJ2%ywFJUx}`P4v(&!K#lbBt zBQr@)ccwBpI2Z~z2#!ff2nM3M;YZZhdewB!SvX>l%-;;yl-xcQ=!^(z9;6l2$=l+R z$rtJPrKqEl!%?9u9@|pk%Rd|6D~m3Y@)FV(b$+(Vx!kqQ`!KD;6{_YOXhX~DjogXP zE&>^1Z>Si?H2tESHExg>F5DfQ<=D4RJyLk|d8f-#a>Qiv>3$btAiD)a>$xfWOg0Wo8^4uB0Wq!k}h~uLa=HK5xP}5r8lP zW^T6TlZ<0_tyWKUc#reWvWpMao>kx52>N5tVK7E(cXc$3ZZX(z0>VQ#WEd)WXdQt%t5!)ABThxX!{TC}dQ6 zrf8N`XmcV|2!ZeEu4C{*_`)ZG+jxYTaO3v}^$SnG#KZ7`rCWf~_=M+sYj2245q6Rw z2u^#}VbaCUUhwf)sHRe|==lN)Wc!I^(CHUxkg6~cN0)8#=x1uxF(!YH`E$BIPR;Q~ z-XNcvZ=;Z&n$>tFqmc^;GE79s^MWDD5HEE!^4E;L<|$EMNj~+8k#)O$JVTfJQVgv# z;vFR{Nc+STnHcTY|N0X$o0Jla$1M+}z=sS@5*|i>@jcv&hx!-_)!1&RKjkN=VV$!P z|A%Z}e_!|n5fg?d{)BMa(Q6CKK8lhG@a@+4{&eL!LP>+4h@D(c(SY-f8_$3;o`(ps zGiZmCPvyb15If@%Q*h`pU$xleC3Oo^BZ%d}#iUDrZ#@ z{vsjQJ1`1kkU$&uLQ3!03|jLj4&AHWTDHslR^c&*Igu*hk~k&ST8ULq7aEfsImSoJcqW+k&a-XLKQMH5yfLIbU- zsVOck{j<87{EAE@<@o~d~qhLiPIu>h@;(y^ErE zEBKwYtMCBBrl1#>&`M`IgEybCz#FHol|`$?%GclcFMfo(n32;#gvM*$XZI3|gx6M? zzDh^b3F=A}LMA2^#CQc#@&W(0QE1}v?%qlG2`nY`I-Q^Hi_=o1>89V)2*ao_;jGX( zZ*TLW0UyOYJIOUvoYg#j%;%}GTlAspjve$hx*Doxs{H3>UMyX0Ng2Pca&`RYA8o!Q z{F{qJ|N4#P8Az}(4VhjI&NdUIDp#q}?%-5=YM0w~$MKy(zzMGSD6Vl7CDWaw5Vy0T z75&5XiZ_(`sv1k(4vX`w8!4$0CzdzwJ6RNeaoE??n-)<0Ozpiz5be_CQz{)T@O#!I z@(LY|SF4O%U`Hz=ri3qF!n%ZZ&AX7vo*VJezHIGNVx#?>Ye>~FWTBJ)&SgoSjd~ZE zy@y9tT^-nM=r9BI0cV9J7!^^t5^q&OPexkPxuYpm=;+y60tfBNjlXaZQ^x*rmd(a` zf}x7n)vL&%07!TJx6`d47#f}?ux_VwDz4{J>U_)Jgu55zgXoR6YP?bV@lu9f39hJ; z4b%XJbHcwZRMI+4ck&|e^Qwn4y)eMR@ZQl8!9pN4C}})HpBbkW@Zx~$B-!!~dEn7B1I*z`;UK*~yQL6RSbQJC2IQ{7C?8H6txOj#uY@%q`UM-o(1}nFYeoEf? z6XYD6f;&64>TKW{221v5-M2ja7f=adv_60C96oECmpb}VF$aEKDj4O+WU>goG^5S; z#Bt-0`6;0{5Bq;Un%3`Ud^qnYF_YTmVVKXZG@xH)RYA-pD1ImTTdcsHV zz4h8%y%N&)PYB#Vv|{JxR)(YxpS^q2x|4?OlFx_lE3mw|-L#&OznoaSzip_>4XCIl zpQS<`0=`r<-QYOEMhjpem%PUWKvzn)-9a?4m_z6R=z6=!kUs=}HMrYLteyVD?L7J5 ziT7-cn**`a5}8!c(tzDe=?Sgl!AHxvK+6#m2vLpaH!eN>xxf_=X$Hg(ZL&S0zP{f5 z>0~&N-uNraj2`OY`KqOZuU@{4jgQB??L?^&rbtBtnYp#PbrS&W`du54UWjQu~^76ZZn@p?@*A=xk zcs{hJ9jCDIvTE5&C|M$8-oeL+-lv)xFAopkKuaG#HfIdQ!3ykyfVIg8Y<|!-e8|`? zVbMUraQ|d$PWpXoT#Y=35yZw@g}oAg0Drz0+2fdf>sG^;_@nPp>J+5`G6me~!P+<# zzTjk%<>Fw7p(`oVgcr*1r7c)2MC&=MEaGdYkqsnkuZ|_kY_qeoww0{xuA(dm1)-LK z*e8q^0lPOkQh~)n(HMdR^Yiy#IfazAAP@pbvyUQ#dd%%`enssx3yYO#I)3g%3Kk<7 zG^A<^c+`6++1~6H=oJuj>JaYbi&a8x9vDpp58eM`Ow<9D# zIzt;ZIutNW?-E|X+668n}O^`O~BaDi6Sd0pJcGP#BzWq{U0{ zTfWfFp5|%XSt!;xKT16?S#9d*?G$p=|9qCnez9mSv66zF#|UF=Otl&h^nzphsdLOv z&=N|cRCthH9>w6`1JMRYWNeFWwA>7?J^0pHHkik*Rk3NOFt|U&Z9a#-_=-#I4VXUg z6TD+4{P)wJrigKLwO3ojt_}+B+zeoPZl8MrRw(Gl(sFVbba{JJQ zJBzB?f_=o%Lb$PzW35&7^M`ltIC*qEr+HdN_oIm_c{-sOKBe(@QUS=gb#IU13^0 z-f+)yr-|Ur2)6VR<<)`o_%N4~#l{7h^l!LBTCqDJW&@Wum;ai*P>`i6!>pU}s6+Gd z&O%2)FyW+3cK#Y|^nKE5=d;wo3h54S&b|J}WAG#!ZJTve7%l#%IDG?q`k~>bXMoIbc5`C6!Dm%!FPQ!jFroGo+#}s z&A5*wt%CYRWY2E8b9eruwpgO%@jM(fFS08t@s#Agy8fa5zp(QGCKRwSTZ)t%*2bq^ zA#D-EhgMcKK&W_`kYsa*gOMMNb7$}SvGZ% zPKL*l)HkL)4o+lJ)>@t*3Hr;$=rN(~+=tabR-u3l90AFAEx*tYXDXpTOx{<2FRJ7D z&gD?HPF1KLyPECotykYy{I}P?A!eloTJ!z;AD&)DWaV&wWGLZF zyKH;RgZ(*A9>$1Vpd@_Pc@}AAED&aYsvyRn+FMH^xbs4F6FB`3#Rq$MF4EQC$-QZj z{4vry;!U}_SufY>N+YKKIB>}+D>oMuOk&c4#STUoWXfRO$4s*`^j62&tehM?3jn!d zFJJQ6LLnOt(pa?-@5F0|?&-C&$m+*XwUG|Az`&!O_fD2Cpji&)aDO~TmG z58|wlF(pnvLjY?PXl+hGmO)nk<};=6oT*X6*KG)Yhsii9WB!tx+;7x5 zG41+`#%TbA;jS+jvG^it3ThW5UQ8}v%+~hJs{X?4z>CKoHg#9j{wdUf==Mk8eQ-`+ z=g<*3Ch&A1(+Dx^9Y5Z@^4=O|SD$f*k=9uW^5m2=j}O1_|G+w`A46rR;Vo3H+Wt~b zd_+y@qLO2~&=#{sR4D6-Gj3h##ohX=_D%0uI&&H(58?2wh!-Bq zx+-kA2SZ}&{lhJGRQ_*?mgjQD{YTc_d#HCFC-6yr45HsrB2#0LUZ^9-RvZ}rG`1lo zDnaAQ1u|ipXqTiIn!m{jx5cI;KHpHWD>}j=@22N(`RVwG`JHv;$6ueuatU@f!J`Ue zkQ{SJoAa;3FuT9v>Qk0I?EEEBOh%Y(p0_&WO)t4m%fu%tN*SS+jHQF}copF~jM_n5 zwc$%=Y*zVxL`HfU^Q$Y%PV

Ken0TC^0X$)ZbHMIAT>lqsz*aZ8O-*s(DdVIeCeL zJ+Z3b%!~JqFN99MO>Z5V64M%2<#@)}Xe%N)6He}%?=vitzmtnPtbZ_2;sO!|eSH-C zMXV$_rm{^L(>^SuVsoKh6x<=2mmHu88wKc-o_<#R(n>(M)%~o#J+dAp9KFqxtr>1( zy|zY$3GyW^2Tyn=P3ykUwjk@FZk_@~ Vx4(S++UySe(bY84c%Wt%{C`Vf?Zp59 literal 0 HcmV?d00001 diff --git a/src/api/interface/index.ts b/src/api/interface/index.ts index c7a5001..9b17b0d 100644 --- a/src/api/interface/index.ts +++ b/src/api/interface/index.ts @@ -1,11 +1,12 @@ import request from "@/utils/request" -import { type aiChatForm , type aiTableForm, type aiResponseData} from '@/api/interface/type' +import { type aiChatForm , type aiTableForm, type aiResponseData, type aiResponsePictureData} from '@/api/interface/type' enum API { AICHAT_URL = "/user/questionSimple", - AIPICTURE_URL = "/user/picture" + AIPICTURE_URL = "/user/picture", + AIMUSIC_URL = "/wordAudio/handleAudioFile" } //对外暴露请求函数 export const reqAiChat = (data: aiChatForm) => request.post(API.AICHAT_URL, data) as Promise; -export const reqAitable = (data: aiTableForm) => request.post(API.AIPICTURE_URL, data) as Promise \ No newline at end of file +export const reqAitable = (data: aiTableForm) => request.post(API.AIPICTURE_URL, data) as Promise; diff --git a/src/api/interface/type.ts b/src/api/interface/type.ts index 5db48f2..f295982 100644 --- a/src/api/interface/type.ts +++ b/src/api/interface/type.ts @@ -1,12 +1,16 @@ //AI接口参数 export interface aiChatForm { question: string, - userId: number + userId: string, + sessionId: string, + token: string } export interface aiTableForm { picture: string userId: string + sessionId: string + token: string } export interface aiResponseData { @@ -18,5 +22,8 @@ export interface aiResponseData { } export interface aiResponsePictureData { - -} \ No newline at end of file + code: number + msg: string + data: string +} + diff --git a/src/api/user/login/index.ts b/src/api/user/login/index.ts index d542bb6..36c719e 100644 --- a/src/api/user/login/index.ts +++ b/src/api/user/login/index.ts @@ -1,8 +1,12 @@ import request from "@/utils/request" -import { type loginForm, type userLoginResponseData } from "./type" +import { type loginForm, type userLoginResponseData, type userRecordResponseData } from "./type" +import { useUserStore } from "@/stores/modules/user" +enum API { + LOGIN_URL = "/user/login", + RECORD_URL = "/user/queryRecord" +} -const LOGIN_URL = "/user/login" +export const reqLogin = (data: loginForm) => request.post(API.LOGIN_URL,data) as Promise - -export const reqLogin = (data: loginForm) => request.post(LOGIN_URL,data) as Promise \ No newline at end of file +export const reqRecordGet = (id: number) => request.post(API.RECORD_URL, id) as Promise \ No newline at end of file diff --git a/src/api/user/login/type.ts b/src/api/user/login/type.ts index 18613e2..4390dba 100644 --- a/src/api/user/login/type.ts +++ b/src/api/user/login/type.ts @@ -1,3 +1,5 @@ +import { number } from "echarts" + export interface loginForm { username:string, password:string @@ -12,5 +14,21 @@ export interface userLoginResponseData { username:string email:string token:string + sessionId:string + } +} + +export interface userRecordResponseData { + code: number + msg: string + data: { + flatMap(arg0: (session: { 文本对话: any[] }) => { username: any; content: any; createdAt: any; updatedAt: any }[]): { username: string; content: string; createdAt: string; updatedAt: string }[] | { username: string; content: string; createdAt: string; updatedAt: string }[] + sessionId: string + 文本对话 : Array<{ + username: string + content: string + createdAt: string + updatedAt: string + }> } } \ No newline at end of file diff --git a/src/api/user/register/index.ts b/src/api/user/register/index.ts index 202678d..c140cec 100644 --- a/src/api/user/register/index.ts +++ b/src/api/user/register/index.ts @@ -9,4 +9,4 @@ enum API{ //对外暴露请求函数 //注册用户信息接口方法 -export const reqRegiter = (data: registerForm) => request.post(API.REGISTER_URL, data) as Promise; \ No newline at end of file +export const reqRegister = (data: registerForm) => request.post(API.REGISTER_URL, data) as Promise; \ No newline at end of file diff --git a/src/api/user/register/type.ts b/src/api/user/register/type.ts index 79df6b4..23cfec0 100644 --- a/src/api/user/register/type.ts +++ b/src/api/user/register/type.ts @@ -1,8 +1,8 @@ //登录接口参数 export interface registerForm{ username:string, - password:string - email: string, + password:string, + email: string } //登录,注册返回数据类型 diff --git a/src/api/user/show/index.ts b/src/api/user/show/index.ts new file mode 100644 index 0000000..1cea8bf --- /dev/null +++ b/src/api/user/show/index.ts @@ -0,0 +1,12 @@ +import { type UserShowResponse } from "./type"; +import request from "@/utils/request"; +import { type UserUpdateForm , type UserUpdateResponse} from "./type"; + +enum API { + USER_SHOW_URL = "/user/show", + USER_UPDATE_URL = "/common/upload" +} + +// 获取用户信息接口方法 +export const reqUserShow = (id: string) => request.post(`${API.USER_SHOW_URL}/${id}`) as Promise; +export const reqUserUpdate = (data: UserUpdateForm) => request.post(API.USER_UPDATE_URL, data) as Promise; \ No newline at end of file diff --git a/src/api/user/show/type.ts b/src/api/user/show/type.ts new file mode 100644 index 0000000..f764671 --- /dev/null +++ b/src/api/user/show/type.ts @@ -0,0 +1,21 @@ +export interface UserShowResponse { + code: number + message: string + data: { + username: string + email: string + imageUrl: string + weatherImageUrl: string + } +} + +export interface UserUpdateForm { + userId: number + file: File +} + +export interface UserUpdateResponse { + code: number + message: string + data: string +} \ No newline at end of file diff --git a/src/assets/fonts/DFKTL1B.TTF b/src/assets/fonts/DFKTL1B.TTF new file mode 100644 index 0000000000000000000000000000000000000000..2dcf336db12a67dfe330716bb298d5856742bbaf GIT binary patch literal 42436 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�Z1tlwYFm*{JFz_&bMc0Q z8}B{66g5|H*X-W(%b#Khaq5*XFQ(#7&6L0PQKH6)kE)jP1dv(xiat9Qc6ABTnh_kGt7m@2`PT?|TU*4!s_F0wXQ0yBQnjCY^N7rNRPd z`=XFd+4*Ef2(zh5*7Z3(Vuqv9Iuzr1jyQN%qu z7{|gH7*_h!Bw474VKO^fO1C^&l4iH2f1?s+-%^-}CcPLfOPqbV8i{w-S&7!Nj+3|! zJh>vRWgL#juo@N}%QYodyshYDcv`%!GMN?Fx9k{HLLCjmX1*Yd4v-iiq3_FvoR=FQ zu-idyuU`h}U@t5lUf&pV9hbXft6eCZdF;BAo8H;OM=BL8b|&RVA|qH__-?j#a++w4 zG|H`%C0h1=E8$dk3+WPlDF3KdL-(olGHo6o|EqwPiA&@38I?Z@Gb|? z8k#&psyV>nHXs==3?SY%8uS{L)cXaZ;3*IlfZ1(Be_&|=M$tYDxpnA;>R|ExYt@kl zwr1>+Wh{U1Ewjy${Q7B`377*x9YM=Z2+8juJhF#XFfY^p^zVW2HPT zMLv4lCEGc#2`uPjY_2UGYY|oOm^oTVn1Y_TD`-T)&0;B$Yvb%@@PbpVJI^;*2rBv& zOC}p{3Ou0>#=2$&Hfd6gV@W63<#}j{Z7 z@)|@JV94;_KpuUbL~PWz?Ld@4X{jH;^r^r{=0B8e(69-dGU}sz4mO4k6w0IURsDf1 zbb^VhRe5v;Lw{O;VZm2pnuv{8s+CJyXJE|m#ScktD;7Z|{K&l|PnVbTDvuvqYn|+N zF-p94qrFhhWi}5lbnS(Dk%bPOxbNmUV#^St9s{F^5iOhvQsO*HcZO z2B&33vz=(lZ_UIf9q|xUG%(jLXCsznG!L(DmFic%W7*PmnSo+)>)eoTYHWz#x97|L>(vCZe;AmJ5H}oE?4vU zdmlPKUfolyFgR9lq4bV@6;DQUQF03VI*#M*b|I$L$C~S^do1VbQp?MXtxGV{o^cf4 zP1JAZ71wKG_zRe3wRl>%Hgk%nyY-uv%0kNb{1$YXP{r!n+VT8uN(w+ef6nFUhjvzZ zrXc3u3p2q^!3;1I^$qPlKwn=-VB&pjBD3wAdl#_TcXfS%AfZsG0}?<_LFVt7L8l_P zE2!2(*p8$Lz{KF=L4*#VZX*@}&^}pk<}u>+=N6|db5}w$79P!9uhh5pKDR525qt7F z zWFIzNBxpmZX1vAU&AMT%w4}KglV6ycf#K~<(sEMiiB;h`=@w7}W1ME>$=%XxELXQ?7Sm0)O2c9)6^JL<=ap~IomFhdV<>6Nh! zc*X!q{n#NO1SGz`tB3I%B*;O_Cqh^&;7K6IflEiy>{lOigQ5@Ex;luo5MHsp=^{f3 zxrbMF7yY+BKfbW6xQ?^u`A@xR;t42Ah;B68_{y11;=Ck?;pp0o5W!wWiOK03zc9t) z_2{Wj_1;DpGvB-}6Tj}E=btLQEa^;MTe69w$Fg3rusCY(ib@%++itek4oz0RCHF;)kL~j7WL0ztVcFFXD}&c?sBqbg5Mdi zc`zGpZ)hv@5}?p0`vDt>$26cYWcg8H)wE1AZ4h%1BHOie=L=acan;lNg4^A!+CB^uBH{5dY|tRn?}cR z!+b0!^VlxDo3dk^pvrHEx$+X`CPYU{VqZ>I{U)rIM&=nZ57<5t$ZP(hSj>A#2|Bd%S#GbnGZ*L zFKmrY9hrZ{y}x+CHUy{lHW^#jjv83O_;8zy|)avz{GAVEZleP`bP6pYyl96d-0v;~m>_$%n| zK*SjA8)^u41P(AzCW13M=EK>{xzdDH@?FaTwtgw%Lek+k5!EVx0u3_pI9M7xW`NZ=N#9y6S zD|c7-JoMH>i~E;txxB-nz<*rv-kqTS01jmE{2mPKBcr~8-2T&|F8lya z17;lhm-}lKg)2-gFlJpQD=V)qL(A@$6=Cymp{cC$KP&-$c1l&pp$r z^uBR=8mewxeFA@fR#He=t;7tmH5zG%*i>z8?tM}w-(|_CFP?dZlFE&J)v?O`jv;aN z-kY7Rjf89bEmQcjSizeul@*wvKP>y)0E~4Big2$AJrjCc==so3Ls!OchJFkBGX4sl z95`oN>%inFiwYDCX3|&lFpxnU#{?}9{V{Cx7Wvg}rUT)DI~dqt8(jpM+Q6ZrHg^NM zA;7_a8A3jj_u*jF?uM)x>@gQeAGshi2eJPcl7*?+R)Jxfd87AQ%Cn%5{2URfS%0Z18Uz$LtFn`2$M~`n^VMYC ze-k59Fmeg>?C7B zBRp0eU7@+;%o|~l$0uoeF&J;q1d?-2#q53a!PmUgCSq}m!pY3-xE53pFMn~Kpk~7O z7>1|aHxis_kOFQ@7!HZ4$rdXKYFJ3g9BJVqD;;j&w??K2%On{t!)Y%%85qju3|w=r^Zj#{5@otc@=XCHIz+DdA2v{aowbQaY#Tg?fvOT^PR9^r9$V$=3J9H>mXc7R@KS&J&xdjBfqfZ3R zN3=|V*pXOILYL1ncJH~hO6}~%t1cRQ;zyw8UZRtU1Rk#4QJe6yl2qQk`Rs02nd<$? z`8^o1u`IeWE|P>5zC$DIO!I4sw0OhCk%BkT`*6jvWP^x!I8#Nf84s`T9@BAX3fUJf zT!Y%_eHaFWmi#p+yGE=s+y%Z4?XzU%@{30|@w*pODp$Dt4oI#%$0Sc#EOr~|)|^

C+ z^gjX2wnsq)eZj#60?5$})Yt)$SIT{XbMuCmMkLz5P9Rp;Y$A?_&ybJ@PNFp|!DGQE zf#LcH$#4}=3qo}8y*`65AAF4L8g2lg9j=Ksv(W9_fun;`F3n&sBnvU&?8cGyNI9Jo z>7vv~x69c=eb-06{L)I-HO(0GTr$RVlAj{GaT5}Fj-|D+xheAYL#uA*SoYm)JmO3l z#=gzZr%jp?qpO&4>HK&jjg#d@KDBq!*+YrW+Q;u3fdM=w$+6Lxo?4eOBL1RwbHT z{EkS=ytmY3osujHk>BPC5@w5JpqZOwn3Uws?Hlv(u;9k5!)Y@tiYykZOm|BsS>Co; zRTDfdd(yB}&gq>XxOUp+vBMAHs1sE)X*rUTU=R>yL~SzK=nRQLFI>98DF38TVG&b_ z=mcr1f-EaBa>szQ2>tV)gj(xYpwjxy(6=#|ZVF>WNM8XAhGok@odBUAKn$2VzzG6R z-#{5F$OeaokMK1>Q)IgzW19z{Tr>dh;AC_(AjdL;9?$_25tHt;008>-r63RpqKzi) zAz<$yTL?PZ4D{s#^ibjeh@9yu@o+2J7AR3`u{w;=XtD|wQVw5ZaZDmGn&+irnXpB{k6N_Q**sFqr!fvf z0O+yYXn6;hYg<5YWI4MEw=1f%(9oHZ9ZS~}wNgIiIARn}hIuaqBA)a-DKSBQR^%jE zO$wqO`NOjWrYrUY7@Fd04dMwHSY8k*338B^yqmNId+aV}a#j@HO~z*yWI=XKXwb)B zF)3;U1Spayd9}tPH)aw77VCbvGarsrXEkGNEG*D=)UBlwMDjs3%*+~-563j-`5*nl z-nwr>sDV9hnmX^RwBjz~JR*-9D)zl9)LNL^2p#8quJ;%F#@i>yUsn_u zOKImchceD7dAyWeS9}b!!eQ6hG0>a{y$=>C`&{Vv0{0UD2a#6*(!fjf(FL17FvJ8f z18+PieFWVWL$*T*LG4F7BIIGVza6k#`G$TR8oUpP6yk^?94u}z~I+$r2Aup%lL zz-fVv0mPX;7%}jZ=-ZL;82TS)sus-Ut!-`WpU=%h2oUt^a;@xaEfy|ZD9se}tdfso z)TF{gvzTf}WIl^U)NVRatJWg<(Z!K;ehm6)Ck~1!!b;U+iHQ{_!P601h{d(Z8B&P5 zVGYw9Vb0Y_0bd4Ga4)@xaMgayUb7JgI)<-(jwks!E0iMcbq!L6i2imW1oF z0m)!1mW(%}bQp?Yij--mHZDH0JMC2)Ckr=Et-IOlPX5~3a?LW`>_<%8seY_8!y3)? zh~61xWQ9v=vv*py$~(O;Gjeh?n<=Idw;+P(G!P8v!&+CoSCaY zR0&On9*0B;#V|WvWxzj3wS&42HE?HrEnV%;ObC>bmjf1o(~wIAefEJAP)l$v`1q>u zaY&5=tPKN5AV5^rM7fe>-k&ll0eoBJ(uK)ZJlg%}?>s+y-iY82kgs_B!DXNs_u^-I zujoAYs#9(hPc7g7xdX&8@RY_R*824`lihl@)L2?xOODK>VK~vr!Svh*N-6A~w;ilj zCyu`NeP;yKpIJ1=2#RXD(OB{q>emvoK<+uraS3QxA;mg0WRC9-$IB!hi!I+em4G?7 zzm?>pQ4A7|^fa4I(WY#8l+pVpj*AQFWTMPaRHDq{I%6oVok&_PKB{n3u@JX2xu)w* zZwS=4Q@|gawh|vpb4!=};MTb7E-T;1z-(q936I5lg2HMGCZ~ z0nbBQ6BtYoOAVBO_CRYfl73)xNHNIb`sWUf{DXyfhEs(`B`aFTuidj$ue268T9Zg` z-$LG!1gve2t=0?c=1On6eXQmuU;dhx+XDXQyp-78`}0Nu zI_HzOpFI_G$5sSk3)7%Igr&=u-#dvBoS<9ygUNNOgYy`e^B4$bAdVKo?*NHVkwYTugE=5KkmHU6hEpYWd^CDN4=>$(SF4zt z%rM!6KU3bbuuPDm6q#CJ<3hnn8F5{QspAS6H{3|32@8bR)@^y@yg&116`D#3^W7q9w)9WcxQ)W44@bR0Yhll=AB8-b6Z+ zB5S!AtQkppe-w+<*qM<6&71bX0l0gsgvi$FyrmWYhR7D0dfN_ z2tbGgW_952_PZhQKq~-1VEq1w&k&viZEeF5b~lIU{Ql5r5Oo2u^a&{76<~>NINt&N zkvS}!PKG0zH?pHVmD#8dHN=~mC_xHl&lUzQvmMVGrWHx>Hu~&F3P2{p0&m9lOi||bxUtpP{9aEBB z%_j+&;f+Ng@ubOcPPz(n4FB=S`PP}YiqC#*;noYChoWju$LM$KF<-Hp9nOU~=B|Hy87F9)p<^4nMQ- z$>q-M>BIHONB2&YDjLH{k=Bi4jm>3lti7qtR84HPJjl`$AB{)OUYMrot|&H&wc6AO zMN}IRMT61GCeA6b{d-T2W)pL#bGP5I*4dn`S1y#QC1^~U&y`zoarX&FtBpk+88?C< zGaT=D(e>UK=kL$)FgGKMm!M-%;#94%V@_;5l!KKmQJM27c(r!~>^aQMgWPT?p1v5+ zkmZo_lo0ZWXj)_4gSx4( zblU5k%=il@56<4BThmjlror6Wcwx2@vv?i?t*OG|0e>~lI8JW&){Scp&n29AyLzHk zNBvuW$0T-@QU$|W6?W)uJahz>QACp#-Vpk1=&J*M*}*P>8|$-4KM6yB(YV_{^jByf zO{uxM;xae}1s7<k!HgtslG3E|NJU{=mExLZ#?oWu5sO=%4C}e1D#nwO(XtEiCH6|&l;n|@j6hXK z)cs#PHu(H2wr*R4KwY$fmNy_E=9DOUPQH&`vkmKk4K|kthlbV2&22)@U*5Ti_>JXaCl*3A-yFTQsCrC3lKRwab53etu@cdP+nvSIw#>uc|LxJ=X%sh(1;tgN)qq3EwwOn@W z&oVWG^Lv++JjIEuC!7bljxv(6*R+WQghxEz+j3K#y}Mc`6}4Vv)rjcHfF!5`>4FeV z6s^6bi_XK_KKO^1GNdamfzX^x_#L#>9dn?xmr3QIPZuv_JfU!AYiumih>q4DI**4nXqi*qT6eT^V) zK7VbobW?7-A&L=64Z_-(ld>$yC0Hh@^;@NAt?hA3Sjm`7*wOgkpEw11a>XY~Ftd(o zwpgn36^bACU`>QKUJ75h6Mq`Vg|OtpAioxML<*|<(CdaLAY7(N=t1ULC?R=RUMk6?*`}kG%+spzWD=%BGp1D9(RX(ptfBmqFl_W8 zs0jVR)h-vsClGjAeIytGfDj=ef=7M?xdgPijjTRT1?t^)!rK)bYv`YWkpP(Bg%QfA z?F4+tCU8NB?E_anj6R3Z3f?zizeR(~f*1>RH;;B6_tXSulkPhp=Inh}P^OP(Fbrk_P^9~T+lz@v1fn-V>;4tqZ6p&!F(q(Z z&P&&63JV)lCS3zC7!DRsM~oOuC#cr#i0u{ySjnroo}Me!?;Q_A^Kz!N(9u%AjV-29 zZn$Gnu)2c8i~REC3vyUCdATUu81-yE%(2inD%db(l#Zq2lAKBuZ-x|Ghn3TCAVyKy zzxT8sOK_x(osE&WsC>}WI2jA8vr_;=m=mCdd0CApB;RsjFh47VWPgv940i-dO;vg>T}r;Nf<8)!?ELKr_`G8KIz0-dwK^5c{2&KtJ|f5m()y{uA9Q5 zRvuFILIE1ugxF>>o0&^$Lb;ZFb?-x@VHbAc`0Xb)PY9Bh^~&q#;~=BcO}FuMy0q_%3+rH^3FX4&Phqd6w@R8pC9>&+cD|BKmcUuswU}e> zD1KamsbEh)r~ymyqp2D}+&3uY2E)RjmmquWJMh4?hZYV4u>fCSu9`Ba;*RS}B&|ODRWZm6e6!p$&;n zO-`hOIvMu&`Eo&*j^VvKGigy6mvrn+2iNnCaWT0yor!20Q@EcH!h7pZB$-W*b!bII zDXaCX8Qsazh+GqNnTExaV+^!Y$}UkzCu(-{80r~n1ay)m!sqP`d+?2+wC~iRK_B{Nr9}d8p1xTm;*dwUfq5-Es z?t^p+wvk8a(^a4SG@vbXOfF!+wui!vU|lEB1nA525N`np(9vGzWUG!ztTg&EEHZzx zU5wkg*_XB4W9xgHDTkQNx^Z5z^pE6Uzf#LO*zsy^w!@sh;oNl(l)TG-?EENZ9iC*d zF@tFqr$;5JuuMcs7)e^K&Be>_+03Rk(z zD!zx-E>M3)@b@J>>@AqL;3;)?iP6hxJG!Hycnd7c_XMn;HOvqC#J>Z`L#hWfZ^!+? z!lo$L3#0`=@4p7zkJw=wrbFTNEe3tu7beVf2o8q40vtd5>5tK&(B6k^10|t>Pkt7f zX5t@?OwJb!{>J@i0@rI_dvpm+tA6xR?0EO?#nE!C^m_f1Yg2pcCAa*(BU9xR=ZGic zQsxFtnr@suQaFSy7ko3Yh4=@tGc&cN@-A-DnT2yA@rwMhZBb9X3Cx$kCTrt96j8vM^lfMlcVbONd{;3 zz&P4^J`>i5%TdOYoS{e2DoS5cH8I>>f@V#3l~AE6>6#ZCw3Wc-vPo_L$>zi*ulkhFI-|7?qX7!wU&TdiSyv`r=qfnsb7F&Hqv1q%IS zBbuX|x;)WxGn&J}`Yrjq$;OxCK=Y*1S~@UoUlb`qYU0pdVL^w=Ry@at*B3ImQhB^u zXf&0GYASKvfobNtAmR@O^g7#_!FJGB^r-#xPRp6zH&Z+ zd%I3w-}{<#W^a396qdPdA3F@o3(`4U8F6wmlRdtcG^{R6KRG}4+>1X`Oc`?b@}b|Q z7pV;QEJ@hI~9CuE5t1oX22HWROw8-J^4m z3+X?2@Fob{&<+oclEe8ZXWL1L-Oe9m3+eqV2kTS2xtIrQ{&8DqjZ#>7CI_=z%HQzZ z@sHkC_q?qS9+sH!s~Qc@S$zAR^v1!4pPA^9TWir)yl^3#EJPwiuAXZidb48e?p?md zOXeGs?%4hl#91#kvp184IX+rTf$1<&7%Ga{_uxlv9V2&DfO zN*4VPYp}Z?+O`HH*q0P?>4DH-RVlDtAh~WoDjT{M*y(2s_y?$ia15Fv(fP0{lvx`)@mCpVT`3~8vq3oMh%Nymd`aZ zRZdR+)N8X&TaJ%(8r4{sVXAvndA;7Mb(4Bp$&QD`t$ZohNNO|Dn2Qs4Hj5*$@OjLM zl3}hm(V4mYoalAbZd~TV>_RIuj)xWKsbORodBEDR%#rAR*o#ndMV1Sq=62G#FO+%G z7hEgm#?5<6aiw)Ay~FJ_U_tkNFgaq!IKmY}A2fa-?OZ8QfNCIWg963C?)!C!VAvbN<%36xxmP}Z-!5zH;fIcveMwGizUGnrK#^Vw`a?3~-QGw&rD?F% z5GRyIk74I3<)}I<5|pLpqHC9{$63q73O<*49iR2Mqr4ltMama=BcVl#1uT)?!5NdG zb>Iy2fY~eA9CKy$a_EQI_BaTb@Pm+fWi}{UJY+|XfJAXVqBf6V=1pferdx$$)Ef@p z@SgvD+a(->0mWi7_p6VcU}Qbn?fu2YT~ldTfc+O3a(e9T56q2M9)9?dRs3_Ty$TbY zR%&-e<5m3YrM1e~%-qF8wOl4CFlCo$z?2ieYd9+jJC=o&!+ZDS;`uQ@W+aj`lee*& zzN3ounb2>;+|fS_{Ru{3!ZtU;Jq8-wIarT6;?NHmKEx#bS9srNMsHyEP;5XvxE;^~ zSq9DmBs643RNMrppeP0qfY1>zYo8&ulLy2o0U02&Xn$WPU(nD5OtF159Ql2`tD$=x zPy{6Huu3g7Ia#m}E}|gx)$pzG5xhe;FxU}nb~F@s0k!wK^<@3WQ!&L@#cq53HB;4c zJZk2Zm=Ds!hs;hcY?^1WGT574a zw4~N%OO}i!%NsVf5Eu(%8ygHZkYk8R#ux~h69PDg3HGo|GQfCdGLr-tAOnX$mN{YO zkl~!kAq*sH=6Bz#>MrNx|M@36ZdcXY>ejvAcE9EKrOWFFSY7ZH?RcZcHiaye# z^<#~0$^oo}cL)ANQ846yUsd+C75eV0xAi=Q;OJ=W^qs4vQcVl$TE2n2y+A#*NXDfU zGn@mRtMh=)jb}p%4arl)O~eQ?gN^pO;qxYnb}$t2mBLa%v^Ua~+G>+;-52s3g4FP`f|aLbJtW6NiouA!kUtiZb zx4RO|(bWTjwj4s~Q!O+X$%uHP=65oohI!q+!ew&T?Mm1iL_!R~4t?g#W_#-64;-~e z7wOP_er(o?OOM`hBp&NtYCikgeb+Lj55;BQCu;G=8XdlR;n3_#fte=2b+wxUFGD z>O=_Sx6INc&-3S;#FN&~tny?i+|bx!t0L+{^Fbg-9_dT;9TUc3l0FA=eGUXW;Aerw z`Z}GQCco1Wa|1n3;v;WlQLy7M&p|CCVoahm&`25q(SlUb`vq>$9i!kDZ-k(t0qMO(Ia}6~&L7m_g-fXKd=c zxY@W|4;@e5UefFD8w)A0a6-m@`?83JphhPpcCrnCbYY7Y|17d?V|1&$82hw8o?v>+ zKL+DLF_U1}@s6nZf%H_TJ!~WzDaes>{amV9I16w5v-NZ$8;aP4=agsO+p~jfcQr&- zdY}~J!*=AxJ&FRn;`w}%3s^}LA!nwfDPgU0>jK>_az*--uUfMMl9(;UL{rtCaa?zTs-dG>qlMvQXDyK%0vGDZb_=wrgm5PnU9J}l| z2vLMEgB04A_ZupZz35Mfa(pu0tCuR>C&av$i5W;vDG0ncl`thO5D=}gQf_*U=9z_u z3fahr(XhAF!zhaj=wwIV&g7zSfpZ?!OvXniLWbr#%FE@frL3i6kpp3?FvBofWci_# z{otOnhfDHZK?q({GN&4LBGDEI43A=AcN$>dSzq*^42Nv(?`0SB=W032zAJR1C<*|m zQPMu&-hfXQj4~aICF+9FNYSrusE8DWjO|zjS>bYc$OapOQwl4OC2*v$V>DRK{|OBY zR^biogbzR~A?ref7r8B)xoO8PRN@A+(C#)okDa_SQR{W~o_XZ$GbayUHl^12a`1X1 zlMKY-^v&oIRsG)nsJ?{mIvr-3tEqeoO??{0bSE|4{KQvZe|mPI@X6x~EW`Y_Gsioj zK&WD;Mn3w*T&hz0cV8~V^r6w;px)zJR)ZlAVuKdxZnRVS>X0spDGUSz2EX$gi2)gO zeku83&MY{twt-x6hr!`%ous+Sg-v#z(e`Zm)j9V(?}-TXOR#U+^q4mAOJ*X zq9G_|ER$%joar9QS5kT`Vk+SSa}zI5EPRbQeDdOz!*_SODWe_r7UJ2~LW2%2^n^(r zxPAgM)=*?$SDFttf&veKsGwlevKPrbR)~!wXLUYcSykRJj3C1tUmdH6NL7vrk#2AA z`dn|U+^VI#(_<48dD+yBR`1AxlhY+si&$foBs&t%cb@;yrO_O7Xif>g^mnP0CV4!L z2ZJjq-R$(Okk5YdT`@xrKYVp^NNgNH?(?_Nl))h$muy^FjA?LXvP(W>=7?e10f7a?1j0s7_RrpSIcWv67wCI+ANLk5 z9Dn4Z){G;kCmTbms}Q|7a&RP%4jFseQV$h^xl);1KD7O_uggnkRpXu#BK=|14I^YX zlc%}mZpH{0G6x)N&Rm|$SqAXJPsO$tD@T9g5v^!#CCNnOhXeL&W^(YckkoTO71DB<>aA~=%_)we|H{ApPl%5E(CRu)eP_tAZ9n~dO z0xYz){a?6-!FBT7{}oMuqXfB>M;c=9s{nH!IEee}PAI{p0HU7Ul?R!O4`_jC3upbo zsSdaAuD@$$?obVA(KRz&&$>gDq=3^QfSZ5G{r{TzVxLNe7Mb1LKwGrHO`NU0hpuc=fOYoIj;w zKa$~XW|LvYYXzw1ajPq^dUmN+9T5P$P-DE>XGiUkk`lrS5aJ(qJ0C<|~IGC`4`h2?M`Nj!cI<2$^C ztI1xkuR_3yeN|C(>U3Qx+eW01crkG;?&(+RVubKAVgK3nIsw0a@eJ?1hGO9H$+1Fa zs^hI@GgDo0ZZ-zI!4|?x?R?2J>aPsPn@umAz?&Z>`j-VF++<_H5sOfZJa_sEBcI9l#aESuPA=QUta%!zqq=t&|eKQ zN_KT!i|dag0sc!|q)a@1O2FD=!g%9`tttzZkCd=dLjkz!q6n5{K<`8(B-2x7=4!@$3M|?5r}oBUZm#sAg9r;+jq5Vi{S% zLihBE5<+#aBEeTb?GZcH?CeO*Tx4^>(OW3d66~HmUCsxC zkxH;sZJ8G&($0hSq6Af3;Q>f$0g|Is%p{G3WJs1LN>V=fY^bn+sK)zlKlL1Q-f9<9 z<<)rx^LOxeB!DPp5ZN8u-^c`ok+2>5RUB2^wbI(HznzFh1GER=yD9iCM6M>Xx-eZQaIU9L zhRq`rO^u5g;bJkX)3V_i$-xp{Lnk#Z`dCo(welou%TL@^f#agr?i(H9kI_?AG)$yf zztT?peZOC}1ITd?r@USidiUJ02=lzpM^8303Huis7oBR+GcyV|@-FMH zSCEQC7rso7r5RC8w$|u%?niVf?QQzm`C6`F36NK|5Y>w4Ng`sD0E?Exa59xI<-iFZ z$xPeb1X2Hn9!%2A2j-^7bX0zNlP0HW260Kzl7W_feoYd58NbL|k+D=R1AmLxPGhHH zNxH0@cKG^Nhg0!PwUgbqaZcDQCs$7u%Vt0gG`9uO1Mnfv6JW20cuw$WGVi-F%X6`= zK%YQvHXrrYvS=aYJE^CF{>3CubKxOH_z0BXr%?6$8uhx9*W7o!5IN@nhY|IJwcU|> zj!YY(HZM_auC?K)H^Qe7mEiS40 zss?n@&m)^n7Y{F678>xFrcytCFqK=`$`nx7DR4*!PS-lg+hOF4W-_^Bfl94b=iYus z5L$}v;pwY-64=Cx$CAM~Ck6t!Xs$k;)=Zwxoueo0XcE9Rfo^vDlhN9&rlNFie%j34 ze@&C)J+)QH7nongR3n?phd{(=b)hv2_9%*!#UT1_+M3D|a5eZo&CJTi@n#;08$N|Q zd+6Nxk$P+V>Yhj{RWVf-25ffa>5tx{c>N;_Q=;WV%RsZcy1vi6RJ)t&6-OsZ-he9E zx9%#gjfjRUNZ#ODd(DIH6tQ?LAFS<}I5G~maq|d$V)-_RZ>|i zb2@290)}8lk|VSa5!7S|i1Qu=<>O)E36Y_^NdFZ!pGf6;ba?-T=x;Uh5MIJ0i`pr; z!(&kqZ77`vDy6WlYd9t%pTabthaiyrVmE%|tx-W&jiGF{zoLFZ{XMl!&+O=Jc#itK zM<$u55d7`D!A$SErX1_oav);}cS3Tz=CT{|bohSgsKau7{&y{1s07y(CYF*b7Kk}T zmd069et9mgdoXPkvRffmEJcA?J- z(1VZ|&b$6M_Mg%sbb~twr^tpJ{tu`!cXo*T#PPM!{QPK%^+rpYD2AiOL^PQZB1Xu+ zwaPJv(?K1(IiJVM75v=!!KZM(gzNxI0cN?45(v1bIJs^ftrvmX8EiMk*1V^u+j3xY znWWKNz7#XNm%lVqo=l@-kYSc-+lZM{iCAvD8=wD9$L^ZQ*9aYW;;s`5)7?wYeB(}C zrNbsF=+GsH_t-{IW7MRs1WuVq|4@Eezim~&S&seLdjV_E`m|OmC<>pu;!y?Nj9I>7 za?}TGYLDKGPlp7*7B+p%(^WV**tnfWsm=t)sCZ>-Aqz0-P?;hM#l1!(5VKODNEMMB zk&2G29|02%_;{qX zqiSVjD&%E6k}i1|o{MNahOaV_K){G;i2C4l$O7Jn&Epw(;`aCTtFTG)*y~tFw%8+$zvZ3@O-7*E%0yIBK2=y z`EsGn|NP3)YT1mBJ@bwG+uU+C5cDv&N5sh1Vi~^mufF`XBM(3Fz&x6+J$?OnIP{Lk z9$KU)-u#YJQH$YZZT`peHI})b^kOmqQRL4yQl$vW;F`3U^7g!I+3dOPR~O@UGp74` z$bL?A&Yc&pj592I2O!ODAfVrR$v>SCLLvH~h?c6Oaxy_5SMwDP{?r-Mr|Lr>D=)*H z{$J5y;V)<(ZPIbNOgAx!5ZXJe>{Pf|ju_~R1WXR*0j471L$KrSrOpW)bl`&rx*wWj zP#{a>kgHO5OphJmfe9Y4JCO=R5D~fJRO|LFVMvkwnU2T#Qs+2XVVbOqGcH^}mS)HD zDDrvo+1a`GM~bKkgbtn!FbpTU+?QopB9vUk*f;UvHZ78cCr|U@xsDIUoeMW+V3E`0 z=rxT8L=_sDrm%>#fc)opKI}v1&X^&!=Hi;@-8tk-hY|qh4f|uINT`@l5XqCgr1CV= zvm_}P4nzx$6GyU}&00E(IBC2vC3qEE2hM}-@d|=>c@9`xastu;*}}lq4yS7YJsae5 zc6U<*W?wpiriB|_mMM)iE5(@3(~p~y5;o-rqa5d{3-9IlTtX|Aww}po=Deo+ zJk6M2OA3-7{aGWg_!wUC2q@#pS>kD>BuL6nJ%v+wEwro~+WXZoKsEx5oj5p`APrGt zZ(+TVc-TJ!ImH*w%1RB?JDHg_;z19(safPmB7{=mU;=Q(iAp>k@C$*U8B)+Hf`&!x zHxnbC`SWV)Xk;dZsRbzN*m6+xDrZL096DS0ysT&Y&yVzee;hSrcJcTsaZu=r^<@Tq z*bUBy5cl>cfk~Fp&B^1eg6bpQibkeWMsX&lYk+~elvDxvj25b%>a&$>w7xd|^@`v3 z;bKn8Dps`|Re6SKoQ%J9)iC2_)~*^rx`p(7ZEE^LUh=&&vnL;pOFn5RJ!(I71bCM( zz)b%S?#}R^CH@^c|0njgYgB_ET{J!8!XN63-id@^Ao(`w0Qz=bNZw6Ym zN-dGdZ0JqAVQ&172{U_d)NW>~JpUD|G_D$nmjiy%FeIDF(XVLg3d38dIhYCvsFTmy-JRLK(%G>!C zTW)AlZX`3_>PB;B1(tDJA3JPlbJO#ag5m3)FpasT)%lRZ-L>?CQO)>5qgQRu*1Q1) zZJ>L-d`**#d#vdTA+xu#zHgm=F;9=jLsFxql{|?Aa297cQlC&k;0i>A?C%+rf)Quf z_DdS)N!CUtSF53@)3Qv;?)}Xg&-Xs{?_ZdDT347yuwTw>|J~{& z+l-v~k8BO~On$$A&&I)}u&M($JpjuCo*NZYQ;T((y6TSHEjpHlyTMo=15O`dMj4#Yl@+kMqC zq^+HtAR=pB?+BcG1AQ~Z2aa((;1MT+LMFIC#5<&RKT(TFa7S|!I~PjaRa`qcM`V%6 z8FzJDJ>n!7I_{crpjvu&?1Vm(l0jj_PTX#1QFoTt9q_KsA~y5xCj-&TLJ_*AXrXEx zKMqJ7zY47RG?EmF^#Y$OAZm3!JYqgFJvhy%25G zYLQT*B*Ny?(SV!v(VSsNyqr|Dc}c9)s+JHebQdSDU*)tJ)gR(e@+juJ6LfsE7;81^ za0*Y>74_!$*!ih!u~Y43m$SK`<~OuZu5j)G>-BE}&dK=gwdMB096M)gCQJLgD7=zc zKWB@E-bf|iW%(=dBC!HxkB8B&q4Eg**hRk@c(|FuaanrsO^1=nbms=@^5~wx-LuTm zw?%KzFT8NiKHhFT`0DoC=bwB2lBO1~ZvXAPul}d(n~zS=e@G+n!AlBSOHCu(1n8L0?A7`)x!pieAUY#SSD$RgTaZ89&xgY-6!DM@CGLP zt?NFX_KSX+k#e%%$70ZnUYR!ly{DKFSR$-Z^tC++;zFV`@yW2M#cz6Ew>&HcJfw)0 z9Yu7fQ~Bf+Yq&c>CwUE_30HRPY7NT;7$yb~(K=*TH6USJWc7gsUFWb)n1o=3xs*u| z2x%xXXdT$aumI806%q`$IonPc#1~3=znDFdovRcBF;O*9@tI2%gi2^WU*f{iJ(C-$ z;9O6Z#p?Z^x>O?&ObSYLxu~E1-*MC=*r-^G`~j;O!F;SBDHYH5J?z_P;w_l;)9+wt zUwu^Z({b^LNHc#QVU+yn$a*di;>1YGjw{mKnZCby;jTdqQL$5L1L9CIvH z1T5;%hW$;L;_FVs=KeNgI4=^FUKW`NN7QH0#g^2D)_k_b*OQHVT#I>I#slPS!UT z+evFoW-p&$`2BnT>_WA1eM>VhJbGw;-jV{v%!P?N?$4&?w-#oFmDG9k#^YqU5e-_A z+5@~ea<#COjm1;UK@WG}0KK=l{nOj05m>ChrSTMfvrDftOP!!8R7RPvGPHVxR9z!7 ztA>?odE&|GGEMX4j1t_p@Ag=4Bx;=QPL*O_Ast{sx*X&(VkTa>34qatDMg|Re6&Fc zE|cxgnCa3r}9;~<2hsvj-vCtG%Q*SZfuK+*urp7=~`n z=LhI3;ju(Go1>%Qbunp49LIxr{!O^#kIA1tgrc%Ynm=O)O`BA<1&>8o=FQFQ!92LyYGV58PIerm#+2 zE&S;{2bZ&dkgIM@j}|JcvG4~EF7(vX$Id+X z{&VSP_=DZgt@8IR?Z5^lzsqLMY@DoAk0p|MU9UCX)u;%a?4#X0t5homO&quEl%dvU zQKqb@%JKM|>9jQwq#jp{qk#k`PL?fZbfnS^C?S!%UP{N9X>EWLG=9hzK;-E?bqR73D@bGFi5oDMHki=3~sch;P3 zXBOMz_EI+@u%51BNsIZo0AE;ufCJ_XXfHM#*)zUBtnq<~E~hp&HAjppy@i=iC9l=mo6vDSag3J*R+Gjw`ybHaBSCxLO{)Nswv$>Z z9b~>l!(CjY??XCMC>JHlk7LV8(rS>CJzl`@XT5?(ha>fiRoP6)s!yU3-m+PrLdO*} zlzr`2fVD7W5( zc2G+lw(TH*Nz4(fyz`1LBmC+OzTFgb+G$vrVk*(ZmOzK%Bb|uK9$I9QG2%q&X=!`P zj?x?Tyf1NfY@vN17&NSE-dJii(kr85szBfSIs%h{OfXW+y_#CvP+vz;eeaL~i5zQ` zqfCY4*7pI@vr>uQkCZI4lV;;;yjEHd{9^0S=SIzHCXza_!r|*}AG2iui;(;KVjWkgJ^}>%(hgdG*m@0(AKpzKQtTgH^ zj;=Inlk=bH0)xXny#0=~L@Zoqk89agf-VOnnOOqnkAL{&{`0vnJD&%~|3AO3;rm~~ zA9}OVXYluRiee8@l;>j<#s8e5e6LcJbdsX{Z=opVClsaK#NYqKO5?rxZHfxvoOPX| zA|Z;3K1oq=m7LrSrIZjb?zfMsL9g139q^PCuP}IH^idx1qR!bDs zyN{v{e2$_Hc_`{IVv0wwdq4UGiaP!TMQx%w`ecQoPQ6S~TcFU>z+gCw?>hHkiaL+q zbOFEhB1*~b!2Oq#6!oS!{_x#b@SS&KeAj+KQTP6mqVC6-AHaPNf#M%NLQ#+WFN%5_ z#`AWJ`7rM6LX-~A#*Jrkp-_a-RnS&Z@huT#|XDT?|4p7Ae#|1t+I G4g5besSASu literal 0 HcmV?d00001 diff --git a/src/assets/fonts/blomster.ttf b/src/assets/fonts/blomster.ttf new file mode 100644 index 0000000000000000000000000000000000000000..b342c50934838a6fc0c80176f0ce2a3fd9a2bee1 GIT binary patch literal 44628 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 literal 0 HcmV?d00001 diff --git a/src/assets/fonts/theFonts.css b/src/assets/fonts/theFonts.css new file mode 100644 index 0000000..fca5426 --- /dev/null +++ b/src/assets/fonts/theFonts.css @@ -0,0 +1,4 @@ +@font-face { + font-family: bigWord; + src: url(./blomster.ttf); +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 4c51d67..42a5c84 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,6 +2,7 @@ import './assets/main.css' import * as ElementPlusIconsVue from '@element-plus/icons-vue' import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' +import '@/assets/fonts/theFonts.css' import { createApp } from 'vue' import { createPinia } from 'pinia' @@ -17,15 +18,10 @@ for (const [key, component] of Object.entries(ElementPlusIconsVue)) { } const pinia = createPinia() + app.use(pinia) app.use(router) app.mount('#app') - - - - - - app.use(ElementPlus) diff --git a/src/stores/modules/user.ts b/src/stores/modules/user.ts index 98cd07b..e6fda8f 100644 --- a/src/stores/modules/user.ts +++ b/src/stores/modules/user.ts @@ -1,36 +1,86 @@ import { defineStore } from 'pinia' -import { reqRegiter } from '@/api/user/register' +import { reqRegister } from '@/api/user/register' import { reqLogin } from '@/api/user/login' import { type registerForm, type userRegisterResponseData } from '@/api/user/register/type' import { type loginForm, type userLoginResponseData } from '@/api/user/login/type' +import { reqAitable } from '@/api/interface' +import { type aiTableForm, type aiResponsePictureData } from '@/api/interface/type' import { useRouter } from 'vue-router' import { ElNotification } from 'element-plus' - // 定义用户状态类型 interface UserState { userId: number token: string username: string email: string + sessionId: string + generatedImages: UserImage[] + currentImage: UserImage | null +} + +interface UserImage { + ossUrl: string + createdAt: number +} + +// localStorage键名常量 +const STORAGE_KEYS = { + USER_ID: 'userId', + TOKEN: 'token', + USERNAME: 'username', + EMAIL: 'email', + SESSION_ID: 'sessionId', + GENERATED_IMAGES: 'generatedImages', + CURRENT_IMAGE: 'currentImage' } -// 创建用户小仓库 export const useUserStore = defineStore('user', { - // 小仓库数据 state: (): UserState => ({ userId: 0, token: '', username: '', - email: '' + email: '', + sessionId: '', + generatedImages: [], + currentImage: null }), actions: { - // 用户注册方法 + /** + * 保存用户基本信息到localStorage + */ + saveUserToLocalStorage() { + localStorage.setItem(STORAGE_KEYS.USER_ID, this.userId.toString()) + localStorage.setItem(STORAGE_KEYS.TOKEN, this.token) + localStorage.setItem(STORAGE_KEYS.USERNAME, this.username) + localStorage.setItem(STORAGE_KEYS.EMAIL, this.email) + localStorage.setItem(STORAGE_KEYS.SESSION_ID, this.sessionId) + }, + + /** + * 从localStorage加载用户基本信息 + */ + loadUserFromLocalStorage() { + const userId = localStorage.getItem(STORAGE_KEYS.USER_ID) + const token = localStorage.getItem(STORAGE_KEYS.TOKEN) + const username = localStorage.getItem(STORAGE_KEYS.USERNAME) + const email = localStorage.getItem(STORAGE_KEYS.EMAIL) + const sessionId = localStorage.getItem(STORAGE_KEYS.SESSION_ID) + + if (userId && token) { + this.userId = parseInt(userId) + this.token = token + this.username = username || '' + this.email = email || '' + this.sessionId = sessionId || '' + } + }, + + // 用户注册方法 async userRegister(data: registerForm) { try { - const result:userRegisterResponseData = await reqRegiter(data) - console.log('Register response:', result) //code,msg,注册成功请登录 + const result: userRegisterResponseData = await reqRegister(data) if (result.code === 200) { ElNotification({ @@ -39,10 +89,7 @@ export const useUserStore = defineStore('user', { type: 'success', duration: 3000 }) - - const router = useRouter() - router.push('/login') - + return true } else { ElNotification({ title: '注册失败', @@ -66,19 +113,17 @@ export const useUserStore = defineStore('user', { async userLogin(data: loginForm) { try { const result: userLoginResponseData = await reqLogin(data) - console.log('Login response:', result) if (result.code === 200) { - // 存储用户信息到状态 this.userId = result.data.id this.email = result.data.email this.username = result.data.username + this.token = result.data.token + this.sessionId = result.data.sessionId - // 存储到本地存储,确保刷新后数据不丢失 - localStorage.setItem('userId', result.data.id.toString()) - - const router = useRouter() - router.push('/') + // 使用新的方法保存用户信息 + this.saveUserToLocalStorage() + this.loadImagesFromStorage() ElNotification({ title: '登录成功', @@ -86,7 +131,7 @@ export const useUserStore = defineStore('user', { type: 'success', duration: 3000 }) - + return true } else { ElNotification({ title: '登录失败', @@ -106,23 +151,127 @@ export const useUserStore = defineStore('user', { } }, - - // 从本地存储初始化用户状态 + // 初始化用户状态 initUserState() { - const userId = localStorage.getItem('userId') - const token = localStorage.getItem('token') - if (userId && token) { - this.userId = parseInt(userId) - this.token = token + this.loadUserFromLocalStorage() + this.loadImagesFromStorage() + }, + + /** + * 从localStorage加载图片数据 + */ + loadImagesFromStorage() { + const imagesJson = localStorage.getItem(STORAGE_KEYS.GENERATED_IMAGES) + if (imagesJson) { + try { + this.generatedImages = JSON.parse(imagesJson) + this.generatedImages.sort((a, b) => (b.createdAt || 0) - (a.createdAt || 0)) + } catch (error) { + console.error('Failed to parse generated images:', error) + this.generatedImages = [] + } + } + + const currentImageJson = localStorage.getItem(STORAGE_KEYS.CURRENT_IMAGE) + if (currentImageJson) { + try { + this.currentImage = JSON.parse(currentImageJson) + } catch (error) { + console.error('Failed to parse current image:', error) + this.currentImage = null + } } + }, + + /** + * 保存图片数据到localStorage + */ + saveImagesToStorage() { + localStorage.setItem(STORAGE_KEYS.GENERATED_IMAGES, JSON.stringify(this.generatedImages)) + console.log('保存生成的图片到localStorage:', this.generatedImages) + localStorage.setItem(STORAGE_KEYS.CURRENT_IMAGE, JSON.stringify(this.currentImage)) + }, + + + // 生成图片方法 + async generateImage(prompt: string) { + try { + const requestData: aiTableForm = { + picture: prompt, + userId: this.userId.toString(), + sessionId: this.sessionId, + token: this.token + } + + const response: aiResponsePictureData = await reqAitable(requestData) + + if (response.code === 200 && response.data) { + const newImage: UserImage = { + ossUrl: response.data, + createdAt: Date.now() + } + + this.generatedImages.unshift(newImage) + this.currentImage = newImage + this.saveImagesToStorage() + + ElNotification({ + title: '图片生成成功', + message: '已生成新图片', + type: 'success', + duration: 3000 + }) + + return newImage.ossUrl + } else { + throw new Error(response.msg || '图片生成失败') + } + } catch (error: any) { + ElNotification({ + title: '生成失败', + message: error.message, + type: 'error', + duration: 3000 + }) + throw error + } + }, + + // 设置当前显示的图片 + setCurrentImage(imageUrl: string) { + const image = this.generatedImages.find(img => img.ossUrl === imageUrl) + if (image) { + this.currentImage = image + localStorage.setItem(STORAGE_KEYS.CURRENT_IMAGE, JSON.stringify(image)) + } + }, + + // 清除用户数据 + clearUserData() { + this.$reset() + Object.values(STORAGE_KEYS).forEach(key => localStorage.removeItem(key)) } }, - //getters计算属性 getters: { - //判断用户是否已登录 + // 判断用户是否已登录 isLoggedIn(): boolean { - return this.userId !== null && this.token !== null + return !!this.token && !!this.userId && !!this.username && !!this.email + }, + + // 获取当前用户的所有图片 + allImages(): UserImage[] { + return this.generatedImages + }, + + // 获取当前显示的图片 + displayedImage(): string | undefined { + return this.currentImage?.ossUrl + }, + + // 检查是否有生成记录 + hasGeneratedImages(): boolean { + return this.generatedImages.length > 0 } } }) \ No newline at end of file diff --git a/src/types/amap.d.ts b/src/types/amap.d.ts new file mode 100644 index 0000000..d2f1030 --- /dev/null +++ b/src/types/amap.d.ts @@ -0,0 +1,71 @@ +// types/amap.d.ts +declare global { + namespace AMap { + // 基础类 + class Map { + constructor(container: HTMLElement, options?: MapOptions); + destroy(): void; + add(overlay: Overlay): void; + setCenter(lnglat: LngLat | [number, number]): void; + setZoom(zoom: number): void; + } + class Marker { + constructor(options?: MarkerOptions); + on(event: string, callback: (event: MapsEvent) => void): void; + getPosition(): LngLat; + setPosition(lnglat: LngLat | [number, number]): void; + } + class InfoWindow { + constructor(options?: InfoWindowOptions); + open(map: Map, position: LngLat | [number, number]): void; + } + class Polyline { + constructor(options?: PolylineOptions); + } + class LngLat { + constructor(lng: number, lat: number); + } + class Pixel { + constructor(x: number, y: number); + } + + // 配置接口 + interface MapOptions { + zoom?: number; + center?: LngLat | [number, number]; + resizeEnable?: boolean; + } + interface MarkerOptions { + position?: LngLat | [number, number]; + icon?: string; + offset?: Pixel; + } + interface InfoWindowOptions { + isCustom?: boolean; + content?: string; + offset?: Pixel; + } + interface PolylineOptions { + path?: (LngLat | [number, number])[]; + strokeColor?: string; + strokeWeight?: number; + strokeStyle?: string; + } + interface MapsEvent { + target: Marker; + } + + // 全局暴露 + const Map: typeof Map; + const Marker: typeof Marker; + const InfoWindow: typeof InfoWindow; + const Polyline: typeof Polyline; + const LngLat: typeof LngLat; + const Pixel: typeof Pixel; + } + + // 全局变量 + const AMap: typeof AMap; +} + +export {}; \ No newline at end of file diff --git a/src/utils/request.ts b/src/utils/request.ts index e05b30c..fe8c2c8 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -58,5 +58,5 @@ request.interceptors.response.use( return Promise.reject(error); }) - // 对外暴露 +// 对外暴露 export default request; \ No newline at end of file diff --git a/src/views/ask/chatAi.vue b/src/views/ask/chatAi.vue index 74be02e..70235b6 100644 --- a/src/views/ask/chatAi.vue +++ b/src/views/ask/chatAi.vue @@ -120,6 +120,7 @@ import { ElMessage } from 'element-plus' import { reqAiChat } from '@/api/interface' import { useUserStore } from '@/stores/modules/user' import { type aiChatForm } from '@/api/interface/type' +import { useRouter } from 'vue-router' //侧边栏开合 @@ -148,63 +149,59 @@ const handleFullscreen = () => { const text = ref() const isShow = ref(false) const handleEnter = (event: KeyboardEvent) => { - // 如果按下Shift+Enter则插入换行 - if (event.shiftKey) { - return - } - // 否则阻止默认行为(不换行) + if (event.shiftKey) return event.preventDefault() + submitClick() // 回车触发提交 } /*对话框交互部分*/ // 获取用户状态 const userStore = useUserStore() -const userId = userStore.userId +const userId = userStore.userId.toString() +const sessionId = userStore.sessionId const backThing = ref() const userThing = ref({ question: text.value ?? '', - userId: userId ?? 1 // 默认用1或默认userId + userId: userId, // 默认用1或默认userId + sessionId: sessionId, + token: userStore.token }) -watch(userThing, async (newValue) => { - if (newValue && newValue.question.trim() && newValue.userId !== null) { - backThing.value = '思考中...' - try { - // 请求 - const res = await reqAiChat({ - question: newValue.question, - userId: newValue.userId - }) - - if (res.code === 200) { - backThing.value = res.data.Respond - } else { - ElMessage.error('请求失败,请稍后再试') - backThing.value = '请求失败,请稍后再试' - } - } catch (error) { - console.error('请求错误:', error) - ElMessage.error('请求错误,请稍后再试') - backThing.value = '请求错误,请稍后再试' - } - } -}) -const submitClick = (): void => { +const submitClick = async (): Promise => { const inputValue = text.value.trim() if (!inputValue) { ElMessage.warning('请输入内容') return } + + isShow.value = true - // 构造包含userId的请求数据 - userThing.value = { - question: inputValue, - userId: userId ?? 1 // 保证userId为number类型 + try { + backThing.value = '思考中...' + userThing.value.question = inputValue // 更新用户输入内容 + + const res = await reqAiChat({ + question: inputValue, + userId: userId, + sessionId: sessionId, + token: userStore.token + }) + + if (res.code === 200) { + backThing.value = res.data.Respond + } else { + ElMessage.error(res.msg || '请求失败,请稍后再试') + backThing.value = '请求失败,请稍后再试' + } + } catch (error) { + console.error('请求错误:', error) + ElMessage.error('请求错误,请稍后再试') + backThing.value = '请求错误,请稍后再试' + } finally { + text.value = '' } - text.value = '' - isShow.value = true } diff --git a/src/views/ask/musicAi.vue b/src/views/ask/musicAi.vue index f27d7e8..104f6d3 100644 --- a/src/views/ask/musicAi.vue +++ b/src/views/ask/musicAi.vue @@ -67,15 +67,48 @@

- - - -
- +
+ + +

发送了一条音频

+
+ user +
+
+ +
+ + AI + +

{{ backThing }}

+
+
+
+ + + +
+

录音时长: {{ duration }}秒

+

文件大小: {{ fileSize }}KB

+ +
+
+ + 暂无录音内容 +
+
+ +
+ + 点我录制 + + + 点我停止 + + + 点我重录 + +
@@ -93,10 +126,14 @@ diff --git a/src/views/ask/tableAi.vue b/src/views/ask/tableAi.vue index c09cef8..a84157b 100644 --- a/src/views/ask/tableAi.vue +++ b/src/views/ask/tableAi.vue @@ -68,9 +68,31 @@
- +
+ + +

{{ userThing.picture }}

+
+ user +
+
+ +
+ + AI + + + + + +
{ document.documentElement.requestFullscreen() } +/*对话框写入部分*/ const text = ref() +const isShow = ref(false) + const handleEnter = (event: KeyboardEvent) => { - // 如果按下Shift+Enter则插入换行 - if (event.shiftKey) { - return + if (!event.shiftKey) { + event.preventDefault() + submitClick() } - // 否则阻止默认行为(不换行) - event.preventDefault() } -const submitClick = () => { - -} +/*对话框交互部分*/ +// 获取用户状态 +const userStore = useUserStore() +const userId = userStore.userId.toString() + +const backThing = ref() +const userThing = ref({ + picture: text.value, + userId: userId , + sessionId: userStore.sessionId, + token: userStore.token +}) + +const submitClick = async () => { + const inputValue = text.value.trim() + if (!inputValue) { + ElMessage.warning('请输入图片描述') + return + } + + try { + isShow.value = true + userThing.value.picture = inputValue + backThing.value = '思考中...' + + // 使用store中的方法生成图片 + const imageData = await userStore.generateImage(inputValue) + backThing.value = imageData + + ElMessage.success('图片生成成功') + console.log('生成的图片:', imageData) // 打印生成的图片数据 + text.value = '' + } catch (error: any) { + console.error('图片生成失败:', error) + ElMessage.error(error.message || '图片生成失败') + backThing.value = '' + } finally { + } +} \ No newline at end of file diff --git a/src/views/login/index.vue b/src/views/login/index.vue index 6179cea..7cda6b6 100644 --- a/src/views/login/index.vue +++ b/src/views/login/index.vue @@ -1,160 +1,352 @@ + + - \ No newline at end of file + \ No newline at end of file diff --git a/src/views/myself/my.vue b/src/views/myself/my.vue index 4f3c656..1683456 100644 --- a/src/views/myself/my.vue +++ b/src/views/myself/my.vue @@ -1,8 +1,6 @@ - + @@ -112,13 +441,27 @@ const handleFullscreen = () => { min-height: 400px; } .el-menu-item-group__title { - height: 0; - width: 0; + height: 0; + width: 0; } .el-main { - margin-top: 0; - padding-top: 0.8%; - margin-left: 0; - padding-left: 0; + margin-top: 0; + padding-top: 0.8%; + margin-left: 0; + padding-left: 0; +} +.tag-display { + display: flex; + width: 80%; + height: 40%; + margin-top: 2%; + align-content: center; + justify-content: center; +} +.tag-text { + width: 100%; + text-align: center; + font-family: bigWord; + font-size: 6vh; } \ No newline at end of file diff --git a/src/views/myself/used.vue b/src/views/myself/used.vue index 475fd6b..ceb8088 100644 --- a/src/views/myself/used.vue +++ b/src/views/myself/used.vue @@ -1,115 +1,161 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/views/table/index.vue b/src/views/table/index.vue index c86dd43..ae91922 100644 --- a/src/views/table/index.vue +++ b/src/views/table/index.vue @@ -1,8 +1,6 @@ \ No newline at end of file From 80373d8188ccdbad9a80ca6a7d9d799dbbe4685e Mon Sep 17 00:00:00 2001 From: IHIRINA <2582067027@qq.com> Date: Wed, 2 Jul 2025 20:53:42 +0800 Subject: [PATCH 04/11] finish? --- components.d.ts | 1 + package-lock.json | 8 +- package.json | 2 +- src/components/LocationMap.vue | 182 ++++++++++++++++++++++++ src/utils/ws.ts | 144 +++++++++++++++++++ src/views/myself/my.vue | 251 ++------------------------------- 6 files changed, 347 insertions(+), 241 deletions(-) create mode 100644 src/components/LocationMap.vue create mode 100644 src/utils/ws.ts diff --git a/components.d.ts b/components.d.ts index 2bfc728..93b8b95 100644 --- a/components.d.ts +++ b/components.d.ts @@ -63,6 +63,7 @@ declare module 'vue' { IconEcosystem: typeof import('./src/components/icons/IconEcosystem.vue')['default'] IconSupport: typeof import('./src/components/icons/IconSupport.vue')['default'] IconTooling: typeof import('./src/components/icons/IconTooling.vue')['default'] + LocationMap: typeof import('./src/components/LocationMap.vue')['default'] Main: typeof import('./src/components/main.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] diff --git a/package-lock.json b/package-lock.json index f7dd675..16bbadd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "@tsconfig/node22": "^22.0.1", "@types/axios": "^0.9.36", "@types/echarts": "^4.9.22", - "@types/node": "^22.14.0", + "@types/node": "^22.15.34", "@types/recordrtc": "^5.6.14", "@vitejs/plugin-vue": "^5.2.3", "@vue/tsconfig": "^0.7.0", @@ -1500,9 +1500,9 @@ } }, "node_modules/@types/node": { - "version": "22.15.3", - "resolved": "https://registry.npmmirror.com/@types/node/-/node-22.15.3.tgz", - "integrity": "sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw==", + "version": "22.15.34", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-22.15.34.tgz", + "integrity": "sha512-8Y6E5WUupYy1Dd0II32BsWAx5MWdcnRd8L84Oys3veg1YrYtNtzgO4CFhiBg6MDSjk7Ay36HYOnU7/tuOzIzcw==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 46efefb..3ca1ab1 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "@tsconfig/node22": "^22.0.1", "@types/axios": "^0.9.36", "@types/echarts": "^4.9.22", - "@types/node": "^22.14.0", + "@types/node": "^22.15.34", "@types/recordrtc": "^5.6.14", "@vitejs/plugin-vue": "^5.2.3", "@vue/tsconfig": "^0.7.0", diff --git a/src/components/LocationMap.vue b/src/components/LocationMap.vue new file mode 100644 index 0000000..63de0ae --- /dev/null +++ b/src/components/LocationMap.vue @@ -0,0 +1,182 @@ + + + + + \ No newline at end of file diff --git a/src/utils/ws.ts b/src/utils/ws.ts new file mode 100644 index 0000000..88aa8ba --- /dev/null +++ b/src/utils/ws.ts @@ -0,0 +1,144 @@ +import { ref, onBeforeUnmount } from 'vue' +import { ElMessage } from 'element-plus' + +export interface WebSocketMessage { + userId: number + latitude: number + longitude: number + recordTime: string +} + +export interface WebSocketResponse { + trackId?: string + status?: string + recordTime?: string +} + +export class RealtimeLocationWS { + private ws: WebSocket | null = null + private sid: string + private userId: number + private wsUrl: string + private retryCount = 0 + private maxRetryCount = 3 + private retryTimer: number | null = null + private messageHandler: ((data: WebSocketResponse) => void) | null = null + + public connected = ref(false) + + constructor(userId: number, host: string, onMessage?: (data: WebSocketResponse) => void) { + this.userId = userId + this.sid = this.generateSessionId() + this.wsUrl = `ws://${host}/realtime/${this.sid}` + this.messageHandler = onMessage || null + this.connect() + } + + private generateSessionId(): string { + return 'sid-' + Math.random().toString(36).substr(2, 9) + Date.now().toString(36) + } + + public connect(): void { + if (this.connected.value) return + + try { + this.ws = new WebSocket(this.wsUrl) + + this.ws.onopen = () => { + this.connected.value = true + this.retryCount = 0 + console.log('WebSocket连接已建立') + } + + this.ws.onmessage = (event) => { + try { + const response: WebSocketResponse = JSON.parse(event.data) + console.log('收到服务端响应:', response) + this.messageHandler?.(response) + } catch (error) { + console.error('解析WebSocket消息失败:', error) + } + } + + this.ws.onerror = (error) => { + console.error('WebSocket错误:', error) + this.reconnect() + } + + this.ws.onclose = () => { + this.connected.value = false + console.log('WebSocket连接已关闭') + this.reconnect() + } + } catch (error) { + console.error('WebSocket初始化失败:', error) + this.reconnect() + } + } + + private reconnect(): void { + if (this.retryCount >= this.maxRetryCount) { + console.error(`已达到最大重试次数(${this.maxRetryCount}),停止重连`) + ElMessage.warning('位置服务连接失败,请刷新页面重试') + return + } + + this.retryCount++ + const delay = Math.min(1000 * 2 ** this.retryCount, 30000) // 指数退避,最大30秒 + + console.log(`将在${delay}ms后尝试第${this.retryCount}次重连...`) + this.retryTimer = window.setTimeout(() => { + this.connect() + }, delay) + } + + public sendLocation(position: [number, number]): boolean { + if (!this.ws || this.ws.readyState !== WebSocket.OPEN) { + console.warn('WebSocket未连接,无法发送位置数据') + return false + } + + const [longitude, latitude] = position + const message: WebSocketMessage = { + userId: this.userId, + latitude, + longitude, + recordTime: new Date().toISOString().split('.')[0] // ISO8601格式,去掉毫秒部分 + } + + try { + this.ws.send(JSON.stringify(message)) + console.log('已发送位置数据:', message) + return true + } catch (error) { + console.error('发送位置数据失败:', error) + return false + } + } + + public close(): void { + if (this.retryTimer) { + clearTimeout(this.retryTimer) + this.retryTimer = null + } + + if (this.ws) { + this.ws.close() + this.ws = null + } + + this.connected.value = false + } +} + +// 导出一个创建WebSocket实例的函数 +export function useRealtimeLocationWS(userId: number, host: string, onMessage?: (data: WebSocketResponse) => void) { + const wsInstance = new RealtimeLocationWS(userId, host, onMessage) + + // 自动在组件卸载时关闭连接 + onBeforeUnmount(() => { + wsInstance.close() + }) + + return wsInstance +} \ No newline at end of file diff --git a/src/views/myself/my.vue b/src/views/myself/my.vue index 1683456..438d9d7 100644 --- a/src/views/myself/my.vue +++ b/src/views/myself/my.vue @@ -85,7 +85,7 @@ 天气图片 - {{ userId }} + {{ id }} 学生 上班族 @@ -100,17 +100,11 @@
-->
-
-
-
- - 正在定位... -
-
- -
-
- +
@@ -126,6 +120,9 @@ import { ChatRound, Memo, UserFilled, FullScreen } from '@element-plus/icons-vue import { reqUserShow, reqUserUpdate } from '@/api/user/show' import type { UserUpdateForm} from '@/api/user/show/type' import { onBeforeMount } from 'vue' +import { useRealtimeLocationWS } from '@/utils/ws' +import LocationMap from '@/components/LocationMap.vue' + // 侧边栏状态 const isCollapse = ref(false) @@ -175,7 +172,6 @@ const allTagsVisible = computed(() => const username = ref('') const email = ref('') const userStore = useUserStore() -const userId = ref() const id = userStore.userId const weatherImage = ref('') @@ -206,233 +202,16 @@ const changeAdvater = async () => { fileInput.click() } -// 地图相关 -interface AMapComponents { - map: AMap.Map | null; - marker: AMap.Marker | null; - infoWindow: AMap.InfoWindow | null; - polyline: AMap.Polyline | null; -} -const mapContainer = ref(null) -const amapComponents = ref({ - map: null, - marker: null, - infoWindow: null, - polyline: null -}) - -const mapLoaded = ref(false) -const locationLoading = ref(false) -const userLocation = ref<[number, number] | null>(null) -const locationError = ref(null) - -// 加载地图脚本 -const loadAMapScript = async (): Promise => { - return new Promise((resolve, reject) => { - if (window.AMap) { - resolve() - return - } - - const script = document.createElement('script') - script.type = 'text/javascript' - script.src = 'https://webapi.amap.com/maps?v=2.0&key=5ee696eaddb2f84093a5721c8e505cf8' - script.async = true - script.defer = true - - script.onload = () => { - if (typeof AMap !== 'undefined' && AMap.Map) { - resolve() - } else { - reject(new Error('高德地图API加载失败')) - } - } - - script.onerror = (e) => { - reject(new Error('加载地图脚本失败: ' + (e as Event).type)) - } - - document.head.appendChild(script) - }) -} - -// 获取浏览器位置 -const getBrowserLocation = (): Promise<[number, number]> => { - return new Promise((resolve, reject) => { - if (!navigator.geolocation) { - reject(new Error('浏览器不支持地理定位')) - return - } - - locationLoading.value = true - locationError.value = null - - const success = (position: GeolocationPosition) => { - const { latitude, longitude } = position.coords - userLocation.value = [longitude, latitude] - resolve([longitude, latitude]) - } - - const error = (err: GeolocationPositionError) => { - let message = '' - switch (err.code) { - case err.PERMISSION_DENIED: - message = '用户拒绝了位置请求' - break - case err.POSITION_UNAVAILABLE: - message = '位置信息不可用' - break - case err.TIMEOUT: - message = '位置请求超时' - break - default: - message = '未知错误' - } - locationError.value = message - reject(new Error(message)) - } - - const options = { - enableHighAccuracy: true, - timeout: 10000, - maximumAge: 0 - } - - navigator.geolocation.getCurrentPosition(success, error, options) - }) +const handlePositionUpdate = (pos: { lng: number; lat: number }) => { + console.log('位置更新:', pos) } -// 初始化地图 -const initMap = async (): Promise => { - try { - // 确保AMap脚本加载 - await loadAMapScript(); - - // 等待DOM完全渲染 - await nextTick(); - - // 检查地图容器是否存在 - if (!mapContainer.value) { - throw new Error('地图容器元素不存在'); - } - - // 强制设置容器尺寸 - mapContainer.value.style.width = '100%'; - mapContainer.value.style.height = '100%'; - - console.log('修复后地图容器尺寸:', - mapContainer.value.offsetWidth, - mapContainer.value.offsetHeight - ); - - // 获取位置中心点 - let center: [number, number]; - try { - center = await getBrowserLocation(); - ElMessage.success('定位成功'); - } catch (err) { - console.warn('使用默认中心点:', err); - center = [116.397428, 39.90923]; // 天安门坐标 - ElMessage.warning('使用默认位置'); - } finally { - locationLoading.value = false; - } - - // 创建地图实例 - amapComponents.value.map = new AMap.Map(mapContainer.value, { - zoom: 15, - center: center, - resizeEnable: true - }); - - // 添加标记 - amapComponents.value.marker = new AMap.Marker({ - position: center, - }); - amapComponents.value.map.add(amapComponents.value.marker); - - // 强制重绘 - setTimeout(() => { - (amapComponents.value.map as any)?.setFitView(); - // 再次检查尺寸 - console.log('地图初始化后容器尺寸:', - mapContainer.value?.offsetWidth, - mapContainer.value?.offsetHeight - ); - }, 300); - - mapLoaded.value = true; - } catch (error: any) { - console.error('地图初始化失败:', error); - ElMessage.error(`地图加载失败: ${error.message}`); - locationError.value = error.message; - } -}; - -// 清理资源 -const cleanupMap = (): void => { - try { - if (amapComponents.value.map) { - amapComponents.value.map.destroy() - amapComponents.value = { - map: null, - marker: null, - infoWindow: null, - polyline: null - } - } - } catch (error) { - console.error('销毁地图失败:', error) +const handleWsMessage = (msg: any) => { + console.log('收到WS消息:', msg) + if (msg.status === 'success') { + ElMessage.success('位置上报成功') } } - -onMounted(async () => { - // 先加载用户信息 - async () => { - try { - const res = await reqUserShow(id.toString()) - if(res.code === 200) { - userId.value = id - username.value = res.data.username || '未设置用户名' - email.value = res.data.email || '未设置邮箱' - weatherImage.value = res.data.weatherImageUrl || '/defaultWeather.png' - imgUrl.value = res.data.imageUrl || '/5.png' - } else { - console.error('获取用户信息失败:', res.message) - } - }catch - (error) { - console.error('修改头像失败:', error) - }finally { - console.log('用户信息加载完成') - } - } - - // 等待DOM更新 - await nextTick(); - - // 确保容器可见 - if (mapContainer.value) { - mapContainer.value.style.display = 'block'; - mapContainer.value.style.visibility = 'visible'; - } - - // 初始化地图 - await initMap(); - console.log(AMap.Map.prototype) - - // 最终检查 - if (amapComponents.value.map) { - setTimeout(() => { - (amapComponents.value.map as any)?.setFitView(); - }, 500); - } -}) - -onBeforeUnmount(() => { - cleanupMap() -}) -