diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 8d349fca4..b62301016 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -22,7 +22,7 @@ _Make sure your have performed every step and checked the applicable boxes befor - [ ] Searched the issue in [issues](https://github.com/emsesp/EMS-ESP32/issues) - [ ] Searched the issue in [discussions](https://github.com/emsesp/EMS-ESP32/discussions) - [ ] Searched the issue in the [docs](https://emsesp.org/Troubleshooting/) -- [ ] Searched the issue in the [chat](https://discord.gg/3J3GgnzpyT) +- [ ] Searched the issue in the [chat](https://discord.gg/GP9DPSgeJq) - [ ] Provide the System information in the area below, taken from `http:///api/system` ```json diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 62c86f614..1deb908ac 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -7,5 +7,5 @@ contact_links: url: https://github.com/emsesp/EMS-ESP32/discussions about: EMS-ESP usage Questions, Feature Requests and Projects. - name: EMS-ESP Users Chat - url: https://discord.gg/3J3GgnzpyT + url: https://discord.gg/GP9DPSgeJq about: Chat for feedback, questions and troubleshooting. diff --git a/README.md b/README.md index 5a8e7ad51..a4d80ad0f 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Guides - + Discord @@ -32,7 +32,7 @@ [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=emsesp_EMS-ESP32&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=emsesp_EMS-ESP32) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/9441142f49424ef891e8f5251866ee6b)](https://app.codacy.com/gh/emsesp/EMS-ESP32/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) [![downloads](https://img.shields.io/github/downloads/emsesp/EMS-ESP32/total.svg)](https://github.com/emsesp/EMS-ESP32/releases) -[![chat](https://img.shields.io/discord/816637840644505620.svg?style=flat-square&color=blueviolet)](https://discord.gg/3J3GgnzpyT) +[![chat](https://img.shields.io/discord/816637840644505620.svg?style=flat-square&color=blueviolet)](https://discord.gg/GP9DPSgeJq) [![GitHub stars](https://img.shields.io/github/stars/emsesp/EMS-ESP32.svg?style=social&label=Star)](https://github.com/emsesp/EMS-ESP32/stargazers) [![GitHub forks](https://img.shields.io/github/forks/emsesp/EMS-ESP32.svg?style=social&label=Fork)](https://github.com/emsesp/EMS-ESP32/network) @@ -40,7 +40,8 @@ **EMS-ESP** is an open-source firmware for the Espressif ESP32 microcontroller to communicate with **EMS** (Energy Management System) compatible equipment from manufacturers such as Bosch, Buderus, Nefit, Junkers, Worcester, Sieger, elm.leblanc and iVT. -It requires a small circuit to interface with the EMS bus which can be purchased from or custom built. +It requires a small circuit to interface with the EMS bus which can be purchased from . These gateways are tested thoroughly and certified to work with EMS-ESP. + ## 📦  **Key Features** @@ -64,17 +65,17 @@ Head over to the [Installation Guide](https://emsesp.org/Installing) section of ## 📋  **Documentation** -Visit [emsesp.org](https://emsesp.org) for more details on how to install and configure EMS-ESP. There is also a collection of Frequently Asked Questions and Troubleshooting tips with example customizations from the community. +Visit [emsesp.org](https://emsesp.org) for more details on how to setup and configure EMS-ESP. You'll also find more a collection of example configuarations, Frequently Asked Questions and Troubleshooting tips. ## 💬  **Getting Support** -To chat with the community reach out on our [Discord Server](https://discord.gg/3J3GgnzpyT). +To chat with the community reach out on our [Discord Server](https://discord.gg/GP9DPSgeJq). -If you find an issue or have a request, see [how to request support](https://emsesp.org/Support/) on how to submit a bug report or feature request. +If you find an issue or have a request, see the [Getting Support](https://emsesp.org/Support/) section of the documentation. Note if you are using a non-BBQKees EMS gateway, you may need to contact the manufacturer for support. ## 🎥  **Live Demo** -For a live demo go to [demo.emsesp.org](https://demo.emsesp.org). Pick a language from the sign on page and log in with any username or password. Note not all features are operational as it's based on static data. +To see a live demo go to [demo.emsesp.org](https://demo.emsesp.org). Pick a language and use any username and password to log in. Note whast you're seeing is static example data so not all features are operational. ## 💖  **Contributors** @@ -84,7 +85,7 @@ If you like **EMS-ESP**, please give it a ✨ on GitHub, or even better fork it ## 📦  **Building** -See the [Building Guide](https://emsesp.org/Building) section of the documentation for instructions on how to build EMS-ESP. +See the [Building the firmware](https://emsesp.org/Building) guide in the documentation for instructions on how to build EMS-ESP from this source code. ## 📢  **Libraries used** diff --git a/cspell.json b/cspell.json index 880eedb9c..075f7629f 100644 --- a/cspell.json +++ b/cspell.json @@ -9,6 +9,7 @@ } ], "dictionaries": ["project-words"], + "caseSensitive": false, "ignorePaths": [ "node_modules", "compile_commands.json", @@ -36,6 +37,7 @@ "pnpm-*.yaml", "vite.config.ts", "lib/esp32-psram/**", - "test/test_api/test_api.h" + "test/test_api/test_api.h", + "lib_standalone/**" ] } \ No newline at end of file diff --git a/interface/package.json b/interface/package.json index 87005f6d9..2aa2b7d5b 100644 --- a/interface/package.json +++ b/interface/package.json @@ -30,7 +30,7 @@ "@mui/material": "^7.3.7", "@preact/compat": "^18.3.1", "@table-library/react-table-library": "4.1.15", - "alova": "3.4.1", + "alova": "3.5.0", "async-validator": "^4.2.5", "etag": "^1.8.1", "formidable": "^3.5.4", @@ -38,34 +38,34 @@ "magic-string": "^0.30.21", "mime-types": "^3.0.2", "preact": "^10.28.2", - "react": "^19.2.3", - "react-dom": "^19.2.3", + "react": "^19.2.4", + "react-dom": "^19.2.4", "react-icons": "^5.5.0", - "react-router": "^7.12.0", + "react-router": "^7.13.0", "react-toastify": "^11.0.5", "typesafe-i18n": "^5.26.2", "typescript": "^5.9.3" }, "devDependencies": { - "@babel/core": "^7.28.5", + "@babel/core": "^7.28.6", "@eslint/js": "^9.39.2", "@preact/compat": "^18.3.1", - "@preact/preset-vite": "^2.10.2", + "@preact/preset-vite": "^2.10.3", "@trivago/prettier-plugin-sort-imports": "^6.0.2", - "@types/node": "^25.0.6", - "@types/react": "^19.2.8", + "@types/node": "^25.1.0", + "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "axe-core": "^4.11.1", "concurrently": "^9.2.1", "eslint": "^9.39.2", "eslint-config-prettier": "^10.1.8", - "prettier": "^3.7.4", + "prettier": "^3.8.1", "rollup-plugin-visualizer": "^6.0.5", - "terser": "^5.44.1", - "typescript-eslint": "^8.52.0", + "terser": "^5.46.0", + "typescript-eslint": "^8.54.0", "vite": "^7.3.1", "vite-plugin-imagemin": "^0.6.1", - "vite-tsconfig-paths": "^6.0.4" + "vite-tsconfig-paths": "^6.0.5" }, - "packageManager": "pnpm@10.28.0+sha512.05df71d1421f21399e053fde567cea34d446fa02c76571441bfc1c7956e98e363088982d940465fd34480d4d90a0668bc12362f8aa88000a64e83d0b0e47be48" + "packageManager": "pnpm@10.28.2+sha512.41872f037ad22f7348e3b1debbaf7e867cfd448f2726d9cf74c08f19507c31d2c8e7a11525b983febc2df640b5438dee6023ebb1f84ed43cc2d654d2bc326264" } diff --git a/interface/pnpm-lock.yaml b/interface/pnpm-lock.yaml index a46d81557..6ce810d9f 100644 --- a/interface/pnpm-lock.yaml +++ b/interface/pnpm-lock.yaml @@ -10,28 +10,28 @@ importers: dependencies: '@alova/adapter-xhr': specifier: 2.3.1 - version: 2.3.1(alova@3.4.1) + version: 2.3.1(alova@3.5.0) '@emotion/react': specifier: ^11.14.0 - version: 11.14.0(@types/react@19.2.8)(react@19.2.3) + version: 11.14.0(@types/react@19.2.10)(react@19.2.4) '@emotion/styled': specifier: ^11.14.1 - version: 11.14.1(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@types/react@19.2.8)(react@19.2.3) + version: 11.14.1(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@types/react@19.2.10)(react@19.2.4) '@mui/icons-material': specifier: ^7.3.7 - version: 7.3.7(@mui/material@7.3.7(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@types/react@19.2.8)(react@19.2.3))(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@types/react@19.2.8)(react@19.2.3) + version: 7.3.7(@mui/material@7.3.7(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@types/react@19.2.10)(react@19.2.4))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(@types/react@19.2.10)(react@19.2.4) '@mui/material': specifier: ^7.3.7 - version: 7.3.7(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@types/react@19.2.8)(react@19.2.3))(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 7.3.7(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@types/react@19.2.10)(react@19.2.4))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@preact/compat': specifier: ^18.3.1 version: 18.3.1(preact@10.28.2) '@table-library/react-table-library': specifier: 4.1.15 - version: 4.1.15(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 4.1.15(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) alova: - specifier: 3.4.1 - version: 3.4.1 + specifier: 3.5.0 + version: 3.5.0 async-validator: specifier: ^4.2.5 version: 4.2.5 @@ -54,20 +54,20 @@ importers: specifier: ^10.28.2 version: 10.28.2 react: - specifier: ^19.2.3 - version: 19.2.3 + specifier: ^19.2.4 + version: 19.2.4 react-dom: - specifier: ^19.2.3 - version: 19.2.3(react@19.2.3) + specifier: ^19.2.4 + version: 19.2.4(react@19.2.4) react-icons: specifier: ^5.5.0 - version: 5.5.0(react@19.2.3) + version: 5.5.0(react@19.2.4) react-router: - specifier: ^7.12.0 - version: 7.12.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^7.13.0 + version: 7.13.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react-toastify: specifier: ^11.0.5 - version: 11.0.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 11.0.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) typesafe-i18n: specifier: ^5.26.2 version: 5.26.2(typescript@5.9.3) @@ -76,26 +76,26 @@ importers: version: 5.9.3 devDependencies: '@babel/core': - specifier: ^7.28.5 - version: 7.28.5 + specifier: ^7.28.6 + version: 7.28.6 '@eslint/js': specifier: ^9.39.2 version: 9.39.2 '@preact/preset-vite': - specifier: ^2.10.2 - version: 2.10.2(@babel/core@7.28.5)(preact@10.28.2)(vite@7.3.1(@types/node@25.0.6)(terser@5.44.1)) + specifier: ^2.10.3 + version: 2.10.3(@babel/core@7.28.6)(preact@10.28.2)(rollup@4.57.0)(vite@7.3.1(@types/node@25.1.0)(terser@5.46.0)) '@trivago/prettier-plugin-sort-imports': specifier: ^6.0.2 - version: 6.0.2(prettier@3.7.4) + version: 6.0.2(prettier@3.8.1) '@types/node': - specifier: ^25.0.6 - version: 25.0.6 + specifier: ^25.1.0 + version: 25.1.0 '@types/react': - specifier: ^19.2.8 - version: 19.2.8 + specifier: ^19.2.10 + version: 19.2.10 '@types/react-dom': specifier: ^19.2.3 - version: 19.2.3(@types/react@19.2.8) + version: 19.2.3(@types/react@19.2.10) axe-core: specifier: ^4.11.1 version: 4.11.1 @@ -109,26 +109,26 @@ importers: specifier: ^10.1.8 version: 10.1.8(eslint@9.39.2) prettier: - specifier: ^3.7.4 - version: 3.7.4 + specifier: ^3.8.1 + version: 3.8.1 rollup-plugin-visualizer: specifier: ^6.0.5 - version: 6.0.5(rollup@4.55.1) + version: 6.0.5(rollup@4.57.0) terser: - specifier: ^5.44.1 - version: 5.44.1 + specifier: ^5.46.0 + version: 5.46.0 typescript-eslint: - specifier: ^8.52.0 - version: 8.52.0(eslint@9.39.2)(typescript@5.9.3) + specifier: ^8.54.0 + version: 8.54.0(eslint@9.39.2)(typescript@5.9.3) vite: specifier: ^7.3.1 - version: 7.3.1(@types/node@25.0.6)(terser@5.44.1) + version: 7.3.1(@types/node@25.1.0)(terser@5.46.0) vite-plugin-imagemin: specifier: ^0.6.1 - version: 0.6.1(vite@7.3.1(@types/node@25.0.6)(terser@5.44.1)) + version: 0.6.1(vite@7.3.1(@types/node@25.1.0)(terser@5.46.0)) vite-tsconfig-paths: - specifier: ^6.0.4 - version: 6.0.4(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.6)(terser@5.44.1)) + specifier: ^6.0.5 + version: 6.0.5(typescript@5.9.3)(vite@7.3.1(@types/node@25.1.0)(terser@5.46.0)) packages: @@ -140,46 +140,46 @@ packages: '@alova/shared@1.3.2': resolution: {integrity: sha512-1XvDLWgYpVZ99MmLl1f3Fw4T6S6pPYk5afz5cwRVjuq8JXEGsDn9IygDKfvRyWqkqCBx7Jif07LIct1O+MVEow==} - '@babel/code-frame@7.27.1': - resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + '@babel/code-frame@7.28.6': + resolution: {integrity: sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.28.5': - resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} + '@babel/compat-data@7.28.6': + resolution: {integrity: sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==} engines: {node: '>=6.9.0'} - '@babel/core@7.28.5': - resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} + '@babel/core@7.28.6': + resolution: {integrity: sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==} engines: {node: '>=6.9.0'} - '@babel/generator@7.28.5': - resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} + '@babel/generator@7.28.6': + resolution: {integrity: sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==} engines: {node: '>=6.9.0'} '@babel/helper-annotate-as-pure@7.27.3': resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.27.2': - resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} engines: {node: '>=6.9.0'} '@babel/helper-globals@7.28.0': resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.27.1': - resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.28.3': - resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-plugin-utils@7.27.1': - resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} engines: {node: '>=6.9.0'} '@babel/helper-string-parser@7.27.1': @@ -194,17 +194,17 @@ packages: resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.28.4': - resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} + '@babel/helpers@7.28.6': + resolution: {integrity: sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.28.5': - resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + '@babel/parser@7.28.6': + resolution: {integrity: sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-syntax-jsx@7.27.1': - resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} + '@babel/plugin-syntax-jsx@7.28.6': + resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -215,26 +215,26 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx@7.27.1': - resolution: {integrity: sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==} + '@babel/plugin-transform-react-jsx@7.28.6': + resolution: {integrity: sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/runtime@7.28.4': - resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} + '@babel/runtime@7.28.6': + resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} engines: {node: '>=6.9.0'} - '@babel/template@7.27.2': - resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.28.5': - resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} + '@babel/traverse@7.28.6': + resolution: {integrity: sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.5': - resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + '@babel/types@7.28.6': + resolution: {integrity: sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==} engines: {node: '>=6.9.0'} '@emotion/babel-plugin@11.13.5': @@ -652,8 +652,8 @@ packages: peerDependencies: preact: '*' - '@preact/preset-vite@2.10.2': - resolution: {integrity: sha512-K9wHlJOtkE+cGqlyQ5v9kL3Ge0Ql4LlIZjkUTL+1zf3nNdF88F9UZN6VTV8jdzBX9Fl7WSzeNMSDG7qECPmSmg==} + '@preact/preset-vite@2.10.3': + resolution: {integrity: sha512-1SiS+vFItpkNdBs7q585PSAIln0wBeBdcpJYbzPs1qipsb/FssnkUioNXuRsb8ZnU8YEQHr+3v8+/mzWSnTQmg==} peerDependencies: '@babel/core': 7.x vite: 2.x || 3.x || 4.x || 5.x || 6.x || 7.x @@ -679,128 +679,150 @@ packages: resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} engines: {node: '>= 8.0.0'} - '@rollup/rollup-android-arm-eabi@4.55.1': - resolution: {integrity: sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==} + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} + 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.57.0': + resolution: {integrity: sha512-tPgXB6cDTndIe1ah7u6amCI1T0SsnlOuKgg10Xh3uizJk4e5M1JGaUMk7J4ciuAUcFpbOiNhm2XIjP9ON0dUqA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.55.1': - resolution: {integrity: sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==} + '@rollup/rollup-android-arm64@4.57.0': + resolution: {integrity: sha512-sa4LyseLLXr1onr97StkU1Nb7fWcg6niokTwEVNOO7awaKaoRObQ54+V/hrF/BP1noMEaaAW6Fg2d/CfLiq3Mg==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.55.1': - resolution: {integrity: sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==} + '@rollup/rollup-darwin-arm64@4.57.0': + resolution: {integrity: sha512-/NNIj9A7yLjKdmkx5dC2XQ9DmjIECpGpwHoGmA5E1AhU0fuICSqSWScPhN1yLCkEdkCwJIDu2xIeLPs60MNIVg==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.55.1': - resolution: {integrity: sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==} + '@rollup/rollup-darwin-x64@4.57.0': + resolution: {integrity: sha512-xoh8abqgPrPYPr7pTYipqnUi1V3em56JzE/HgDgitTqZBZ3yKCWI+7KUkceM6tNweyUKYru1UMi7FC060RyKwA==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.55.1': - resolution: {integrity: sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==} + '@rollup/rollup-freebsd-arm64@4.57.0': + resolution: {integrity: sha512-PCkMh7fNahWSbA0OTUQ2OpYHpjZZr0hPr8lId8twD7a7SeWrvT3xJVyza+dQwXSSq4yEQTMoXgNOfMCsn8584g==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.55.1': - resolution: {integrity: sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==} + '@rollup/rollup-freebsd-x64@4.57.0': + resolution: {integrity: sha512-1j3stGx+qbhXql4OCDZhnK7b01s6rBKNybfsX+TNrEe9JNq4DLi1yGiR1xW+nL+FNVvI4D02PUnl6gJ/2y6WJA==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.55.1': - resolution: {integrity: sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==} + '@rollup/rollup-linux-arm-gnueabihf@4.57.0': + resolution: {integrity: sha512-eyrr5W08Ms9uM0mLcKfM/Uzx7hjhz2bcjv8P2uynfj0yU8GGPdz8iYrBPhiLOZqahoAMB8ZiolRZPbbU2MAi6Q==} cpu: [arm] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.55.1': - resolution: {integrity: sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==} + '@rollup/rollup-linux-arm-musleabihf@4.57.0': + resolution: {integrity: sha512-Xds90ITXJCNyX9pDhqf85MKWUI4lqjiPAipJ8OLp8xqI2Ehk+TCVhF9rvOoN8xTbcafow3QOThkNnrM33uCFQA==} cpu: [arm] os: [linux] + libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.55.1': - resolution: {integrity: sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==} + '@rollup/rollup-linux-arm64-gnu@4.57.0': + resolution: {integrity: sha512-Xws2KA4CLvZmXjy46SQaXSejuKPhwVdaNinldoYfqruZBaJHqVo6hnRa8SDo9z7PBW5x84SH64+izmldCgbezw==} cpu: [arm64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.55.1': - resolution: {integrity: sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==} + '@rollup/rollup-linux-arm64-musl@4.57.0': + resolution: {integrity: sha512-hrKXKbX5FdaRJj7lTMusmvKbhMJSGWJ+w++4KmjiDhpTgNlhYobMvKfDoIWecy4O60K6yA4SnztGuNTQF+Lplw==} cpu: [arm64] os: [linux] + libc: [musl] - '@rollup/rollup-linux-loong64-gnu@4.55.1': - resolution: {integrity: sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==} + '@rollup/rollup-linux-loong64-gnu@4.57.0': + resolution: {integrity: sha512-6A+nccfSDGKsPm00d3xKcrsBcbqzCTAukjwWK6rbuAnB2bHaL3r9720HBVZ/no7+FhZLz/U3GwwZZEh6tOSI8Q==} cpu: [loong64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-loong64-musl@4.55.1': - resolution: {integrity: sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==} + '@rollup/rollup-linux-loong64-musl@4.57.0': + resolution: {integrity: sha512-4P1VyYUe6XAJtQH1Hh99THxr0GKMMwIXsRNOceLrJnaHTDgk1FTcTimDgneRJPvB3LqDQxUmroBclQ1S0cIJwQ==} cpu: [loong64] os: [linux] + libc: [musl] - '@rollup/rollup-linux-ppc64-gnu@4.55.1': - resolution: {integrity: sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==} + '@rollup/rollup-linux-ppc64-gnu@4.57.0': + resolution: {integrity: sha512-8Vv6pLuIZCMcgXre6c3nOPhE0gjz1+nZP6T+hwWjr7sVH8k0jRkH+XnfjjOTglyMBdSKBPPz54/y1gToSKwrSQ==} cpu: [ppc64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-ppc64-musl@4.55.1': - resolution: {integrity: sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==} + '@rollup/rollup-linux-ppc64-musl@4.57.0': + resolution: {integrity: sha512-r1te1M0Sm2TBVD/RxBPC6RZVwNqUTwJTA7w+C/IW5v9Ssu6xmxWEi+iJQlpBhtUiT1raJ5b48pI8tBvEjEFnFA==} cpu: [ppc64] os: [linux] + libc: [musl] - '@rollup/rollup-linux-riscv64-gnu@4.55.1': - resolution: {integrity: sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==} + '@rollup/rollup-linux-riscv64-gnu@4.57.0': + resolution: {integrity: sha512-say0uMU/RaPm3CDQLxUUTF2oNWL8ysvHkAjcCzV2znxBr23kFfaxocS9qJm+NdkRhF8wtdEEAJuYcLPhSPbjuQ==} cpu: [riscv64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.55.1': - resolution: {integrity: sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==} + '@rollup/rollup-linux-riscv64-musl@4.57.0': + resolution: {integrity: sha512-/MU7/HizQGsnBREtRpcSbSV1zfkoxSTR7wLsRmBPQ8FwUj5sykrP1MyJTvsxP5KBq9SyE6kH8UQQQwa0ASeoQQ==} cpu: [riscv64] os: [linux] + libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.55.1': - resolution: {integrity: sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==} + '@rollup/rollup-linux-s390x-gnu@4.57.0': + resolution: {integrity: sha512-Q9eh+gUGILIHEaJf66aF6a414jQbDnn29zeu0eX3dHMuysnhTvsUvZTCAyZ6tJhUjnvzBKE4FtuaYxutxRZpOg==} cpu: [s390x] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.55.1': - resolution: {integrity: sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==} + '@rollup/rollup-linux-x64-gnu@4.57.0': + resolution: {integrity: sha512-OR5p5yG5OKSxHReWmwvM0P+VTPMwoBS45PXTMYaskKQqybkS3Kmugq1W+YbNWArF8/s7jQScgzXUhArzEQ7x0A==} cpu: [x64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.55.1': - resolution: {integrity: sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==} + '@rollup/rollup-linux-x64-musl@4.57.0': + resolution: {integrity: sha512-XeatKzo4lHDsVEbm1XDHZlhYZZSQYym6dg2X/Ko0kSFgio+KXLsxwJQprnR48GvdIKDOpqWqssC3iBCjoMcMpw==} cpu: [x64] os: [linux] + libc: [musl] - '@rollup/rollup-openbsd-x64@4.55.1': - resolution: {integrity: sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==} + '@rollup/rollup-openbsd-x64@4.57.0': + resolution: {integrity: sha512-Lu71y78F5qOfYmubYLHPcJm74GZLU6UJ4THkf/a1K7Tz2ycwC2VUbsqbJAXaR6Bx70SRdlVrt2+n5l7F0agTUw==} cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.55.1': - resolution: {integrity: sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==} + '@rollup/rollup-openharmony-arm64@4.57.0': + resolution: {integrity: sha512-v5xwKDWcu7qhAEcsUubiav7r+48Uk/ENWdr82MBZZRIm7zThSxCIVDfb3ZeRRq9yqk+oIzMdDo6fCcA5DHfMyA==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.55.1': - resolution: {integrity: sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==} + '@rollup/rollup-win32-arm64-msvc@4.57.0': + resolution: {integrity: sha512-XnaaaSMGSI6Wk8F4KK3QP7GfuuhjGchElsVerCplUuxRIzdvZ7hRBpLR0omCmw+kI2RFJB80nenhOoGXlJ5TfQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.55.1': - resolution: {integrity: sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==} + '@rollup/rollup-win32-ia32-msvc@4.57.0': + resolution: {integrity: sha512-3K1lP+3BXY4t4VihLw5MEg6IZD3ojSYzqzBG571W3kNQe4G4CcFpSUQVgurYgib5d+YaCjeFow8QivWp8vuSvA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.55.1': - resolution: {integrity: sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==} + '@rollup/rollup-win32-x64-gnu@4.57.0': + resolution: {integrity: sha512-MDk610P/vJGc5L5ImE4k5s+GZT3en0KoK1MKPXCRgzmksAMk79j4h3k1IerxTNqwDLxsGxStEZVBqG0gIqZqoA==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.55.1': - resolution: {integrity: sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==} + '@rollup/rollup-win32-x64-msvc@4.57.0': + resolution: {integrity: sha512-Zv7v6q6aV+VslnpwzqKAmrk5JdVkLUzok2208ZXGipjb+msxBr/fJPZyeEXiFgH7k62Ak0SLIfxQRZQvTuf7rQ==} cpu: [x64] os: [win32] @@ -875,8 +897,8 @@ packages: resolution: {integrity: sha512-zmPitbQ8+6zNutpwgcQuLcsEpn/Cj54Kbn7L5pX0Os5kdWplB7xPgEh/g+SWOB/qmows2gpuCaPyduq8ZZRnxA==} deprecated: This is a stub types definition. minimatch provides its own type definitions, so you do not need this installed. - '@types/node@25.0.6': - resolution: {integrity: sha512-NNu0sjyNxpoiW3YuVFfNz7mxSQ+S4X2G28uqg2s+CzoqoQjLPsWSbsFFyztIAqt2vb8kfEAsJNepMGPTxFDx3Q==} + '@types/node@25.1.0': + resolution: {integrity: sha512-t7frlewr6+cbx+9Ohpl0NOTKXZNV9xHRmNOvql47BFJKcEG1CxtxlPEEe+gR9uhVWM4DwhnvTF110mIL4yP9RA==} '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} @@ -894,8 +916,8 @@ packages: peerDependencies: '@types/react': '*' - '@types/react@19.2.8': - resolution: {integrity: sha512-3MbSL37jEchWZz2p2mjntRZtPt837ij10ApxKfgmXCTuHWagYg7iA5bqPw6C8BMPfwidlvfPI/fxOc42HLhcyg==} + '@types/react@19.2.10': + resolution: {integrity: sha512-WPigyYuGhgZ/cTPRXB2EwUw+XvsRA3GqHlsP4qteqrnnjDrApbS7MxcGr/hke5iUoeB7E/gQtrs9I37zAJ0Vjw==} '@types/responselike@1.0.3': resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} @@ -903,63 +925,63 @@ packages: '@types/svgo@2.6.4': resolution: {integrity: sha512-l4cmyPEckf8moNYHdJ+4wkHvFxjyW6ulm9l4YGaOxeyBWPhBOT0gvni1InpFPdzx1dKf/2s62qGITwxNWnPQng==} - '@typescript-eslint/eslint-plugin@8.52.0': - resolution: {integrity: sha512-okqtOgqu2qmZJ5iN4TWlgfF171dZmx2FzdOv2K/ixL2LZWDStL8+JgQerI2sa8eAEfoydG9+0V96m7V+P8yE1Q==} + '@typescript-eslint/eslint-plugin@8.54.0': + resolution: {integrity: sha512-hAAP5io/7csFStuOmR782YmTthKBJ9ND3WVL60hcOjvtGFb+HJxH4O5huAcmcZ9v9G8P+JETiZ/G1B8MALnWZQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.52.0 + '@typescript-eslint/parser': ^8.54.0 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.52.0': - resolution: {integrity: sha512-iIACsx8pxRnguSYhHiMn2PvhvfpopO9FXHyn1mG5txZIsAaB6F0KwbFnUQN3KCiG3Jcuad/Cao2FAs1Wp7vAyg==} + '@typescript-eslint/parser@8.54.0': + resolution: {integrity: sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.52.0': - resolution: {integrity: sha512-xD0MfdSdEmeFa3OmVqonHi+Cciab96ls1UhIF/qX/O/gPu5KXD0bY9lu33jj04fjzrXHcuvjBcBC+D3SNSadaw==} + '@typescript-eslint/project-service@8.54.0': + resolution: {integrity: sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.52.0': - resolution: {integrity: sha512-ixxqmmCcc1Nf8S0mS0TkJ/3LKcC8mruYJPOU6Ia2F/zUUR4pApW7LzrpU3JmtePbRUTes9bEqRc1Gg4iyRnDzA==} + '@typescript-eslint/scope-manager@8.54.0': + resolution: {integrity: sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.52.0': - resolution: {integrity: sha512-jl+8fzr/SdzdxWJznq5nvoI7qn2tNYV/ZBAEcaFMVXf+K6jmXvAFrgo/+5rxgnL152f//pDEAYAhhBAZGrVfwg==} + '@typescript-eslint/tsconfig-utils@8.54.0': + resolution: {integrity: sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.52.0': - resolution: {integrity: sha512-JD3wKBRWglYRQkAtsyGz1AewDu3mTc7NtRjR/ceTyGoPqmdS5oCdx/oZMWD5Zuqmo6/MpsYs0wp6axNt88/2EQ==} + '@typescript-eslint/type-utils@8.54.0': + resolution: {integrity: sha512-hiLguxJWHjjwL6xMBwD903ciAwd7DmK30Y9Axs/etOkftC3ZNN9K44IuRD/EB08amu+Zw6W37x9RecLkOo3pMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.52.0': - resolution: {integrity: sha512-LWQV1V4q9V4cT4H5JCIx3481iIFxH1UkVk+ZkGGAV1ZGcjGI9IoFOfg3O6ywz8QqCDEp7Inlg6kovMofsNRaGg==} + '@typescript-eslint/types@8.54.0': + resolution: {integrity: sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.52.0': - resolution: {integrity: sha512-XP3LClsCc0FsTK5/frGjolyADTh3QmsLp6nKd476xNI9CsSsLnmn4f0jrzNoAulmxlmNIpeXuHYeEQv61Q6qeQ==} + '@typescript-eslint/typescript-estree@8.54.0': + resolution: {integrity: sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.52.0': - resolution: {integrity: sha512-wYndVMWkweqHpEpwPhwqE2lnD2DxC6WVLupU/DOt/0/v+/+iQbbzO3jOHjmBMnhu0DgLULvOaU4h4pwHYi2oRQ==} + '@typescript-eslint/utils@8.54.0': + resolution: {integrity: sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.52.0': - resolution: {integrity: sha512-ink3/Zofus34nmBsPjow63FP5M7IGff0RKAgqR6+CFpdk22M7aLwC9gOcLGYqr7MczLPzZVERW9hRog3O4n1sQ==} + '@typescript-eslint/visitor-keys@8.54.0': + resolution: {integrity: sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} acorn-jsx@5.3.2: @@ -975,8 +997,8 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - alova@3.4.1: - resolution: {integrity: sha512-xGChKIiCHDqcMglF9RyuWAsk+ltwnja8Dp4MgRIRbUlhOi8XFiQnaoWwIQzJcODKeblmmiFAK7YrYnpskFZWLA==} + alova@3.5.0: + resolution: {integrity: sha512-G3jdC9AQ6QzHKNO7X/J68kcS8rDtwjhruRb2WcxGOi78k5oU+1aGRIiGroqJbVqHQvh1HWgY6IFzyI6PY9J9Eg==} engines: {node: '>= 18.0.0'} ansi-regex@2.1.1: @@ -1042,8 +1064,8 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.9.14: - resolution: {integrity: sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==} + baseline-browser-mapping@2.9.19: + resolution: {integrity: sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==} hasBin: true bin-build@3.0.0: @@ -1132,8 +1154,8 @@ packages: resolution: {integrity: sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==} engines: {node: '>=0.10.0'} - caniuse-lite@1.0.30001764: - resolution: {integrity: sha512-9JGuzl2M+vPL+pz70gtMF9sHdMFbY9FJaQBi186cHKH3pSzDvzoUJUPV6fqiKIMyXbud9ZLg4F3Yza1vJ1+93g==} + caniuse-lite@1.0.30001766: + resolution: {integrity: sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==} caw@2.0.1: resolution: {integrity: sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==} @@ -1352,8 +1374,8 @@ packages: duplexer3@0.1.5: resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==} - electron-to-chromium@1.5.267: - resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} + electron-to-chromium@1.5.279: + resolution: {integrity: sha512-0bblUU5UNdOt5G7XqGiJtpZMONma6WAfq9vsFmtn9x1+joAObr6x1chfqyxFSDCAFwFhCQDrqeAr6MYdpwJ9Hg==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -2134,8 +2156,8 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} - lodash-es@4.17.22: - resolution: {integrity: sha512-XEawp1t0gxSi9x01glktRZ5HDy0HXqrM0x5pXQM98EaI0NxO6jVM7omDOxsuEo5UIASAnm2bRp1Jt/e0a2XU8Q==} + lodash-es@4.17.23: + resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==} lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -2490,8 +2512,8 @@ packages: resolution: {integrity: sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==} engines: {node: '>=4'} - prettier@3.7.4: - resolution: {integrity: sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==} + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} engines: {node: '>=14'} hasBin: true @@ -2524,10 +2546,10 @@ packages: rate-limiter-flexible@5.0.5: resolution: {integrity: sha512-+/dSQfo+3FYwYygUs/V2BBdwGa9nFtakDwKt4l0bnvNB53TNT++QSFewwHX9qXrZJuMe9j+TUaU21lm5ARgqdQ==} - react-dom@19.2.3: - resolution: {integrity: sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==} + react-dom@19.2.4: + resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} peerDependencies: - react: ^19.2.3 + react: ^19.2.4 react-icons@5.5.0: resolution: {integrity: sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==} @@ -2537,11 +2559,11 @@ packages: react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - react-is@19.2.3: - resolution: {integrity: sha512-qJNJfu81ByyabuG7hPFEbXqNcWSU3+eVus+KJs+0ncpGfMyYdvSmxiJxbWR65lYi1I+/0HBcliO029gc4F+PnA==} + react-is@19.2.4: + resolution: {integrity: sha512-W+EWGn2v0ApPKgKKCy/7s7WHXkboGcsrXE+2joLyVxkbyVQfO3MUEaUQDHoSmb8TFFrSKYa9mw64WZHNHSDzYA==} - react-router@7.12.0: - resolution: {integrity: sha512-kTPDYPFzDVGIIGNLS5VJykK0HfHLY5MF3b+xj0/tTyNYL1gF1qs7u67Z9jEhQk2sQ98SUaHxlG31g1JtF7IfVw==} + react-router@7.13.0: + resolution: {integrity: sha512-PZgus8ETambRT17BUm/LL8lX3Of+oiLaPuVTRH3l1eLvSPpKO3AvhAEb5N7ihAFZQrYDqkvvWfFh9p0z9VsjLw==} engines: {node: '>=20.0.0'} peerDependencies: react: '>=18' @@ -2575,8 +2597,8 @@ packages: react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react@19.2.3: - resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} + react@19.2.4: + resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} engines: {node: '>=0.10.0'} read-pkg-up@1.0.1: @@ -2640,8 +2662,8 @@ packages: rollup: optional: true - rollup@4.55.1: - resolution: {integrity: sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==} + rollup@4.57.0: + resolution: {integrity: sha512-e5lPJi/aui4TO1LpAXIRLySmwXSE8k3b9zoGfd42p67wzxog4WHjiZF3M2uheQih4DGyc25QEV4yRBbpueNiUA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -2863,8 +2885,8 @@ packages: resolution: {integrity: sha512-ZOn6nJUgvgC09+doCEF3oB+r3ag7kUvlsXEGX069QRD60p+P3uP7XG9N2/at+EyIRGSN//ZY3LyEotA1YpmjuA==} engines: {node: '>=4'} - terser@5.44.1: - resolution: {integrity: sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==} + terser@5.46.0: + resolution: {integrity: sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==} engines: {node: '>=10'} hasBin: true @@ -2939,8 +2961,8 @@ packages: peerDependencies: typescript: '>=3.5.1' - typescript-eslint@8.52.0: - resolution: {integrity: sha512-atlQQJ2YkO4pfTVQmQ+wvYQwexPDOIgo+RaVcD7gHgzy/IQA+XTyuxNM9M9TVXvttkF7koBHmcwisKdOAf2EcA==} + typescript-eslint@8.54.0: + resolution: {integrity: sha512-CKsJ+g53QpsNPqbzUsfKVgd3Lny4yKZ1pP4qN3jdMOg/sisIDLGyDMezycquXLE5JsEU0wp3dGNdzig0/fmSVQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -3003,13 +3025,10 @@ packages: peerDependencies: vite: 5.x || 6.x || 7.x - vite-tsconfig-paths@6.0.4: - resolution: {integrity: sha512-iIsEJ+ek5KqRTK17pmxtgIxXtqr3qDdE6OxrP9mVeGhVDNXRJTKN/l9oMbujTQNzMLe6XZ8qmpztfbkPu2TiFQ==} + vite-tsconfig-paths@6.0.5: + resolution: {integrity: sha512-f/WvY6ekHykUF1rWJUAbCU7iS/5QYDIugwpqJA+ttwKbxSbzNlqlE8vZSrsnxNQciUW+z6lvhlXMaEyZn9MSig==} peerDependencies: vite: '*' - peerDependenciesMeta: - vite: - optional: true vite@7.3.1: resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} @@ -3051,8 +3070,8 @@ packages: yaml: optional: true - which-typed-array@1.1.19: - resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + which-typed-array@1.1.20: + resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} engines: {node: '>= 0.4'} which@1.3.1: @@ -3110,32 +3129,32 @@ packages: snapshots: - '@alova/adapter-xhr@2.3.1(alova@3.4.1)': + '@alova/adapter-xhr@2.3.1(alova@3.5.0)': dependencies: '@alova/shared': 1.3.2 - alova: 3.4.1 + alova: 3.5.0 '@alova/shared@1.3.2': {} - '@babel/code-frame@7.27.1': + '@babel/code-frame@7.28.6': dependencies: '@babel/helper-validator-identifier': 7.28.5 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.28.5': {} + '@babel/compat-data@7.28.6': {} - '@babel/core@7.28.5': + '@babel/core@7.28.6': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.5 - '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) - '@babel/helpers': 7.28.4 - '@babel/parser': 7.28.5 - '@babel/template': 7.27.2 - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/code-frame': 7.28.6 + '@babel/generator': 7.28.6 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.28.6) + '@babel/helpers': 7.28.6 + '@babel/parser': 7.28.6 + '@babel/template': 7.28.6 + '@babel/traverse': 7.28.6 + '@babel/types': 7.28.6 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 debug: 4.4.3 @@ -3145,21 +3164,21 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.28.5': + '@babel/generator@7.28.6': dependencies: - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/parser': 7.28.6 + '@babel/types': 7.28.6 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 '@babel/helper-annotate-as-pure@7.27.3': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.28.6 - '@babel/helper-compilation-targets@7.27.2': + '@babel/helper-compilation-targets@7.28.6': dependencies: - '@babel/compat-data': 7.28.5 + '@babel/compat-data': 7.28.6 '@babel/helper-validator-option': 7.27.1 browserslist: 4.28.1 lru-cache: 5.1.1 @@ -3167,23 +3186,23 @@ snapshots: '@babel/helper-globals@7.28.0': {} - '@babel/helper-module-imports@7.27.1': + '@babel/helper-module-imports@7.28.6': dependencies: - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/traverse': 7.28.6 + '@babel/types': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': + '@babel/helper-module-transforms@7.28.6(@babel/core@7.28.6)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-imports': 7.27.1 + '@babel/core': 7.28.6 + '@babel/helper-module-imports': 7.28.6 '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/helper-plugin-utils@7.27.1': {} + '@babel/helper-plugin-utils@7.28.6': {} '@babel/helper-string-parser@7.27.1': {} @@ -3191,67 +3210,67 @@ snapshots: '@babel/helper-validator-option@7.27.1': {} - '@babel/helpers@7.28.4': + '@babel/helpers@7.28.6': dependencies: - '@babel/template': 7.27.2 - '@babel/types': 7.28.5 + '@babel/template': 7.28.6 + '@babel/types': 7.28.6 - '@babel/parser@7.28.5': + '@babel/parser@7.28.6': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.28.6 - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.28.6)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.28.6)': dependencies: - '@babel/core': 7.28.5 - '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.5) + '@babel/core': 7.28.6 + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.28.6) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.28.6)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.6 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) - '@babel/types': 7.28.5 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.28.6) + '@babel/types': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/runtime@7.28.4': {} + '@babel/runtime@7.28.6': {} - '@babel/template@7.27.2': + '@babel/template@7.28.6': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/code-frame': 7.28.6 + '@babel/parser': 7.28.6 + '@babel/types': 7.28.6 - '@babel/traverse@7.28.5': + '@babel/traverse@7.28.6': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.5 + '@babel/code-frame': 7.28.6 + '@babel/generator': 7.28.6 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.5 - '@babel/template': 7.27.2 - '@babel/types': 7.28.5 + '@babel/parser': 7.28.6 + '@babel/template': 7.28.6 + '@babel/types': 7.28.6 debug: 4.4.3 transitivePeerDependencies: - supports-color - '@babel/types@7.28.5': + '@babel/types@7.28.6': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 '@emotion/babel-plugin@11.13.5': dependencies: - '@babel/helper-module-imports': 7.27.1 - '@babel/runtime': 7.28.4 + '@babel/helper-module-imports': 7.28.6 + '@babel/runtime': 7.28.6 '@emotion/hash': 0.9.2 '@emotion/memoize': 0.9.0 '@emotion/serialize': 1.3.3 @@ -3280,19 +3299,19 @@ snapshots: '@emotion/memoize@0.9.0': {} - '@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3)': + '@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4)': dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 '@emotion/babel-plugin': 11.13.5 '@emotion/cache': 11.14.0 '@emotion/serialize': 1.3.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.3) + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.4) '@emotion/utils': 1.4.2 '@emotion/weak-memoize': 0.4.0 hoist-non-react-statics: 3.3.2 - react: 19.2.3 + react: 19.2.4 optionalDependencies: - '@types/react': 19.2.8 + '@types/react': 19.2.10 transitivePeerDependencies: - supports-color @@ -3306,26 +3325,26 @@ snapshots: '@emotion/sheet@1.4.0': {} - '@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@types/react@19.2.8)(react@19.2.3)': + '@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@types/react@19.2.10)(react@19.2.4)': dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 '@emotion/babel-plugin': 11.13.5 '@emotion/is-prop-valid': 1.4.0 - '@emotion/react': 11.14.0(@types/react@19.2.8)(react@19.2.3) + '@emotion/react': 11.14.0(@types/react@19.2.10)(react@19.2.4) '@emotion/serialize': 1.3.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.3) + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.4) '@emotion/utils': 1.4.2 - react: 19.2.3 + react: 19.2.4 optionalDependencies: - '@types/react': 19.2.8 + '@types/react': 19.2.10 transitivePeerDependencies: - supports-color '@emotion/unitless@0.10.0': {} - '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.2.3)': + '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.2.4)': dependencies: - react: 19.2.3 + react: 19.2.4 '@emotion/utils@1.4.2': {} @@ -3501,90 +3520,90 @@ snapshots: '@mui/core-downloads-tracker@7.3.7': {} - '@mui/icons-material@7.3.7(@mui/material@7.3.7(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@types/react@19.2.8)(react@19.2.3))(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@types/react@19.2.8)(react@19.2.3)': + '@mui/icons-material@7.3.7(@mui/material@7.3.7(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@types/react@19.2.10)(react@19.2.4))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(@types/react@19.2.10)(react@19.2.4)': dependencies: - '@babel/runtime': 7.28.4 - '@mui/material': 7.3.7(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@types/react@19.2.8)(react@19.2.3))(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react: 19.2.3 + '@babel/runtime': 7.28.6 + '@mui/material': 7.3.7(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@types/react@19.2.10)(react@19.2.4))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 optionalDependencies: - '@types/react': 19.2.8 + '@types/react': 19.2.10 - '@mui/material@7.3.7(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@types/react@19.2.8)(react@19.2.3))(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@mui/material@7.3.7(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@types/react@19.2.10)(react@19.2.4))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 '@mui/core-downloads-tracker': 7.3.7 - '@mui/system': 7.3.7(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@types/react@19.2.8)(react@19.2.3))(@types/react@19.2.8)(react@19.2.3) - '@mui/types': 7.4.10(@types/react@19.2.8) - '@mui/utils': 7.3.7(@types/react@19.2.8)(react@19.2.3) + '@mui/system': 7.3.7(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@types/react@19.2.10)(react@19.2.4))(@types/react@19.2.10)(react@19.2.4) + '@mui/types': 7.4.10(@types/react@19.2.10) + '@mui/utils': 7.3.7(@types/react@19.2.10)(react@19.2.4) '@popperjs/core': 2.11.8 - '@types/react-transition-group': 4.4.12(@types/react@19.2.8) + '@types/react-transition-group': 4.4.12(@types/react@19.2.10) clsx: 2.1.1 csstype: 3.2.3 prop-types: 15.8.1 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - react-is: 19.2.3 - react-transition-group: 4.4.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-is: 19.2.4 + react-transition-group: 4.4.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) optionalDependencies: - '@emotion/react': 11.14.0(@types/react@19.2.8)(react@19.2.3) - '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@types/react@19.2.8)(react@19.2.3) - '@types/react': 19.2.8 + '@emotion/react': 11.14.0(@types/react@19.2.10)(react@19.2.4) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@types/react@19.2.10)(react@19.2.4) + '@types/react': 19.2.10 - '@mui/private-theming@7.3.7(@types/react@19.2.8)(react@19.2.3)': + '@mui/private-theming@7.3.7(@types/react@19.2.10)(react@19.2.4)': dependencies: - '@babel/runtime': 7.28.4 - '@mui/utils': 7.3.7(@types/react@19.2.8)(react@19.2.3) + '@babel/runtime': 7.28.6 + '@mui/utils': 7.3.7(@types/react@19.2.10)(react@19.2.4) prop-types: 15.8.1 - react: 19.2.3 + react: 19.2.4 optionalDependencies: - '@types/react': 19.2.8 + '@types/react': 19.2.10 - '@mui/styled-engine@7.3.7(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@types/react@19.2.8)(react@19.2.3))(react@19.2.3)': + '@mui/styled-engine@7.3.7(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@types/react@19.2.10)(react@19.2.4))(react@19.2.4)': dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 '@emotion/cache': 11.14.0 '@emotion/serialize': 1.3.3 '@emotion/sheet': 1.4.0 csstype: 3.2.3 prop-types: 15.8.1 - react: 19.2.3 + react: 19.2.4 optionalDependencies: - '@emotion/react': 11.14.0(@types/react@19.2.8)(react@19.2.3) - '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@types/react@19.2.8)(react@19.2.3) + '@emotion/react': 11.14.0(@types/react@19.2.10)(react@19.2.4) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@types/react@19.2.10)(react@19.2.4) - '@mui/system@7.3.7(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@types/react@19.2.8)(react@19.2.3))(@types/react@19.2.8)(react@19.2.3)': + '@mui/system@7.3.7(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@types/react@19.2.10)(react@19.2.4))(@types/react@19.2.10)(react@19.2.4)': dependencies: - '@babel/runtime': 7.28.4 - '@mui/private-theming': 7.3.7(@types/react@19.2.8)(react@19.2.3) - '@mui/styled-engine': 7.3.7(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@types/react@19.2.8)(react@19.2.3))(react@19.2.3) - '@mui/types': 7.4.10(@types/react@19.2.8) - '@mui/utils': 7.3.7(@types/react@19.2.8)(react@19.2.3) + '@babel/runtime': 7.28.6 + '@mui/private-theming': 7.3.7(@types/react@19.2.10)(react@19.2.4) + '@mui/styled-engine': 7.3.7(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@types/react@19.2.10)(react@19.2.4))(react@19.2.4) + '@mui/types': 7.4.10(@types/react@19.2.10) + '@mui/utils': 7.3.7(@types/react@19.2.10)(react@19.2.4) clsx: 2.1.1 csstype: 3.2.3 prop-types: 15.8.1 - react: 19.2.3 + react: 19.2.4 optionalDependencies: - '@emotion/react': 11.14.0(@types/react@19.2.8)(react@19.2.3) - '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(@types/react@19.2.8)(react@19.2.3) - '@types/react': 19.2.8 + '@emotion/react': 11.14.0(@types/react@19.2.10)(react@19.2.4) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(@types/react@19.2.10)(react@19.2.4) + '@types/react': 19.2.10 - '@mui/types@7.4.10(@types/react@19.2.8)': + '@mui/types@7.4.10(@types/react@19.2.10)': dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 optionalDependencies: - '@types/react': 19.2.8 + '@types/react': 19.2.10 - '@mui/utils@7.3.7(@types/react@19.2.8)(react@19.2.3)': + '@mui/utils@7.3.7(@types/react@19.2.10)(react@19.2.4)': dependencies: - '@babel/runtime': 7.28.4 - '@mui/types': 7.4.10(@types/react@19.2.8) + '@babel/runtime': 7.28.6 + '@mui/types': 7.4.10(@types/react@19.2.10) '@types/prop-types': 15.7.15 clsx: 2.1.1 prop-types: 15.8.1 - react: 19.2.3 - react-is: 19.2.3 + react: 19.2.4 + react-is: 19.2.4 optionalDependencies: - '@types/react': 19.2.8 + '@types/react': 19.2.10 '@noble/hashes@1.8.0': {} @@ -3610,20 +3629,21 @@ snapshots: dependencies: preact: 10.28.2 - '@preact/preset-vite@2.10.2(@babel/core@7.28.5)(preact@10.28.2)(vite@7.3.1(@types/node@25.0.6)(terser@5.44.1))': + '@preact/preset-vite@2.10.3(@babel/core@7.28.6)(preact@10.28.2)(rollup@4.57.0)(vite@7.3.1(@types/node@25.1.0)(terser@5.46.0))': dependencies: - '@babel/core': 7.28.5 - '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.5) - '@prefresh/vite': 2.4.11(preact@10.28.2)(vite@7.3.1(@types/node@25.0.6)(terser@5.44.1)) - '@rollup/pluginutils': 4.2.1 - babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.28.5) + '@babel/core': 7.28.6 + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.28.6) + '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.6) + '@prefresh/vite': 2.4.11(preact@10.28.2)(vite@7.3.1(@types/node@25.1.0)(terser@5.46.0)) + '@rollup/pluginutils': 5.3.0(rollup@4.57.0) + babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.28.6) debug: 4.4.3 picocolors: 1.1.1 - vite: 7.3.1(@types/node@25.0.6)(terser@5.44.1) - vite-prerender-plugin: 0.5.12(vite@7.3.1(@types/node@25.0.6)(terser@5.44.1)) + vite: 7.3.1(@types/node@25.1.0)(terser@5.46.0) + vite-prerender-plugin: 0.5.12(vite@7.3.1(@types/node@25.1.0)(terser@5.46.0)) transitivePeerDependencies: - preact + - rollup - supports-color '@prefresh/babel-plugin@0.5.2': {} @@ -3634,15 +3654,15 @@ snapshots: '@prefresh/utils@1.2.1': {} - '@prefresh/vite@2.4.11(preact@10.28.2)(vite@7.3.1(@types/node@25.0.6)(terser@5.44.1))': + '@prefresh/vite@2.4.11(preact@10.28.2)(vite@7.3.1(@types/node@25.1.0)(terser@5.46.0))': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.6 '@prefresh/babel-plugin': 0.5.2 '@prefresh/core': 1.5.9(preact@10.28.2) '@prefresh/utils': 1.2.1 '@rollup/pluginutils': 4.2.1 preact: 10.28.2 - vite: 7.3.1(@types/node@25.0.6)(terser@5.44.1) + vite: 7.3.1(@types/node@25.1.0)(terser@5.46.0) transitivePeerDependencies: - supports-color @@ -3651,103 +3671,111 @@ snapshots: estree-walker: 2.0.2 picomatch: 2.3.1 - '@rollup/rollup-android-arm-eabi@4.55.1': + '@rollup/pluginutils@5.3.0(rollup@4.57.0)': + dependencies: + '@types/estree': 1.0.8 + estree-walker: 2.0.2 + picomatch: 4.0.3 + optionalDependencies: + rollup: 4.57.0 + + '@rollup/rollup-android-arm-eabi@4.57.0': optional: true - '@rollup/rollup-android-arm64@4.55.1': + '@rollup/rollup-android-arm64@4.57.0': optional: true - '@rollup/rollup-darwin-arm64@4.55.1': + '@rollup/rollup-darwin-arm64@4.57.0': optional: true - '@rollup/rollup-darwin-x64@4.55.1': + '@rollup/rollup-darwin-x64@4.57.0': optional: true - '@rollup/rollup-freebsd-arm64@4.55.1': + '@rollup/rollup-freebsd-arm64@4.57.0': optional: true - '@rollup/rollup-freebsd-x64@4.55.1': + '@rollup/rollup-freebsd-x64@4.57.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.55.1': + '@rollup/rollup-linux-arm-gnueabihf@4.57.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.55.1': + '@rollup/rollup-linux-arm-musleabihf@4.57.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.55.1': + '@rollup/rollup-linux-arm64-gnu@4.57.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.55.1': + '@rollup/rollup-linux-arm64-musl@4.57.0': optional: true - '@rollup/rollup-linux-loong64-gnu@4.55.1': + '@rollup/rollup-linux-loong64-gnu@4.57.0': optional: true - '@rollup/rollup-linux-loong64-musl@4.55.1': + '@rollup/rollup-linux-loong64-musl@4.57.0': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.55.1': + '@rollup/rollup-linux-ppc64-gnu@4.57.0': optional: true - '@rollup/rollup-linux-ppc64-musl@4.55.1': + '@rollup/rollup-linux-ppc64-musl@4.57.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.55.1': + '@rollup/rollup-linux-riscv64-gnu@4.57.0': optional: true - '@rollup/rollup-linux-riscv64-musl@4.55.1': + '@rollup/rollup-linux-riscv64-musl@4.57.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.55.1': + '@rollup/rollup-linux-s390x-gnu@4.57.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.55.1': + '@rollup/rollup-linux-x64-gnu@4.57.0': optional: true - '@rollup/rollup-linux-x64-musl@4.55.1': + '@rollup/rollup-linux-x64-musl@4.57.0': optional: true - '@rollup/rollup-openbsd-x64@4.55.1': + '@rollup/rollup-openbsd-x64@4.57.0': optional: true - '@rollup/rollup-openharmony-arm64@4.55.1': + '@rollup/rollup-openharmony-arm64@4.57.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.55.1': + '@rollup/rollup-win32-arm64-msvc@4.57.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.55.1': + '@rollup/rollup-win32-ia32-msvc@4.57.0': optional: true - '@rollup/rollup-win32-x64-gnu@4.55.1': + '@rollup/rollup-win32-x64-gnu@4.57.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.55.1': + '@rollup/rollup-win32-x64-msvc@4.57.0': optional: true '@sindresorhus/is@0.7.0': {} - '@table-library/react-table-library@4.1.15(@emotion/react@11.14.0(@types/react@19.2.8)(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + '@table-library/react-table-library@4.1.15(@emotion/react@11.14.0(@types/react@19.2.10)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@emotion/react': 11.14.0(@types/react@19.2.8)(react@19.2.3) + '@emotion/react': 11.14.0(@types/react@19.2.10)(react@19.2.4) clsx: 1.1.1 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - react-virtualized-auto-sizer: 1.0.26(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - react-window: 1.8.11(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-virtualized-auto-sizer: 1.0.26(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react-window: 1.8.11(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@trivago/prettier-plugin-sort-imports@6.0.2(prettier@3.7.4)': + '@trivago/prettier-plugin-sort-imports@6.0.2(prettier@3.8.1)': dependencies: - '@babel/generator': 7.28.5 - '@babel/parser': 7.28.5 - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/generator': 7.28.6 + '@babel/parser': 7.28.6 + '@babel/traverse': 7.28.6 + '@babel/types': 7.28.6 javascript-natural-sort: 0.7.1 - lodash-es: 4.17.22 + lodash-es: 4.17.23 minimatch: 9.0.5 parse-imports-exports: 0.2.4 - prettier: 3.7.4 + prettier: 3.8.1 transitivePeerDependencies: - supports-color @@ -3758,7 +3786,7 @@ snapshots: '@types/glob@7.2.0': dependencies: '@types/minimatch': 6.0.0 - '@types/node': 25.0.6 + '@types/node': 25.1.0 '@types/imagemin-gifsicle@7.0.4': dependencies: @@ -3787,19 +3815,19 @@ snapshots: '@types/imagemin@7.0.1': dependencies: - '@types/node': 25.0.6 + '@types/node': 25.1.0 '@types/json-schema@7.0.15': {} '@types/keyv@3.1.4': dependencies: - '@types/node': 25.0.6 + '@types/node': 25.1.0 '@types/minimatch@6.0.0': dependencies: minimatch: 10.1.1 - '@types/node@25.0.6': + '@types/node@25.1.0': dependencies: undici-types: 7.16.0 @@ -3807,34 +3835,34 @@ snapshots: '@types/prop-types@15.7.15': {} - '@types/react-dom@19.2.3(@types/react@19.2.8)': + '@types/react-dom@19.2.3(@types/react@19.2.10)': dependencies: - '@types/react': 19.2.8 + '@types/react': 19.2.10 - '@types/react-transition-group@4.4.12(@types/react@19.2.8)': + '@types/react-transition-group@4.4.12(@types/react@19.2.10)': dependencies: - '@types/react': 19.2.8 + '@types/react': 19.2.10 - '@types/react@19.2.8': + '@types/react@19.2.10': dependencies: csstype: 3.2.3 '@types/responselike@1.0.3': dependencies: - '@types/node': 25.0.6 + '@types/node': 25.1.0 '@types/svgo@2.6.4': dependencies: - '@types/node': 25.0.6 + '@types/node': 25.1.0 - '@typescript-eslint/eslint-plugin@8.52.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.52.0(eslint@9.39.2)(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.52.0 - '@typescript-eslint/type-utils': 8.52.0(eslint@9.39.2)(typescript@5.9.3) - '@typescript-eslint/utils': 8.52.0(eslint@9.39.2)(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.52.0 + '@typescript-eslint/parser': 8.54.0(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/type-utils': 8.54.0(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.54.0 eslint: 9.39.2 ignore: 7.0.5 natural-compare: 1.4.0 @@ -3843,41 +3871,41 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.52.0(eslint@9.39.2)(typescript@5.9.3)': + '@typescript-eslint/parser@8.54.0(eslint@9.39.2)(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.52.0 - '@typescript-eslint/types': 8.52.0 - '@typescript-eslint/typescript-estree': 8.52.0(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.52.0 + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.54.0 debug: 4.4.3 eslint: 9.39.2 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.52.0(typescript@5.9.3)': + '@typescript-eslint/project-service@8.54.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.52.0(typescript@5.9.3) - '@typescript-eslint/types': 8.52.0 + '@typescript-eslint/tsconfig-utils': 8.54.0(typescript@5.9.3) + '@typescript-eslint/types': 8.54.0 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.52.0': + '@typescript-eslint/scope-manager@8.54.0': dependencies: - '@typescript-eslint/types': 8.52.0 - '@typescript-eslint/visitor-keys': 8.52.0 + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/visitor-keys': 8.54.0 - '@typescript-eslint/tsconfig-utils@8.52.0(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.54.0(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.52.0(eslint@9.39.2)(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.54.0(eslint@9.39.2)(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.52.0 - '@typescript-eslint/typescript-estree': 8.52.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.52.0(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2)(typescript@5.9.3) debug: 4.4.3 eslint: 9.39.2 ts-api-utils: 2.4.0(typescript@5.9.3) @@ -3885,14 +3913,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.52.0': {} + '@typescript-eslint/types@8.54.0': {} - '@typescript-eslint/typescript-estree@8.52.0(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.54.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.52.0(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.52.0(typescript@5.9.3) - '@typescript-eslint/types': 8.52.0 - '@typescript-eslint/visitor-keys': 8.52.0 + '@typescript-eslint/project-service': 8.54.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.54.0(typescript@5.9.3) + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/visitor-keys': 8.54.0 debug: 4.4.3 minimatch: 9.0.5 semver: 7.7.3 @@ -3902,20 +3930,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.52.0(eslint@9.39.2)(typescript@5.9.3)': + '@typescript-eslint/utils@8.54.0(eslint@9.39.2)(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2) - '@typescript-eslint/scope-manager': 8.52.0 - '@typescript-eslint/types': 8.52.0 - '@typescript-eslint/typescript-estree': 8.52.0(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) eslint: 9.39.2 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.52.0': + '@typescript-eslint/visitor-keys@8.54.0': dependencies: - '@typescript-eslint/types': 8.52.0 + '@typescript-eslint/types': 8.54.0 eslint-visitor-keys: 4.2.1 acorn-jsx@5.3.2(acorn@8.15.0): @@ -3931,7 +3959,7 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 - alova@3.4.1: + alova@3.5.0: dependencies: '@alova/shared': 1.3.2 rate-limiter-flexible: 5.0.5 @@ -3970,19 +3998,19 @@ snapshots: babel-plugin-macros@3.1.0: dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 cosmiconfig: 7.1.0 resolve: 1.22.11 - babel-plugin-transform-hook-names@1.0.2(@babel/core@7.28.5): + babel-plugin-transform-hook-names@1.0.2(@babel/core@7.28.6): dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.6 balanced-match@1.0.2: {} base64-js@1.5.1: {} - baseline-browser-mapping@2.9.14: {} + baseline-browser-mapping@2.9.19: {} bin-build@3.0.0: dependencies: @@ -4039,9 +4067,9 @@ snapshots: browserslist@4.28.1: dependencies: - baseline-browser-mapping: 2.9.14 - caniuse-lite: 1.0.30001764 - electron-to-chromium: 1.5.267 + baseline-browser-mapping: 2.9.19 + caniuse-lite: 1.0.30001766 + electron-to-chromium: 1.5.279 node-releases: 2.0.27 update-browserslist-db: 1.2.3(browserslist@4.28.1) @@ -4099,7 +4127,7 @@ snapshots: camelcase@2.1.1: {} - caniuse-lite@1.0.30001764: {} + caniuse-lite@1.0.30001766: {} caw@2.0.1: dependencies: @@ -4312,7 +4340,7 @@ snapshots: dom-helpers@5.2.1: dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 csstype: 3.2.3 dom-serializer@1.4.1: @@ -4386,7 +4414,7 @@ snapshots: duplexer3@0.1.5: {} - electron-to-chromium@1.5.267: {} + electron-to-chromium@1.5.279: {} emoji-regex@8.0.0: {} @@ -5093,7 +5121,7 @@ snapshots: is-typed-array@1.1.15: dependencies: - which-typed-array: 1.1.19 + which-typed-array: 1.1.20 is-utf8@0.2.1: {} @@ -5184,7 +5212,7 @@ snapshots: dependencies: p-locate: 5.0.0 - lodash-es@4.17.22: {} + lodash-es@4.17.23: {} lodash.merge@4.6.2: {} @@ -5432,7 +5460,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.27.1 + '@babel/code-frame': 7.28.6 error-ex: 1.3.4 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -5505,7 +5533,7 @@ snapshots: prepend-http@2.0.0: {} - prettier@3.7.4: {} + prettier@3.8.1: {} process-nextick-args@2.0.1: {} @@ -5536,55 +5564,55 @@ snapshots: rate-limiter-flexible@5.0.5: {} - react-dom@19.2.3(react@19.2.3): + react-dom@19.2.4(react@19.2.4): dependencies: - react: 19.2.3 + react: 19.2.4 scheduler: 0.27.0 - react-icons@5.5.0(react@19.2.3): + react-icons@5.5.0(react@19.2.4): dependencies: - react: 19.2.3 + react: 19.2.4 react-is@16.13.1: {} - react-is@19.2.3: {} + react-is@19.2.4: {} - react-router@7.12.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + react-router@7.13.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: cookie: 1.1.1 - react: 19.2.3 + react: 19.2.4 set-cookie-parser: 2.7.2 optionalDependencies: - react-dom: 19.2.3(react@19.2.3) + react-dom: 19.2.4(react@19.2.4) - react-toastify@11.0.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + react-toastify@11.0.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: clsx: 2.1.1 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) - react-transition-group@4.4.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + react-transition-group@4.4.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) - react-virtualized-auto-sizer@1.0.26(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + react-virtualized-auto-sizer@1.0.26(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) - react-window@1.8.11(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + react-window@1.8.11(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 memoize-one: 5.2.1 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) - react@19.2.3: {} + react@19.2.4: {} read-pkg-up@1.0.1: dependencies: @@ -5638,44 +5666,44 @@ snapshots: dependencies: glob: 7.2.3 - rollup-plugin-visualizer@6.0.5(rollup@4.55.1): + rollup-plugin-visualizer@6.0.5(rollup@4.57.0): dependencies: open: 8.4.2 picomatch: 4.0.3 source-map: 0.7.6 yargs: 17.7.2 optionalDependencies: - rollup: 4.55.1 + rollup: 4.57.0 - rollup@4.55.1: + rollup@4.57.0: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.55.1 - '@rollup/rollup-android-arm64': 4.55.1 - '@rollup/rollup-darwin-arm64': 4.55.1 - '@rollup/rollup-darwin-x64': 4.55.1 - '@rollup/rollup-freebsd-arm64': 4.55.1 - '@rollup/rollup-freebsd-x64': 4.55.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.55.1 - '@rollup/rollup-linux-arm-musleabihf': 4.55.1 - '@rollup/rollup-linux-arm64-gnu': 4.55.1 - '@rollup/rollup-linux-arm64-musl': 4.55.1 - '@rollup/rollup-linux-loong64-gnu': 4.55.1 - '@rollup/rollup-linux-loong64-musl': 4.55.1 - '@rollup/rollup-linux-ppc64-gnu': 4.55.1 - '@rollup/rollup-linux-ppc64-musl': 4.55.1 - '@rollup/rollup-linux-riscv64-gnu': 4.55.1 - '@rollup/rollup-linux-riscv64-musl': 4.55.1 - '@rollup/rollup-linux-s390x-gnu': 4.55.1 - '@rollup/rollup-linux-x64-gnu': 4.55.1 - '@rollup/rollup-linux-x64-musl': 4.55.1 - '@rollup/rollup-openbsd-x64': 4.55.1 - '@rollup/rollup-openharmony-arm64': 4.55.1 - '@rollup/rollup-win32-arm64-msvc': 4.55.1 - '@rollup/rollup-win32-ia32-msvc': 4.55.1 - '@rollup/rollup-win32-x64-gnu': 4.55.1 - '@rollup/rollup-win32-x64-msvc': 4.55.1 + '@rollup/rollup-android-arm-eabi': 4.57.0 + '@rollup/rollup-android-arm64': 4.57.0 + '@rollup/rollup-darwin-arm64': 4.57.0 + '@rollup/rollup-darwin-x64': 4.57.0 + '@rollup/rollup-freebsd-arm64': 4.57.0 + '@rollup/rollup-freebsd-x64': 4.57.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.57.0 + '@rollup/rollup-linux-arm-musleabihf': 4.57.0 + '@rollup/rollup-linux-arm64-gnu': 4.57.0 + '@rollup/rollup-linux-arm64-musl': 4.57.0 + '@rollup/rollup-linux-loong64-gnu': 4.57.0 + '@rollup/rollup-linux-loong64-musl': 4.57.0 + '@rollup/rollup-linux-ppc64-gnu': 4.57.0 + '@rollup/rollup-linux-ppc64-musl': 4.57.0 + '@rollup/rollup-linux-riscv64-gnu': 4.57.0 + '@rollup/rollup-linux-riscv64-musl': 4.57.0 + '@rollup/rollup-linux-s390x-gnu': 4.57.0 + '@rollup/rollup-linux-x64-gnu': 4.57.0 + '@rollup/rollup-linux-x64-musl': 4.57.0 + '@rollup/rollup-openbsd-x64': 4.57.0 + '@rollup/rollup-openharmony-arm64': 4.57.0 + '@rollup/rollup-win32-arm64-msvc': 4.57.0 + '@rollup/rollup-win32-ia32-msvc': 4.57.0 + '@rollup/rollup-win32-x64-gnu': 4.57.0 + '@rollup/rollup-win32-x64-msvc': 4.57.0 fsevents: 2.3.3 run-parallel@1.2.0: @@ -5875,7 +5903,7 @@ snapshots: temp-dir: 1.0.0 uuid: 3.4.0 - terser@5.44.1: + terser@5.46.0: dependencies: '@jridgewell/source-map': 0.3.11 acorn: 8.15.0 @@ -5939,12 +5967,12 @@ snapshots: dependencies: typescript: 5.9.3 - typescript-eslint@8.52.0(eslint@9.39.2)(typescript@5.9.3): + typescript-eslint@8.54.0(eslint@9.39.2)(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.52.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3) - '@typescript-eslint/parser': 8.52.0(eslint@9.39.2)(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.52.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.52.0(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/parser': 8.54.0(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2)(typescript@5.9.3) eslint: 9.39.2 typescript: 5.9.3 transitivePeerDependencies: @@ -5990,7 +6018,7 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - vite-plugin-imagemin@0.6.1(vite@7.3.1(@types/node@25.0.6)(terser@5.44.1)): + vite-plugin-imagemin@0.6.1(vite@7.3.1(@types/node@25.1.0)(terser@5.46.0)): dependencies: '@types/imagemin': 7.0.1 '@types/imagemin-gifsicle': 7.0.4 @@ -6015,11 +6043,11 @@ snapshots: imagemin-webp: 6.1.0 jpegtran-bin: 6.0.1 pathe: 0.2.0 - vite: 7.3.1(@types/node@25.0.6)(terser@5.44.1) + vite: 7.3.1(@types/node@25.1.0)(terser@5.46.0) transitivePeerDependencies: - supports-color - vite-prerender-plugin@0.5.12(vite@7.3.1(@types/node@25.0.6)(terser@5.44.1)): + vite-prerender-plugin@0.5.12(vite@7.3.1(@types/node@25.1.0)(terser@5.46.0)): dependencies: kolorist: 1.8.0 magic-string: 0.30.21 @@ -6027,33 +6055,32 @@ snapshots: simple-code-frame: 1.3.0 source-map: 0.7.6 stack-trace: 1.0.0-pre2 - vite: 7.3.1(@types/node@25.0.6)(terser@5.44.1) + vite: 7.3.1(@types/node@25.1.0)(terser@5.46.0) - vite-tsconfig-paths@6.0.4(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.6)(terser@5.44.1)): + vite-tsconfig-paths@6.0.5(typescript@5.9.3)(vite@7.3.1(@types/node@25.1.0)(terser@5.46.0)): dependencies: debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.9.3) - optionalDependencies: - vite: 7.3.1(@types/node@25.0.6)(terser@5.44.1) + vite: 7.3.1(@types/node@25.1.0)(terser@5.46.0) transitivePeerDependencies: - supports-color - typescript - vite@7.3.1(@types/node@25.0.6)(terser@5.44.1): + vite@7.3.1(@types/node@25.1.0)(terser@5.46.0): dependencies: esbuild: 0.27.2 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.55.1 + rollup: 4.57.0 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 25.0.6 + '@types/node': 25.1.0 fsevents: 2.3.3 - terser: 5.44.1 + terser: 5.46.0 - which-typed-array@1.1.19: + which-typed-array@1.1.20: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.8 diff --git a/interface/src/app/main/Help.tsx b/interface/src/app/main/Help.tsx index 320b55ba0..e227cb2b2 100644 --- a/interface/src/app/main/Help.tsx +++ b/interface/src/app/main/Help.tsx @@ -120,7 +120,7 @@ const HelpComponent = () => { label: () => LL.HELP_INFORMATION_1() }, { - href: 'https://discord.gg/3J3GgnzpyT', + href: 'https://discord.gg/GP9DPSgeJq', icon: , label: () => LL.HELP_INFORMATION_2() }, diff --git a/lib/uuid-console/src/uuid/console.h b/lib/uuid-console/src/uuid/console.h index e8f54d79e..1730058e9 100644 --- a/lib/uuid-console/src/uuid/console.h +++ b/lib/uuid-console/src/uuid/console.h @@ -34,6 +34,7 @@ #include #include +#include #include #include @@ -1645,22 +1646,22 @@ class Shell : public std::enable_shared_from_this, public uuid::log::Hand uint8_t cursor_ = 0; /*!< cursor position from end of line */ uint8_t esc_ = 0; /*!< esc sequence running */ - Stream & stream_; /*!< Stream used for the input/output of this shell. @since 3.0.0 */ - std::shared_ptr commands_; /*!< Commands available for execution in this shell. @since 0.1.0 */ - std::deque context_; /*!< Context stack for this shell. Affects which commands are available. Should never be empty. @since 0.1.0 */ - unsigned int flags_ = 0; /*!< Current flags for this shell. Affects which commands are available. @since 0.1.0 */ + Stream & stream_; /*!< Stream used for the input/output of this shell. @since 3.0.0 */ + std::shared_ptr commands_; /*!< Commands available for execution in this shell. @since 0.1.0 */ + std::deque> context_; /*!< Context stack for this shell. Affects which commands are available. Should never be empty. @since 0.1.0 */ + unsigned int flags_ = 0; /*!< Current flags for this shell. Affects which commands are available. @since 0.1.0 */ #if UUID_CONSOLE_THREAD_SAFE mutable std::mutex mutex_; /*!< Mutex for queued log messages. @since 1.0.0 */ #endif - unsigned long log_message_id_ = 0; /*!< The next identifier to use for queued log messages. @since 0.1.0 */ - std::list log_messages_; /*!< Queued log messages, in the order they were received. @since 0.1.0 */ - size_t maximum_log_messages_ = MAX_LOG_MESSAGES; /*!< Maximum command line length in bytes. @since 0.6.0 */ - std::string line_buffer_; /*!< Command line buffer. Limited to maximum_command_line_length() bytes. @since 0.1.0 */ - size_t maximum_command_line_length_ = MAX_COMMAND_LINE_LENGTH; /*!< Maximum command line length in bytes. @since 0.6.0 */ - unsigned char previous_ = 0; /*!< Previous character that was entered on the command line. Used to detect CRLF line endings. @since 0.1.0 */ - Mode mode_ = Mode::NORMAL; /*!< Current execution mode. @since 0.1.0 */ - std::unique_ptr mode_data_ = nullptr; /*!< Data associated with the current execution mode. @since 0.1.0 */ - bool stopped_ = false; /*!< Indicates that the shell has been stopped. @since 0.1.0 */ + unsigned long log_message_id_ = 0; /*!< The next identifier to use for queued log messages. @since 0.1.0 */ + std::list> log_messages_; /*!< Queued log messages, in the order they were received. @since 0.1.0 */ + size_t maximum_log_messages_ = MAX_LOG_MESSAGES; /*!< Maximum command line length in bytes. @since 0.6.0 */ + std::string line_buffer_; /*!< Command line buffer. Limited to maximum_command_line_length() bytes. @since 0.1.0 */ + size_t maximum_command_line_length_ = MAX_COMMAND_LINE_LENGTH; /*!< Maximum command line length in bytes. @since 0.6.0 */ + unsigned char previous_ = 0; /*!< Previous character that was entered on the command line. Used to detect CRLF line endings. @since 0.1.0 */ + Mode mode_ = Mode::NORMAL; /*!< Current execution mode. @since 0.1.0 */ + std::unique_ptr mode_data_ = nullptr; /*!< Data associated with the current execution mode. @since 0.1.0 */ + bool stopped_ = false; /*!< Indicates that the shell has been stopped. @since 0.1.0 */ bool prompt_displayed_ = false; /*!< Indicates that a command prompt has been displayed, so that the output of invoke_command() is correct. @since 0.1.0 */ uint64_t idle_time_ = 0; /*!< Time the shell became idle. @since 0.7.0 */ uint64_t idle_timeout_ = 0; /*!< Idle timeout (in milliseconds). @since 0.7.0 */ @@ -1786,7 +1787,7 @@ class CommandLine { * @return A reference to the parameters. * @since 0.6.0 */ - inline std::vector & operator*() { + inline std::vector> & operator*() { return parameters_; } /** @@ -1795,7 +1796,7 @@ class CommandLine { * @return A reference to the parameters. * @since 0.6.0 */ - inline const std::vector & operator*() const { + inline const std::vector> & operator*() const { return parameters_; } /** @@ -1804,7 +1805,7 @@ class CommandLine { * @return A pointer to the parameters. * @since 0.4.0 */ - inline std::vector * operator->() { + inline std::vector> * operator->() { return ¶meters_; } /** @@ -1813,7 +1814,7 @@ class CommandLine { * @return A pointer to the parameters. * @since 0.4.0 */ - inline const std::vector * operator->() const { + inline const std::vector> * operator->() const { return ¶meters_; } @@ -1843,8 +1844,8 @@ class CommandLine { bool trailing_space = false; /*!< Command line has a trailing space. @since 0.4.0 */ private: - std::vector parameters_; /*!< Separate command line parameters. @since 0.4.0 */ - size_t escape_parameters_ = std::numeric_limits::max(); /*!< Number of initial arguments to escape in output. @since 0.5.0 */ + std::vector> parameters_; /*!< Separate command line parameters. @since 0.4.0 */ + size_t escape_parameters_ = std::numeric_limits::max(); /*!< Number of initial arguments to escape in output. @since 0.5.0 */ }; /** diff --git a/lib/uuid-log/src/log.cpp b/lib/uuid-log/src/log.cpp index b10a4ba6a..2515a8b10 100644 --- a/lib/uuid-log/src/log.cpp +++ b/lib/uuid-log/src/log.cpp @@ -232,7 +232,7 @@ void Logger::vlog(Level level, const char * format, va_list ap) const { } void Logger::vlog(Level level, Facility facility, const char * format, va_list ap) const { - std::vector text(MAX_LOG_LENGTH + 1); + std::vector> text(MAX_LOG_LENGTH + 1); if (vsnprintf(text.data(), text.size(), format, ap) <= 0) { return; @@ -241,7 +241,7 @@ void Logger::vlog(Level level, Facility facility, const char * format, va_list a dispatch(level, facility, text); } -void Logger::dispatch(Level level, Facility facility, std::vector & text) const { +void Logger::dispatch(Level level, Facility facility, std::vector> & text) const { std::shared_ptr message = std::make_shared(get_uptime_ms(), level, facility, name_, text.data()); text.resize(0); diff --git a/lib/uuid-log/src/uuid/log.h b/lib/uuid-log/src/uuid/log.h index 66e932a23..beac1b189 100644 --- a/lib/uuid-log/src/uuid/log.h +++ b/lib/uuid-log/src/uuid/log.h @@ -31,6 +31,7 @@ #include #include +#include #include #ifndef UUID_COMMON_THREAD_SAFE @@ -645,7 +646,7 @@ class Logger { * @param[in] text Log message text. * @since 1.0.0 */ - void dispatch(Level level, Facility facility, std::vector & text) const; + void dispatch(Level level, Facility facility, std::vector> & text) const; static std::atomic global_level_; /*!< Minimum global log level across all handlers. @since 3.0.0 */ #if UUID_LOG_THREAD_SAFE @@ -723,7 +724,7 @@ class PrintHandler : public uuid::log::Handler { mutable std::mutex mutex_; /*!< Mutex for configuration, state and queued log messages. @since 2.3.0 */ #endif size_t maximum_log_messages_ = MAX_LOG_MESSAGES; /*!< Maximum number of log messages to buffer before they are output. @since 2.2.0 */ - std::list> log_messages_; /*!< Queued log messages, in the order they were received. @since 2.2.0 */ + std::list, AllocatorPSRAM>> log_messages_; /*!< Queued log messages, in the order they were received. @since 2.2.0 */ }; } // namespace log diff --git a/lib/uuid-syslog/src/uuid/syslog.h b/lib/uuid-syslog/src/uuid/syslog.h index a7f725238..58f91dae4 100644 --- a/lib/uuid-syslog/src/uuid/syslog.h +++ b/lib/uuid-syslog/src/uuid/syslog.h @@ -28,6 +28,7 @@ #include #include +#include #include #ifndef UUID_LOG_THREAD_SAFE @@ -321,7 +322,7 @@ class SyslogService : public uuid::log::Handler { #endif size_t maximum_log_messages_ = MAX_LOG_MESSAGES; /*!< Maximum number of log messages to buffer before they are output. @since 1.0.0 */ unsigned long log_message_id_ = 0; /*!< The next identifier to use for queued log messages. @since 1.0.0 */ - std::list log_messages_; /*!< Queued log messages, in the order they were received. @since 1.0.0 */ + std::list> log_messages_; /*!< Queued log messages, in the order they were received. @since 1.0.0 */ uint64_t mark_interval_ = 0; /*!< Mark interval in milliseconds. @since 2.0.0 */ uint64_t last_message_ = 0; /*!< Last message/mark time. @since 2.0.0 */ diff --git a/lib/uuid-telnet/src/stream.cpp b/lib/uuid-telnet/src/stream.cpp index adf5f16ec..c59b02787 100644 --- a/lib/uuid-telnet/src/stream.cpp +++ b/lib/uuid-telnet/src/stream.cpp @@ -249,7 +249,7 @@ size_t TelnetStream::write(uint8_t data) { } size_t TelnetStream::write(const uint8_t * buffer, size_t size) { - std::vector data; + std::vector> data; data.reserve(size); while (size-- > 0) { @@ -310,7 +310,7 @@ size_t TelnetStream::raw_write(unsigned char data) { return 1; } -size_t TelnetStream::raw_write(const std::vector & data) { +size_t TelnetStream::raw_write(const std::vector> & data) { return raw_write(reinterpret_cast(data.data()), data.size()); } diff --git a/lib/uuid-telnet/src/uuid/telnet.h b/lib/uuid-telnet/src/uuid/telnet.h index fb1245de9..a679859b7 100644 --- a/lib/uuid-telnet/src/uuid/telnet.h +++ b/lib/uuid-telnet/src/uuid/telnet.h @@ -33,6 +33,7 @@ #include #include +#include #include namespace uuid { @@ -203,7 +204,7 @@ class TelnetStream : public ::Stream { * @return The number of bytes that were output. * @since 0.1.0 */ - size_t raw_write(const std::vector & data); + size_t raw_write(const std::vector> & data); /** * Write an array of bytes directly to the output stream. * @@ -222,7 +223,7 @@ class TelnetStream : public ::Stream { unsigned char previous_in_ = 0; /*!< Previous character that was received. Used to detect CR NUL. @since 0.1.0 */ unsigned char previous_out_ = 0; /*!< Previous character that was sent. Used to insert NUL after CR without LF. @since 0.1.0 */ int peek_ = -1; /*!< Previously read data cached by peek(). @since 0.1.0 */ - std::vector output_buffer_; /*!< Buffer data to be output until a read function is called. @since 0.1.0 */ + std::vector> output_buffer_; /*!< Buffer data to be output until a read function is called. @since 0.1.0 */ }; /** @@ -425,7 +426,7 @@ class TelnetService { WiFiServer server_; /*!< TCP server. @since 0.1.0 */ size_t maximum_connections_ = MAX_CONNECTIONS; /*!< Maximum number of concurrent open connections. @since 0.1.0 */ - std::list connections_; /*!< Open connections. @since 0.1.0 */ + std::list> connections_; /*!< Open connections. @since 0.1.0 */ shell_factory_function shell_factory_; /*!< Function to create a shell. @since 0.1.0 */ unsigned long initial_idle_timeout_ = DEFAULT_IDLE_TIMEOUT; /*!< Initial idle timeout (in seconds). @since 0.1.0 */ unsigned long write_timeout_ = DEFAULT_WRITE_TIMEOUT; /*!< Write timeout (in milliseconds). @since 0.1.0 */ diff --git a/lib_standalone/AsyncTCP.h b/lib_standalone/AsyncTCP.h index 58307baab..67d733238 100644 --- a/lib_standalone/AsyncTCP.h +++ b/lib_standalone/AsyncTCP.h @@ -19,12 +19,164 @@ class AsyncClient { class AsyncServer { public: AsyncServer(uint16_t port) - : _port(port){}; - ~AsyncServer(){}; + : _port(port) {}; + ~AsyncServer() {}; protected: uint16_t _port; }; +namespace asyncsrv { + +static constexpr const char empty[] = ""; + +static constexpr const char T__opaque[] = "\", opaque=\""; +static constexpr const char T_100_CONTINUE[] = "100-continue"; +static constexpr const char T_13[] = "13"; +static constexpr const char T_ACCEPT[] = "Accept"; +static constexpr const char T_Accept_Ranges[] = "Accept-Ranges"; +static constexpr const char T_attachment[] = "attachment; filename=\""; +static constexpr const char T_AUTH[] = "Authorization"; +static constexpr const char T_auth_nonce[] = "\", qop=\"auth\", nonce=\""; +static constexpr const char T_BASIC[] = "Basic"; +static constexpr const char T_BASIC_REALM[] = "Basic realm=\""; +static constexpr const char T_BEARER[] = "Bearer"; +static constexpr const char T_BODY[] = "body"; +static constexpr const char T_Cache_Control[] = "Cache-Control"; +static constexpr const char T_chunked[] = "chunked"; +static constexpr const char T_close[] = "close"; +static constexpr const char T_cnonce[] = "cnonce"; +static constexpr const char T_Connection[] = "Connection"; +static constexpr const char T_Content_Disposition[] = "Content-Disposition"; +static constexpr const char T_Content_Encoding[] = "Content-Encoding"; +static constexpr const char T_Content_Length[] = "Content-Length"; +static constexpr const char T_Content_Type[] = "Content-Type"; +static constexpr const char T_Content_Location[] = "Content-Location"; +static constexpr const char T_Cookie[] = "Cookie"; +static constexpr const char T_CORS_ACAC[] = "Access-Control-Allow-Credentials"; +static constexpr const char T_CORS_ACAH[] = "Access-Control-Allow-Headers"; +static constexpr const char T_CORS_ACAM[] = "Access-Control-Allow-Methods"; +static constexpr const char T_CORS_ACAO[] = "Access-Control-Allow-Origin"; +static constexpr const char T_CORS_ACMA[] = "Access-Control-Max-Age"; +static constexpr const char T_CORS_O[] = "Origin"; +static constexpr const char T_data_[] = "data: "; +static constexpr const char T_Date[] = "Date"; +static constexpr const char T_DIGEST[] = "Digest"; +static constexpr const char T_DIGEST_[] = "Digest "; +static constexpr const char T_ETag[] = "ETag"; +static constexpr const char T_event_[] = "event: "; +static constexpr const char T_EXPECT[] = "Expect"; +static constexpr const char T_FALSE[] = "false"; +static constexpr const char T_filename[] = "filename"; +static constexpr const char T_gzip[] = "gzip"; +static constexpr const char T_Host[] = "host"; +static constexpr const char T_HTTP_1_0[] = "HTTP/1.0"; +static constexpr const char T_HTTP_100_CONT[] = "HTTP/1.1 100 Continue\r\n\r\n"; +static constexpr const char T_id__[] = "id: "; +static constexpr const char T_IMS[] = "If-Modified-Since"; +static constexpr const char T_INM[] = "If-None-Match"; +static constexpr const char T_inline[] = "inline"; +static constexpr const char T_keep_alive[] = "keep-alive"; +static constexpr const char T_Last_Event_ID[] = "Last-Event-ID"; +static constexpr const char T_Last_Modified[] = "Last-Modified"; +static constexpr const char T_LOCATION[] = "Location"; +static constexpr const char T_LOGIN_REQ[] = "Login Required"; +static constexpr const char T_MULTIPART_[] = "multipart/"; +static constexpr const char T_name[] = "name"; +static constexpr const char T_nc[] = "nc"; +static constexpr const char T_no_cache[] = "no-cache"; +static constexpr const char T_nonce[] = "nonce"; +static constexpr const char T_none[] = "none"; +static constexpr const char T_opaque[] = "opaque"; +static constexpr const char T_qop[] = "qop"; +static constexpr const char T_realm[] = "realm"; +static constexpr const char T_realm__[] = "realm=\""; +static constexpr const char T_response[] = "response"; +static constexpr const char T_retry_[] = "retry: "; +static constexpr const char T_retry_after[] = "Retry-After"; +static constexpr const char T_nn[] = "\n\n"; +static constexpr const char T_rn[] = "\r\n"; +static constexpr const char T_rnrn[] = "\r\n\r\n"; +static constexpr const char T_Server[] = "Server"; +static constexpr const char T_Transfer_Encoding[] = "Transfer-Encoding"; +static constexpr const char T_TRUE[] = "true"; +static constexpr const char T_UPGRADE[] = "Upgrade"; +static constexpr const char T_uri[] = "uri"; +static constexpr const char T_username[] = "username"; +static constexpr const char T_WS[] = "websocket"; +static constexpr const char T_WWW_AUTH[] = "WWW-Authenticate"; + +// HTTP Methods +static constexpr const char T_ANY[] = "ANY"; +static constexpr const char T_GET[] = "GET"; +static constexpr const char T_POST[] = "POST"; +static constexpr const char T_PUT[] = "PUT"; +static constexpr const char T_DELETE[] = "DELETE"; +static constexpr const char T_PATCH[] = "PATCH"; +static constexpr const char T_HEAD[] = "HEAD"; +static constexpr const char T_OPTIONS[] = "OPTIONS"; +static constexpr const char T_UNKNOWN[] = "UNKNOWN"; + +// Req content types +static constexpr const char T_RCT_NOT_USED[] = "RCT_NOT_USED"; +static constexpr const char T_RCT_DEFAULT[] = "RCT_DEFAULT"; +static constexpr const char T_RCT_HTTP[] = "RCT_HTTP"; +static constexpr const char T_RCT_WS[] = "RCT_WS"; +static constexpr const char T_RCT_EVENT[] = "RCT_EVENT"; +static constexpr const char T_ERROR[] = "ERROR"; + +// extensions & MIME-Types +static constexpr const char T__avif[] = ".avif"; // AVIF: Highly compressed images. Compatible with all modern browsers. +static constexpr const char T__csv[] = ".csv"; // CSV: Data logging and configuration +static constexpr const char T__css[] = ".css"; // CSS: Styling for web interfaces +static constexpr const char T__gif[] = ".gif"; // GIF: Simple animations. Legacy support +static constexpr const char T__gz[] = ".gz"; // GZ: compressed files +static constexpr const char T__htm[] = ".htm"; // HTM: Web interface files +static constexpr const char T__html[] = ".html"; // HTML: Web interface files +static constexpr const char T__ico[] = ".ico"; // ICO: Favicons, system icons. Legacy support +static constexpr const char T__jpg[] = ".jpg"; // JPEG/JPG: Photos. Legacy support +static constexpr const char T__js[] = ".js"; // JavaScript: Interactive functionality +static constexpr const char T__json[] = ".json"; // JSON: Data exchange format +static constexpr const char T__mp4[] = ".mp4"; // MP4: Proprietary format. Worse compression than WEBM. +static constexpr const char T__mjs[] = ".mjs"; // MJS: JavaScript module format +static constexpr const char T__opus[] = ".opus"; // OPUS: High compression audio format +static constexpr const char T__pdf[] = ".pdf"; // PDF: Universal document format +static constexpr const char T__png[] = ".png"; // PNG: Icons, logos, transparency. Legacy support +static constexpr const char T__svg[] = ".svg"; // SVG: Vector graphics, icons (scalable, tiny file sizes) +static constexpr const char T__ttf[] = ".ttf"; // TTF: Font file. Legacy support +static constexpr const char T__txt[] = ".txt"; // TXT: Plain text files +static constexpr const char T__webm[] = ".webm"; // WebM: Video. Open source, optimized for web. Compatible with all modern browsers. +static constexpr const char T__webp[] = ".webp"; // WebP: Highly compressed images. Compatible with all modern browsers. +static constexpr const char T__woff[] = ".woff"; // WOFF: Font file. Legacy support +static constexpr const char T__woff2[] = ".woff2"; // WOFF2: Better compression. Compatible with all modern browsers. +static constexpr const char T__xml[] = ".xml"; // XML: Configuration and data files +static constexpr const char T_application_javascript[] = "application/javascript"; // Obsolete type for JavaScript +static constexpr const char T_application_json[] = "application/json"; +static constexpr const char T_application_msgpack[] = "application/msgpack"; +static constexpr const char T_application_octet_stream[] = "application/octet-stream"; +static constexpr const char T_application_pdf[] = "application/pdf"; +static constexpr const char T_app_xform_urlencoded[] = "application/x-www-form-urlencoded"; +static constexpr const char T_audio_opus[] = "audio/opus"; +static constexpr const char T_font_ttf[] = "font/ttf"; +static constexpr const char T_font_woff[] = "font/woff"; +static constexpr const char T_font_woff2[] = "font/woff2"; +static constexpr const char T_image_avif[] = "image/avif"; +static constexpr const char T_image_gif[] = "image/gif"; +static constexpr const char T_image_jpeg[] = "image/jpeg"; +static constexpr const char T_image_png[] = "image/png"; +static constexpr const char T_image_svg_xml[] = "image/svg+xml"; +static constexpr const char T_image_webp[] = "image/webp"; +static constexpr const char T_image_x_icon[] = "image/x-icon"; +static constexpr const char T_text_css[] = "text/css"; +static constexpr const char T_text_csv[] = "text/csv"; +static constexpr const char T_text_event_stream[] = "text/event-stream"; +static constexpr const char T_text_html[] = "text/html"; +static constexpr const char T_text_javascript[] = "text/javascript"; +static constexpr const char T_text_plain[] = "text/plain"; +static constexpr const char T_text_xml[] = "text/xml"; +static constexpr const char T_video_mp4[] = "video/mp4"; +static constexpr const char T_video_webm[] = "video/webm"; +} // namespace asyncsrv + #endif diff --git a/mock-api/package.json b/mock-api/package.json index d05239e7b..5b8a4efed 100644 --- a/mock-api/package.json +++ b/mock-api/package.json @@ -13,7 +13,7 @@ "@trivago/prettier-plugin-sort-imports": "^6.0.2", "formidable": "^3.5.4", "itty-router": "^5.0.22", - "prettier": "^3.7.4" + "prettier": "^3.8.1" }, - "packageManager": "pnpm@10.28.0+sha512.05df71d1421f21399e053fde567cea34d446fa02c76571441bfc1c7956e98e363088982d940465fd34480d4d90a0668bc12362f8aa88000a64e83d0b0e47be48" + "packageManager": "pnpm@10.28.2+sha512.41872f037ad22f7348e3b1debbaf7e867cfd448f2726d9cf74c08f19507c31d2c8e7a11525b983febc2df640b5438dee6023ebb1f84ed43cc2d654d2bc326264" } diff --git a/mock-api/pnpm-lock.yaml b/mock-api/pnpm-lock.yaml index 5f50a949e..e717c29eb 100644 --- a/mock-api/pnpm-lock.yaml +++ b/mock-api/pnpm-lock.yaml @@ -13,7 +13,7 @@ importers: version: 3.1.3 '@trivago/prettier-plugin-sort-imports': specifier: ^6.0.2 - version: 6.0.2(prettier@3.7.4) + version: 6.0.2(prettier@3.8.1) formidable: specifier: ^3.5.4 version: 3.5.4 @@ -21,17 +21,17 @@ importers: specifier: ^5.0.22 version: 5.0.22 prettier: - specifier: ^3.7.4 - version: 3.7.4 + specifier: ^3.8.1 + version: 3.8.1 packages: - '@babel/code-frame@7.27.1': - resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + '@babel/code-frame@7.28.6': + resolution: {integrity: sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==} engines: {node: '>=6.9.0'} - '@babel/generator@7.28.5': - resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} + '@babel/generator@7.28.6': + resolution: {integrity: sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==} engines: {node: '>=6.9.0'} '@babel/helper-globals@7.28.0': @@ -46,21 +46,21 @@ packages: resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} - '@babel/parser@7.28.5': - resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + '@babel/parser@7.28.6': + resolution: {integrity: sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/template@7.27.2': - resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.28.5': - resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} + '@babel/traverse@7.28.6': + resolution: {integrity: sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.5': - resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + '@babel/types@7.28.6': + resolution: {integrity: sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==} engines: {node: '>=6.9.0'} '@jridgewell/gen-mapping@0.3.13': @@ -145,8 +145,8 @@ packages: engines: {node: '>=6'} hasBin: true - lodash-es@4.17.22: - resolution: {integrity: sha512-XEawp1t0gxSi9x01glktRZ5HDy0HXqrM0x5pXQM98EaI0NxO6jVM7omDOxsuEo5UIASAnm2bRp1Jt/e0a2XU8Q==} + lodash-es@4.17.23: + resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==} minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} @@ -167,8 +167,8 @@ packages: picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - prettier@3.7.4: - resolution: {integrity: sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==} + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} engines: {node: '>=14'} hasBin: true @@ -177,16 +177,16 @@ packages: snapshots: - '@babel/code-frame@7.27.1': + '@babel/code-frame@7.28.6': dependencies: '@babel/helper-validator-identifier': 7.28.5 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/generator@7.28.5': + '@babel/generator@7.28.6': dependencies: - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/parser': 7.28.6 + '@babel/types': 7.28.6 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 @@ -197,29 +197,29 @@ snapshots: '@babel/helper-validator-identifier@7.28.5': {} - '@babel/parser@7.28.5': + '@babel/parser@7.28.6': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.28.6 - '@babel/template@7.27.2': + '@babel/template@7.28.6': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/code-frame': 7.28.6 + '@babel/parser': 7.28.6 + '@babel/types': 7.28.6 - '@babel/traverse@7.28.5': + '@babel/traverse@7.28.6': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.5 + '@babel/code-frame': 7.28.6 + '@babel/generator': 7.28.6 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.5 - '@babel/template': 7.27.2 - '@babel/types': 7.28.5 + '@babel/parser': 7.28.6 + '@babel/template': 7.28.6 + '@babel/types': 7.28.6 debug: 4.4.3 transitivePeerDependencies: - supports-color - '@babel/types@7.28.5': + '@babel/types@7.28.6': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 @@ -246,17 +246,17 @@ snapshots: dependencies: '@noble/hashes': 1.8.0 - '@trivago/prettier-plugin-sort-imports@6.0.2(prettier@3.7.4)': + '@trivago/prettier-plugin-sort-imports@6.0.2(prettier@3.8.1)': dependencies: - '@babel/generator': 7.28.5 - '@babel/parser': 7.28.5 - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/generator': 7.28.6 + '@babel/parser': 7.28.6 + '@babel/traverse': 7.28.6 + '@babel/types': 7.28.6 javascript-natural-sort: 0.7.1 - lodash-es: 4.17.22 + lodash-es: 4.17.23 minimatch: 9.0.5 parse-imports-exports: 0.2.4 - prettier: 3.7.4 + prettier: 3.8.1 transitivePeerDependencies: - supports-color @@ -291,7 +291,7 @@ snapshots: jsesc@3.1.0: {} - lodash-es@4.17.22: {} + lodash-es@4.17.23: {} minimatch@9.0.5: dependencies: @@ -311,6 +311,6 @@ snapshots: picocolors@1.1.1: {} - prettier@3.7.4: {} + prettier@3.8.1: {} wrappy@1.0.2: {} diff --git a/platformio.ini b/platformio.ini index 31ac85d60..b031b9a8f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -106,7 +106,7 @@ board_build.filesystem = littlefs lib_deps = bblanchon/ArduinoJson @ 7.4.2 ESP32Async/AsyncTCP @ 3.4.10 - ESP32Async/ESPAsyncWebServer @ 3.9.4 + ESP32Async/ESPAsyncWebServer @ 3.9.5 https://github.com/emsesp/EMS-ESP-Modules.git @ 1.0.8 diff --git a/project-words.txt b/project-words.txt index ea16610ce..62705f645 100644 --- a/project-words.txt +++ b/project-words.txt @@ -1,76 +1,71 @@ abluft -Abluft abluftfeuchte -Abluftfeuchtefühler +abluftfeuchtefühler abluftgebläse abluftqualität -Abluftqualitätsfühler -ABRT +abluftqualitätsfühler +abrt absburnpow accomodate aceotrope -ACTIVEHIGH -ACTIVELOW -Adafruit +activehigh +activelow +adafruit adde adress +ahsx +airbypass airhumidity airpurgemode airquality -Airquality -Ajcks -AKMP +ajcks +akmp aktivieren allvalues -ALLVALUES alova -Alova alphanum alse alternatingop altopprio altopprioheat +analogenabled analogsensor -ANALOGSENSOR analogsensors analyse -Anschlussvariante +anschlussvariante apicalls apifails apiflags -APIP -APIURL -APLL +apip +apiurl +apll appfree -APPSIZE +appsize appused -APSSID -APSTA -ARDUHAL +apssid +apsta +arduhal arduinojson -ARDUINOJSON -ARDUINOOTA -Arjan -Arlott -Arwed -ASSOCED -ASTATES +arduinoota +arjan +arlott +arwed +assoced +astates asym asymetric asyncesp -ASYNCEVENTSOURCE -ASYNCTCP -ASYNCWEBSERVER -ASYNCWEBSERVERHANDLERIMPL -ASYNCWEBSERVERRESPONSEIMPL -ASYNCWEBSOCKET -ASYNCWEBSYNCHRONIZATION +asynceventsource +asynctcp +asyncwebserver +asyncwebserverhandlerimpl +asyncwebserverresponseimpl +asyncwebsocket +asyncwebsynchronization atoint ausreichend außenluft -Außenluft authmode -AUTHMODE autodst automode autoscroll @@ -79,6 +74,7 @@ auxelecheatnrgconsheating auxelecheatnrgconspool auxelecheatnrgconstotal auxheaterdelay +auxheaterlevel auxheateroff auxheateronly auxheaterstatus @@ -87,85 +83,89 @@ auxheatrmode auxlimitstart auxmaxlimit avty -AWSC -Azubuike +awsc +azubuike badems basepoint -BASEREG +basereg +bblanchon bbqkees -Benoit +beddouble +bedsingle +benoit bertmelis -Bertrik +bertrik bitb bitptr bittimes bitupdate bitvalue -BLANCHON +blanchon blockend blockheader blockheadersize blocksize blocktime -Blowerspeed -Boardprofile -BOARDPROFILE +blowerspeed +boardprofile boilhystoff boilhyston boiltemp bolier +bolv boosttime bootable bootloader bottomtemp +bowlmix breakp +brotlin bssid -Bssid -BSSID buderus -Buderus -BUDERUS budrus -BUFBLOCKSIZE +bufblocksize bufferedflow burngas burnmaxpower burnminperiod burnminpower -Burnpower +burnpower burnstarts burnworkmin -Bytetime +bytetime calinttemp catagory cbuf -Cerapur +cerapur +česky cfamily changeloglevel chargeduration chargeoptimization chargepump chargetype -Chmela +chefhat +chimneysweeper +chmela circmode circprog circpump circswitchtime +circtc cked clangtidy climatezone clockoffset clockrate -CLSD +clsd cmdfunction cmdfunctions -Codacy +codacy codeunit -COILDATA +coildata coilset coldshot -Coldshot -COLDSHOT +coldtemp collectormaxtemp collectormintemp collectorshutdown @@ -173,20 +173,21 @@ collectortemp collectortype colmax colmin -Comf +comf comfdiff comfoff comforttemp comfstop -Commpressor +commandsfunctions +commpressor compstartmod -Condens +condens configdone connack -Connack -CONNACK connectcb connectcount +constlow +constmed controlmode coolingcircuit coolingon @@ -194,35 +195,35 @@ coolingstarts cooloffdelay coolondelay coolstart -COOLSTART coredata -Coredump +coredump coulod cppcheck -CPPCHECK cppdefines -CPPDEFINES cpplint cprint cpsell -CSOURCES +csources cstate +ctkwh curburnpow curflow curflowtemp +currhum curroominfl currsetpoint +currsolarinfl currtemp curtemp curvebase curveend curveon customentities -CUSTOMENTITIES -CUSTOMENTITY +customentity customlist customname -CXXSOURCES +customsupport +cxxsources cylbottomtemp cylheated cylinderpumpmod @@ -232,123 +233,117 @@ cylmiddletemp cylprio cylpriority cylpumpmod +cyltoptemp dailyheating dailyheattime +dailytemp dallassensor dampedoutdoortemp dangel -Dangel -DARDUINO -DARDUINOJSON +darduino +darduinojson datafield datalast -Dauer +dauer dayhightemp daylightsaving daylow -DAYLOW daylowtemp daymid -DAYMID daymidtemp daymode daytemp -DBOARD -DCLANG -DCORE -DEFAULTIDLETIME -DEFAULTTIMEOUT +dboard +dclang +dcore +defaultidletime +defaulttimeout defterm delayboiler delimieter delt -DEMC -DEMSESP -DEPFLAGS +deltatret +demc +demsesp +depflags depower depowering derefenced designtemp desitnation -DESP -Deutsch +desp +deutsch devicedata -DEVICEDATA deviceentities -DEVICEENTITIES -DEVICEERROR +deviceerror devicename -DEVICENAME devicetype devicevalue -DEVICEVALUE devicevalues +devkitc devtype dewoffset dewpoint +dewtemp dewtemperature dhwmintemp dhwprio dhwvalve +dhwx +difftemp disassoc -DISASSOC -Disballance -DISCONN -Disconnectfn -DISCR +disballance +disconn +disconnectfn +discr disinfectday disinfecthour disinfectiontemp disinfecttime displaycode -Domoticz -DOMOTICZ -DONEWIRE +domoticz +donewire doub doublematchflow drehzahl -Drehzahlanpassung +drehzahlanpassung dscrc -Dsonar -DTASMOTA -DUARATION -Eacj -EASYCOM -Eburner +dsonar +dtasmota +duaration +eacj +easycom +eburner ecodiff -Ecomline +ecomline ecooff ecoplus -Ecoplus ecoplusdiff ecoplusoff ecoplusstop ecostop ecotemp efuse -Efuse einschlafen +eldhw elec -Elec electricfactor -ELGs +elgendhw +elgenheat +elgs +elheat elheatstep emergencyops emergencytemp -EMESESP -EMODBUS +emesesp +emodbus emsdevice -EMSDEVICE emsdevices emsdevicevalue -EMSDEVICEVALUE emsesp -EMSESP -EMSFACTORY +emsfactory emsplus -EMSPLUS emsuart -EMSUART encodestate endcond energycostratio @@ -358,45 +353,45 @@ energypriceel energypricegas energytoday energytotal -Enthalpie +enthalpie entityid entitypath enumupdate -Enviline -Equipt +enviline +equipt erct erdwärmetauscher -Erdwärmetauscher +errordisp errornumber esphome espressif -Espressif -Espressif's +espressif's esptool etharp -ETSI +etsi evenodd everslick -Ewen +ewen exhausttemp externalcyl +fanspd fanwork fastheatup fastheatupfactor -FCGENERIC -FCILLEGAL +favs +fcgeneric +fcillegal fcmap -FCUSER +fcuser fdata fernbed -Fernbed fetchblock feucht -Feuchteschutz +feuchteschutz ffunction filesiz -Filterlaufzeit -Filterwechsel +filterlaufzeit +filterwechsel fipa firstscan fixarray @@ -406,69 +401,65 @@ fixmap fixstr flamecurr floordry -Floordry floordrying floordrystatus floordrytemp floorheating flowbuffer -FLOWCTRL +flowctrl flowoffset -FLOWOFFSET flowsensor flowsettemp flowtemp -Flowtemp flowtemphc flowtempoffset -Flowtemps +flowtemps flowtempvf fnames footpoint forceheatingoff forrmat fortluft -Fortluft fossile fossilefactor fprofile -FPSTR +fpstr +français freeable freemem -Frostgrenztemperatur -Frostschutz -FSFS +frostgrenztemperatur +frostschutz +fsfs fstotal ftest +fueldhw +fuelheat fullscreen fulltopic -Funktion -Furtheron +funktion +furtheron gasmeter gasmeterheat -Genuino -Gerätetyp +genuino +gerätetyp getserver getservername ggdb gifsicle -GIQFZUG +giqfzug glbl -Gochkov +gochkov gpio -GPIO gpios -GPIOs -GPOC -Greenstar -Grokhotkov +gpoc +greenstar +grokhotkov haclimate -systemstatus -Harwerth +hardwarestatus +harwerth headersize headertemp healthcheck -HEALTHCHECK heatandcool heatassistpower heatassistvalve @@ -477,7 +468,7 @@ heatcable heatcnt heatcntflowtemp heatcntrettemp -Heatcounter +heatcounter heatdrainpan heatexchangertemp heatingactivated @@ -487,7 +478,6 @@ heatingcircuits heatingciruit heatingcurve heatingoff -HEATINGOFF heatingpid heatingpump heatingpumpmod @@ -500,29 +490,26 @@ heatmetering heatoffdelay heatondelay heatpump -Heatpump -HEATPUMP heatpumpoutput heatpumps heatrequest -Heatronic +heatronic heatsource -Heatsource -HEATSOURCE heatsources heatstarts heattemp +heattransfer heattransfersystem heatup -Heatup heatvalve heatworkmin -Heizkeis -HEXDIGIT -HEXDUMP +heizkeis +hexdigit +hexdump hextoa hextoint -Heyse +heyse +hideled highfive hinzufügen historial @@ -531,7 +518,7 @@ holidaymode holidaymodes holidaytemp homeassistant -HOMEASSISTANT +hottemp hpactivity hpbrinein hpbrineout @@ -541,6 +528,7 @@ hpcircspd hpcompon hpcompspd hpcooling +hpcurrpower hpea hphystcool hphystheat @@ -554,6 +542,7 @@ hpoperatingstate hpph hppl hppower +hppowerlimit hppumpmode hpsetdiffpress hpshutdown @@ -563,23 +552,20 @@ hptc hptl hptr hptw -Hristo -HTTPC +hristo +httpc humi -HUMI -HVAC +hvac hwaddr hwrevision hybriddhw hybridstrategy hydr -Hydr hyst -Hyst hystoff hyston ibutton -ICCARM +iccarm icondegrees iconkb iconlmin @@ -587,25 +573,26 @@ iconnum iconpercent iconua idedata -Iele +iele ignwork -Iiwi -Ijoy -Imlhd +iiwi +ijoy +imlhd inbyte inexhaust infresh inkscape -INPROGRESS +inprogress instaliert instantstart intensiv -Intensiv +intergral intoffset inttemp +intvl invers invertiert -IRAM +iram isbroadcast isglobal islinklocal @@ -613,40 +600,40 @@ isloopback ismixed ismulticast isnum -Isrc +isrc isrunning issign issitelocal isuniquelocal isvalid isystem -Italiano +italiano itty ivtclock +jtag junkersclock kamin -Kamin -Karlesky -Keelbypass +karlesky +keelbypass +keepwarm keepwarmtemp -Kees -Kernighan's +kees +kernighan's keysvalues klappe kmin -KMIN kompakt -Konfig +konfig kwertie -Kwmoar +kwmoar labellen -Larios +larios lastcode lastpayload lastresponse lasttopic -LATXCLR -LATXSET +latxclr +latxset layeredbuffer ldata ldus @@ -654,58 +641,54 @@ ledc leistung lgcov libdeps -LIBRETINY -Licence -Liligo +libretiny +licence +liligo linebuf littlefs -LITTLEFS llen +lltoa lmin -LMIN lockguard lockmq -Logamatic -Logamax -Logano -Logavent -LOGDEVICE +logamatic +logamax +logano +logatherm +logavent +logdevice logentry -Logomatic -LOGRAW +logomatic +lograw lolin -Lolin -LOLIN -Lovato +lovato lownoisemode lownoisestart lownoisestop lowpressure lowtopic -Lufqualität -Luft -Lüfterstufe +lufqualität +luft +lüfterstufe luftfeuchte -Luftfeuchte -Luftfeuchtefühler -Luftqualfühl -Lüftungsfrostschutz -Lukás +luftfeuchtefühler +luftqualfühl +lüftungsfrostschutz +lukás maintenancedate maintenancemessage maintenancetime malloc mandefrost manualtemp -Manuell -Margolis -Marko +manuell +margolis +marko masterthermostat mathieucarbou maxalloc -MAXBUFFERSIZE +maxbuffersize maxflow -MAXFLOW maxflowtemp maxheat maxheatcomp @@ -716,18 +699,17 @@ maxpower maxt maxtemp maxv -MBAP +mbap mbar -MBAR mbed mbedtsl mdio -MDNS -Melis -Mellis -MEMPOL +mdns +melis +mellis +mempol memsiz -MENUCONFIG +menuconfig messagebuffer messagetime metercomp @@ -735,12 +717,12 @@ metercool metereheat meterheat metertotal +mfgadd mheyse microcontroller -Microcontroller mindcase minexttemp -MINFLOW +minflow minflowtemp miniv minmod @@ -750,58 +732,48 @@ mintempsilent minv misa mischer -Mischer mischerposition mixertemp mixingvalves -Mjhl -Mjkz +mjhl +mjkz mlongcalls -MMIO -Mmode -MMPLUS +mmio +mmode +mmplus mockserver modbus -Modbus -MODBUS modee modetype -MODULELIBRARY -Moduline +modulelibrary +moduline mozjpeg mqtt -Mqtt -MQTT mqttclient mqttconnects mqttcount mqttfails +mqttreconnects msgpack -Msgpack msgstr msys -Msys mtext mult -Mysys +mysys nachheiz -Nachheiz nachheizreg -Nachheizregister +nachheizregister nameserver ncmd ncols -Ndrop -Nederlands +ndrop +nederlands nefit -Nefit -NEFIT negcond negheat nein -Nennvolumentstrom +nennvolumentstrom neopixel -Neopixel netcmp netflowtemp netif @@ -811,26 +783,24 @@ newpcb newrssi nightmode nighttemp -NODEMCU +nodemcu nofrost -NOFROST nofrostmode nofrosttemp nominalpower nomis nompower -NOPULL -NOREDUCE +nopull +noreduce noreducetemp -Norsk +norsk nosleep nostdinc notepack notoken -NOTOKEN -NOTRANSLATION -NOTSET -NOTYPE +notranslation +notset +notype nrgconscomp nrgconscompcooling nrgconscompheating @@ -846,16 +816,15 @@ nrgsupppool nrgsupptotal nrgtotal nrgww -NSIs +nsis ntag -NUBD +nubd nullptr numericoperator -NUMJOBS +numjobs numop -NUMOP -Nwcl -Nystrom +nwcl +nystrom odata oddparity öffnen @@ -863,15 +832,13 @@ offsettemp offtemp oilpreheat oldoffset -Olimex -OLIMEX -OLIMEXPOE +olimex +olimexpoe +omea onchange -ONCHANGE onetimekey onewire -ONEWIRE -Ooops +ooops operatingstate opmode optipng @@ -881,46 +848,46 @@ outdoortemp outexhaust outfresh outpow -Packr +packr pacman partitionname partymode payloadbuffer pbutton -PBUTTON penv periph -PERIPH persistance physaddr -PICO +pico pinchange -PINGREQ -PINGRESP -PINGTEST -PIOENV +pingreq +pingresp +pingtest +pinout +pioarduino +pioenv plainwatermode platformio -Platformio -PLATFORMIO pngquant polltime -Polski +polski poolsettemp +poolshunt +poolshuntstatus poolstarts -PORTX +pooltemp +portx +powerreduction powervalues prerel -Prerel primepump primepumpmod printfln prioitise prioritise -PRIXPTR -PROBEREQRECVED +prixptr +probereqrecved proddy -Proddy productid proga progb @@ -929,125 +896,128 @@ progd proge progf progmem -Progmem -PROGMEM progmode +proplow psram -Psram -PSRAM pswid ptys -Puback -PUBACK -PUBACKs -Pubcomp -PUBCOMP -PUBCOMPs -Pubrec -PUBREC -PUBRECs -Pubrel -PUBREL -PUBRELs +puback +pubacks +pubcomp +pubcomps +pubrec +pubrecs +pubrel +pubrels pumpcharacter pumpdelay pumpkick pumpminmod +pumpmod pumpmode pumpmodmax pumpmodmin +pumpontemp +pumpopt pumpstatus +pumpstep pumpworktime pvcooling pvenabledhw pvlen pvlowercool +pvmaxcomp pvraiseheat pvstr -PWRCAP -PYTHONEXE -QOSRESERVED +pwrcap +pythonexe +qosreserved qtxt -Qube +qube questionmark queuecount raumluftfechte raumluftqualität rawstr -RCPLUS +rcplus readback readelf recved +redtemp +redthreshold reducehours reduceminutes reducemode reducetemp -Referer +referer registercount registeroffset rego -Rego -RELNOTES -Remmerswaal's +relais +relnotes +remmerswaal's remotehum remoteseltemp -REMOTESELTEMP remotetemp reqconntype reqs +requiredtemp retheatassist rettemp returncodes reuest -RFBASE +rfbase rfds -RFSENSOR -Rinterval +rfsensor +rinterval riscv rjwats -Rlistener -RMII +rlistener +rmii roboto romminfluencefactor roomcontrol -ROOMCONTROL roomcontroller roomcontrollers -Roomctrl +roomctrl +roomdata +roomflow roomhold roominfl roominflfactor roominfluence -ROOMINFLUENCE +roomload +roomname +roomparams +roomschedule roomsensor +roomsettings roomtemp roomtempdiff roomtemperature -Roomtemperature -ROOMTHERMOSTAT -Rrts -Rserial -Rskip +roomthermostat +roomthermostats +rrts +rserial +rskip rssi -Rssi -RSSI runqueue rxfails -RXFIFO +rxfifo rxreceived rxservice -Saavedra +saavedra safebuild -SAMD +samd saveandactivate scalefactor scancnt scanretry -SCHEDULEFLAG +scheduleflag schließen -SCLK +sclk sday -SDIO +sdio selburnpow selflowtemp seltemp @@ -1062,10 +1032,10 @@ sensorname sensorreads sensortype seperator -SERVERCLASS +serverclass servicecode servicecodenumber -SERVICEKEY +servicekey setburnpow setburnpower setflowtemp @@ -1075,28 +1045,30 @@ setpower setpumppower setreturntemp settemp -Settemp settemplow settingsfiles setvalue -SHORTNAMES +shortnames +showeralert +showertimer +shuntingyard sieger -Sieger -SIEGER signon -Sikken +sikken silentfrom silentmode silentto skipchar skipt sleepmode -Slovenčina -SLTKA +slovenčina +sltka smallitoa -Smartline +smartline sntp +sofasingle solarenabled +solarinfl solarmode solarmodule solarpower @@ -1107,34 +1079,36 @@ solarpumpmode solartemp solekreispumpe soll -Speicher +speicher +spidqs +spiio squaremeters -Srts -STACONNECTED -STADISCONNECTED -STAIPASSIGNED +srts +staconnected +stadisconnected +staipassigned +startshp +starttemp starttemperature -STARTVALUE +startvalue statusbyte stickbreaker -Stickbreaker -Stoffregen +stoffregen +stoptime storagetemp -Störung -STRINGARRAY -STRINGIZE -Studt -Studt's +störung +stringarray +stringize +studt +studt's suback -Suback -SUBACK substract summermode summersetmode summertemp supchan -SUPCHAN -Svenska +suprapur +svenska svmap swapflowtemp swaprettemp @@ -1145,27 +1119,27 @@ switchoff switchonoptimization switchovertemp switchprogmode +switchprogram switchtemp switchtime +switchtimeww sycle syspress sysrettemp -Tado -TADO +systemstatus +tado tapactivated tapwarmwater tapwater tapwateractive targetflowtemp -TARGETHOSTINTERVAL +targethostinterval tasmota -Tasmota -TASMOTA -Tasmota's +tasmota's tbreak +teddybear tele tempauto -TEMPAUTO tempautotemp tempdiffboiler tempdiffcool @@ -1174,44 +1148,48 @@ tempecoplus temperatur temperaturcorrection temperaturesensor -TEMPERATURESENSOR templevel tempok tempparmode +temprature tempsensor -TEMPSENSOR +tempstatus testtemperature thermaldisinfect thermostate -Tillotson +tillotson timeoutcnt timestr -Toastify +toastify toencode toolbelt -TOOMANY -Topline +toomany +topline totalcompstarts tpcb -TRACELOG +tracelog +transferpump +transferpumpmod transre treemap -Trendline -Trewitt +trendline +trewitt triaging -Triaging -TRISXCLR -TRISXSET +trisxclr +trisxset trivago trocken -TRUEFALSE +truefalse +tsens tseslint -Türk +türk turnoffdiff turnondiff +txen txerror txfails -TXMODE +txmode +txpause txread txreads txservice @@ -1222,21 +1200,19 @@ typehh typeids typel typesafe -Typesafe -UART +uart ubauptime ucrt ultostr -Umladesystem -UNDERCLOCK +umladesystem +underclock unflags -UNICORE -Unpackr -Unported -UNSUB -Unsuback -UNSUBACK -UPLOADCMD +unicore +unpackr +unported +unsub +unsuback +uploadcmd uptimecomp uptimecompcooling uptimecompheating @@ -1244,60 +1220,64 @@ uptimecomppool uptimecontrol uptimetotal userprogram -Uutils -VACREDUCE +uutils +vacationmode +vacreduce vacreducemode vacreducetemp validateid -VALIDATORC -VALIDATORR +validatorc +validatorr valu -VALUECONFIG +valueconfig valuename +valvereturn valvesettime valvestatus -Vander -Ventil +vander +vchip +ventil ventinspeed ventmode ventoutspeed venv verwendete -Vflag +vflag viewtopic virtaddr -Volumenstromabgleich -Voord +volumenstromabgleich +voord vorheizer vorheizreg vpcooling vrey -Vybm -Wärmetauscher +vybm +wärmetauscher +washingmachine watchid wayon wayvalve -Wconversion -Wdiv +wconversion +wdiv webui wemos -Wemos -Werror -Wextra +werror +wextra whenmodeoff -WIFICLIENT +wificlient +wifireconnects wifistrength winsock withexitstatus -Wmaybe -Worchester +wmaybe +worchester workm workmin worktime -WOULDBLOCK -Wswitch -Wtype -Wunused +wouldblock +wswitch +wtype +wunused wwactivated wwcharge wwchargeduration @@ -1313,6 +1293,7 @@ wwmodes wwonetime wwprio wwseltemp +wwstarts wwswitchtime wwtankmiddletemp wwtapactivated @@ -1320,132 +1301,26 @@ wwtemp wwtemplow wwvacations wwwhenmodeoff -Xclnt -XRTU -XTCP -XVCJ -Yerger -Yerger's +xclnt +xiao +xrtu +xtcp +xvcj +yerger +yerger's yubox -Zivanovic -Živanović -Zlcn +zadig +zivanovic +živanović +zlcn zolder -Zolder zqhi -ZSIs +zsis zuluft -Zuluft zuluftebläse zuluftgebläse zulufttemp zyxwvutsrqponmlkjihgfedcba -Omea -Bolv -hardwarestatus -hpcurrpower -hppowerlimit -CUSTOMSUPPORT -favs -Logatherm -TSENS -pumpontemp -Česky -pioarduino -switchtimeww -pvmaxcomp -powerreduction -starttemp -heattransfer -poolshunt -poolshuntstatus -pooltemp -stoptime -showertimer -showeralert -CTKWH -wifireconnects -mqttreconnects -wwstarts -auxheaterlevel -startshp -cyltoptemp -transferpump -transferpumpmod -startshp -tempstatus -difftemp -redtemp -requiredtemp -coldtemp -redtemp -hottemp -dailytemp -circtc -keepwarm -pumpmod -valvereturn -deltatret -errordisp -commandsfunctions -hideled -analogenabled -dhwx -ahsx -roomflow -roomload -intvl -Français -lltoa -redthreshold -JTAG -fuelheat -elheat -elgenheat -fueldhw -eldhw -elgendhw -solarinfl -currsolarinfl -temprature -bblanchon -vacationmode -airbypass -Suprapur -mfgadd -shuntingyard -XIAO -zadig -devkitc -Roomthermostats -Roomname -Roomsettings -Roomparams -Roomdata -Roomschedule -dewtemp -chefhat -sofasingle -bowlmix -bedsingle -beddouble -teddybear -washingmachine -switchprogram -brotlin -fanspd -currhum -pumpstep -constmed -constlow -proplow -chimneysweeper -pumpopt -intergral -vchip -SPIIO -SPIDQS -txpause -relais -pinout -TXEN \ No newline at end of file +ACAO +ACAH +ACAC diff --git a/src/ESP32React/APSettingsService.cpp b/src/ESP32React/APSettingsService.cpp index e26d3647d..b0e3480be 100644 --- a/src/ESP32React/APSettingsService.cpp +++ b/src/ESP32React/APSettingsService.cpp @@ -21,24 +21,24 @@ void APSettingsService::begin() { // wait 10 sec on STA disconnect before starting AP void APSettingsService::WiFiEvent(WiFiEvent_t event) { - uint8_t was_connected = _connected; + const uint8_t was_connected = _connected; switch (event) { case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: - _connected &= ~1; + _connected &= ~1U; break; case ARDUINO_EVENT_ETH_DISCONNECTED: - _connected &= ~2; + _connected &= ~2U; break; case ARDUINO_EVENT_WIFI_STA_GOT_IP: case ARDUINO_EVENT_WIFI_STA_GOT_IP6: - _connected |= 1; + _connected |= 1U; break; case ARDUINO_EVENT_ETH_GOT_IP: case ARDUINO_EVENT_ETH_GOT_IP6: - _connected |= 2; + _connected |= 2U; break; default: - break; + return; } // wait 10 sec before starting AP if (was_connected && !_connected) { @@ -52,18 +52,19 @@ void APSettingsService::reconfigureAP() { } void APSettingsService::loop() { - unsigned long currentMillis = uuid::get_uptime(); - unsigned long manageElapsed = static_cast(currentMillis - _lastManaged); - if (manageElapsed >= MANAGE_NETWORK_DELAY) { + const unsigned long currentMillis = uuid::get_uptime(); + if ((currentMillis - _lastManaged) >= MANAGE_NETWORK_DELAY) { _lastManaged = currentMillis; manageAP(); } - handleDNS(); + if (_dnsServer) { + handleDNS(); + } } void APSettingsService::manageAP() { - WiFiMode_t currentWiFiMode = WiFi.getMode(); + const WiFiMode_t currentWiFiMode = WiFi.getMode(); if (_state.provisionMode == AP_MODE_ALWAYS || (_state.provisionMode == AP_MODE_DISCONNECTED && !_connected)) { if (_reconfigureAp || currentWiFiMode == WIFI_OFF || currentWiFiMode == WIFI_STA) { startAP(); @@ -87,8 +88,10 @@ void APSettingsService::startAP() { WiFi.setTxPower(WIFI_POWER_8_5dBm); // https://www.wemos.cc/en/latest/c3/c3_mini_1_0_0.html#about-wifi #endif if (!_dnsServer) { - IPAddress apIp = WiFi.softAPIP(); - emsesp::EMSESP::logger().info("Starting Access Point with captive portal on %s", apIp.toString().c_str()); + const IPAddress apIp = WiFi.softAPIP(); + char ipStr[16]; + snprintf(ipStr, sizeof(ipStr), "%u.%u.%u.%u", apIp[0], apIp[1], apIp[2], apIp[3]); + emsesp::EMSESP::logger().info("Starting Access Point with captive portal on %s", ipStr); _dnsServer = new DNSServer; _dnsServer->start(DNS_PORT, "*", apIp); } @@ -111,8 +114,8 @@ void APSettingsService::handleDNS() { } APNetworkStatus APSettingsService::getAPNetworkStatus() { - WiFiMode_t currentWiFiMode = WiFi.getMode(); - bool apActive = currentWiFiMode == WIFI_AP || currentWiFiMode == WIFI_AP_STA; + const WiFiMode_t currentWiFiMode = WiFi.getMode(); + const bool apActive = (currentWiFiMode == WIFI_AP || currentWiFiMode == WIFI_AP_STA); if (apActive && _state.provisionMode != AP_MODE_ALWAYS && WiFi.status() == WL_CONNECTED) { return APNetworkStatus::LINGERING; @@ -135,7 +138,7 @@ void APSettings::read(const APSettings & settings, JsonObject root) { } StateUpdateResult APSettings::update(JsonObject root, APSettings & settings) { - APSettings newSettings = {}; + APSettings newSettings{}; newSettings.provisionMode = static_cast(root["provision_mode"] | FACTORY_AP_PROVISION_MODE); switch (settings.provisionMode) { diff --git a/src/ESP32React/APSettingsService.h b/src/ESP32React/APSettingsService.h index fda384bc8..9b52f84d0 100644 --- a/src/ESP32React/APSettingsService.h +++ b/src/ESP32React/APSettingsService.h @@ -1,5 +1,5 @@ -#ifndef APSettingsConfig_h -#define APSettingsConfig_h +#ifndef APSettingsService_h +#define APSettingsService_h #include "HttpEndpoint.h" #include "FSPersistence.h" @@ -70,9 +70,9 @@ class APSettings { IPAddress subnetMask; bool operator==(const APSettings & settings) const { - return provisionMode == settings.provisionMode && ssid == settings.ssid && password == settings.password && channel == settings.channel - && ssidHidden == settings.ssidHidden && maxClients == settings.maxClients && localIP == settings.localIP && gatewayIP == settings.gatewayIP - && subnetMask == settings.subnetMask; + return provisionMode == settings.provisionMode && channel == settings.channel && ssidHidden == settings.ssidHidden + && maxClients == settings.maxClients && localIP == settings.localIP && gatewayIP == settings.gatewayIP + && subnetMask == settings.subnetMask && ssid == settings.ssid && password == settings.password; } static void read(const APSettings & settings, JsonObject root); @@ -96,8 +96,8 @@ class APSettingsService : public StatefulService { // for the management delay loop volatile unsigned long _lastManaged; - volatile boolean _reconfigureAp; - uint8_t _connected; + volatile bool _reconfigureAp; + volatile uint8_t _connected; void reconfigureAP(); void manageAP(); diff --git a/src/ESP32React/ESP32React.cpp b/src/ESP32React/ESP32React.cpp index 72bd28a2d..41536153f 100644 --- a/src/ESP32React/ESP32React.cpp +++ b/src/ESP32React/ESP32React.cpp @@ -2,6 +2,8 @@ #include "WWWData.h" // include auto-generated static web resources +static constexpr const char CACHE_CONTROL[] = "public,max-age=60"; + ESP32React::ESP32React(AsyncWebServer * server, FS * fs) : _securitySettingsService(server, fs) , _networkSettingsService(server, fs, &_securitySettingsService) @@ -22,21 +24,18 @@ ESP32React::ESP32React(AsyncWebServer * server, FS * fs) ArRequestHandlerFunction indexHtmlHandler = nullptr; WWWData::registerRoutes([server, &indexHtmlHandler](const char * uri, const String & contentType, const uint8_t * content, size_t len, const String & hash) { - ArRequestHandlerFunction requestHandler = [contentType, content, len, hash](AsyncWebServerRequest * request) { - AsyncWebServerResponse * response; + String etag = "\"" + hash + "\""; // RFC9110: ETag must be enclosed in double quotes - // Check if the client already has the same version and respond with a 304 (Not modified) - if (request->header("If-None-Match").equals(hash)) { - response = request->beginResponse(304); - } else { - response = request->beginResponse(200, contentType, content, len); - response->addHeader("Content-Encoding", "gzip"); // not br for brotlin only works over HTTPS + ArRequestHandlerFunction requestHandler = [contentType, content, len, etag](AsyncWebServerRequest * request) { + if (request->header(asyncsrv::T_INM) == etag) { + request->send(304); + return; } - // always send these headers - see https://datatracker.ietf.org/doc/html/rfc7232#section-4.1 - response->addHeader("ETag", hash); - response->addHeader("Cache-Control", "no-cache"); // Requires revalidation before using cached content (ETags enable 304 responses) - + AsyncWebServerResponse * response = request->beginResponse(200, contentType, content, len); + response->addHeader(asyncsrv::T_Content_Encoding, asyncsrv::T_gzip, false); + response->addHeader(asyncsrv::T_ETag, etag, false); + response->addHeader(asyncsrv::T_Cache_Control, CACHE_CONTROL, false); request->send(response); }; @@ -69,11 +68,11 @@ void ESP32React::begin() { _networkSettingsService.read([&](NetworkSettings & networkSettings) { DefaultHeaders & defaultHeaders = DefaultHeaders::Instance(); if (networkSettings.enableCORS) { - defaultHeaders.addHeader("Access-Control-Allow-Origin", networkSettings.CORSOrigin); - defaultHeaders.addHeader("Access-Control-Allow-Headers", "Accept, Content-Type, Authorization"); - defaultHeaders.addHeader("Access-Control-Allow-Credentials", "true"); + defaultHeaders.addHeader(asyncsrv::T_CORS_ACAO, networkSettings.CORSOrigin); + defaultHeaders.addHeader(asyncsrv::T_CORS_ACAH, "Accept, Content-Type, Authorization"); + defaultHeaders.addHeader(asyncsrv::T_CORS_ACAC, "true"); } - defaultHeaders.addHeader("Server", networkSettings.hostname); + defaultHeaders.addHeader(asyncsrv::T_Server, networkSettings.hostname); }); _apSettingsService.begin(); _ntpSettingsService.begin(); diff --git a/src/ESP32React/JsonUtils.h b/src/ESP32React/JsonUtils.h index 0d2ff9fa5..7870f34a6 100644 --- a/src/ESP32React/JsonUtils.h +++ b/src/ESP32React/JsonUtils.h @@ -10,20 +10,23 @@ class JsonUtils { public: static void readIP(JsonObject root, const String & key, IPAddress & ip, const String & def) { - IPAddress defaultIp = {}; + IPAddress defaultIp{}; if (!defaultIp.fromString(def)) { defaultIp = INADDR_NONE; } readIP(root, key, ip, defaultIp); } static void readIP(JsonObject root, const String & key, IPAddress & ip, const IPAddress & defaultIp = INADDR_NONE) { - if (!root[key].is() || !ip.fromString(root[key].as())) { + const JsonVariant value = root[key]; + if (!value.is() || !ip.fromString(value.as())) { ip = defaultIp; } } static void writeIP(JsonObject root, const String & key, const IPAddress & ip) { if (IPUtils::isSet(ip)) { - root[key] = ip.toString(); + char ipStr[16]; + snprintf(ipStr, sizeof(ipStr), "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); + root[key] = ipStr; } } }; diff --git a/src/ESP32React/MqttSettingsService.cpp b/src/ESP32React/MqttSettingsService.cpp index 11c84462e..1c07748f0 100644 --- a/src/ESP32React/MqttSettingsService.cpp +++ b/src/ESP32React/MqttSettingsService.cpp @@ -255,7 +255,7 @@ void MqttSettings::read(MqttSettings & settings, JsonObject root) { } StateUpdateResult MqttSettings::update(JsonObject root, MqttSettings & settings) { - MqttSettings newSettings = {}; + MqttSettings newSettings; bool changed = false; #ifndef TASMOTA_SDK diff --git a/src/ESP32React/MqttSettingsService.h b/src/ESP32React/MqttSettingsService.h index 83cf751dd..36b52fa74 100644 --- a/src/ESP32React/MqttSettingsService.h +++ b/src/ESP32React/MqttSettingsService.h @@ -125,11 +125,11 @@ class MqttSettingsService : public StatefulService { FSPersistence _fsPersistence; // variable to help manage connection - bool _reconfigureMqtt; - unsigned long _disconnectedAt; + volatile bool _reconfigureMqtt; + volatile unsigned long _disconnectedAt; // connection status - espMqttClientTypes::DisconnectReason _disconnectReason; + volatile espMqttClientTypes::DisconnectReason _disconnectReason; // the MQTT client instance MqttClient * _mqttClient; diff --git a/src/ESP32React/NTPSettingsService.h b/src/ESP32React/NTPSettingsService.h index 4b3bbce69..635b68f1c 100644 --- a/src/ESP32React/NTPSettingsService.h +++ b/src/ESP32React/NTPSettingsService.h @@ -49,7 +49,7 @@ class NTPSettingsService : public StatefulService { private: HttpEndpoint _httpEndpoint; FSPersistence _fsPersistence; - bool _connected; + volatile bool _connected; void WiFiEvent(WiFiEvent_t event); void configureNTP(); diff --git a/src/ESP32React/NetworkSettingsService.h b/src/ESP32React/NetworkSettingsService.h index f35186bf6..7c1ed0ff7 100644 --- a/src/ESP32React/NetworkSettingsService.h +++ b/src/ESP32React/NetworkSettingsService.h @@ -102,10 +102,10 @@ class NetworkSettingsService : public StatefulService { HttpEndpoint _httpEndpoint; FSPersistence _fsPersistence; - unsigned long _lastConnectionAttempt; - bool _stopping; + volatile unsigned long _lastConnectionAttempt; + volatile bool _stopping; - uint16_t connectcount_ = 0; // number of wifi reconnects + volatile uint16_t connectcount_ = 0; // number of wifi reconnects void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info); void mDNS_start() const; diff --git a/src/core/command.h b/src/core/command.h index 61fcb9c49..6ab6b1230 100644 --- a/src/core/command.h +++ b/src/core/command.h @@ -19,7 +19,7 @@ #ifndef EMSESP_COMMAND_H_ #define EMSESP_COMMAND_H_ -#include +#include #include "console.h" #include @@ -153,8 +153,8 @@ class Command { class SUrlParser { private: - std::unordered_map m_keysvalues; - std::vector m_folders; + std::map m_keysvalues; + std::vector m_folders; public: SUrlParser() = default; @@ -166,7 +166,7 @@ class SUrlParser { return m_folders; }; - std::unordered_map & params() { + std::map & params() { return m_keysvalues; }; diff --git a/src/core/emsdevice.cpp b/src/core/emsdevice.cpp index 29f0cdffb..7e96e4479 100644 --- a/src/core/emsdevice.cpp +++ b/src/core/emsdevice.cpp @@ -1720,8 +1720,8 @@ void EMSdevice::get_value_json(JsonObject json, DeviceValue & dv) { // generate Prometheus metrics format from device values std::string EMSdevice::get_metrics_prometheus(const int8_t tag) { - std::string result; - std::unordered_map seen_metrics; + std::string result; + std::map seen_metrics; // Helper function to check if a device value type is supported for Prometheus metrics auto is_supported_type = [](uint8_t type) -> bool { diff --git a/src/core/emsdevice.h b/src/core/emsdevice.h index efd535693..93675ade7 100644 --- a/src/core/emsdevice.h +++ b/src/core/emsdevice.h @@ -26,7 +26,7 @@ #include "emsdevicevalue.h" #include -#include +#include namespace emsesp { diff --git a/src/core/emsesp.h b/src/core/emsesp.h index b3ed04267..416c1bea7 100644 --- a/src/core/emsesp.h +++ b/src/core/emsesp.h @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/core/emsfactory.h b/src/core/emsfactory.h index d2ac63707..771aad4af 100644 --- a/src/core/emsfactory.h +++ b/src/core/emsfactory.h @@ -19,14 +19,15 @@ #ifndef EMSESP_EMSFACTORY_H_ #define EMSESP_EMSFACTORY_H_ -#include #include // for unique_ptr +#include -#include "emsdevice.h" +// Forward declaration +namespace emsesp { +class EMSdevice; +} // Macro for class registration -// Anonymous namespace is used to make the definitions here private to the current -// compilation unit (current file). It is equivalent to the old C static keyword. #define REGISTER_FACTORY(derivedClass, device_type) \ namespace { \ auto registry_##derivedClass = ConcreteEMSFactory(device_type); \ @@ -34,30 +35,29 @@ namespace emsesp { -class EMSdevice; // forward declaration, for gcc linking - class EMSFactory { public: virtual ~EMSFactory() = default; - // Register factory object of derived class - // using the device_type as the unique identifier - static auto registerFactory(const uint8_t device_type, EMSFactory * factory) -> void { - auto & reg = EMSFactory::getRegister(); - reg[device_type] = factory; - } - using FactoryMap = std::map; + // Register factory object of derived class using the device_type as the unique identifier + static inline auto registerFactory(const uint8_t device_type, EMSFactory * factory) -> void { + getRegister()[device_type] = factory; + } + // returns all registered classes (really only for debugging) - static auto device_handlers() -> FactoryMap { - return EMSFactory::getRegister(); + static inline auto device_handlers() -> const FactoryMap & { + return getRegister(); } // Construct derived class returning an unique ptr static auto add(const uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * default_name, uint8_t flags, uint8_t brand) -> std::unique_ptr { - return std::unique_ptr(EMSFactory::makeRaw(device_type, device_id, product_id, version, default_name, flags, brand)); + if (auto * ptr = makeRaw(device_type, device_id, product_id, version, default_name, flags, brand)) { + return std::unique_ptr(ptr); + } + return nullptr; } virtual auto construct(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand) const @@ -65,7 +65,7 @@ class EMSFactory { private: // Force global variable to be initialized, thus it avoids the "initialization order fiasco" - static auto getRegister() -> FactoryMap & { + static inline auto getRegister() -> FactoryMap & { static FactoryMap classRegister{}; return classRegister; } @@ -74,11 +74,9 @@ class EMSFactory { // find which EMS device it is and use that class static auto makeRaw(const uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand) -> EMSdevice * { - auto it = EMSFactory::getRegister().find(device_type); - if (it != EMSFactory::getRegister().end()) { - return it->second->construct(device_type, device_id, product_id, version, name, flags, brand); - } - return nullptr; + const auto & reg = getRegister(); + const auto it = reg.find(device_type); + return (it != reg.end()) ? it->second->construct(device_type, device_id, product_id, version, name, flags, brand) : nullptr; } }; @@ -86,7 +84,7 @@ template class ConcreteEMSFactory : EMSFactory { public: // Register this global object on the EMSFactory register - ConcreteEMSFactory(const uint8_t device_type) { + explicit ConcreteEMSFactory(const uint8_t device_type) { EMSFactory::registerFactory(device_type, this); } diff --git a/src/core/shuntingYard.cpp b/src/core/shuntingYard.cpp index 62e738bfb..d90b0a9c7 100644 --- a/src/core/shuntingYard.cpp +++ b/src/core/shuntingYard.cpp @@ -344,8 +344,12 @@ bool isnum(const std::string & s) { std::string commands(std::string & expr, bool quotes) { auto expr_new = Helpers::toLower(expr); for (uint8_t device = 0; device < EMSdevice::DeviceType::UNKNOWN; device++) { - std::string d = (std::string)EMSdevice::device_type_2_device_name(device) + "/"; - auto f = expr_new.find(d); + // Optimized: build string with reserve to avoid temporary allocations + std::string d; + d.reserve(32); // typical device name length + "/" + d = EMSdevice::device_type_2_device_name(device); + d += "/"; + auto f = expr_new.find(d); while (f != std::string::npos) { // entity names are alphanumeric or _ auto e = expr_new.find_first_not_of("/._abcdefghijklmnopqrstuvwxyz0123456789", f); @@ -367,9 +371,11 @@ std::string commands(std::string & expr, bool quotes) { JsonDocument doc_in; JsonObject output = doc_out.to(); JsonObject input = doc_in.to(); - std::string cmd_s = "api/" + std::string(cmd); + // Optimized: use stack buffer for small strings to avoid heap allocation + char cmd_s[COMMAND_MAX_LENGTH + 5]; // "api/" prefix + cmd + snprintf(cmd_s, sizeof(cmd_s), "api/%s", cmd); - auto return_code = Command::process(cmd_s.c_str(), true, input, output); + auto return_code = Command::process(cmd_s, true, input, output); // check for no value (entity is valid but has no value set) if (return_code != CommandRet::OK && return_code != CommandRet::NO_VALUE) { return expr = ""; @@ -725,7 +731,7 @@ std::string compute(const std::string & expr) { // if there is data, force a POST if (value.length() || Helpers::toLower(method) == "post") { if (value.find_first_of('{') != std::string::npos) { - http.addHeader("Content-Type", "application/json"); // auto-set to JSON + http.addHeader(asyncsrv::T_Content_Type, asyncsrv::T_application_json, false); // auto-set to JSON } httpResult = http.POST(value.c_str()); } else { diff --git a/src/core/system.cpp b/src/core/system.cpp index d031a05f2..f523c68b7 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -1761,8 +1761,8 @@ void System::get_value_json(JsonObject output, const std::string & circuit, cons // generate Prometheus metrics format from system values std::string System::get_metrics_prometheus() { - std::string result; - std::unordered_map seen_metrics; + std::string result; + std::map seen_metrics; result.reserve(16000); diff --git a/src/devices/connect.h b/src/devices/connect.h index ea846c2b8..bbe647119 100644 --- a/src/devices/connect.h +++ b/src/devices/connect.h @@ -68,7 +68,7 @@ class Connect : public EMSdevice { bool set_childlock(const char * value, const int8_t id); bool set_icon(const char * value, const int8_t id); - std::vector> room_circuits_; + std::vector, AllocatorPSRAM>> room_circuits_; void process_OutdoorTemp(std::shared_ptr telegram); void process_RCTime(std::shared_ptr telegram); diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index bbefe086b..4ebe5d33d 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -59,7 +59,8 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i if (model == EMSdevice::EMS_DEVICE_FLAG_RC10) { monitor_typeids = {0xB1}; set_typeids = {0xB0}; - for (uint8_t i = 0; i < monitor_typeids.size(); i++) { + const size_t size = monitor_typeids.size(); + for (uint8_t i = 0; i < size; i++) { register_telegram_type(monitor_typeids[i], "RC10Monitor", false, MAKE_PF_CB(process_RC10Monitor)); register_telegram_type(set_typeids[i], "RC10Set", false, MAKE_PF_CB(process_RC10Set)); } @@ -70,7 +71,8 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i set_typeids = {0x3D, 0x47, 0x51, 0x5B}; timer_typeids = {0x3F, 0x49, 0x53, 0x5D}; timer2_typeids = {0x42, 0x4C, 0x56, 0x60}; - for (uint8_t i = 0; i < monitor_typeids.size(); i++) { + const size_t size = monitor_typeids.size(); + for (uint8_t i = 0; i < size; i++) { register_telegram_type(monitor_typeids[i], "RC35Monitor", false, MAKE_PF_CB(process_RC35Monitor)); register_telegram_type(set_typeids[i], "RC35Set", false, MAKE_PF_CB(process_RC35Set)); register_telegram_type(timer_typeids[i], "RC35Timer", false, MAKE_PF_CB(process_RC35Timer)); @@ -88,7 +90,8 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i set_typeids = {0xA8}; curve_typeids = {0x90}; timer_typeids = {0x8F}; - for (uint8_t i = 0; i < monitor_typeids.size(); i++) { + const size_t size = monitor_typeids.size(); + for (uint8_t i = 0; i < size; i++) { register_telegram_type(monitor_typeids[i], "RC20Monitor", false, MAKE_PF_CB(process_RC20Monitor)); register_telegram_type(set_typeids[i], "RC20Set", false, MAKE_PF_CB(process_RC20Set)); register_telegram_type(curve_typeids[i], "RC20Temp", false, MAKE_PF_CB(process_RC20Temp)); @@ -103,7 +106,8 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i if (device_id == 0x17) { // master monitor_typeids = {0xAE}; set_typeids = {0xAD}; - for (uint8_t i = 0; i < monitor_typeids.size(); i++) { + const size_t size = monitor_typeids.size(); + for (uint8_t i = 0; i < size; i++) { register_telegram_type(monitor_typeids[i], "RC20Monitor", false, MAKE_PF_CB(process_RC20Monitor_2)); register_telegram_type(set_typeids[i], "RC20Set", false, MAKE_PF_CB(process_RC20Set_2)); } @@ -117,7 +121,8 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i set_typeids = {0xA7}; curve_typeids = {0x40}; timer_typeids = {0x3F}; - for (uint8_t i = 0; i < monitor_typeids.size(); i++) { + const size_t size = monitor_typeids.size(); + for (uint8_t i = 0; i < size; i++) { register_telegram_type(monitor_typeids[i], "RC30Monitor", false, MAKE_PF_CB(process_RC30Monitor)); register_telegram_type(set_typeids[i], "RC30Set", false, MAKE_PF_CB(process_RC30Set)); register_telegram_type(curve_typeids[i], "RC30Temp", false, MAKE_PF_CB(process_RC30Temp)); @@ -131,15 +136,16 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i // EASY } else if (model == EMSdevice::EMS_DEVICE_FLAG_EASY) { monitor_typeids = {0x0A}; - set_typeids = {}; + set_typeids.clear(); register_telegram_type(monitor_typeids[0], "EasyMonitor", true, MAKE_PF_CB(process_EasyMonitor)); register_telegram_type(0x02A5, "EasyMonitor", false, MAKE_PF_CB(process_EasyMonitor)); // CRF } else if (model == EMSdevice::EMS_DEVICE_FLAG_CRF) { monitor_typeids = {0x02A5, 0x02A6, 0x02A7, 0x02A8}; - set_typeids = {}; - for (uint8_t i = 0; i < monitor_typeids.size(); i++) { + set_typeids.clear(); + const size_t size = monitor_typeids.size(); + for (uint8_t i = 0; i < size; i++) { register_telegram_type(monitor_typeids[i], "CRFMonitor", false, MAKE_PF_CB(process_CRFMonitor)); } @@ -163,14 +169,16 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i summer2_typeids = {0x0471, 0x0472, 0x0473, 0x0474, 0x0475, 0x0476, 0x0477, 0x0478}; hp_typeids = {0x0467, 0x0468, 0x0469, 0x046A}; hpmode_typeids = {0x0291, 0x0292, 0x0293, 0x0294}; - for (uint8_t i = 0; i < monitor_typeids.size(); i++) { + const size_t monitor_size = monitor_typeids.size(); + for (uint8_t i = 0; i < monitor_size; i++) { register_telegram_type(monitor_typeids[i], "RC300Monitor", false, MAKE_PF_CB(process_RC300Monitor)); register_telegram_type(set_typeids[i], "RC300Set", false, MAKE_PF_CB(process_RC300Set)); register_telegram_type(summer_typeids[i], "RC300Summer", false, MAKE_PF_CB(process_RC300Summer)); register_telegram_type(curve_typeids[i], "RC300Curves", false, MAKE_PF_CB(process_RC300Curve)); register_telegram_type(summer2_typeids[i], "RC300Summer2", false, MAKE_PF_CB(process_RC300Summer2)); } - for (uint8_t i = 0; i < set2_typeids.size(); i++) { + const size_t set2_size = set2_typeids.size(); + for (uint8_t i = 0; i < set2_size; i++) { // register_telegram_type(set2_typeids[i], "RC300Set2", false, MAKE_PF_CB(process_RC300Set2)); register_telegram_type(set2_typeids[i], "RC300Set2", false, MAKE_PF_CB(process_PID)); register_telegram_type(hp_typeids[i], "HPSet", false, MAKE_PF_CB(process_HPSet)); @@ -210,19 +218,20 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i } monitor_typeids = {0x016F, 0x0170, 0x0171, 0x0172}; - for (uint8_t i = 0; i < monitor_typeids.size(); i++) { + const size_t junkers_size = monitor_typeids.size(); + for (uint8_t i = 0; i < junkers_size; i++) { register_telegram_type(monitor_typeids[i], "JunkersMonitor", false, MAKE_PF_CB(process_JunkersMonitor)); } if (has_flags(EMSdevice::EMS_DEVICE_FLAG_JUNKERS_OLD)) { // FR120, FR100 set_typeids = {0x0179, 0x017A, 0x017B, 0x017C}; - for (uint8_t i = 0; i < monitor_typeids.size(); i++) { + for (uint8_t i = 0; i < junkers_size; i++) { register_telegram_type(set_typeids[i], "JunkersSet", false, MAKE_PF_CB(process_JunkersSet2)); } } else { set_typeids = {0x0165, 0x0166, 0x0167, 0x0168}; - for (uint8_t i = 0; i < monitor_typeids.size(); i++) { + for (uint8_t i = 0; i < junkers_size; i++) { register_telegram_type(set_typeids[i], "JunkersSet", false, MAKE_PF_CB(process_JunkersSet)); } } @@ -237,10 +246,12 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i // query all the heating circuits. This is only done once. // The automatic fetch will from now on only update the active heating circuits - for (uint8_t i = 0; i < monitor_typeids.size(); i++) { + const size_t monitor_size_final = monitor_typeids.size(); + for (uint8_t i = 0; i < monitor_size_final; i++) { EMSESP::send_read_request(monitor_typeids[i], device_id); } - for (uint8_t i = 0; i < set_typeids.size(); i++) { + const size_t set_size = set_typeids.size(); + for (uint8_t i = 0; i < set_size; i++) { EMSESP::send_read_request(set_typeids[i], device_id); } @@ -293,7 +304,8 @@ std::shared_ptr Thermostat::heating_circuit(std::sha // not found, search monitor message types if (hc_num == 0) { - for (uint8_t i = 0; i < monitor_typeids.size(); i++) { + const size_t monitor_size = monitor_typeids.size(); + for (uint8_t i = 0; i < monitor_size; i++) { if (monitor_typeids[i] == telegram->type_id) { hc_num = i + 1; toggle_ = true; @@ -304,7 +316,8 @@ std::shared_ptr Thermostat::heating_circuit(std::sha // not found, search status message/set types if (hc_num == 0) { - for (uint8_t i = 0; i < set_typeids.size(); i++) { + const size_t set_size = set_typeids.size(); + for (uint8_t i = 0; i < set_size; i++) { if (set_typeids[i] == telegram->type_id) { hc_num = i + 1; break; @@ -314,7 +327,8 @@ std::shared_ptr Thermostat::heating_circuit(std::sha // not found, search set2 types if (hc_num == 0) { - for (uint8_t i = 0; i < set2_typeids.size(); i++) { + const size_t set2_size = set2_typeids.size(); + for (uint8_t i = 0; i < set2_size; i++) { if (set2_typeids[i] == telegram->type_id) { hc_num = i + 1; break; @@ -324,7 +338,8 @@ std::shared_ptr Thermostat::heating_circuit(std::sha // not found, search summer message types if (hc_num == 0) { - for (uint8_t i = 0; i < summer_typeids.size(); i++) { + const size_t summer_size = summer_typeids.size(); + for (uint8_t i = 0; i < summer_size; i++) { if (summer_typeids[i] == telegram->type_id) { hc_num = i + 1; break; @@ -334,7 +349,8 @@ std::shared_ptr Thermostat::heating_circuit(std::sha // not found, search summer message types if (hc_num == 0) { - for (uint8_t i = 0; i < summer2_typeids.size(); i++) { + const size_t summer2_size = summer2_typeids.size(); + for (uint8_t i = 0; i < summer2_size; i++) { if (summer2_typeids[i] == telegram->type_id) { hc_num = i + 1; break; @@ -344,7 +360,8 @@ std::shared_ptr Thermostat::heating_circuit(std::sha // not found, search heating_curve message types if (hc_num == 0) { - for (uint8_t i = 0; i < curve_typeids.size(); i++) { + const size_t curve_size = curve_typeids.size(); + for (uint8_t i = 0; i < curve_size; i++) { if (curve_typeids[i] == telegram->type_id) { hc_num = i + 1; break; @@ -354,7 +371,8 @@ std::shared_ptr Thermostat::heating_circuit(std::sha // not found, search timer message types if (hc_num == 0) { - for (uint8_t i = 0; i < timer_typeids.size(); i++) { + const size_t timer_size = timer_typeids.size(); + for (uint8_t i = 0; i < timer_size; i++) { if (timer_typeids[i] == telegram->type_id) { hc_num = i + 1; break; @@ -364,7 +382,8 @@ std::shared_ptr Thermostat::heating_circuit(std::sha // not found, search timer message types if (hc_num == 0) { - for (uint8_t i = 0; i < timer2_typeids.size(); i++) { + const size_t timer2_size = timer2_typeids.size(); + for (uint8_t i = 0; i < timer2_size; i++) { if (timer2_typeids[i] == telegram->type_id) { hc_num = i + 1; break; @@ -374,7 +393,8 @@ std::shared_ptr Thermostat::heating_circuit(std::sha // not found, search heatpump message types if (hc_num == 0) { - for (uint8_t i = 0; i < hp_typeids.size(); i++) { + const size_t hp_size = hp_typeids.size(); + for (uint8_t i = 0; i < hp_size; i++) { if (hp_typeids[i] == telegram->type_id) { hc_num = i + 1; break; @@ -383,7 +403,8 @@ std::shared_ptr Thermostat::heating_circuit(std::sha } if (hc_num == 0) { - for (uint8_t i = 0; i < hpmode_typeids.size(); i++) { + const size_t hpmode_size = hpmode_typeids.size(); + for (uint8_t i = 0; i < hpmode_size; i++) { if (hpmode_typeids[i] == telegram->type_id) { hc_num = i + 1; break; diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 2bc1e18fc..a5da5f73f 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -244,16 +244,16 @@ class Thermostat : public EMSdevice { } // each thermostat has a list of heating controller type IDs for reading and writing - std::vector monitor_typeids; - std::vector set_typeids; - std::vector set2_typeids; - std::vector timer_typeids; - std::vector timer2_typeids; - std::vector summer_typeids; - std::vector summer2_typeids; - std::vector curve_typeids; - std::vector hp_typeids; - std::vector hpmode_typeids; + std::vector> monitor_typeids; + std::vector> set_typeids; + std::vector> set2_typeids; + std::vector> timer_typeids; + std::vector> timer2_typeids; + std::vector> summer_typeids; + std::vector> summer2_typeids; + std::vector> curve_typeids; + std::vector> hp_typeids; + std::vector> hpmode_typeids; // standard for all thermostats char status_[20]; // online or offline @@ -305,8 +305,8 @@ class Thermostat : public EMSdevice { uint8_t pvRaiseHeat_; uint8_t pvLowerCool_; - std::vector> heating_circuits_; // each thermostat can have multiple heating circuits - std::vector> dhw_circuits_; // each thermostat can have multiple dhw circuits + std::vector, AllocatorPSRAM>> heating_circuits_; // each thermostat can have multiple heating circuits + std::vector, AllocatorPSRAM>> dhw_circuits_; // each thermostat can have multiple dhw circuits // Generic Types static constexpr uint16_t EMS_TYPE_RCTime = 0x06; // time diff --git a/src/emsesp_version.h b/src/emsesp_version.h index f352db534..90d3b27d0 100644 --- a/src/emsesp_version.h +++ b/src/emsesp_version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.8.2-dev.0" +#define EMSESP_APP_VERSION "3.8.2-dev.1" diff --git a/src/web/WebSchedulerService.cpp b/src/web/WebSchedulerService.cpp index 943d30b21..70da3063f 100644 --- a/src/web/WebSchedulerService.cpp +++ b/src/web/WebSchedulerService.cpp @@ -248,18 +248,24 @@ void WebSchedulerService::publish(const bool force) { snprintf(val_obj, sizeof(val_obj), "value_json['%s']", scheduleItem.name); snprintf(val_cond, sizeof(val_cond), "%s is defined", val_obj); + // Optimized: use stack buffer instead of string concatenation to avoid heap allocations + char val_tpl[150]; if (Mqtt::discovery_type() == Mqtt::discoveryType::HOMEASSISTANT) { - config["val_tpl"] = (std::string) "{{" + val_obj + " if " + val_cond + "}}"; + snprintf(val_tpl, sizeof(val_tpl), "{{%s if %s}}", val_obj, val_cond); } else { - config["val_tpl"] = (std::string) "{{" + val_obj + "}}"; // omit value conditional Jinja2 template code + snprintf(val_tpl, sizeof(val_tpl), "{{%s}}", val_obj); // omit value conditional Jinja2 template code } + config["val_tpl"] = val_tpl; char uniq_s[70]; snprintf(uniq_s, sizeof(uniq_s), "%s_%s", F_(scheduler), scheduleItem.name); config["uniq_id"] = uniq_s; config["name"] = (const char *)scheduleItem.name; - config["def_ent_id"] = std::string("switch.") + uniq_s; + // Optimized: use stack buffer instead of string concatenation + char def_ent_id[80]; + snprintf(def_ent_id, sizeof(def_ent_id), "switch.%s", uniq_s); + config["def_ent_id"] = def_ent_id; char topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; char command_topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; @@ -331,7 +337,7 @@ bool WebSchedulerService::command(const char * name, const std::string & command int httpResult = 0; if (value.length() || method == "post") { // we have all lowercase if (value.find_first_of('{') != std::string::npos) { - http.addHeader("Content-Type", "application/json"); // auto-set to JSON + http.addHeader(asyncsrv::T_Content_Type, asyncsrv::T_application_json, false); // auto-set to JSON } httpResult = http.POST(value.c_str()); } else { diff --git a/src/web/WebSettingsService.cpp b/src/web/WebSettingsService.cpp index 5d2dc0354..03d5e95ee 100644 --- a/src/web/WebSettingsService.cpp +++ b/src/web/WebSettingsService.cpp @@ -496,7 +496,15 @@ void WebSettings::set_board_profile(WebSettings & settings) { System::load_board_profile(data, settings.board_profile.c_str()); } - EMSESP::logger().info("Loaded board profile %s", settings.board_profile.c_str()); +// log board profile and PSRAM info +#ifndef EMSESP_STANDALONE + uint32_t psram_size = ESP.getPsramSize() / 1024; // in KB + if (psram_size > 0) { + EMSESP::logger().info("Loaded board profile %s, PSRAM: %lu KB", settings.board_profile.c_str(), psram_size); + } else { + EMSESP::logger().info("Loaded board profile %s, PSRAM: not available", settings.board_profile.c_str()); + } +#endif // apply the new board profile settings // 0=led, 1=dallas, 2=rx, 3=tx, 4=button, 5=phy_type, 6=eth_power, 7=eth_phy_addr, 8=eth_clock_mode, 9=led_type