From 30a8e6f62e581aedae36b7c57058a8c106dfbc2e Mon Sep 17 00:00:00 2001 From: DuRuofu Date: Mon, 17 Feb 2025 17:02:38 +0800 Subject: [PATCH] =?UTF-8?q?update:=20=E6=B7=BB=E5=8A=A0Web=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1Vue3=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../restful_server_vue3/CMakeLists.txt | 5 + code/09.extra/restful_server_vue3/README.md | 141 + .../restful_server_vue3/dependencies.lock | 28 + .../front/vue3-demo/.gitignore | 30 + .../front/vue3-demo/README.md | 33 + .../front/vue3-demo/auto-imports.d.ts | 10 + .../front/vue3-demo/components.d.ts | 22 + .../front/vue3-demo/env.d.ts | 7 + .../front/vue3-demo/index.html | 13 + .../front/vue3-demo/package.json | 33 + .../front/vue3-demo/pnpm-lock.yaml | 2958 +++++++++++++++++ .../front/vue3-demo/public/favicon.ico | Bin 0 -> 4286 bytes .../front/vue3-demo/src/App.vue | 40 + .../front/vue3-demo/src/assets/base.css | 86 + .../front/vue3-demo/src/assets/logo.svg | 1 + .../front/vue3-demo/src/assets/main.css | 35 + .../vue3-demo/src/components/HelloWorld.vue | 41 + .../vue3-demo/src/components/TheWelcome.vue | 94 + .../vue3-demo/src/components/WelcomeItem.vue | 87 + .../src/components/icons/IconCommunity.vue | 7 + .../components/icons/IconDocumentation.vue | 7 + .../src/components/icons/IconEcosystem.vue | 7 + .../src/components/icons/IconSupport.vue | 7 + .../src/components/icons/IconTooling.vue | 19 + .../front/vue3-demo/src/main.ts | 12 + .../front/vue3-demo/src/router/index.ts | 23 + .../front/vue3-demo/src/views/AboutView.vue | 15 + .../front/vue3-demo/src/views/HomeView.vue | 9 + .../front/vue3-demo/tsconfig.app.json | 12 + .../front/vue3-demo/tsconfig.json | 11 + .../front/vue3-demo/tsconfig.node.json | 19 + .../front/vue3-demo/vite.config.ts | 38 + .../front/web-demo/.browserslistrc | 3 + .../front/web-demo/.editorconfig | 5 + .../front/web-demo/.eslintrc.js | 17 + .../front/web-demo/.gitignore | 26 + .../front/web-demo/babel.config.js | 5 + .../front/web-demo/package.json | 32 + .../front/web-demo/postcss.config.js | 5 + .../front/web-demo/public/favicon.ico | Bin 0 -> 6429 bytes .../front/web-demo/public/index.html | 19 + .../front/web-demo/src/App.vue | 55 + .../front/web-demo/src/assets/logo.png | Bin 0 -> 37327 bytes .../front/web-demo/src/main.js | 16 + .../front/web-demo/src/plugins/vuetify.js | 7 + .../front/web-demo/src/router.js | 29 + .../front/web-demo/src/store.js | 28 + .../front/web-demo/src/views/Chart.vue | 41 + .../front/web-demo/src/views/Home.vue | 40 + .../front/web-demo/src/views/Light.vue | 62 + .../front/web-demo/vue.config.js | 11 + .../restful_server_vue3/main/CMakeLists.txt | 12 + .../main/Kconfig.projbuild | 51 + .../restful_server_vue3/main/esp_rest_main.c | 138 + .../main/idf_component.yml | 8 + .../restful_server_vue3/main/rest_server.c | 226 ++ .../partitions_example.csv | 6 + .../restful_server_vue3/sdkconfig.defaults | 7 + .../sdkconfig.defaults.esp32p4 | 2 + 59 files changed, 4701 insertions(+) create mode 100644 code/09.extra/restful_server_vue3/CMakeLists.txt create mode 100644 code/09.extra/restful_server_vue3/README.md create mode 100644 code/09.extra/restful_server_vue3/dependencies.lock create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/.gitignore create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/README.md create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/auto-imports.d.ts create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/components.d.ts create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/env.d.ts create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/index.html create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/package.json create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/pnpm-lock.yaml create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/public/favicon.ico create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/src/App.vue create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/src/assets/base.css create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/src/assets/logo.svg create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/src/assets/main.css create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/src/components/HelloWorld.vue create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/src/components/TheWelcome.vue create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/src/components/WelcomeItem.vue create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/src/components/icons/IconCommunity.vue create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/src/components/icons/IconDocumentation.vue create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/src/components/icons/IconEcosystem.vue create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/src/components/icons/IconSupport.vue create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/src/components/icons/IconTooling.vue create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/src/main.ts create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/src/router/index.ts create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/src/views/AboutView.vue create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/src/views/HomeView.vue create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/tsconfig.app.json create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/tsconfig.json create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/tsconfig.node.json create mode 100644 code/09.extra/restful_server_vue3/front/vue3-demo/vite.config.ts create mode 100644 code/09.extra/restful_server_vue3/front/web-demo/.browserslistrc create mode 100644 code/09.extra/restful_server_vue3/front/web-demo/.editorconfig create mode 100644 code/09.extra/restful_server_vue3/front/web-demo/.eslintrc.js create mode 100644 code/09.extra/restful_server_vue3/front/web-demo/.gitignore create mode 100644 code/09.extra/restful_server_vue3/front/web-demo/babel.config.js create mode 100644 code/09.extra/restful_server_vue3/front/web-demo/package.json create mode 100644 code/09.extra/restful_server_vue3/front/web-demo/postcss.config.js create mode 100644 code/09.extra/restful_server_vue3/front/web-demo/public/favicon.ico create mode 100644 code/09.extra/restful_server_vue3/front/web-demo/public/index.html create mode 100644 code/09.extra/restful_server_vue3/front/web-demo/src/App.vue create mode 100644 code/09.extra/restful_server_vue3/front/web-demo/src/assets/logo.png create mode 100644 code/09.extra/restful_server_vue3/front/web-demo/src/main.js create mode 100644 code/09.extra/restful_server_vue3/front/web-demo/src/plugins/vuetify.js create mode 100644 code/09.extra/restful_server_vue3/front/web-demo/src/router.js create mode 100644 code/09.extra/restful_server_vue3/front/web-demo/src/store.js create mode 100644 code/09.extra/restful_server_vue3/front/web-demo/src/views/Chart.vue create mode 100644 code/09.extra/restful_server_vue3/front/web-demo/src/views/Home.vue create mode 100644 code/09.extra/restful_server_vue3/front/web-demo/src/views/Light.vue create mode 100644 code/09.extra/restful_server_vue3/front/web-demo/vue.config.js create mode 100644 code/09.extra/restful_server_vue3/main/CMakeLists.txt create mode 100644 code/09.extra/restful_server_vue3/main/Kconfig.projbuild create mode 100644 code/09.extra/restful_server_vue3/main/esp_rest_main.c create mode 100644 code/09.extra/restful_server_vue3/main/idf_component.yml create mode 100644 code/09.extra/restful_server_vue3/main/rest_server.c create mode 100644 code/09.extra/restful_server_vue3/partitions_example.csv create mode 100644 code/09.extra/restful_server_vue3/sdkconfig.defaults create mode 100644 code/09.extra/restful_server_vue3/sdkconfig.defaults.esp32p4 diff --git a/code/09.extra/restful_server_vue3/CMakeLists.txt b/code/09.extra/restful_server_vue3/CMakeLists.txt new file mode 100644 index 0000000..244f174 --- /dev/null +++ b/code/09.extra/restful_server_vue3/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.16) + + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(restful_server) diff --git a/code/09.extra/restful_server_vue3/README.md b/code/09.extra/restful_server_vue3/README.md new file mode 100644 index 0000000..1cfe472 --- /dev/null +++ b/code/09.extra/restful_server_vue3/README.md @@ -0,0 +1,141 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | + +# HTTP Restful API Server Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +## Overview + +This example mainly introduces how to implement a RESTful API server and HTTP server on ESP32, with a frontend browser UI. + +This example designs several APIs to fetch resources as follows: + +| API | Method | Resource Example | Description | Page URL | +| -------------------------- | ------ | ----------------------------------------------------- | ---------------------------------------------------------------------------------------- | -------- | +| `/api/v1/system/info` | `GET` | {
version:"v4.0-dev",
cores:2
} | Used for clients to get system information like IDF version, ESP32 cores, etc | `/` | +| `/api/v1/temp/raw` | `GET` | {
raw:22
} | Used for clients to get raw temperature data read from sensor | `/chart` | +| `/api/v1/light/brightness` | `POST` | {
red:160,
green:160,
blue:160
} | Used for clients to upload control values to ESP32 in order to control LED’s brightness | `/light` | + +**Page URL** is the URL of the webpage which will send a request to the API. + +### About mDNS + +The IP address of an IoT device may vary from time to time, so it’s impracticable to hard code the IP address in the webpage. In this example, we use the `mDNS` to parse the domain name `esp-home.local`, so that we can alway get access to the web server by this URL no matter what the real IP address behind it. See [here](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/protocols/mdns.html) for more information about mDNS. + +**Notes: mDNS is installed by default on most operating systems or is available as separate package.** + +### About deploy mode + +In development mode, it would be awful to flash the whole webpages every time we update the html, js or css files. So it is highly recommended to deploy the webpage to host PC via `semihost` technology. Whenever the browser fetch the webpage, ESP32 can forward the required files located on host PC. By this mean, it will save a lot of time when designing new pages. + +After developing, the pages should be deployed to one of the following destinations: + +* SPI Flash - which is recommended when the website after built is small (e.g. less than 2MB). +* SD Card - which would be an option when the website after built is very large that the SPI Flash have not enough space to hold (e.g. larger than 2MB). + +### About frontend framework + +Many famous frontend frameworks (e.g. Vue, React, Angular) can be used in this example. Here we just take [Vue](https://vuejs.org/) as example and adopt the [vuetify](https://vuetifyjs.com/) as the UI library. + +## How to use example + +### Hardware Required + +To run this example, you need an ESP32 dev board (e.g. ESP32-WROVER Kit, ESP32-Ethernet-Kit) or ESP32 core board (e.g. ESP32-DevKitC). An extra JTAG adapter might also needed if you choose to deploy the website by semihosting. For more information about supported JTAG adapter, please refer to [select JTAG adapter](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/jtag-debugging/index.html#jtag-debugging-selecting-jtag-adapter). Or if you choose to deploy the website to SD card, an extra SD slot board is needed. + +#### Pin Assignment: + +Only if you deploy the website to SD card, then the following pin connection is used in this example. + +| ESP32 | SD Card | +| ------ | ------- | +| GPIO2 | D0 | +| GPIO4 | D1 | +| GPIO12 | D2 | +| GPIO13 | D3 | +| GPIO14 | CLK | +| GPIO15 | CMD | + + +### Configure the project + +Open the project configuration menu (`idf.py menuconfig`). + +In the `Example Connection Configuration` menu: + +* Choose the network interface in `Connect using` option based on your board. Currently we support both Wi-Fi and Ethernet. +* If you select the Wi-Fi interface, you also have to set: + * Wi-Fi SSID and Wi-Fi password that your esp32 will connect to. +* If you select the Ethernet interface, you also have to set: + * PHY model in `Ethernet PHY` option, e.g. IP101. + * PHY address in `PHY Address` option, which should be determined by your board schematic. + * EMAC Clock mode, GPIO used by SMI. + +In the `Example Configuration` menu: + +* Set the domain name in `mDNS Host Name` option. +* Choose the deploy mode in `Website deploy mode`, currently we support deploy website to host PC, SD card and SPI Nor flash. + * If we choose to `Deploy website to host (JTAG is needed)`, then we also need to specify the full path of the website in `Host path to mount (e.g. absolute path to web dist directory)`. +* Set the mount point of the website in `Website mount point in VFS` option, the default value is `/www`. + +### Build and Flash + +After the webpage design work has been finished, you should compile them by running following commands: + +```bash +cd path_to_this_example/front/web-demo +npm install +npm run build +``` +> **_NOTE:_** This example needs `nodejs` version `v10.19.0` + +After a while, you will see a `dist` directory which contains all the website files (e.g. html, js, css, images). + +Run `idf.py -p PORT flash monitor` to build and flash the project.. + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. + +### Extra steps to do for deploying website by semihost + +We need to run the latest version of OpenOCD which should support semihost feature when we test this deploy mode: + +```bash +openocd-esp32/bin/openocd -s openocd-esp32/share/openocd/scripts -f board/esp32-wrover-kit-3.3v.cfg +``` + +## Example Output + +### Render webpage in browser + +In your browser, enter the URL where the website located (e.g. `http://esp-home.local`). You can also enter the IP address that ESP32 obtained if your operating system currently don't have support for mDNS service. + +Besides that, this example also enables the NetBIOS feature with the domain name `esp-home`. If your OS supports NetBIOS and has enabled it (e.g. Windows has native support for NetBIOS), then the URL `http://esp-home` should also work. + +![esp_home_local](https://dl.espressif.com/dl/esp-idf/docs/_static/esp_home_local.gif) + +### ESP monitor output + +In the *Light* page, after we set up the light color and click on the check button, the browser will send a post request to ESP32, and in the console, we just print the color value. + +```bash +I (6115) example_connect: Connected to Ethernet +I (6115) example_connect: IPv4 address: 192.168.2.151 +I (6325) esp-home: Partition size: total: 1920401, used: 1587575 +I (6325) esp-rest: Starting HTTP Server +I (128305) esp-rest: File sending complete +I (128565) esp-rest: File sending complete +I (128855) esp-rest: File sending complete +I (129525) esp-rest: File sending complete +I (129855) esp-rest: File sending complete +I (137485) esp-rest: Light control: red = 50, green = 85, blue = 28 +``` + +## Troubleshooting + +1. Error occurred when building example: `...front/web-demo/dist doesn't exit. Please run 'npm run build' in ...front/web-demo`. + * When you choose to deploy website to SPI flash, make sure the `dist` directory has been generated before you building this example. + +(For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you as soon as possible.) diff --git a/code/09.extra/restful_server_vue3/dependencies.lock b/code/09.extra/restful_server_vue3/dependencies.lock new file mode 100644 index 0000000..28527ca --- /dev/null +++ b/code/09.extra/restful_server_vue3/dependencies.lock @@ -0,0 +1,28 @@ +dependencies: + espressif/mdns: + component_hash: 26d0b8b207c7d8382cb3c103a9add9c75ca4dc0ef172b03a98af2c2254b2792b + dependencies: + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.6.0 + idf: + source: + type: idf + version: 5.3.2 + protocol_examples_common: + dependencies: [] + source: + path: /home/duruofu/esp/esp-idf-v5.3.2/examples/common_components/protocol_examples_common + type: local + version: '*' +direct_dependencies: +- espressif/mdns +- idf +- protocol_examples_common +manifest_hash: 0b40f4dd4eebae44dde3077bcc2620c3baef19ebafa1af344ab3e749f1e64412 +target: esp32s3 +version: 2.0.0 diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/.gitignore b/code/09.extra/restful_server_vue3/front/vue3-demo/.gitignore new file mode 100644 index 0000000..8ee54e8 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/.gitignore @@ -0,0 +1,30 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +.DS_Store +dist +dist-ssr +coverage +*.local + +/cypress/videos/ +/cypress/screenshots/ + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +*.tsbuildinfo diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/README.md b/code/09.extra/restful_server_vue3/front/vue3-demo/README.md new file mode 100644 index 0000000..5a6d9f1 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/README.md @@ -0,0 +1,33 @@ +# vue3-demo + +This template should help get you started developing with Vue 3 in Vite. + +## Recommended IDE Setup + +[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur). + +## Type Support for `.vue` Imports in TS + +TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types. + +## Customize configuration + +See [Vite Configuration Reference](https://vite.dev/config/). + +## Project Setup + +```sh +pnpm install +``` + +### Compile and Hot-Reload for Development + +```sh +pnpm dev +``` + +### Type-Check, Compile and Minify for Production + +```sh +pnpm build +``` diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/auto-imports.d.ts b/code/09.extra/restful_server_vue3/front/vue3-demo/auto-imports.d.ts new file mode 100644 index 0000000..9d24007 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/auto-imports.d.ts @@ -0,0 +1,10 @@ +/* eslint-disable */ +/* prettier-ignore */ +// @ts-nocheck +// noinspection JSUnusedGlobalSymbols +// Generated by unplugin-auto-import +// biome-ignore lint: disable +export {} +declare global { + +} diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/components.d.ts b/code/09.extra/restful_server_vue3/front/vue3-demo/components.d.ts new file mode 100644 index 0000000..ff5e7a8 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/components.d.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +// @ts-nocheck +// Generated by unplugin-vue-components +// Read more: https://github.com/vuejs/core/pull/3399 +export {} + +/* prettier-ignore */ +declare module 'vue' { + export interface GlobalComponents { + ElButton: typeof import('element-plus/es')['ElButton'] + 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'] + RouterLink: typeof import('vue-router')['RouterLink'] + RouterView: typeof import('vue-router')['RouterView'] + TheWelcome: typeof import('./src/components/TheWelcome.vue')['default'] + WelcomeItem: typeof import('./src/components/WelcomeItem.vue')['default'] + } +} diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/env.d.ts b/code/09.extra/restful_server_vue3/front/vue3-demo/env.d.ts new file mode 100644 index 0000000..941ce20 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/env.d.ts @@ -0,0 +1,7 @@ +/// +declare module '*.vue' { + import type { DefineComponent } from 'vue' + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types + const component: DefineComponent<{}, {}, any> + export default component +} diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/index.html b/code/09.extra/restful_server_vue3/front/vue3-demo/index.html new file mode 100644 index 0000000..9e5fc8f --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite App + + +
+ + + diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/package.json b/code/09.extra/restful_server_vue3/front/vue3-demo/package.json new file mode 100644 index 0000000..17927fa --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/package.json @@ -0,0 +1,33 @@ +{ + "name": "vue3-demo", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "run-p type-check \"build-only {@}\" --", + "preview": "vite preview", + "build-only": "vite build", + "type-check": "vue-tsc --build" + }, + "dependencies": { + "axios": "^1.7.9", + "element-plus": "^2.9.4", + "vue": "^3.5.13", + "vue-router": "^4.5.0" + }, + "devDependencies": { + "@tsconfig/node22": "^22.0.0", + "@types/node": "^22.13.1", + "@vitejs/plugin-vue": "^5.2.1", + "@vue/tsconfig": "^0.7.0", + "npm-run-all2": "^7.0.2", + "sass": "^1.85.0", + "typescript": "~5.7.3", + "unplugin-auto-import": "^19.1.0", + "unplugin-vue-components": "^28.1.0", + "vite": "^6.0.11", + "vite-plugin-vue-devtools": "^7.7.1", + "vue-tsc": "^2.2.0" + } +} diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/pnpm-lock.yaml b/code/09.extra/restful_server_vue3/front/vue3-demo/pnpm-lock.yaml new file mode 100644 index 0000000..a4f5461 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/pnpm-lock.yaml @@ -0,0 +1,2958 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + axios: + specifier: ^1.7.9 + version: 1.7.9 + element-plus: + specifier: ^2.9.4 + version: 2.9.4(vue@3.5.13(typescript@5.7.3)) + vue: + specifier: ^3.5.13 + version: 3.5.13(typescript@5.7.3) + vue-router: + specifier: ^4.5.0 + version: 4.5.0(vue@3.5.13(typescript@5.7.3)) + devDependencies: + '@tsconfig/node22': + specifier: ^22.0.0 + version: 22.0.0 + '@types/node': + specifier: ^22.13.1 + version: 22.13.4 + '@vitejs/plugin-vue': + specifier: ^5.2.1 + version: 5.2.1(vite@6.1.0(@types/node@22.13.4)(sass@1.85.0))(vue@3.5.13(typescript@5.7.3)) + '@vue/tsconfig': + specifier: ^0.7.0 + version: 0.7.0(typescript@5.7.3)(vue@3.5.13(typescript@5.7.3)) + npm-run-all2: + specifier: ^7.0.2 + version: 7.0.2 + sass: + specifier: ^1.85.0 + version: 1.85.0 + typescript: + specifier: ~5.7.3 + version: 5.7.3 + unplugin-auto-import: + specifier: ^19.1.0 + version: 19.1.0(@vueuse/core@9.13.0(vue@3.5.13(typescript@5.7.3))) + unplugin-vue-components: + specifier: ^28.1.0 + version: 28.1.0(@babel/parser@7.26.9)(vue@3.5.13(typescript@5.7.3)) + vite: + specifier: ^6.0.11 + version: 6.1.0(@types/node@22.13.4)(sass@1.85.0) + vite-plugin-vue-devtools: + specifier: ^7.7.1 + version: 7.7.2(rollup@4.34.8)(vite@6.1.0(@types/node@22.13.4)(sass@1.85.0))(vue@3.5.13(typescript@5.7.3)) + vue-tsc: + specifier: ^2.2.0 + version: 2.2.2(typescript@5.7.3) + +packages: + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@antfu/utils@0.7.10': + resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==} + + '@babel/code-frame@7.26.2': + resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.26.8': + resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.26.9': + resolution: {integrity: sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.26.9': + resolution: {integrity: sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.25.9': + resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.26.5': + resolution: {integrity: sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.26.9': + resolution: {integrity: sha512-ubbUqCofvxPRurw5L8WTsCLSkQiVpov4Qx0WMA+jUN+nXBK8ADPlJO1grkFw5CWKC5+sZSOfuGMdX1aI1iT9Sg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-member-expression-to-functions@7.25.9': + resolution: {integrity: sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.25.9': + resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.26.0': + resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.25.9': + resolution: {integrity: sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.26.5': + resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-replace-supers@7.26.5': + resolution: {integrity: sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.25.9': + resolution: {integrity: sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.25.9': + resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.26.9': + resolution: {integrity: sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.26.9': + resolution: {integrity: sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-proposal-decorators@7.25.9': + resolution: {integrity: sha512-smkNLL/O1ezy9Nhy4CNosc4Va+1wo5w4gzSZeLe6y6dM4mmHfYOCPolXQPHQxonZCF+ZyebxN9vqOolkYrSn5g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-decorators@7.25.9': + resolution: {integrity: sha512-ryzI0McXUPJnRCvMo4lumIKZUzhYUO/ScI+Mz4YVaTLt04DHNSjEUjKVvbzQjZFLuod/cYEc07mJWhzl6v4DPg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.26.0': + resolution: {integrity: sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.25.9': + resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.25.9': + resolution: {integrity: sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.26.8': + resolution: {integrity: sha512-bME5J9AC8ChwA7aEPJ6zym3w7aObZULHhbNLU0bKUhKsAkylkzUdq+0kdymh9rzi8nlNFl2bmldFBCKNJBUpuw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/template@7.26.9': + resolution: {integrity: sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.26.9': + resolution: {integrity: sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.26.9': + resolution: {integrity: sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==} + engines: {node: '>=6.9.0'} + + '@ctrl/tinycolor@3.6.1': + resolution: {integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==} + engines: {node: '>=10'} + + '@element-plus/icons-vue@2.3.1': + resolution: {integrity: sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg==} + peerDependencies: + vue: ^3.2.0 + + '@esbuild/aix-ppc64@0.24.2': + resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.24.2': + resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.24.2': + resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.24.2': + resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.24.2': + resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.24.2': + resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.24.2': + resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.24.2': + resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.24.2': + resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.24.2': + resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.24.2': + resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.24.2': + resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.24.2': + resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.24.2': + resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.24.2': + resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.24.2': + resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.24.2': + resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.24.2': + resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.24.2': + resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.24.2': + resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.24.2': + resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.24.2': + resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.24.2': + resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.24.2': + resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.24.2': + resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@floating-ui/core@1.6.9': + resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==} + + '@floating-ui/dom@1.6.13': + resolution: {integrity: sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==} + + '@floating-ui/utils@0.2.9': + resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} + + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@parcel/watcher-android-arm64@2.5.1': + resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-darwin-arm64@2.5.1': + resolution: {integrity: sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.5.1': + resolution: {integrity: sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-freebsd-x64@2.5.1': + resolution: {integrity: sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-linux-arm-glibc@2.5.1': + resolution: {integrity: sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm-musl@2.5.1': + resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm64-glibc@2.5.1': + resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-arm64-musl@2.5.1': + resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-x64-glibc@2.5.1': + resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-linux-x64-musl@2.5.1': + resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-win32-arm64@2.5.1': + resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-ia32@2.5.1': + resolution: {integrity: sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + + '@parcel/watcher-win32-x64@2.5.1': + resolution: {integrity: sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher@2.5.1': + resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} + engines: {node: '>= 10.0.0'} + + '@polka/url@1.0.0-next.28': + resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} + + '@rollup/pluginutils@5.1.4': + resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.34.8': + resolution: {integrity: sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.34.8': + resolution: {integrity: sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.34.8': + resolution: {integrity: sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.34.8': + resolution: {integrity: sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.34.8': + resolution: {integrity: sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.34.8': + resolution: {integrity: sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.34.8': + resolution: {integrity: sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.34.8': + resolution: {integrity: sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.34.8': + resolution: {integrity: sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.34.8': + resolution: {integrity: sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loongarch64-gnu@4.34.8': + resolution: {integrity: sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.34.8': + resolution: {integrity: sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.34.8': + resolution: {integrity: sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.34.8': + resolution: {integrity: sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.34.8': + resolution: {integrity: sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.34.8': + resolution: {integrity: sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.34.8': + resolution: {integrity: sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.34.8': + resolution: {integrity: sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.34.8': + resolution: {integrity: sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==} + cpu: [x64] + os: [win32] + + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + + '@sxzz/popperjs-es@2.11.7': + resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==} + + '@tsconfig/node22@22.0.0': + resolution: {integrity: sha512-twLQ77zevtxobBOD4ToAtVmuYrpeYUh3qh+TEp+08IWhpsrIflVHqQ1F1CiPxQGL7doCdBIOOCF+1Tm833faNg==} + + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + '@types/lodash-es@4.17.12': + resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + + '@types/lodash@4.17.15': + resolution: {integrity: sha512-w/P33JFeySuhN6JLkysYUK2gEmy9kHHFN7E8ro0tkfmlDOgxBDzWEZ/J8cWA+fHqFevpswDTFZnDx+R9lbL6xw==} + + '@types/node@22.13.4': + resolution: {integrity: sha512-ywP2X0DYtX3y08eFVx5fNIw7/uIv8hYUKgXoK8oayJlLnKcRfEYCxWMVE1XagUdVtCJlZT1AU4LXEABW+L1Peg==} + + '@types/web-bluetooth@0.0.16': + resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} + + '@vitejs/plugin-vue@5.2.1': + resolution: {integrity: sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 + vue: ^3.2.25 + + '@volar/language-core@2.4.11': + resolution: {integrity: sha512-lN2C1+ByfW9/JRPpqScuZt/4OrUUse57GLI6TbLgTIqBVemdl1wNcZ1qYGEo2+Gw8coYLgCy7SuKqn6IrQcQgg==} + + '@volar/source-map@2.4.11': + resolution: {integrity: sha512-ZQpmafIGvaZMn/8iuvCFGrW3smeqkq/IIh9F1SdSx9aUl0J4Iurzd6/FhmjNO5g2ejF3rT45dKskgXWiofqlZQ==} + + '@volar/typescript@2.4.11': + resolution: {integrity: sha512-2DT+Tdh88Spp5PyPbqhyoYavYCPDsqbHLFwcUI9K1NlY1YgUJvujGdrqUp0zWxnW7KWNTr3xSpMuv2WnaTKDAw==} + + '@vue/babel-helper-vue-transform-on@1.2.5': + resolution: {integrity: sha512-lOz4t39ZdmU4DJAa2hwPYmKc8EsuGa2U0L9KaZaOJUt0UwQNjNA3AZTq6uEivhOKhhG1Wvy96SvYBoFmCg3uuw==} + + '@vue/babel-plugin-jsx@1.2.5': + resolution: {integrity: sha512-zTrNmOd4939H9KsRIGmmzn3q2zvv1mjxkYZHgqHZgDrXz5B1Q3WyGEjO2f+JrmKghvl1JIRcvo63LgM1kH5zFg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true + + '@vue/babel-plugin-resolve-type@1.2.5': + resolution: {integrity: sha512-U/ibkQrf5sx0XXRnUZD1mo5F7PkpKyTbfXM3a3rC4YnUz6crHEz9Jg09jzzL6QYlXNto/9CePdOg/c87O4Nlfg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@vue/compiler-core@3.5.13': + resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} + + '@vue/compiler-dom@3.5.13': + resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} + + '@vue/compiler-sfc@3.5.13': + resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} + + '@vue/compiler-ssr@3.5.13': + resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} + + '@vue/compiler-vue2@2.7.16': + resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} + + '@vue/devtools-api@6.6.4': + resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} + + '@vue/devtools-core@7.7.2': + resolution: {integrity: sha512-lexREWj1lKi91Tblr38ntSsy6CvI8ba7u+jmwh2yruib/ltLUcsIzEjCnrkh1yYGGIKXbAuYV2tOG10fGDB9OQ==} + peerDependencies: + vue: ^3.0.0 + + '@vue/devtools-kit@7.7.2': + resolution: {integrity: sha512-CY0I1JH3Z8PECbn6k3TqM1Bk9ASWxeMtTCvZr7vb+CHi+X/QwQm5F1/fPagraamKMAHVfuuCbdcnNg1A4CYVWQ==} + + '@vue/devtools-shared@7.7.2': + resolution: {integrity: sha512-uBFxnp8gwW2vD6FrJB8JZLUzVb6PNRG0B0jBnHsOH8uKyva2qINY8PTF5Te4QlTbMDqU5K6qtJDr6cNsKWhbOA==} + + '@vue/language-core@2.2.2': + resolution: {integrity: sha512-QotO41kurE5PLf3vrNgGTk3QswO2PdUFjBwNiOi7zMmGhwb25PSTh9hD1MCgKC06AVv+8sZQvlL3Do4TTVHSiQ==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@vue/reactivity@3.5.13': + resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==} + + '@vue/runtime-core@3.5.13': + resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==} + + '@vue/runtime-dom@3.5.13': + resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==} + + '@vue/server-renderer@3.5.13': + resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==} + peerDependencies: + vue: 3.5.13 + + '@vue/shared@3.5.13': + resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} + + '@vue/tsconfig@0.7.0': + resolution: {integrity: sha512-ku2uNz5MaZ9IerPPUyOHzyjhXoX2kVJaVf7hL315DC17vS6IiZRmmCPfggNbU16QTvM80+uYYy3eYJB59WCtvg==} + peerDependencies: + typescript: 5.x + vue: ^3.4.0 + peerDependenciesMeta: + typescript: + optional: true + vue: + optional: true + + '@vueuse/core@9.13.0': + resolution: {integrity: sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==} + + '@vueuse/metadata@9.13.0': + resolution: {integrity: sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==} + + '@vueuse/shared@9.13.0': + resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==} + + acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + engines: {node: '>=0.4.0'} + hasBin: true + + alien-signals@1.0.3: + resolution: {integrity: sha512-zQOh3wAYK5ujENxvBBR3CFGF/b6afaSzZ/c9yNhJ1ENrGHETvpUuKQsa93Qrclp0+PzTF93MaZ7scVp1uUozhA==} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + async-validator@4.2.5: + resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios@1.7.9: + resolution: {integrity: sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + birpc@0.2.19: + resolution: {integrity: sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.24.4: + resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + caniuse-lite@1.0.30001700: + resolution: {integrity: sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ==} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + copy-anything@3.0.5: + resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} + engines: {node: '>=12.13'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + + de-indent@1.0.2: + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} + + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + default-browser-id@5.0.0: + resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} + engines: {node: '>=18'} + + default-browser@5.2.1: + resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==} + engines: {node: '>=18'} + + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + detect-libc@1.0.3: + resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} + engines: {node: '>=0.10'} + hasBin: true + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + electron-to-chromium@1.5.101: + resolution: {integrity: sha512-L0ISiQrP/56Acgu4/i/kfPwWSgrzYZUnQrC0+QPFuhqlLP1Ir7qzPPDVS9BcKIyWTRU8+o6CC8dKw38tSWhYIA==} + + element-plus@2.9.4: + resolution: {integrity: sha512-sGnW0wd9zf6lEGixXV2gfwx3X6VTMkP52qTkX7zbURJ2oariyslrKTBh2txt1sdn1pUvj2l0KY3OfSXoZGmDOw==} + peerDependencies: + vue: ^3.2.0 + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + error-stack-parser-es@0.1.5: + resolution: {integrity: sha512-xHku1X40RO+fO8yJ8Wh2f2rZWVjqyhb1zgq1yZ8aZRQkv6OOKhKWRUaht3eSCUbAOBaKIgM+ykwFLE+QUxgGeg==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + esbuild@0.24.2: + resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + execa@9.5.2: + resolution: {integrity: sha512-EHlpxMCpHWSAh1dgS6bVeoLAXGnJNdR93aabr4QCGbzOM73o5XmRfM/e5FUqsw3aagP8S8XEWUWFAxnRBnAF0Q==} + engines: {node: ^18.19.0 || >=20.5.0} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fastq@1.19.0: + resolution: {integrity: sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==} + + fdir@6.4.3: + resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.2: + resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==} + engines: {node: '>= 6'} + + fs-extra@11.3.0: + resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==} + engines: {node: '>=14.14'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-intrinsic@1.2.7: + resolution: {integrity: sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + + html-tags@3.3.1: + resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} + engines: {node: '>=8'} + + human-signals@8.0.0: + resolution: {integrity: sha512-/1/GPCpDUCCYwlERiYjxoczfP0zfvZMU/OWgQPMya9AbAE24vseigFdhAMObpc8Q4lc/kjutPfUddDYyAmejnA==} + engines: {node: '>=18.18.0'} + + immutable@5.0.3: + resolution: {integrity: sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + + is-what@4.1.16: + resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} + engines: {node: '>=12.13'} + + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isexe@3.1.1: + resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} + engines: {node: '>=16'} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-parse-even-better-errors@4.0.0: + resolution: {integrity: sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==} + engines: {node: ^18.17.0 || >=20.5.0} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + + local-pkg@1.0.0: + resolution: {integrity: sha512-bbgPw/wmroJsil/GgL4qjDzs5YLTBMQ99weRsok1XCDccQeehbHA/I1oRvk2NPtr7KGZgT/Y5tPRnAtMqeG2Kg==} + engines: {node: '>=14'} + + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + + lodash-unified@1.0.3: + resolution: {integrity: sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==} + peerDependencies: + '@types/lodash-es': '*' + lodash: '*' + lodash-es: '*' + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + memoize-one@6.0.0: + resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==} + + memorystream@0.3.1: + resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} + engines: {node: '>= 0.10.0'} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + + mlly@1.7.4: + resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} + + mrmime@2.0.0: + resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} + engines: {node: '>=10'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + + nanoid@3.3.8: + resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@5.1.0: + resolution: {integrity: sha512-zDAl/llz8Ue/EblwSYwdxGBYfj46IM1dhjVi8dyp9LQffoIGxJEAHj2oeZ4uNcgycSRcQ83CnfcZqEJzVDLcDw==} + engines: {node: ^18 || >=20} + hasBin: true + + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + + node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-wheel-es@1.2.0: + resolution: {integrity: sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==} + + npm-normalize-package-bin@4.0.0: + resolution: {integrity: sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==} + engines: {node: ^18.17.0 || >=20.5.0} + + npm-run-all2@7.0.2: + resolution: {integrity: sha512-7tXR+r9hzRNOPNTvXegM+QzCuMjzUIIq66VDunL6j60O4RrExx32XUhlrS7UK4VcdGw5/Wxzb3kfNcFix9JKDA==} + engines: {node: ^18.17.0 || >=20.5.0, npm: '>= 9'} + hasBin: true + + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} + engines: {node: '>=18'} + + open@10.1.0: + resolution: {integrity: sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==} + engines: {node: '>=18'} + + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + pidtree@0.6.0: + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} + engines: {node: '>=0.10'} + hasBin: true + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + postcss@8.5.2: + resolution: {integrity: sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==} + engines: {node: ^10 || ^12 || >=14} + + pretty-ms@9.2.0: + resolution: {integrity: sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==} + engines: {node: '>=18'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + read-package-json-fast@4.0.0: + resolution: {integrity: sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg==} + engines: {node: ^18.17.0 || >=20.5.0} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + + rollup@4.34.8: + resolution: {integrity: sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-applescript@7.0.0: + resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} + engines: {node: '>=18'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + sass@1.85.0: + resolution: {integrity: sha512-3ToiC1xZ1Y8aU7+CkgCI/tqyuPXEmYGJXO7H4uqp0xkLXUqp88rQQ4j1HmP37xSJLbCJPaIiv+cT1y+grssrww==} + engines: {node: '>=14.0.0'} + hasBin: true + + scule@1.3.0: + resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.8.2: + resolution: {integrity: sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==} + engines: {node: '>= 0.4'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sirv@3.0.0: + resolution: {integrity: sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==} + engines: {node: '>=18'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + speakingurl@14.0.1: + resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} + engines: {node: '>=0.10.0'} + + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + + strip-literal@3.0.0: + resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} + + superjson@2.2.2: + resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==} + engines: {node: '>=16'} + + svg-tags@1.0.0: + resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} + + tinyglobby@0.2.10: + resolution: {integrity: sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==} + engines: {node: '>=12.0.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + typescript@5.7.3: + resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.5.4: + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + + undici-types@6.20.0: + resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + + unimport@4.1.1: + resolution: {integrity: sha512-j9+fijH6aDd05yv1fXlyt7HSxtOWtGtrZeYTVBsSUg57Iuf+Ps2itIZjeyu7bEQ4k0WOgYhHrdW8m/pJgOpl5g==} + engines: {node: '>=18.12.0'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unplugin-auto-import@19.1.0: + resolution: {integrity: sha512-B+TGBEBHqY9aR+7YfShfLujETOHstzpV+yaqgy5PkfV0QG7Py+TYMX7vJ9W4SrysHR+UzR+gzcx/nuZjmPeclA==} + engines: {node: '>=14'} + peerDependencies: + '@nuxt/kit': ^3.2.2 + '@vueuse/core': '*' + peerDependenciesMeta: + '@nuxt/kit': + optional: true + '@vueuse/core': + optional: true + + unplugin-utils@0.2.4: + resolution: {integrity: sha512-8U/MtpkPkkk3Atewj1+RcKIjb5WBimZ/WSLhhR3w6SsIj8XJuKTacSP8g+2JhfSGw0Cb125Y+2zA/IzJZDVbhA==} + engines: {node: '>=18.12.0'} + + unplugin-vue-components@28.1.0: + resolution: {integrity: sha512-ScHoDBTf7NVxM+YzzV1b1YNHU1rRnLWIG5hhD8D3hKjgYLd6FNJife0zQhUafv3NKuGLdujRgoqy2vcdt7a55g==} + engines: {node: '>=14'} + peerDependencies: + '@babel/parser': ^7.15.8 + '@nuxt/kit': ^3.2.2 + vue: 2 || 3 + peerDependenciesMeta: + '@babel/parser': + optional: true + '@nuxt/kit': + optional: true + + unplugin@2.2.0: + resolution: {integrity: sha512-m1ekpSwuOT5hxkJeZGRxO7gXbXT3gF26NjQ7GdVHoLoF8/nopLcd/QfPigpCy7i51oFHiRJg/CyHhj4vs2+KGw==} + engines: {node: '>=18.12.0'} + + update-browserslist-db@1.1.2: + resolution: {integrity: sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + vite-hot-client@0.2.4: + resolution: {integrity: sha512-a1nzURqO7DDmnXqabFOliz908FRmIppkBKsJthS8rbe8hBEXwEwe4C3Pp33Z1JoFCYfVL4kTOMLKk0ZZxREIeA==} + peerDependencies: + vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 + + vite-plugin-inspect@0.8.9: + resolution: {integrity: sha512-22/8qn+LYonzibb1VeFZmISdVao5kC22jmEKm24vfFE8siEn47EpVcCLYMv6iKOYMJfjSvSJfueOwcFCkUnV3A==} + engines: {node: '>=14'} + peerDependencies: + '@nuxt/kit': '*' + vite: ^3.1.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.1 + peerDependenciesMeta: + '@nuxt/kit': + optional: true + + vite-plugin-vue-devtools@7.7.2: + resolution: {integrity: sha512-5V0UijQWiSBj32blkyPEqIbzc6HO9c1bwnBhx+ay2dzU0FakH+qMdNUT8nF9BvDE+i6I1U8CqCuJiO20vKEdQw==} + engines: {node: '>=v14.21.3'} + peerDependencies: + vite: ^3.1.0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0 + + vite-plugin-vue-inspector@5.3.1: + resolution: {integrity: sha512-cBk172kZKTdvGpJuzCCLg8lJ909wopwsu3Ve9FsL1XsnLBiRT9U3MePcqrgGHgCX2ZgkqZmAGR8taxw+TV6s7A==} + peerDependencies: + vite: ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0 + + vite@6.1.0: + resolution: {integrity: sha512-RjjMipCKVoR4hVfPY6GQTgveinjNuyLw+qruksLDvA5ktI1150VmcMBKmQaEWJhg/j6Uaf6dNCNA0AfdzUb/hQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vscode-uri@3.1.0: + resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} + + vue-demi@0.14.10: + resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-router@4.5.0: + resolution: {integrity: sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==} + peerDependencies: + vue: ^3.2.0 + + vue-tsc@2.2.2: + resolution: {integrity: sha512-1icPKkxAA5KTAaSwg0wVWdE48EdsH8fgvcbAiqojP4jXKl6LEM3soiW1aG/zrWrFt8Mw1ncG2vG1PvpZpVfehA==} + hasBin: true + peerDependencies: + typescript: '>=5.0.0' + + vue@3.5.13: + resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + which@5.0.0: + resolution: {integrity: sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yoctocolors@2.1.1: + resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==} + engines: {node: '>=18'} + +snapshots: + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + + '@antfu/utils@0.7.10': {} + + '@babel/code-frame@7.26.2': + dependencies: + '@babel/helper-validator-identifier': 7.25.9 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.26.8': {} + + '@babel/core@7.26.9': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.9 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.9) + '@babel/helpers': 7.26.9 + '@babel/parser': 7.26.9 + '@babel/template': 7.26.9 + '@babel/traverse': 7.26.9 + '@babel/types': 7.26.9 + convert-source-map: 2.0.0 + debug: 4.4.0 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.26.9': + dependencies: + '@babel/parser': 7.26.9 + '@babel/types': 7.26.9 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.25.9': + dependencies: + '@babel/types': 7.26.9 + + '@babel/helper-compilation-targets@7.26.5': + dependencies: + '@babel/compat-data': 7.26.8 + '@babel/helper-validator-option': 7.25.9 + browserslist: 4.24.4 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.26.9(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-member-expression-to-functions': 7.25.9 + '@babel/helper-optimise-call-expression': 7.25.9 + '@babel/helper-replace-supers': 7.26.5(@babel/core@7.26.9) + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + '@babel/traverse': 7.26.9 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-member-expression-to-functions@7.25.9': + dependencies: + '@babel/traverse': 7.26.9 + '@babel/types': 7.26.9 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.25.9': + dependencies: + '@babel/traverse': 7.26.9 + '@babel/types': 7.26.9 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + '@babel/traverse': 7.26.9 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.25.9': + dependencies: + '@babel/types': 7.26.9 + + '@babel/helper-plugin-utils@7.26.5': {} + + '@babel/helper-replace-supers@7.26.5(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-member-expression-to-functions': 7.25.9 + '@babel/helper-optimise-call-expression': 7.25.9 + '@babel/traverse': 7.26.9 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.25.9': + dependencies: + '@babel/traverse': 7.26.9 + '@babel/types': 7.26.9 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.25.9': {} + + '@babel/helper-validator-identifier@7.25.9': {} + + '@babel/helper-validator-option@7.25.9': {} + + '@babel/helpers@7.26.9': + dependencies: + '@babel/template': 7.26.9 + '@babel/types': 7.26.9 + + '@babel/parser@7.26.9': + dependencies: + '@babel/types': 7.26.9 + + '@babel/plugin-proposal-decorators@7.25.9(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-create-class-features-plugin': 7.26.9(@babel/core@7.26.9) + '@babel/helper-plugin-utils': 7.26.5 + '@babel/plugin-syntax-decorators': 7.25.9(@babel/core@7.26.9) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-syntax-decorators@7.25.9(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-import-attributes@7.26.0(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-transform-typescript@7.26.8(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-create-class-features-plugin': 7.26.9(@babel/core@7.26.9) + '@babel/helper-plugin-utils': 7.26.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.9) + transitivePeerDependencies: + - supports-color + + '@babel/template@7.26.9': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/parser': 7.26.9 + '@babel/types': 7.26.9 + + '@babel/traverse@7.26.9': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.9 + '@babel/parser': 7.26.9 + '@babel/template': 7.26.9 + '@babel/types': 7.26.9 + debug: 4.4.0 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.26.9': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + + '@ctrl/tinycolor@3.6.1': {} + + '@element-plus/icons-vue@2.3.1(vue@3.5.13(typescript@5.7.3))': + dependencies: + vue: 3.5.13(typescript@5.7.3) + + '@esbuild/aix-ppc64@0.24.2': + optional: true + + '@esbuild/android-arm64@0.24.2': + optional: true + + '@esbuild/android-arm@0.24.2': + optional: true + + '@esbuild/android-x64@0.24.2': + optional: true + + '@esbuild/darwin-arm64@0.24.2': + optional: true + + '@esbuild/darwin-x64@0.24.2': + optional: true + + '@esbuild/freebsd-arm64@0.24.2': + optional: true + + '@esbuild/freebsd-x64@0.24.2': + optional: true + + '@esbuild/linux-arm64@0.24.2': + optional: true + + '@esbuild/linux-arm@0.24.2': + optional: true + + '@esbuild/linux-ia32@0.24.2': + optional: true + + '@esbuild/linux-loong64@0.24.2': + optional: true + + '@esbuild/linux-mips64el@0.24.2': + optional: true + + '@esbuild/linux-ppc64@0.24.2': + optional: true + + '@esbuild/linux-riscv64@0.24.2': + optional: true + + '@esbuild/linux-s390x@0.24.2': + optional: true + + '@esbuild/linux-x64@0.24.2': + optional: true + + '@esbuild/netbsd-arm64@0.24.2': + optional: true + + '@esbuild/netbsd-x64@0.24.2': + optional: true + + '@esbuild/openbsd-arm64@0.24.2': + optional: true + + '@esbuild/openbsd-x64@0.24.2': + optional: true + + '@esbuild/sunos-x64@0.24.2': + optional: true + + '@esbuild/win32-arm64@0.24.2': + optional: true + + '@esbuild/win32-ia32@0.24.2': + optional: true + + '@esbuild/win32-x64@0.24.2': + optional: true + + '@floating-ui/core@1.6.9': + dependencies: + '@floating-ui/utils': 0.2.9 + + '@floating-ui/dom@1.6.13': + dependencies: + '@floating-ui/core': 1.6.9 + '@floating-ui/utils': 0.2.9 + + '@floating-ui/utils@0.2.9': {} + + '@jridgewell/gen-mapping@0.3.8': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.0 + + '@parcel/watcher-android-arm64@2.5.1': + optional: true + + '@parcel/watcher-darwin-arm64@2.5.1': + optional: true + + '@parcel/watcher-darwin-x64@2.5.1': + optional: true + + '@parcel/watcher-freebsd-x64@2.5.1': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-arm-musl@2.5.1': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.5.1': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-x64-musl@2.5.1': + optional: true + + '@parcel/watcher-win32-arm64@2.5.1': + optional: true + + '@parcel/watcher-win32-ia32@2.5.1': + optional: true + + '@parcel/watcher-win32-x64@2.5.1': + optional: true + + '@parcel/watcher@2.5.1': + dependencies: + detect-libc: 1.0.3 + is-glob: 4.0.3 + micromatch: 4.0.8 + node-addon-api: 7.1.1 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.5.1 + '@parcel/watcher-darwin-arm64': 2.5.1 + '@parcel/watcher-darwin-x64': 2.5.1 + '@parcel/watcher-freebsd-x64': 2.5.1 + '@parcel/watcher-linux-arm-glibc': 2.5.1 + '@parcel/watcher-linux-arm-musl': 2.5.1 + '@parcel/watcher-linux-arm64-glibc': 2.5.1 + '@parcel/watcher-linux-arm64-musl': 2.5.1 + '@parcel/watcher-linux-x64-glibc': 2.5.1 + '@parcel/watcher-linux-x64-musl': 2.5.1 + '@parcel/watcher-win32-arm64': 2.5.1 + '@parcel/watcher-win32-ia32': 2.5.1 + '@parcel/watcher-win32-x64': 2.5.1 + optional: true + + '@polka/url@1.0.0-next.28': {} + + '@rollup/pluginutils@5.1.4(rollup@4.34.8)': + dependencies: + '@types/estree': 1.0.6 + estree-walker: 2.0.2 + picomatch: 4.0.2 + optionalDependencies: + rollup: 4.34.8 + + '@rollup/rollup-android-arm-eabi@4.34.8': + optional: true + + '@rollup/rollup-android-arm64@4.34.8': + optional: true + + '@rollup/rollup-darwin-arm64@4.34.8': + optional: true + + '@rollup/rollup-darwin-x64@4.34.8': + optional: true + + '@rollup/rollup-freebsd-arm64@4.34.8': + optional: true + + '@rollup/rollup-freebsd-x64@4.34.8': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.34.8': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.34.8': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.34.8': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.34.8': + optional: true + + '@rollup/rollup-linux-loongarch64-gnu@4.34.8': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.34.8': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.34.8': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.34.8': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.34.8': + optional: true + + '@rollup/rollup-linux-x64-musl@4.34.8': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.34.8': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.34.8': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.34.8': + optional: true + + '@sec-ant/readable-stream@0.4.1': {} + + '@sindresorhus/merge-streams@4.0.0': {} + + '@sxzz/popperjs-es@2.11.7': {} + + '@tsconfig/node22@22.0.0': {} + + '@types/estree@1.0.6': {} + + '@types/lodash-es@4.17.12': + dependencies: + '@types/lodash': 4.17.15 + + '@types/lodash@4.17.15': {} + + '@types/node@22.13.4': + dependencies: + undici-types: 6.20.0 + + '@types/web-bluetooth@0.0.16': {} + + '@vitejs/plugin-vue@5.2.1(vite@6.1.0(@types/node@22.13.4)(sass@1.85.0))(vue@3.5.13(typescript@5.7.3))': + dependencies: + vite: 6.1.0(@types/node@22.13.4)(sass@1.85.0) + vue: 3.5.13(typescript@5.7.3) + + '@volar/language-core@2.4.11': + dependencies: + '@volar/source-map': 2.4.11 + + '@volar/source-map@2.4.11': {} + + '@volar/typescript@2.4.11': + dependencies: + '@volar/language-core': 2.4.11 + path-browserify: 1.0.1 + vscode-uri: 3.1.0 + + '@vue/babel-helper-vue-transform-on@1.2.5': {} + + '@vue/babel-plugin-jsx@1.2.5(@babel/core@7.26.9)': + dependencies: + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.9) + '@babel/template': 7.26.9 + '@babel/traverse': 7.26.9 + '@babel/types': 7.26.9 + '@vue/babel-helper-vue-transform-on': 1.2.5 + '@vue/babel-plugin-resolve-type': 1.2.5(@babel/core@7.26.9) + html-tags: 3.3.1 + svg-tags: 1.0.0 + optionalDependencies: + '@babel/core': 7.26.9 + transitivePeerDependencies: + - supports-color + + '@vue/babel-plugin-resolve-type@1.2.5(@babel/core@7.26.9)': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/core': 7.26.9 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/parser': 7.26.9 + '@vue/compiler-sfc': 3.5.13 + transitivePeerDependencies: + - supports-color + + '@vue/compiler-core@3.5.13': + dependencies: + '@babel/parser': 7.26.9 + '@vue/shared': 3.5.13 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.13': + dependencies: + '@vue/compiler-core': 3.5.13 + '@vue/shared': 3.5.13 + + '@vue/compiler-sfc@3.5.13': + dependencies: + '@babel/parser': 7.26.9 + '@vue/compiler-core': 3.5.13 + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-ssr': 3.5.13 + '@vue/shared': 3.5.13 + estree-walker: 2.0.2 + magic-string: 0.30.17 + postcss: 8.5.2 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.5.13': + dependencies: + '@vue/compiler-dom': 3.5.13 + '@vue/shared': 3.5.13 + + '@vue/compiler-vue2@2.7.16': + dependencies: + de-indent: 1.0.2 + he: 1.2.0 + + '@vue/devtools-api@6.6.4': {} + + '@vue/devtools-core@7.7.2(vite@6.1.0(@types/node@22.13.4)(sass@1.85.0))(vue@3.5.13(typescript@5.7.3))': + dependencies: + '@vue/devtools-kit': 7.7.2 + '@vue/devtools-shared': 7.7.2 + mitt: 3.0.1 + nanoid: 5.1.0 + pathe: 2.0.3 + vite-hot-client: 0.2.4(vite@6.1.0(@types/node@22.13.4)(sass@1.85.0)) + vue: 3.5.13(typescript@5.7.3) + transitivePeerDependencies: + - vite + + '@vue/devtools-kit@7.7.2': + dependencies: + '@vue/devtools-shared': 7.7.2 + birpc: 0.2.19 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 1.0.0 + speakingurl: 14.0.1 + superjson: 2.2.2 + + '@vue/devtools-shared@7.7.2': + dependencies: + rfdc: 1.4.1 + + '@vue/language-core@2.2.2(typescript@5.7.3)': + dependencies: + '@volar/language-core': 2.4.11 + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-vue2': 2.7.16 + '@vue/shared': 3.5.13 + alien-signals: 1.0.3 + minimatch: 9.0.5 + muggle-string: 0.4.1 + path-browserify: 1.0.1 + optionalDependencies: + typescript: 5.7.3 + + '@vue/reactivity@3.5.13': + dependencies: + '@vue/shared': 3.5.13 + + '@vue/runtime-core@3.5.13': + dependencies: + '@vue/reactivity': 3.5.13 + '@vue/shared': 3.5.13 + + '@vue/runtime-dom@3.5.13': + dependencies: + '@vue/reactivity': 3.5.13 + '@vue/runtime-core': 3.5.13 + '@vue/shared': 3.5.13 + csstype: 3.1.3 + + '@vue/server-renderer@3.5.13(vue@3.5.13(typescript@5.7.3))': + dependencies: + '@vue/compiler-ssr': 3.5.13 + '@vue/shared': 3.5.13 + vue: 3.5.13(typescript@5.7.3) + + '@vue/shared@3.5.13': {} + + '@vue/tsconfig@0.7.0(typescript@5.7.3)(vue@3.5.13(typescript@5.7.3))': + optionalDependencies: + typescript: 5.7.3 + vue: 3.5.13(typescript@5.7.3) + + '@vueuse/core@9.13.0(vue@3.5.13(typescript@5.7.3))': + dependencies: + '@types/web-bluetooth': 0.0.16 + '@vueuse/metadata': 9.13.0 + '@vueuse/shared': 9.13.0(vue@3.5.13(typescript@5.7.3)) + vue-demi: 0.14.10(vue@3.5.13(typescript@5.7.3)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/metadata@9.13.0': {} + + '@vueuse/shared@9.13.0(vue@3.5.13(typescript@5.7.3))': + dependencies: + vue-demi: 0.14.10(vue@3.5.13(typescript@5.7.3)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + acorn@8.14.0: {} + + alien-signals@1.0.3: {} + + ansi-styles@6.2.1: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + async-validator@4.2.5: {} + + asynckit@0.4.0: {} + + axios@1.7.9: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.2 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + balanced-match@1.0.2: {} + + binary-extensions@2.3.0: {} + + birpc@0.2.19: {} + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.24.4: + dependencies: + caniuse-lite: 1.0.30001700 + electron-to-chromium: 1.5.101 + node-releases: 2.0.19 + update-browserslist-db: 1.1.2(browserslist@4.24.4) + + bundle-name@4.1.0: + dependencies: + run-applescript: 7.0.0 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + caniuse-lite@1.0.30001700: {} + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + confbox@0.1.8: {} + + convert-source-map@2.0.0: {} + + copy-anything@3.0.5: + dependencies: + is-what: 4.1.16 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + csstype@3.1.3: {} + + dayjs@1.11.13: {} + + de-indent@1.0.2: {} + + debug@4.4.0: + dependencies: + ms: 2.1.3 + + default-browser-id@5.0.0: {} + + default-browser@5.2.1: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.0 + + define-lazy-prop@3.0.0: {} + + delayed-stream@1.0.0: {} + + detect-libc@1.0.3: + optional: true + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + electron-to-chromium@1.5.101: {} + + element-plus@2.9.4(vue@3.5.13(typescript@5.7.3)): + dependencies: + '@ctrl/tinycolor': 3.6.1 + '@element-plus/icons-vue': 2.3.1(vue@3.5.13(typescript@5.7.3)) + '@floating-ui/dom': 1.6.13 + '@popperjs/core': '@sxzz/popperjs-es@2.11.7' + '@types/lodash': 4.17.15 + '@types/lodash-es': 4.17.12 + '@vueuse/core': 9.13.0(vue@3.5.13(typescript@5.7.3)) + async-validator: 4.2.5 + dayjs: 1.11.13 + escape-html: 1.0.3 + lodash: 4.17.21 + lodash-es: 4.17.21 + lodash-unified: 1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.17.21)(lodash@4.17.21) + memoize-one: 6.0.0 + normalize-wheel-es: 1.2.0 + vue: 3.5.13(typescript@5.7.3) + transitivePeerDependencies: + - '@vue/composition-api' + + entities@4.5.0: {} + + error-stack-parser-es@0.1.5: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.2.7 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + esbuild@0.24.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.24.2 + '@esbuild/android-arm': 0.24.2 + '@esbuild/android-arm64': 0.24.2 + '@esbuild/android-x64': 0.24.2 + '@esbuild/darwin-arm64': 0.24.2 + '@esbuild/darwin-x64': 0.24.2 + '@esbuild/freebsd-arm64': 0.24.2 + '@esbuild/freebsd-x64': 0.24.2 + '@esbuild/linux-arm': 0.24.2 + '@esbuild/linux-arm64': 0.24.2 + '@esbuild/linux-ia32': 0.24.2 + '@esbuild/linux-loong64': 0.24.2 + '@esbuild/linux-mips64el': 0.24.2 + '@esbuild/linux-ppc64': 0.24.2 + '@esbuild/linux-riscv64': 0.24.2 + '@esbuild/linux-s390x': 0.24.2 + '@esbuild/linux-x64': 0.24.2 + '@esbuild/netbsd-arm64': 0.24.2 + '@esbuild/netbsd-x64': 0.24.2 + '@esbuild/openbsd-arm64': 0.24.2 + '@esbuild/openbsd-x64': 0.24.2 + '@esbuild/sunos-x64': 0.24.2 + '@esbuild/win32-arm64': 0.24.2 + '@esbuild/win32-ia32': 0.24.2 + '@esbuild/win32-x64': 0.24.2 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@5.0.0: {} + + estree-walker@2.0.2: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.6 + + execa@9.5.2: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.6 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 8.0.0 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 6.0.0 + pretty-ms: 9.2.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.1.1 + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fastq@1.19.0: + dependencies: + reusify: 1.0.4 + + fdir@6.4.3(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + + figures@6.1.0: + dependencies: + is-unicode-supported: 2.1.0 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + follow-redirects@1.15.9: {} + + form-data@4.0.2: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + mime-types: 2.1.35 + + fs-extra@11.3.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gensync@1.0.0-beta.2: {} + + get-intrinsic@1.2.7: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + globals@11.12.0: {} + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + he@1.2.0: {} + + hookable@5.5.3: {} + + html-tags@3.3.1: {} + + human-signals@8.0.0: {} + + immutable@5.0.3: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-docker@3.0.0: {} + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-number@7.0.0: {} + + is-plain-obj@4.1.0: {} + + is-stream@4.0.1: {} + + is-unicode-supported@2.1.0: {} + + is-what@4.1.16: {} + + is-wsl@3.1.0: + dependencies: + is-inside-container: 1.0.0 + + isexe@2.0.0: {} + + isexe@3.1.1: {} + + js-tokens@4.0.0: {} + + js-tokens@9.0.1: {} + + jsesc@3.1.0: {} + + json-parse-even-better-errors@4.0.0: {} + + json5@2.2.3: {} + + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + kolorist@1.8.0: {} + + local-pkg@1.0.0: + dependencies: + mlly: 1.7.4 + pkg-types: 1.3.1 + + lodash-es@4.17.21: {} + + lodash-unified@1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.17.21)(lodash@4.17.21): + dependencies: + '@types/lodash-es': 4.17.12 + lodash: 4.17.21 + lodash-es: 4.17.21 + + lodash@4.17.21: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + math-intrinsics@1.1.0: {} + + memoize-one@6.0.0: {} + + memorystream@0.3.1: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + mitt@3.0.1: {} + + mlly@1.7.4: + dependencies: + acorn: 8.14.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.5.4 + + mrmime@2.0.0: {} + + ms@2.1.3: {} + + muggle-string@0.4.1: {} + + nanoid@3.3.8: {} + + nanoid@5.1.0: {} + + node-addon-api@7.1.1: + optional: true + + node-releases@2.0.19: {} + + normalize-path@3.0.0: {} + + normalize-wheel-es@1.2.0: {} + + npm-normalize-package-bin@4.0.0: {} + + npm-run-all2@7.0.2: + dependencies: + ansi-styles: 6.2.1 + cross-spawn: 7.0.6 + memorystream: 0.3.1 + minimatch: 9.0.5 + pidtree: 0.6.0 + read-package-json-fast: 4.0.0 + shell-quote: 1.8.2 + which: 5.0.0 + + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + + open@10.1.0: + dependencies: + default-browser: 5.2.1 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + is-wsl: 3.1.0 + + parse-ms@4.0.0: {} + + path-browserify@1.0.1: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + pathe@2.0.3: {} + + perfect-debounce@1.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.2: {} + + pidtree@0.6.0: {} + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.7.4 + pathe: 2.0.3 + + postcss@8.5.2: + dependencies: + nanoid: 3.3.8 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + pretty-ms@9.2.0: + dependencies: + parse-ms: 4.0.0 + + proxy-from-env@1.1.0: {} + + queue-microtask@1.2.3: {} + + read-package-json-fast@4.0.0: + dependencies: + json-parse-even-better-errors: 4.0.0 + npm-normalize-package-bin: 4.0.0 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + readdirp@4.1.2: {} + + reusify@1.0.4: {} + + rfdc@1.4.1: {} + + rollup@4.34.8: + dependencies: + '@types/estree': 1.0.6 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.34.8 + '@rollup/rollup-android-arm64': 4.34.8 + '@rollup/rollup-darwin-arm64': 4.34.8 + '@rollup/rollup-darwin-x64': 4.34.8 + '@rollup/rollup-freebsd-arm64': 4.34.8 + '@rollup/rollup-freebsd-x64': 4.34.8 + '@rollup/rollup-linux-arm-gnueabihf': 4.34.8 + '@rollup/rollup-linux-arm-musleabihf': 4.34.8 + '@rollup/rollup-linux-arm64-gnu': 4.34.8 + '@rollup/rollup-linux-arm64-musl': 4.34.8 + '@rollup/rollup-linux-loongarch64-gnu': 4.34.8 + '@rollup/rollup-linux-powerpc64le-gnu': 4.34.8 + '@rollup/rollup-linux-riscv64-gnu': 4.34.8 + '@rollup/rollup-linux-s390x-gnu': 4.34.8 + '@rollup/rollup-linux-x64-gnu': 4.34.8 + '@rollup/rollup-linux-x64-musl': 4.34.8 + '@rollup/rollup-win32-arm64-msvc': 4.34.8 + '@rollup/rollup-win32-ia32-msvc': 4.34.8 + '@rollup/rollup-win32-x64-msvc': 4.34.8 + fsevents: 2.3.3 + + run-applescript@7.0.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + sass@1.85.0: + dependencies: + chokidar: 4.0.3 + immutable: 5.0.3 + source-map-js: 1.2.1 + optionalDependencies: + '@parcel/watcher': 2.5.1 + + scule@1.3.0: {} + + semver@6.3.1: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shell-quote@1.8.2: {} + + signal-exit@4.1.0: {} + + sirv@3.0.0: + dependencies: + '@polka/url': 1.0.0-next.28 + mrmime: 2.0.0 + totalist: 3.0.1 + + source-map-js@1.2.1: {} + + speakingurl@14.0.1: {} + + strip-final-newline@4.0.0: {} + + strip-literal@3.0.0: + dependencies: + js-tokens: 9.0.1 + + superjson@2.2.2: + dependencies: + copy-anything: 3.0.5 + + svg-tags@1.0.0: {} + + tinyglobby@0.2.10: + dependencies: + fdir: 6.4.3(picomatch@4.0.2) + picomatch: 4.0.2 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + totalist@3.0.1: {} + + typescript@5.7.3: {} + + ufo@1.5.4: {} + + undici-types@6.20.0: {} + + unicorn-magic@0.3.0: {} + + unimport@4.1.1: + dependencies: + acorn: 8.14.0 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + fast-glob: 3.3.3 + local-pkg: 1.0.0 + magic-string: 0.30.17 + mlly: 1.7.4 + pathe: 2.0.3 + picomatch: 4.0.2 + pkg-types: 1.3.1 + scule: 1.3.0 + strip-literal: 3.0.0 + unplugin: 2.2.0 + unplugin-utils: 0.2.4 + + universalify@2.0.1: {} + + unplugin-auto-import@19.1.0(@vueuse/core@9.13.0(vue@3.5.13(typescript@5.7.3))): + dependencies: + local-pkg: 1.0.0 + magic-string: 0.30.17 + picomatch: 4.0.2 + unimport: 4.1.1 + unplugin: 2.2.0 + unplugin-utils: 0.2.4 + optionalDependencies: + '@vueuse/core': 9.13.0(vue@3.5.13(typescript@5.7.3)) + + unplugin-utils@0.2.4: + dependencies: + pathe: 2.0.3 + picomatch: 4.0.2 + + unplugin-vue-components@28.1.0(@babel/parser@7.26.9)(vue@3.5.13(typescript@5.7.3)): + dependencies: + chokidar: 3.6.0 + debug: 4.4.0 + local-pkg: 1.0.0 + magic-string: 0.30.17 + mlly: 1.7.4 + tinyglobby: 0.2.10 + unplugin: 2.2.0 + unplugin-utils: 0.2.4 + vue: 3.5.13(typescript@5.7.3) + optionalDependencies: + '@babel/parser': 7.26.9 + transitivePeerDependencies: + - supports-color + + unplugin@2.2.0: + dependencies: + acorn: 8.14.0 + webpack-virtual-modules: 0.6.2 + + update-browserslist-db@1.1.2(browserslist@4.24.4): + dependencies: + browserslist: 4.24.4 + escalade: 3.2.0 + picocolors: 1.1.1 + + vite-hot-client@0.2.4(vite@6.1.0(@types/node@22.13.4)(sass@1.85.0)): + dependencies: + vite: 6.1.0(@types/node@22.13.4)(sass@1.85.0) + + vite-plugin-inspect@0.8.9(rollup@4.34.8)(vite@6.1.0(@types/node@22.13.4)(sass@1.85.0)): + dependencies: + '@antfu/utils': 0.7.10 + '@rollup/pluginutils': 5.1.4(rollup@4.34.8) + debug: 4.4.0 + error-stack-parser-es: 0.1.5 + fs-extra: 11.3.0 + open: 10.1.0 + perfect-debounce: 1.0.0 + picocolors: 1.1.1 + sirv: 3.0.0 + vite: 6.1.0(@types/node@22.13.4)(sass@1.85.0) + transitivePeerDependencies: + - rollup + - supports-color + + vite-plugin-vue-devtools@7.7.2(rollup@4.34.8)(vite@6.1.0(@types/node@22.13.4)(sass@1.85.0))(vue@3.5.13(typescript@5.7.3)): + dependencies: + '@vue/devtools-core': 7.7.2(vite@6.1.0(@types/node@22.13.4)(sass@1.85.0))(vue@3.5.13(typescript@5.7.3)) + '@vue/devtools-kit': 7.7.2 + '@vue/devtools-shared': 7.7.2 + execa: 9.5.2 + sirv: 3.0.0 + vite: 6.1.0(@types/node@22.13.4)(sass@1.85.0) + vite-plugin-inspect: 0.8.9(rollup@4.34.8)(vite@6.1.0(@types/node@22.13.4)(sass@1.85.0)) + vite-plugin-vue-inspector: 5.3.1(vite@6.1.0(@types/node@22.13.4)(sass@1.85.0)) + transitivePeerDependencies: + - '@nuxt/kit' + - rollup + - supports-color + - vue + + vite-plugin-vue-inspector@5.3.1(vite@6.1.0(@types/node@22.13.4)(sass@1.85.0)): + dependencies: + '@babel/core': 7.26.9 + '@babel/plugin-proposal-decorators': 7.25.9(@babel/core@7.26.9) + '@babel/plugin-syntax-import-attributes': 7.26.0(@babel/core@7.26.9) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.26.9) + '@babel/plugin-transform-typescript': 7.26.8(@babel/core@7.26.9) + '@vue/babel-plugin-jsx': 1.2.5(@babel/core@7.26.9) + '@vue/compiler-dom': 3.5.13 + kolorist: 1.8.0 + magic-string: 0.30.17 + vite: 6.1.0(@types/node@22.13.4)(sass@1.85.0) + transitivePeerDependencies: + - supports-color + + vite@6.1.0(@types/node@22.13.4)(sass@1.85.0): + dependencies: + esbuild: 0.24.2 + postcss: 8.5.2 + rollup: 4.34.8 + optionalDependencies: + '@types/node': 22.13.4 + fsevents: 2.3.3 + sass: 1.85.0 + + vscode-uri@3.1.0: {} + + vue-demi@0.14.10(vue@3.5.13(typescript@5.7.3)): + dependencies: + vue: 3.5.13(typescript@5.7.3) + + vue-router@4.5.0(vue@3.5.13(typescript@5.7.3)): + dependencies: + '@vue/devtools-api': 6.6.4 + vue: 3.5.13(typescript@5.7.3) + + vue-tsc@2.2.2(typescript@5.7.3): + dependencies: + '@volar/typescript': 2.4.11 + '@vue/language-core': 2.2.2(typescript@5.7.3) + typescript: 5.7.3 + + vue@3.5.13(typescript@5.7.3): + dependencies: + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-sfc': 3.5.13 + '@vue/runtime-dom': 3.5.13 + '@vue/server-renderer': 3.5.13(vue@3.5.13(typescript@5.7.3)) + '@vue/shared': 3.5.13 + optionalDependencies: + typescript: 5.7.3 + + webpack-virtual-modules@0.6.2: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + which@5.0.0: + dependencies: + isexe: 3.1.1 + + yallist@3.1.1: {} + + yoctocolors@2.1.1: {} diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/public/favicon.ico b/code/09.extra/restful_server_vue3/front/vue3-demo/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..df36fcfb72584e00488330b560ebcf34a41c64c2 GIT binary patch literal 4286 zcmds*O-Phc6o&64GDVCEQHxsW(p4>LW*W<827=Unuo8sGpRux(DN@jWP-e29Wl%wj zY84_aq9}^Am9-cWTD5GGEo#+5Fi2wX_P*bo+xO!)p*7B;iKlbFd(U~_d(U?#hLj56 zPhFkj-|A6~Qk#@g^#D^U0XT1cu=c-vu1+SElX9NR;kzAUV(q0|dl0|%h|dI$%VICy zJnu2^L*Te9JrJMGh%-P79CL0}dq92RGU6gI{v2~|)p}sG5x0U*z<8U;Ij*hB9z?ei z@g6Xq-pDoPl=MANPiR7%172VA%r)kevtV-_5H*QJKFmd;8yA$98zCxBZYXTNZ#QFk2(TX0;Y2dt&WitL#$96|gJY=3xX zpCoi|YNzgO3R`f@IiEeSmKrPSf#h#Qd<$%Ej^RIeeYfsxhPMOG`S`Pz8q``=511zm zAm)MX5AV^5xIWPyEu7u>qYs?pn$I4nL9J!=K=SGlKLXpE<5x+2cDTXq?brj?n6sp= zphe9;_JHf40^9~}9i08r{XM$7HB!`{Ys~TK0kx<}ZQng`UPvH*11|q7&l9?@FQz;8 zx!=3<4seY*%=OlbCbcae?5^V_}*K>Uo6ZWV8mTyE^B=DKy7-sdLYkR5Z?paTgK-zyIkKjIcpyO z{+uIt&YSa_$QnN_@t~L014dyK(fOOo+W*MIxbA6Ndgr=Y!f#Tokqv}n<7-9qfHkc3 z=>a|HWqcX8fzQCT=dqVbogRq!-S>H%yA{1w#2Pn;=e>JiEj7Hl;zdt-2f+j2%DeVD zsW0Ab)ZK@0cIW%W7z}H{&~yGhn~D;aiP4=;m-HCo`BEI+Kd6 z={Xwx{TKxD#iCLfl2vQGDitKtN>z|-AdCN|$jTFDg0m3O`WLD4_s#$S literal 0 HcmV?d00001 diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/src/App.vue b/code/09.extra/restful_server_vue3/front/vue3-demo/src/App.vue new file mode 100644 index 0000000..76faa54 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/src/App.vue @@ -0,0 +1,40 @@ + + + + + diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/src/assets/base.css b/code/09.extra/restful_server_vue3/front/vue3-demo/src/assets/base.css new file mode 100644 index 0000000..8816868 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/src/assets/base.css @@ -0,0 +1,86 @@ +/* color palette from */ +:root { + --vt-c-white: #ffffff; + --vt-c-white-soft: #f8f8f8; + --vt-c-white-mute: #f2f2f2; + + --vt-c-black: #181818; + --vt-c-black-soft: #222222; + --vt-c-black-mute: #282828; + + --vt-c-indigo: #2c3e50; + + --vt-c-divider-light-1: rgba(60, 60, 60, 0.29); + --vt-c-divider-light-2: rgba(60, 60, 60, 0.12); + --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65); + --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); + + --vt-c-text-light-1: var(--vt-c-indigo); + --vt-c-text-light-2: rgba(60, 60, 60, 0.66); + --vt-c-text-dark-1: var(--vt-c-white); + --vt-c-text-dark-2: rgba(235, 235, 235, 0.64); +} + +/* semantic color variables for this project */ +:root { + --color-background: var(--vt-c-white); + --color-background-soft: var(--vt-c-white-soft); + --color-background-mute: var(--vt-c-white-mute); + + --color-border: var(--vt-c-divider-light-2); + --color-border-hover: var(--vt-c-divider-light-1); + + --color-heading: var(--vt-c-text-light-1); + --color-text: var(--vt-c-text-light-1); + + --section-gap: 160px; +} + +@media (prefers-color-scheme: dark) { + :root { + --color-background: var(--vt-c-black); + --color-background-soft: var(--vt-c-black-soft); + --color-background-mute: var(--vt-c-black-mute); + + --color-border: var(--vt-c-divider-dark-2); + --color-border-hover: var(--vt-c-divider-dark-1); + + --color-heading: var(--vt-c-text-dark-1); + --color-text: var(--vt-c-text-dark-2); + } +} + +*, +*::before, +*::after { + box-sizing: border-box; + margin: 0; + font-weight: normal; +} + +body { + min-height: 100vh; + color: var(--color-text); + background: var(--color-background); + transition: + color 0.5s, + background-color 0.5s; + line-height: 1.6; + font-family: + Inter, + -apple-system, + BlinkMacSystemFont, + 'Segoe UI', + Roboto, + Oxygen, + Ubuntu, + Cantarell, + 'Fira Sans', + 'Droid Sans', + 'Helvetica Neue', + sans-serif; + font-size: 15px; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/src/assets/logo.svg b/code/09.extra/restful_server_vue3/front/vue3-demo/src/assets/logo.svg new file mode 100644 index 0000000..7565660 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/src/assets/logo.svg @@ -0,0 +1 @@ + diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/src/assets/main.css b/code/09.extra/restful_server_vue3/front/vue3-demo/src/assets/main.css new file mode 100644 index 0000000..36fb845 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/src/assets/main.css @@ -0,0 +1,35 @@ +@import './base.css'; + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + font-weight: normal; +} + +a, +.green { + text-decoration: none; + color: hsla(160, 100%, 37%, 1); + transition: 0.4s; + padding: 3px; +} + +@media (hover: hover) { + a:hover { + background-color: hsla(160, 100%, 37%, 0.2); + } +} + +@media (min-width: 1024px) { + body { + display: flex; + place-items: center; + } + + #app { + display: grid; + grid-template-columns: 1fr 1fr; + padding: 0 2rem; + } +} diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/HelloWorld.vue b/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/HelloWorld.vue new file mode 100644 index 0000000..d174cf8 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/HelloWorld.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/TheWelcome.vue b/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/TheWelcome.vue new file mode 100644 index 0000000..ae6eec3 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/TheWelcome.vue @@ -0,0 +1,94 @@ + + + diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/WelcomeItem.vue b/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/WelcomeItem.vue new file mode 100644 index 0000000..6d7086a --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/WelcomeItem.vue @@ -0,0 +1,87 @@ + + + diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/icons/IconCommunity.vue b/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/icons/IconCommunity.vue new file mode 100644 index 0000000..2dc8b05 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/icons/IconCommunity.vue @@ -0,0 +1,7 @@ + diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/icons/IconDocumentation.vue b/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/icons/IconDocumentation.vue new file mode 100644 index 0000000..6d4791c --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/icons/IconDocumentation.vue @@ -0,0 +1,7 @@ + diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/icons/IconEcosystem.vue b/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/icons/IconEcosystem.vue new file mode 100644 index 0000000..c3a4f07 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/icons/IconEcosystem.vue @@ -0,0 +1,7 @@ + diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/icons/IconSupport.vue b/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/icons/IconSupport.vue new file mode 100644 index 0000000..7452834 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/icons/IconSupport.vue @@ -0,0 +1,7 @@ + diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/icons/IconTooling.vue b/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/icons/IconTooling.vue new file mode 100644 index 0000000..660598d --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/src/components/icons/IconTooling.vue @@ -0,0 +1,19 @@ + + diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/src/main.ts b/code/09.extra/restful_server_vue3/front/vue3-demo/src/main.ts new file mode 100644 index 0000000..ffb813a --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/src/main.ts @@ -0,0 +1,12 @@ +// import './assets/main.css' +import "element-plus/theme-chalk/el-message-box.css"; + +import { createApp } from 'vue' +import App from './App.vue' +import router from './router' + +const app = createApp(App) + +app.use(router) + +app.mount('#app') diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/src/router/index.ts b/code/09.extra/restful_server_vue3/front/vue3-demo/src/router/index.ts new file mode 100644 index 0000000..3e49915 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/src/router/index.ts @@ -0,0 +1,23 @@ +import { createRouter, createWebHistory } from 'vue-router' +import HomeView from '../views/HomeView.vue' + +const router = createRouter({ + history: createWebHistory(import.meta.env.BASE_URL), + routes: [ + { + path: '/', + name: 'home', + component: HomeView, + }, + { + path: '/about', + name: 'about', + // route level code-splitting + // this generates a separate chunk (About.[hash].js) for this route + // which is lazy-loaded when the route is visited. + component: () => import('../views/AboutView.vue'), + }, + ], +}) + +export default router diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/src/views/AboutView.vue b/code/09.extra/restful_server_vue3/front/vue3-demo/src/views/AboutView.vue new file mode 100644 index 0000000..756ad2a --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/src/views/AboutView.vue @@ -0,0 +1,15 @@ + + + diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/src/views/HomeView.vue b/code/09.extra/restful_server_vue3/front/vue3-demo/src/views/HomeView.vue new file mode 100644 index 0000000..d5c0217 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/src/views/HomeView.vue @@ -0,0 +1,9 @@ + + + diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/tsconfig.app.json b/code/09.extra/restful_server_vue3/front/vue3-demo/tsconfig.app.json new file mode 100644 index 0000000..913b8f2 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/tsconfig.app.json @@ -0,0 +1,12 @@ +{ + "extends": "@vue/tsconfig/tsconfig.dom.json", + "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], + "exclude": ["src/**/__tests__/*"], + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + + "paths": { + "@/*": ["./src/*"] + } + } +} diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/tsconfig.json b/code/09.extra/restful_server_vue3/front/vue3-demo/tsconfig.json new file mode 100644 index 0000000..66b5e57 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/tsconfig.json @@ -0,0 +1,11 @@ +{ + "files": [], + "references": [ + { + "path": "./tsconfig.node.json" + }, + { + "path": "./tsconfig.app.json" + } + ] +} diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/tsconfig.node.json b/code/09.extra/restful_server_vue3/front/vue3-demo/tsconfig.node.json new file mode 100644 index 0000000..a83dfc9 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/tsconfig.node.json @@ -0,0 +1,19 @@ +{ + "extends": "@tsconfig/node22/tsconfig.json", + "include": [ + "vite.config.*", + "vitest.config.*", + "cypress.config.*", + "nightwatch.conf.*", + "playwright.config.*", + "eslint.config.*" + ], + "compilerOptions": { + "noEmit": true, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + + "module": "ESNext", + "moduleResolution": "Bundler", + "types": ["node"] + } +} diff --git a/code/09.extra/restful_server_vue3/front/vue3-demo/vite.config.ts b/code/09.extra/restful_server_vue3/front/vue3-demo/vite.config.ts new file mode 100644 index 0000000..79059f1 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/vue3-demo/vite.config.ts @@ -0,0 +1,38 @@ +import { fileURLToPath, URL } from 'node:url' + +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' +import vueDevTools from 'vite-plugin-vue-devtools' +import AutoImport from 'unplugin-auto-import/vite' +import Components from 'unplugin-vue-components/vite' +import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [ + vue(), + vueDevTools(), + AutoImport({ + resolvers: [ElementPlusResolver()], + }), + Components({ + resolvers: [ElementPlusResolver()], + }), + ], + resolve: { + alias: { + '@': fileURLToPath(new URL('./src', import.meta.url)) + }, + }, + server: { + cors: true, + proxy: { + '/api': { + target: 'http://192.168.90.206:80', + //target: 'http://esp-home.local:80', + changeOrigin: true, + ws: true + } + } + }, +}) diff --git a/code/09.extra/restful_server_vue3/front/web-demo/.browserslistrc b/code/09.extra/restful_server_vue3/front/web-demo/.browserslistrc new file mode 100644 index 0000000..8e8f537 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/web-demo/.browserslistrc @@ -0,0 +1,3 @@ +> 1% +last 2 versions +not ie <= 8 diff --git a/code/09.extra/restful_server_vue3/front/web-demo/.editorconfig b/code/09.extra/restful_server_vue3/front/web-demo/.editorconfig new file mode 100644 index 0000000..8f88145 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/web-demo/.editorconfig @@ -0,0 +1,5 @@ +[*.{js,jsx,ts,tsx,vue}] +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/code/09.extra/restful_server_vue3/front/web-demo/.eslintrc.js b/code/09.extra/restful_server_vue3/front/web-demo/.eslintrc.js new file mode 100644 index 0000000..87d6cb8 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/web-demo/.eslintrc.js @@ -0,0 +1,17 @@ +module.exports = { + root: true, + env: { + node: true + }, + 'extends': [ + 'plugin:vue/essential', + '@vue/standard' + ], + rules: { + 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', + 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' + }, + parserOptions: { + parser: 'babel-eslint' + } +} diff --git a/code/09.extra/restful_server_vue3/front/web-demo/.gitignore b/code/09.extra/restful_server_vue3/front/web-demo/.gitignore new file mode 100644 index 0000000..1667ff3 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/web-demo/.gitignore @@ -0,0 +1,26 @@ +.DS_Store +node_modules +/dist + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +# APIs used in this example is simple and stable enough. +# There shouldn't be risk of compatibility unless the major version of some library changed. +# To compress the package size, just exclude the package-lock.json file. +package-lock.json diff --git a/code/09.extra/restful_server_vue3/front/web-demo/babel.config.js b/code/09.extra/restful_server_vue3/front/web-demo/babel.config.js new file mode 100644 index 0000000..c8e69f5 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/web-demo/babel.config.js @@ -0,0 +1,5 @@ +module.exports = { + presets: [ + '@vue/app' + ] +} diff --git a/code/09.extra/restful_server_vue3/front/web-demo/package.json b/code/09.extra/restful_server_vue3/front/web-demo/package.json new file mode 100644 index 0000000..23613f4 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/web-demo/package.json @@ -0,0 +1,32 @@ +{ + "name": "web-demo", + "version": "0.1.0", + "private": true, + "scripts": { + "serve": "vue-cli-service serve", + "build": "vue-cli-service build", + "lint": "vue-cli-service lint" + }, + "dependencies": { + "axios": "^0.21.1", + "core-js": "^2.6.5", + "vue": "^2.6.10", + "vue-router": "^3.0.3", + "vuetify": "^1.5.14", + "vuex": "^3.0.1" + }, + "devDependencies": { + "@vue/cli-plugin-babel": "^3.7.0", + "@vue/cli-plugin-eslint": "^3.7.0", + "@vue/cli-service": "^3.7.0", + "@vue/eslint-config-standard": "^4.0.0", + "babel-eslint": "^10.0.1", + "eslint": "^5.16.0", + "eslint-plugin-vue": "^5.0.0", + "stylus": "^0.54.5", + "stylus-loader": "^3.0.1", + "vue-cli-plugin-vuetify": "^0.5.0", + "vue-template-compiler": "^2.5.21", + "vuetify-loader": "^1.0.5" + } +} diff --git a/code/09.extra/restful_server_vue3/front/web-demo/postcss.config.js b/code/09.extra/restful_server_vue3/front/web-demo/postcss.config.js new file mode 100644 index 0000000..2be0631 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/web-demo/postcss.config.js @@ -0,0 +1,5 @@ +module.exports = { + plugins: { + autoprefixer: {} + } +} diff --git a/code/09.extra/restful_server_vue3/front/web-demo/public/favicon.ico b/code/09.extra/restful_server_vue3/front/web-demo/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..17b8ff3cb6c3c920c732f563c2507c8472dfb95c GIT binary patch literal 6429 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 + + + + + + + ESP-HOME + + + + + +
+ + + diff --git a/code/09.extra/restful_server_vue3/front/web-demo/src/App.vue b/code/09.extra/restful_server_vue3/front/web-demo/src/App.vue new file mode 100644 index 0000000..eaec12a --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/web-demo/src/App.vue @@ -0,0 +1,55 @@ + + + diff --git a/code/09.extra/restful_server_vue3/front/web-demo/src/assets/logo.png b/code/09.extra/restful_server_vue3/front/web-demo/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..c19919e5cafb7933aa0815c044461ddde4f765ac GIT binary patch literal 37327 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

hB-DHf$}=oQdIfrhPXj4tbqj#Pa=cE6wDP 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 h(App) +}).$mount('#app') diff --git a/code/09.extra/restful_server_vue3/front/web-demo/src/plugins/vuetify.js b/code/09.extra/restful_server_vue3/front/web-demo/src/plugins/vuetify.js new file mode 100644 index 0000000..b4391fd --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/web-demo/src/plugins/vuetify.js @@ -0,0 +1,7 @@ +import Vue from 'vue' +import Vuetify from 'vuetify/lib' +import 'vuetify/src/stylus/app.styl' + +Vue.use(Vuetify, { + iconfont: 'md', +}) diff --git a/code/09.extra/restful_server_vue3/front/web-demo/src/router.js b/code/09.extra/restful_server_vue3/front/web-demo/src/router.js new file mode 100644 index 0000000..9183be2 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/web-demo/src/router.js @@ -0,0 +1,29 @@ +import Vue from 'vue' +import Router from 'vue-router' +import Home from './views/Home.vue' +import Chart from './views/Chart.vue' +import Light from './views/Light.vue' + +Vue.use(Router) + +export default new Router({ + mode: 'history', + base: process.env.BASE_URL, + routes: [ + { + path: '/', + name: 'home', + component: Home + }, + { + path: '/chart', + name: 'chart', + component: Chart + }, + { + path: '/light', + name: 'light', + component: Light + } + ] +}) diff --git a/code/09.extra/restful_server_vue3/front/web-demo/src/store.js b/code/09.extra/restful_server_vue3/front/web-demo/src/store.js new file mode 100644 index 0000000..b6e8eab --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/web-demo/src/store.js @@ -0,0 +1,28 @@ +import Vue from 'vue' +import Vuex from 'vuex' +import axios from 'axios' + +Vue.use(Vuex) + +export default new Vuex.Store({ + state: { + chart_value: [8, 2, 5, 9, 5, 11, 3, 5, 10, 0, 1, 8, 2, 9, 0, 13, 10, 7, 16], + }, + mutations: { + update_chart_value(state, new_value) { + state.chart_value.push(new_value); + state.chart_value.shift(); + } + }, + actions: { + update_chart_value({ commit }) { + axios.get("/api/v1/temp/raw") + .then(data => { + commit("update_chart_value", data.data.raw); + }) + .catch(error => { + console.log(error); + }); + } + } +}) diff --git a/code/09.extra/restful_server_vue3/front/web-demo/src/views/Chart.vue b/code/09.extra/restful_server_vue3/front/web-demo/src/views/Chart.vue new file mode 100644 index 0000000..719127a --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/web-demo/src/views/Chart.vue @@ -0,0 +1,41 @@ + + + diff --git a/code/09.extra/restful_server_vue3/front/web-demo/src/views/Home.vue b/code/09.extra/restful_server_vue3/front/web-demo/src/views/Home.vue new file mode 100644 index 0000000..6b70bc5 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/web-demo/src/views/Home.vue @@ -0,0 +1,40 @@ + + + diff --git a/code/09.extra/restful_server_vue3/front/web-demo/src/views/Light.vue b/code/09.extra/restful_server_vue3/front/web-demo/src/views/Light.vue new file mode 100644 index 0000000..423da98 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/web-demo/src/views/Light.vue @@ -0,0 +1,62 @@ + + + diff --git a/code/09.extra/restful_server_vue3/front/web-demo/vue.config.js b/code/09.extra/restful_server_vue3/front/web-demo/vue.config.js new file mode 100644 index 0000000..e1ae459 --- /dev/null +++ b/code/09.extra/restful_server_vue3/front/web-demo/vue.config.js @@ -0,0 +1,11 @@ +module.exports = { + devServer: { + proxy: { + '/api': { + target: 'http://esp-home.local:80', + changeOrigin: true, + ws: true + } + } + } +} diff --git a/code/09.extra/restful_server_vue3/main/CMakeLists.txt b/code/09.extra/restful_server_vue3/main/CMakeLists.txt new file mode 100644 index 0000000..47f2d64 --- /dev/null +++ b/code/09.extra/restful_server_vue3/main/CMakeLists.txt @@ -0,0 +1,12 @@ +idf_component_register(SRCS "esp_rest_main.c" + "rest_server.c" + INCLUDE_DIRS ".") + +if(CONFIG_EXAMPLE_WEB_DEPLOY_SF) + set(WEB_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../front/vue3-demo") + if(EXISTS ${WEB_SRC_DIR}/dist) + spiffs_create_partition_image(www ${WEB_SRC_DIR}/dist FLASH_IN_PROJECT) + else() + message(FATAL_ERROR "${WEB_SRC_DIR}/dist doesn't exit. Please run 'npm run build' in ${WEB_SRC_DIR}") + endif() +endif() diff --git a/code/09.extra/restful_server_vue3/main/Kconfig.projbuild b/code/09.extra/restful_server_vue3/main/Kconfig.projbuild new file mode 100644 index 0000000..8379401 --- /dev/null +++ b/code/09.extra/restful_server_vue3/main/Kconfig.projbuild @@ -0,0 +1,51 @@ +menu "Example Configuration" + + config EXAMPLE_MDNS_HOST_NAME + string "mDNS Host Name" + default "esp-home" + help + Specify the domain name used in the mDNS service. + Note that webpage also take it as a part of URL where it will send GET/POST requests to. + + choice EXAMPLE_WEB_DEPLOY_MODE + prompt "Website deploy mode" + default EXAMPLE_WEB_DEPLOY_SEMIHOST + help + Select website deploy mode. + You can deploy website to host, and ESP32 will retrieve them in a semihost way (JTAG is needed). + You can deploy website to SD card or SPI flash, and ESP32 will retrieve them via SDIO/SPI interface. + Detailed operation steps are listed in the example README file. + config EXAMPLE_WEB_DEPLOY_SEMIHOST + bool "Deploy website to host (JTAG is needed)" + help + Deploy website to host. + It is recommended to choose this mode during developing. + config EXAMPLE_WEB_DEPLOY_SD + depends on IDF_TARGET_ESP32 + bool "Deploy website to SD card" + help + Deploy website to SD card. + Choose this production mode if the size of website is too large (bigger than 2MB). + config EXAMPLE_WEB_DEPLOY_SF + bool "Deploy website to SPI Nor Flash" + help + Deploy website to SPI Nor Flash. + Choose this production mode if the size of website is small (less than 2MB). + endchoice + + if EXAMPLE_WEB_DEPLOY_SEMIHOST + config EXAMPLE_HOST_PATH_TO_MOUNT + string "Host path to mount (e.g. absolute path to web dist directory)" + default "PATH-TO-WEB-DIST_DIR" + help + When using semihost in ESP32, you should specify the host path which will be mounted to VFS. + Note that only absolute path is acceptable. + endif + + config EXAMPLE_WEB_MOUNT_POINT + string "Website mount point in VFS" + default "/www" + help + Specify the mount point in VFS. + +endmenu diff --git a/code/09.extra/restful_server_vue3/main/esp_rest_main.c b/code/09.extra/restful_server_vue3/main/esp_rest_main.c new file mode 100644 index 0000000..9aae34b --- /dev/null +++ b/code/09.extra/restful_server_vue3/main/esp_rest_main.c @@ -0,0 +1,138 @@ +/* HTTP Restful API Server Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include "sdkconfig.h" +#include "driver/gpio.h" +#include "esp_vfs_semihost.h" +#include "esp_vfs_fat.h" +#include "esp_spiffs.h" +#include "sdmmc_cmd.h" +#include "nvs_flash.h" +#include "esp_netif.h" +#include "esp_event.h" +#include "esp_log.h" +#include "mdns.h" +#include "lwip/apps/netbiosns.h" +#include "protocol_examples_common.h" +#if CONFIG_EXAMPLE_WEB_DEPLOY_SD +#include "driver/sdmmc_host.h" +#endif + +#define MDNS_INSTANCE "esp home web server" + +static const char *TAG = "example"; + +esp_err_t start_rest_server(const char *base_path); + +static void initialise_mdns(void) +{ + mdns_init(); + mdns_hostname_set(CONFIG_EXAMPLE_MDNS_HOST_NAME); + mdns_instance_name_set(MDNS_INSTANCE); + + mdns_txt_item_t serviceTxtData[] = { + {"board", "esp32"}, + {"path", "/"} + }; + + ESP_ERROR_CHECK(mdns_service_add("ESP32-WebServer", "_http", "_tcp", 80, serviceTxtData, + sizeof(serviceTxtData) / sizeof(serviceTxtData[0]))); +} + +#if CONFIG_EXAMPLE_WEB_DEPLOY_SEMIHOST +esp_err_t init_fs(void) +{ + esp_err_t ret = esp_vfs_semihost_register(CONFIG_EXAMPLE_WEB_MOUNT_POINT); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to register semihost driver (%s)!", esp_err_to_name(ret)); + return ESP_FAIL; + } + return ESP_OK; +} +#endif + +#if CONFIG_EXAMPLE_WEB_DEPLOY_SD +esp_err_t init_fs(void) +{ + sdmmc_host_t host = SDMMC_HOST_DEFAULT(); + sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); + + gpio_set_pull_mode(15, GPIO_PULLUP_ONLY); // CMD + gpio_set_pull_mode(2, GPIO_PULLUP_ONLY); // D0 + gpio_set_pull_mode(4, GPIO_PULLUP_ONLY); // D1 + gpio_set_pull_mode(12, GPIO_PULLUP_ONLY); // D2 + gpio_set_pull_mode(13, GPIO_PULLUP_ONLY); // D3 + + esp_vfs_fat_sdmmc_mount_config_t mount_config = { + .format_if_mount_failed = true, + .max_files = 4, + .allocation_unit_size = 16 * 1024 + }; + + sdmmc_card_t *card; + esp_err_t ret = esp_vfs_fat_sdmmc_mount(CONFIG_EXAMPLE_WEB_MOUNT_POINT, &host, &slot_config, &mount_config, &card); + if (ret != ESP_OK) { + if (ret == ESP_FAIL) { + ESP_LOGE(TAG, "Failed to mount filesystem."); + } else { + ESP_LOGE(TAG, "Failed to initialize the card (%s)", esp_err_to_name(ret)); + } + return ESP_FAIL; + } + /* print card info if mount successfully */ + sdmmc_card_print_info(stdout, card); + return ESP_OK; +} +#endif + +#if CONFIG_EXAMPLE_WEB_DEPLOY_SF +esp_err_t init_fs(void) +{ + esp_vfs_spiffs_conf_t conf = { + .base_path = CONFIG_EXAMPLE_WEB_MOUNT_POINT, + .partition_label = NULL, + .max_files = 5, + .format_if_mount_failed = false + }; + esp_err_t ret = esp_vfs_spiffs_register(&conf); + + if (ret != ESP_OK) { + if (ret == ESP_FAIL) { + ESP_LOGE(TAG, "Failed to mount or format filesystem"); + } else if (ret == ESP_ERR_NOT_FOUND) { + ESP_LOGE(TAG, "Failed to find SPIFFS partition"); + } else { + ESP_LOGE(TAG, "Failed to initialize SPIFFS (%s)", esp_err_to_name(ret)); + } + return ESP_FAIL; + } + + size_t total = 0, used = 0; + ret = esp_spiffs_info(NULL, &total, &used); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to get SPIFFS partition information (%s)", esp_err_to_name(ret)); + } else { + ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used); + } + return ESP_OK; +} +#endif + +void app_main(void) +{ + ESP_ERROR_CHECK(nvs_flash_init()); + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + initialise_mdns(); + netbiosns_init(); + netbiosns_set_name(CONFIG_EXAMPLE_MDNS_HOST_NAME); + + ESP_ERROR_CHECK(example_connect()); + ESP_ERROR_CHECK(init_fs()); + ESP_ERROR_CHECK(start_rest_server(CONFIG_EXAMPLE_WEB_MOUNT_POINT)); +} diff --git a/code/09.extra/restful_server_vue3/main/idf_component.yml b/code/09.extra/restful_server_vue3/main/idf_component.yml new file mode 100644 index 0000000..4c96cd1 --- /dev/null +++ b/code/09.extra/restful_server_vue3/main/idf_component.yml @@ -0,0 +1,8 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/mdns: "^1.0.3" + ## Required IDF version + idf: + version: ">=5.0" + protocol_examples_common: + path: ${IDF_PATH}/examples/common_components/protocol_examples_common diff --git a/code/09.extra/restful_server_vue3/main/rest_server.c b/code/09.extra/restful_server_vue3/main/rest_server.c new file mode 100644 index 0000000..ee4785b --- /dev/null +++ b/code/09.extra/restful_server_vue3/main/rest_server.c @@ -0,0 +1,226 @@ +/* HTTP Restful API Server + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include +#include "esp_http_server.h" +#include "esp_chip_info.h" +#include "esp_random.h" +#include "esp_log.h" +#include "esp_vfs.h" +#include "cJSON.h" + +static const char *REST_TAG = "esp-rest"; +#define REST_CHECK(a, str, goto_tag, ...) \ + do \ + { \ + if (!(a)) \ + { \ + ESP_LOGE(REST_TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + goto goto_tag; \ + } \ + } while (0) + +#define FILE_PATH_MAX (ESP_VFS_PATH_MAX + 128) +#define SCRATCH_BUFSIZE (10240) + +typedef struct rest_server_context { + char base_path[ESP_VFS_PATH_MAX + 1]; + char scratch[SCRATCH_BUFSIZE]; +} rest_server_context_t; + +#define CHECK_FILE_EXTENSION(filename, ext) (strcasecmp(&filename[strlen(filename) - strlen(ext)], ext) == 0) + +/* Set HTTP response content type according to file extension */ +static esp_err_t set_content_type_from_file(httpd_req_t *req, const char *filepath) +{ + const char *type = "text/plain"; + if (CHECK_FILE_EXTENSION(filepath, ".html")) { + type = "text/html"; + } else if (CHECK_FILE_EXTENSION(filepath, ".js")) { + type = "application/javascript"; + } else if (CHECK_FILE_EXTENSION(filepath, ".css")) { + type = "text/css"; + } else if (CHECK_FILE_EXTENSION(filepath, ".png")) { + type = "image/png"; + } else if (CHECK_FILE_EXTENSION(filepath, ".ico")) { + type = "image/x-icon"; + } else if (CHECK_FILE_EXTENSION(filepath, ".svg")) { + type = "text/xml"; + } + return httpd_resp_set_type(req, type); +} + +/* Send HTTP response with the contents of the requested file */ +static esp_err_t rest_common_get_handler(httpd_req_t *req) +{ + char filepath[FILE_PATH_MAX]; + + rest_server_context_t *rest_context = (rest_server_context_t *)req->user_ctx; + strlcpy(filepath, rest_context->base_path, sizeof(filepath)); + if (req->uri[strlen(req->uri) - 1] == '/') { + strlcat(filepath, "/index.html", sizeof(filepath)); + } else { + strlcat(filepath, req->uri, sizeof(filepath)); + } + int fd = open(filepath, O_RDONLY, 0); + if (fd == -1) { + ESP_LOGE(REST_TAG, "Failed to open file : %s", filepath); + /* Respond with 500 Internal Server Error */ + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to read existing file"); + return ESP_FAIL; + } + + set_content_type_from_file(req, filepath); + + char *chunk = rest_context->scratch; + ssize_t read_bytes; + do { + /* Read file in chunks into the scratch buffer */ + read_bytes = read(fd, chunk, SCRATCH_BUFSIZE); + if (read_bytes == -1) { + ESP_LOGE(REST_TAG, "Failed to read file : %s", filepath); + } else if (read_bytes > 0) { + /* Send the buffer contents as HTTP response chunk */ + if (httpd_resp_send_chunk(req, chunk, read_bytes) != ESP_OK) { + close(fd); + ESP_LOGE(REST_TAG, "File sending failed!"); + /* Abort sending file */ + httpd_resp_sendstr_chunk(req, NULL); + /* Respond with 500 Internal Server Error */ + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to send file"); + return ESP_FAIL; + } + } + } while (read_bytes > 0); + /* Close file after sending complete */ + close(fd); + ESP_LOGI(REST_TAG, "File sending complete"); + /* Respond with an empty chunk to signal HTTP response completion */ + httpd_resp_send_chunk(req, NULL, 0); + return ESP_OK; +} + +/* Simple handler for light brightness control */ +static esp_err_t light_brightness_post_handler(httpd_req_t *req) +{ + int total_len = req->content_len; + int cur_len = 0; + char *buf = ((rest_server_context_t *)(req->user_ctx))->scratch; + int received = 0; + if (total_len >= SCRATCH_BUFSIZE) { + /* Respond with 500 Internal Server Error */ + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "content too long"); + return ESP_FAIL; + } + while (cur_len < total_len) { + received = httpd_req_recv(req, buf + cur_len, total_len); + if (received <= 0) { + /* Respond with 500 Internal Server Error */ + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to post control value"); + return ESP_FAIL; + } + cur_len += received; + } + buf[total_len] = '\0'; + + cJSON *root = cJSON_Parse(buf); + int red = cJSON_GetObjectItem(root, "red")->valueint; + int green = cJSON_GetObjectItem(root, "green")->valueint; + int blue = cJSON_GetObjectItem(root, "blue")->valueint; + ESP_LOGI(REST_TAG, "Light control: red = %d, green = %d, blue = %d", red, green, blue); + cJSON_Delete(root); + httpd_resp_sendstr(req, "Post control value successfully"); + return ESP_OK; +} + +/* Simple handler for getting system handler */ +static esp_err_t system_info_get_handler(httpd_req_t *req) +{ + httpd_resp_set_type(req, "application/json"); + cJSON *root = cJSON_CreateObject(); + esp_chip_info_t chip_info; + esp_chip_info(&chip_info); + cJSON_AddStringToObject(root, "version", IDF_VER); + cJSON_AddNumberToObject(root, "cores", chip_info.cores); + const char *sys_info = cJSON_Print(root); + httpd_resp_sendstr(req, sys_info); + free((void *)sys_info); + cJSON_Delete(root); + return ESP_OK; +} + +/* Simple handler for getting temperature data */ +static esp_err_t temperature_data_get_handler(httpd_req_t *req) +{ + httpd_resp_set_type(req, "application/json"); + cJSON *root = cJSON_CreateObject(); + cJSON_AddNumberToObject(root, "raw", esp_random() % 20); + const char *sys_info = cJSON_Print(root); + httpd_resp_sendstr(req, sys_info); + free((void *)sys_info); + cJSON_Delete(root); + return ESP_OK; +} + +esp_err_t start_rest_server(const char *base_path) +{ + REST_CHECK(base_path, "wrong base path", err); + rest_server_context_t *rest_context = calloc(1, sizeof(rest_server_context_t)); + REST_CHECK(rest_context, "No memory for rest context", err); + strlcpy(rest_context->base_path, base_path, sizeof(rest_context->base_path)); + + httpd_handle_t server = NULL; + httpd_config_t config = HTTPD_DEFAULT_CONFIG(); + config.uri_match_fn = httpd_uri_match_wildcard; + + ESP_LOGI(REST_TAG, "Starting HTTP Server"); + REST_CHECK(httpd_start(&server, &config) == ESP_OK, "Start server failed", err_start); + + /* URI handler for fetching system info */ + httpd_uri_t system_info_get_uri = { + .uri = "/api/v1/system/info", + .method = HTTP_GET, + .handler = system_info_get_handler, + .user_ctx = rest_context + }; + httpd_register_uri_handler(server, &system_info_get_uri); + + /* URI handler for fetching temperature data */ + httpd_uri_t temperature_data_get_uri = { + .uri = "/api/v1/temp/raw", + .method = HTTP_GET, + .handler = temperature_data_get_handler, + .user_ctx = rest_context + }; + httpd_register_uri_handler(server, &temperature_data_get_uri); + + /* URI handler for light brightness control */ + httpd_uri_t light_brightness_post_uri = { + .uri = "/api/v1/light/brightness", + .method = HTTP_POST, + .handler = light_brightness_post_handler, + .user_ctx = rest_context + }; + httpd_register_uri_handler(server, &light_brightness_post_uri); + + /* URI handler for getting web server files */ + httpd_uri_t common_get_uri = { + .uri = "/*", + .method = HTTP_GET, + .handler = rest_common_get_handler, + .user_ctx = rest_context + }; + httpd_register_uri_handler(server, &common_get_uri); + + return ESP_OK; +err_start: + free(rest_context); +err: + return ESP_FAIL; +} diff --git a/code/09.extra/restful_server_vue3/partitions_example.csv b/code/09.extra/restful_server_vue3/partitions_example.csv new file mode 100644 index 0000000..72ca8fa --- /dev/null +++ b/code/09.extra/restful_server_vue3/partitions_example.csv @@ -0,0 +1,6 @@ +# Name, Type, SubType, Offset, Size, Flags +# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +factory, app, factory, 0x10000, 1M, +www, data, spiffs, , 2M, diff --git a/code/09.extra/restful_server_vue3/sdkconfig.defaults b/code/09.extra/restful_server_vue3/sdkconfig.defaults new file mode 100644 index 0000000..34b4b22 --- /dev/null +++ b/code/09.extra/restful_server_vue3/sdkconfig.defaults @@ -0,0 +1,7 @@ +CONFIG_HTTPD_MAX_REQ_HDR_LEN=1024 +CONFIG_SPIFFS_OBJ_NAME_LEN=64 +CONFIG_FATFS_LFN_HEAP=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_example.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions_example.csv" diff --git a/code/09.extra/restful_server_vue3/sdkconfig.defaults.esp32p4 b/code/09.extra/restful_server_vue3/sdkconfig.defaults.esp32p4 new file mode 100644 index 0000000..4a92468 --- /dev/null +++ b/code/09.extra/restful_server_vue3/sdkconfig.defaults.esp32p4 @@ -0,0 +1,2 @@ +CONFIG_MDNS_PREDEF_NETIF_STA=n +CONFIG_MDNS_PREDEF_NETIF_AP=n