diff --git a/.dockerignore b/.dockerignore index 66bedec..5b41fe6 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,3 @@ .env node_modules -.git +.git \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 899fb1a..0000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,13 +0,0 @@ -# To get started with Dependabot version updates, you'll need to specify which -# package ecosystems to update and where the package manifests are located. -# Please see the documentation for all configuration options: -# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file - -version: 2 -updates: - - package-ecosystem: npm - directory: "/" - schedule: - interval: daily - time: '20:00' - open-pull-requests-limit: 10 diff --git a/.gitignore b/.gitignore index 559c261..1515b73 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ node_modules # Keep environment variables out of version control .env + +src/external diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index b713171..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "protobufs"] - path = src/protobufs - url = https://github.com/meshtastic/protobufs.git diff --git a/Dockerfile b/Dockerfile index 4094a66..993acb1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,29 +1,16 @@ -FROM node:lts-alpine AS build - -RUN apk add --no-cache openssl +FROM node:lts-alpine WORKDIR /app # Copy only package files and install deps # This layer will be cached as long as package*.json don't change COPY package*.json package-lock.json* ./ -RUN --mount=type=cache,target=/root/.npm npm ci --omit=dev +RUN npm ci # Copy the rest of your source COPY . . -# Pre-generate prisma client -RUN node_modules/.bin/prisma generate - -FROM node:lts-alpine - RUN apk add --no-cache openssl -USER node:node -WORKDIR /app - -COPY --from=build --chown=node:node /app . - - -EXPOSE 8080 +EXPOSE 8080 \ No newline at end of file diff --git a/README.md b/README.md index 2ee653b..7987abd 100644 --- a/README.md +++ b/README.md @@ -65,11 +65,6 @@ git clone https://github.com/liamcottle/meshtastic-map cd meshtastic-map ``` -Install Meshtastic protobufs definitions -``` -git clone https://github.com/meshtastic/protobufs src/protobufs -``` - Install NodeJS dependencies ``` @@ -127,6 +122,9 @@ You will now need to restart the `index.js` and `mqtt.js` scripts. ## MQTT Collector +> Please note, due to the Meshtastic protobuf schema files being locked under a GPLv3 license, these are not provided in this MIT licensed project. +You will need to obtain these files yourself to be able to use the MQTT Collector. + By default, the [MQTT Collector](./src/mqtt.js) connects to the public Meshtastic MQTT server. Alternatively, you may provide the relevant options shown in the help section below to connect to your own MQTT server along with your own decryption keys. diff --git a/docker-compose.yml b/docker-compose.yml index 026bb0c..85d17e6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -30,18 +30,6 @@ services: DATABASE_URL: "mysql://root:password@database:3306/meshtastic-map?connection_limit=100" MAP_OPTS: "" # add any custom index.js options here - # publishes mqtt packets via websocket - meshtastic-ws: - container_name: meshtastic-ws - build: - context: . - dockerfile: ./Dockerfile - command: /app/docker/ws.sh - ports: - - 8081:8081/tcp - environment: - WS_OPTS: "" - # runs the database to store everything from mqtt database: container_name: database diff --git a/docker/ws.sh b/docker/ws.sh deleted file mode 100755 index 71d4048..0000000 --- a/docker/ws.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -echo "Starting websocket publisher" -exec node src/ws.js ${WS_OPTS} - diff --git a/package-lock.json b/package-lock.json index 1fb2318..532eb19 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,19 +9,37 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@prisma/client": "^6.16.2", - "command-line-args": "^6.0.1", - "command-line-usage": "^7.0.3", - "compression": "^1.8.1", - "cors": "^2.8.5", - "express": "^5.2.1", - "mqtt": "^5.14.1", - "protobufjs": "^7.5.4", - "ws": "^8.18.3" + "@prisma/client": "^5.11.0", + "command-line-args": "^5.2.1", + "command-line-usage": "^7.0.1", + "compression": "^1.7.4", + "express": "^5.0.0", + "mqtt": "^5.3.6", + "protobufjs": "^7.2.6" }, "devDependencies": { - "jest": "^30.1.3", - "prisma": "^6.16.2" + "jest": "^29.7.0", + "prisma": "^5.10.2" + } + }, + "node_modules/@75lb/deep-merge": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@75lb/deep-merge/-/deep-merge-1.1.1.tgz", + "integrity": "sha512-xvgv6pkMGBA6GwdyJbNAnDmfAIR/DfWhrj9jgWh3TY7gRm3KO46x/GPjRg6wJ0nOepwqrNxFfojebh0Df4h4Tw==", + "dependencies": { + "lodash.assignwith": "^4.2.0", + "typical": "^7.1.1" + }, + "engines": { + "node": ">=12.17" + } + }, + "node_modules/@75lb/deep-merge/node_modules/typical": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", + "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==", + "engines": { + "node": ">=12.17" } }, "node_modules/@ampproject/remapping": { @@ -29,7 +47,6 @@ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -39,48 +56,43 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", - "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", + "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.3.tgz", - "integrity": "sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", "dev": true, - "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.3", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helpers": "^7.28.3", - "@babel/parser": "^7.28.3", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.3", - "@babel/types": "^7.28.2", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -96,11 +108,10 @@ } }, "node_modules/@babel/core/node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, - "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -117,36 +128,32 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@babel/generator": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", - "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.3", - "@babel/types": "^7.28.2", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" + "@babel/types": "^7.25.6", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", + "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-validator-option": "^7.27.1", - "browserslist": "^4.24.0", + "@babel/compat-data": "^7.25.2", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -159,45 +166,33 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, - "license": "ISC", "dependencies": { "yallist": "^3.0.2" } }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", + "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.28.3" + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.2" }, "engines": { "node": ">=6.9.0" @@ -207,67 +202,160 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "node_modules/@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.3.tgz", - "integrity": "sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw==", - "dev": true, - "license": "MIT", "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.2" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/parser": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.3.tgz", - "integrity": "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==", + "node_modules/@babel/helper-string-parser": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", + "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.28.2" + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.6" }, "bin": { "parser": "bin/babel-parser.js" @@ -281,7 +369,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -294,7 +381,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -307,7 +393,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -320,7 +405,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -332,13 +416,12 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", - "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz", + "integrity": "sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -352,7 +435,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -365,7 +447,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -374,13 +455,12 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", - "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -394,7 +474,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -407,7 +486,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -420,7 +498,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -433,7 +510,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -446,7 +522,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -459,7 +534,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -472,7 +546,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -488,7 +561,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -500,13 +572,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", - "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.4.tgz", + "integrity": "sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -516,54 +587,53 @@ } }, "node_modules/@babel/runtime": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.2.tgz", - "integrity": "sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==", - "license": "MIT", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", + "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.3.tgz", - "integrity": "sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.3", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.3", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.2", - "debug": "^4.3.1" + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6", + "debug": "^4.3.1", + "globals": "^11.1.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse/node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, - "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -580,18 +650,17 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@babel/types": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", - "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" @@ -601,67 +670,13 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@emnapi/core": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.5.0.tgz", - "integrity": "sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.1.0", - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.5.0.tgz", - "integrity": "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", - "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } + "dev": true }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, - "license": "ISC", "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", @@ -678,67 +693,64 @@ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@jest/console": { - "version": "30.1.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.1.2.tgz", - "integrity": "sha512-BGMAxj8VRmoD0MoA/jo9alMXSRoqW8KPeqOfEo1ncxnRLatTBCpRoOwlwlEMdudp68Q6WSGwYrrLtTGOh8fLzw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/types": "30.0.5", + "@jest/types": "^29.6.3", "@types/node": "*", - "chalk": "^4.1.2", - "jest-message-util": "30.1.0", - "jest-util": "30.0.5", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", "slash": "^3.0.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/core": { - "version": "30.1.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.1.3.tgz", - "integrity": "sha512-LIQz7NEDDO1+eyOA2ZmkiAyYvZuo6s1UxD/e2IHldR6D7UYogVq3arTmli07MkENLq6/3JEQjp0mA8rrHHJ8KQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/console": "30.1.2", - "@jest/pattern": "30.0.1", - "@jest/reporters": "30.1.3", - "@jest/test-result": "30.1.3", - "@jest/transform": "30.1.2", - "@jest/types": "30.0.5", + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "ansi-escapes": "^4.3.2", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "exit-x": "^0.2.2", - "graceful-fs": "^4.2.11", - "jest-changed-files": "30.0.5", - "jest-config": "30.1.3", - "jest-haste-map": "30.1.0", - "jest-message-util": "30.1.0", - "jest-regex-util": "30.0.1", - "jest-resolve": "30.1.3", - "jest-resolve-dependencies": "30.1.3", - "jest-runner": "30.1.3", - "jest-runtime": "30.1.3", - "jest-snapshot": "30.1.2", - "jest-util": "30.0.5", - "jest-validate": "30.1.0", - "jest-watcher": "30.1.3", - "micromatch": "^4.0.8", - "pretty-format": "30.0.5", - "slash": "^3.0.0" + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" @@ -749,150 +761,111 @@ } } }, - "node_modules/@jest/diff-sequences": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", - "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/@jest/environment": { - "version": "30.1.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.1.2.tgz", - "integrity": "sha512-N8t1Ytw4/mr9uN28OnVf0SYE2dGhaIxOVYcwsf9IInBKjvofAjbFRvedvBBlyTYk2knbJTiEjEJ2PyyDIBnd9w==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/fake-timers": "30.1.2", - "@jest/types": "30.0.5", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "30.0.5" + "jest-mock": "^29.7.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect": { - "version": "30.1.2", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.1.2.tgz", - "integrity": "sha512-tyaIExOwQRCxPCGNC05lIjWJztDwk2gPDNSDGg1zitXJJ8dC3++G/CRjE5mb2wQsf89+lsgAgqxxNpDLiCViTA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", "dev": true, - "license": "MIT", "dependencies": { - "expect": "30.1.2", - "jest-snapshot": "30.1.2" + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "30.1.2", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.1.2.tgz", - "integrity": "sha512-HXy1qT/bfdjCv7iC336ExbqqYtZvljrV8odNdso7dWK9bSeHtLlvwWWC3YSybSPL03Gg5rug6WLCZAZFH72m0A==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/get-type": "30.1.0" + "jest-get-type": "^29.6.3" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "30.1.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.1.2.tgz", - "integrity": "sha512-Beljfv9AYkr9K+ETX9tvV61rJTY706BhBUtiaepQHeEGfe0DbpvUA5Z3fomwc5Xkhns6NWrcFDZn+72fLieUnA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/types": "30.0.5", - "@sinonjs/fake-timers": "^13.0.0", + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "30.1.0", - "jest-mock": "30.0.5", - "jest-util": "30.0.5" + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/get-type": { - "version": "30.1.0", - "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", - "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/globals": { - "version": "30.1.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.1.2.tgz", - "integrity": "sha512-teNTPZ8yZe3ahbYnvnVRDeOjr+3pu2uiAtNtrEsiMjVPPj+cXd5E/fr8BL7v/T7F31vYdEHrI5cC/2OoO/vM9A==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/environment": "30.1.2", - "@jest/expect": "30.1.2", - "@jest/types": "30.0.5", - "jest-mock": "30.0.5" + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/pattern": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", - "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.0.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/reporters": { - "version": "30.1.3", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.1.3.tgz", - "integrity": "sha512-VWEQmJWfXMOrzdFEOyGjUEOuVXllgZsoPtEHZzfdNz18RmzJ5nlR6kp8hDdY8dDS1yGOXAY7DHT+AOHIPSBV0w==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", "dev": true, - "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "30.1.2", - "@jest/test-result": "30.1.3", - "@jest/transform": "30.1.2", - "@jest/types": "30.0.5", - "@jridgewell/trace-mapping": "^0.3.25", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", "@types/node": "*", - "chalk": "^4.1.2", - "collect-v8-coverage": "^1.0.2", - "exit-x": "^0.2.2", - "glob": "^10.3.10", - "graceful-fs": "^4.2.11", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-instrument": "^6.0.0", "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^5.0.0", + "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "30.1.0", - "jest-util": "30.0.5", - "jest-worker": "30.1.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", "slash": "^3.0.0", - "string-length": "^4.0.2", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", "v8-to-istanbul": "^9.0.1" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" @@ -904,136 +877,116 @@ } }, "node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, - "license": "MIT", "dependencies": { - "@sinclair/typebox": "^0.34.0" + "@sinclair/typebox": "^0.27.8" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/snapshot-utils": { - "version": "30.1.2", - "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.1.2.tgz", - "integrity": "sha512-vHoMTpimcPSR7OxS2S0V1Cpg8eKDRxucHjoWl5u4RQcnxqQrV3avETiFpl8etn4dqxEGarBeHbIBety/f8mLXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "30.0.5", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "natural-compare": "^1.4.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/source-map": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz", - "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", "dev": true, - "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "callsites": "^3.1.0", - "graceful-fs": "^4.2.11" + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/test-result": { - "version": "30.1.3", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.1.3.tgz", - "integrity": "sha512-P9IV8T24D43cNRANPPokn7tZh0FAFnYS2HIfi5vK18CjRkTDR9Y3e1BoEcAJnl4ghZZF4Ecda4M/k41QkvurEQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/console": "30.1.2", - "@jest/types": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "collect-v8-coverage": "^1.0.2" + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/test-sequencer": { - "version": "30.1.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.1.3.tgz", - "integrity": "sha512-82J+hzC0qeQIiiZDThh+YUadvshdBswi5nuyXlEmXzrhw5ZQSRHeQ5LpVMD/xc8B3wPePvs6VMzHnntxL+4E3w==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/test-result": "30.1.3", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.1.0", + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", "slash": "^3.0.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/transform": { - "version": "30.1.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.1.2.tgz", - "integrity": "sha512-UYYFGifSgfjujf1Cbd3iU/IQoSd6uwsj8XHj5DSDf5ERDcWMdJOPTkHWXj4U+Z/uMagyOQZ6Vne8C4nRIrCxqA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/core": "^7.27.4", - "@jest/types": "30.0.5", - "@jridgewell/trace-mapping": "^0.3.25", - "babel-plugin-istanbul": "^7.0.0", - "chalk": "^4.1.2", + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.1.0", - "jest-regex-util": "30.0.1", - "jest-util": "30.0.5", - "micromatch": "^4.0.8", - "pirates": "^4.0.7", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", "slash": "^3.0.0", - "write-file-atomic": "^5.0.1" + "write-file-atomic": "^4.0.2" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/types": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.0.5.tgz", - "integrity": "sha512-aREYa3aku9SSnea4aX6bhKn4bgv3AXkgijoQgbYV3yvbiGt6z+MQ85+6mIhx9DsKW2BuB/cLR/A+tcMThx+KLQ==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, - "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { @@ -1041,149 +994,95 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, - "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, - "license": "MIT" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.30", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz", - "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", - "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.10.0" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@pkgr/core": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", - "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/pkgr" - } - }, "node_modules/@prisma/client": { - "version": "6.16.2", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.16.2.tgz", - "integrity": "sha512-E00PxBcalMfYO/TWnXobBVUai6eW/g5OsifWQsQDzJYm7yaY+IRLo7ZLsaefi0QkTpxfuhFcQ/w180i6kX3iJw==", + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.16.1.tgz", + "integrity": "sha512-wM9SKQjF0qLxdnOZIVAIMKiz6Hu7vDt4FFAih85K1dk/Rr2mdahy6d3QP41K62N9O0DJJA//gUDA3Mp49xsKIg==", "hasInstallScript": true, - "license": "Apache-2.0", "engines": { - "node": ">=18.18" + "node": ">=16.13" }, "peerDependencies": { - "prisma": "*", - "typescript": ">=5.1.0" + "prisma": "*" }, "peerDependenciesMeta": { "prisma": { "optional": true - }, - "typescript": { - "optional": true } } }, - "node_modules/@prisma/config": { - "version": "6.16.2", - "resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.16.2.tgz", - "integrity": "sha512-mKXSUrcqXj0LXWPmJsK2s3p9PN+aoAbyMx7m5E1v1FufofR1ZpPoIArjjzOIm+bJRLLvYftoNYLx1tbHgF9/yg==", - "devOptional": true, - "license": "Apache-2.0", - "dependencies": { - "c12": "3.1.0", - "deepmerge-ts": "7.1.5", - "effect": "3.16.12", - "empathic": "2.0.0" - } - }, "node_modules/@prisma/debug": { - "version": "6.16.2", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.16.2.tgz", - "integrity": "sha512-bo4/gA/HVV6u8YK2uY6glhNsJ7r+k/i5iQ9ny/3q5bt9ijCj7WMPUwfTKPvtEgLP+/r26Z686ly11hhcLiQ8zA==", - "devOptional": true, - "license": "Apache-2.0" + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.16.1.tgz", + "integrity": "sha512-JsNgZAg6BD9RInLSrg7ZYzo11N7cVvYArq3fHGSD89HSgtN0VDdjV6bib7YddbcO6snzjchTiLfjeTqBjtArVQ==", + "devOptional": true }, "node_modules/@prisma/engines": { - "version": "6.16.2", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.16.2.tgz", - "integrity": "sha512-7yf3AjfPUgsg/l7JSu1iEhsmZZ/YE00yURPjTikqm2z4btM0bCl2coFtTGfeSOWbQMmq45Jab+53yGUIAT1sjA==", + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.16.1.tgz", + "integrity": "sha512-KkyF3eIUtBIyp5A/rJHCtwQO18OjpGgx18PzjyGcJDY/+vNgaVyuVd+TgwBgeq6NLdd1XMwRCI+58vinHsAdfA==", "devOptional": true, "hasInstallScript": true, - "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "6.16.2", - "@prisma/engines-version": "6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43", - "@prisma/fetch-engine": "6.16.2", - "@prisma/get-platform": "6.16.2" + "@prisma/debug": "5.16.1", + "@prisma/engines-version": "5.16.0-24.34ace0eb2704183d2c05b60b52fba5c43c13f303", + "@prisma/fetch-engine": "5.16.1", + "@prisma/get-platform": "5.16.1" } }, "node_modules/@prisma/engines-version": { - "version": "6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43.tgz", - "integrity": "sha512-ThvlDaKIVrnrv97ujNFDYiQbeMQpLa0O86HFA2mNoip4mtFqM7U5GSz2ie1i2xByZtvPztJlNRgPsXGeM/kqAA==", - "devOptional": true, - "license": "Apache-2.0" + "version": "5.16.0-24.34ace0eb2704183d2c05b60b52fba5c43c13f303", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.16.0-24.34ace0eb2704183d2c05b60b52fba5c43c13f303.tgz", + "integrity": "sha512-HkT2WbfmFZ9WUPyuJHhkiADxazHg8Y4gByrTSVeb3OikP6tjQ7txtSUGu9OBOBH0C13dPKN2qqH12xKtHu/Hiw==", + "devOptional": true }, "node_modules/@prisma/fetch-engine": { - "version": "6.16.2", - "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.16.2.tgz", - "integrity": "sha512-wPnZ8DMRqpgzye758ZvfAMiNJRuYpz+rhgEBZi60ZqDIgOU2694oJxiuu3GKFeYeR/hXxso4/2oBC243t/whxQ==", + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.16.1.tgz", + "integrity": "sha512-oOkjaPU1lhcA/Rvr4GVfd1NLJBwExgNBE36Ueq7dr71kTMwy++a3U3oLd2ZwrV9dj9xoP6LjCcky799D9nEt4w==", "devOptional": true, - "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "6.16.2", - "@prisma/engines-version": "6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43", - "@prisma/get-platform": "6.16.2" + "@prisma/debug": "5.16.1", + "@prisma/engines-version": "5.16.0-24.34ace0eb2704183d2c05b60b52fba5c43c13f303", + "@prisma/get-platform": "5.16.1" } }, "node_modules/@prisma/get-platform": { - "version": "6.16.2", - "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.16.2.tgz", - "integrity": "sha512-U/P36Uke5wS7r1+omtAgJpEB94tlT4SdlgaeTc6HVTTT93pXj7zZ+B/cZnmnvjcNPfWddgoDx8RLjmQwqGDYyA==", + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.16.1.tgz", + "integrity": "sha512-R4IKnWnMkR2nUAbU5gjrPehdQYUUd7RENFD2/D+xXTNhcqczp0N+WEGQ3ViyI3+6mtVcjjNIMdnUTNyu3GxIgA==", "devOptional": true, - "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "6.16.2" + "@prisma/debug": "5.16.1" } }, "node_modules/@protobufjs/aspromise": { @@ -1241,48 +1140,27 @@ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, "node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true }, "node_modules/@sinonjs/commons": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" } }, "node_modules/@sinonjs/fake-timers": { - "version": "13.0.5", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", - "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^3.0.1" - } - }, - "node_modules/@standard-schema/spec": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", - "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.0.tgz", - "integrity": "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" + "@sinonjs/commons": "^3.0.0" } }, "node_modules/@types/babel__core": { @@ -1290,7 +1168,6 @@ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", @@ -1300,11 +1177,10 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", - "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" } @@ -1314,35 +1190,40 @@ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, - "license": "MIT", "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", - "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.28.2" + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" } }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@types/istanbul-lib-report": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, - "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" } @@ -1352,7 +1233,6 @@ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" } @@ -1366,26 +1246,24 @@ } }, "node_modules/@types/readable-stream": { - "version": "4.0.21", - "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.21.tgz", - "integrity": "sha512-19eKVv9tugr03IgfXlA9UVUVRbW6IuqRO5B92Dl4a6pT7K8uaGrNS0GkxiZD0BOk6PLuXl5FhWl//eX/pzYdTQ==", - "license": "MIT", + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.14.tgz", + "integrity": "sha512-xZn/AuUbCMShGsqH/ehZtGDwQtbx00M9rZ2ENLe4tOjFZ/JFeWMhEZkk2fEe1jAUqqEAURIkFJ7Az/go8mM1/w==", "dependencies": { - "@types/node": "*" + "@types/node": "*", + "safe-buffer": "~5.1.1" } }, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@types/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", - "license": "MIT", + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", "dependencies": { "@types/node": "*" } @@ -1395,7 +1273,6 @@ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", "dev": true, - "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } @@ -1404,290 +1281,12 @@ "version": "21.0.3", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "dev": true, - "license": "ISC" - }, - "node_modules/@unrs/resolver-binding-android-arm-eabi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", - "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@unrs/resolver-binding-android-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", - "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", - "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", - "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-freebsd-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", - "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", - "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", - "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", - "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", - "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", - "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", - "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", - "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", - "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-x64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", - "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-x64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", - "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-wasm32-wasi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", - "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@napi-rs/wasm-runtime": "^0.2.11" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", - "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", - "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@unrs/resolver-binding-win32-x64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", - "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "dev": true }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "license": "MIT", "dependencies": { "event-target-shim": "^5.0.0" }, @@ -1695,12 +1294,23 @@ "node": ">=6.5" } }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, - "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -1712,16 +1322,12 @@ } }, "node_modules/ansi-regex": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz", - "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "node": ">=8" } }, "node_modules/ansi-styles": { @@ -1743,7 +1349,6 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, - "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -1757,80 +1362,91 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/array-back": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", - "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", - "license": "MIT", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", "engines": { - "node": ">=12.17" + "node": ">=6" } }, "node_modules/babel-jest": { - "version": "30.1.2", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.1.2.tgz", - "integrity": "sha512-IQCus1rt9kaSh7PQxLYRY5NmkNrNlU2TpabzwV7T2jljnpdHOcmnYYv8QmE04Li4S3a2Lj8/yXyET5pBarPr6g==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/transform": "30.1.2", - "@types/babel__core": "^7.20.5", - "babel-plugin-istanbul": "^7.0.0", - "babel-preset-jest": "30.0.1", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", "slash": "^3.0.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { - "@babel/core": "^7.11.0" + "@babel/core": "^7.8.0" } }, "node_modules/babel-plugin-istanbul": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.0.tgz", - "integrity": "sha512-C5OzENSx/A+gt7t4VH1I2XsflxyPUmXRFPKBxt33xncdOmq7oROVM3bZv9Ysjjkv8OJYDMa+tKuKMvqU/H3xdw==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-instrument": "^6.0.2", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", "test-exclude": "^6.0.0" }, "engines": { - "node": ">=12" + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" } }, "node_modules/babel-plugin-jest-hoist": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.0.1.tgz", - "integrity": "sha512-zTPME3pI50NsFW8ZBaVIOeAxzEY7XHlmWeXXu9srI+9kNfzCUTy8MFan46xOGZY8NZThMqq+e3qZUKsvXbasnQ==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.27.3", - "@types/babel__core": "^7.20.5" + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/babel-preset-current-node-syntax": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", - "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", + "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", @@ -1849,32 +1465,30 @@ "@babel/plugin-syntax-top-level-await": "^7.14.5" }, "peerDependencies": { - "@babel/core": "^7.0.0 || ^8.0.0-0" + "@babel/core": "^7.0.0" } }, "node_modules/babel-preset-jest": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.0.1.tgz", - "integrity": "sha512-+YHejD5iTWI46cZmcc/YtX4gaKBtdqCHCVfuVinizVpbmyjO3zYmeuyFdfA8duRqQZfgCAMlsfmkVbJ+e2MAJw==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", "dev": true, - "license": "MIT", "dependencies": { - "babel-plugin-jest-hoist": "30.0.1", - "babel-preset-current-node-syntax": "^1.1.0" + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { - "@babel/core": "^7.11.0" + "@babel/core": "^7.0.0" } }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/base64-js": { "version": "1.5.1", @@ -1893,14 +1507,12 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/bl": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-6.1.0.tgz", - "integrity": "sha512-ClDyJGQkc8ZtzdAAbAwBmhMSpwN/sC9HA8jxdYm6nVUbCfZbe2mgza4qh7AuEYyEPB/c4Kznf9s66bnsKMQDjw==", - "license": "MIT", + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/bl/-/bl-6.0.13.tgz", + "integrity": "sha512-tMncAcpsyjZgAVbVFupVIaB2xud13xxT59fdHkuszY2jdZkqIWfpQdmII1fOe3kOGAz0mNLTIHEm+KxpYsQKKg==", "dependencies": { "@types/readable-stream": "^4.0.0", "buffer": "^6.0.3", @@ -1909,34 +1521,36 @@ } }, "node_modules/body-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.1.tgz", - "integrity": "sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==", - "license": "MIT", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", + "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", - "debug": "^4.4.3", + "debug": "^4.4.0", "http-errors": "^2.0.0", - "iconv-lite": "^0.7.0", + "iconv-lite": "^0.6.3", "on-finished": "^2.4.1", "qs": "^6.14.0", - "raw-body": "^3.0.1", - "type-is": "^2.0.1" + "raw-body": "^3.0.0", + "type-is": "^2.0.0" }, "engines": { "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" } }, "node_modules/body-parser/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "dependencies": { "ms": "^2.1.3" }, @@ -1952,17 +1566,16 @@ "node_modules/body-parser/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, "node_modules/braces": { @@ -1970,7 +1583,6 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, - "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -1978,22 +1590,10 @@ "node": ">=8" } }, - "node_modules/broker-factory": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/broker-factory/-/broker-factory-3.1.8.tgz", - "integrity": "sha512-xmVnYN0FZtynhPUmAnN+/MFRdbDi3syCuxWV7o7s78FcIN0pjDtn9mUrVqEgdjQkbfojRhlPWbYbXJkMCyddrg==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.27.6", - "fast-unique-numbers": "^9.0.22", - "tslib": "^2.8.1", - "worker-factory": "^7.0.44" - } - }, "node_modules/browserslist": { - "version": "4.25.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.4.tgz", - "integrity": "sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", + "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", "dev": true, "funding": [ { @@ -2009,13 +1609,11 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", - "peer": true, "dependencies": { - "caniuse-lite": "^1.0.30001737", - "electron-to-chromium": "^1.5.211", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.3" + "caniuse-lite": "^1.0.30001663", + "electron-to-chromium": "^1.5.28", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -2029,7 +1627,6 @@ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, - "license": "Apache-2.0", "dependencies": { "node-int64": "^0.4.0" } @@ -2052,7 +1649,6 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -2064,48 +1660,17 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", "engines": { "node": ">= 0.8" } }, - "node_modules/c12": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/c12/-/c12-3.1.0.tgz", - "integrity": "sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "chokidar": "^4.0.3", - "confbox": "^0.2.2", - "defu": "^6.1.4", - "dotenv": "^16.6.1", - "exsolve": "^1.0.7", - "giget": "^2.0.0", - "jiti": "^2.4.2", - "ohash": "^2.0.11", - "pathe": "^2.0.3", - "perfect-debounce": "^1.0.0", - "pkg-types": "^2.2.0", - "rc9": "^2.1.2" - }, - "peerDependencies": { - "magicast": "^0.3.5" - }, - "peerDependenciesMeta": { - "magicast": { - "optional": true - } - } - }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" @@ -2118,7 +1683,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" @@ -2135,7 +1699,6 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -2145,15 +1708,14 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001739", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001739.tgz", - "integrity": "sha512-y+j60d6ulelrNSwpPyrHdl+9mJnQzHBr08xm48Qno0nSk4h3Qojh+ziv2qE6rXf4k3tadF4o1J/1tAbVm1NtnA==", + "version": "1.0.30001664", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001664.tgz", + "integrity": "sha512-AmE7k4dXiNKQipgn7a2xg558IRqPN3jMQY/rOsbxDhrd0tyChwbITBfiwtnqz8bi2M5mIWbxAYBvk7W7QBUS2g==", "dev": true, "funding": [ { @@ -2168,8 +1730,7 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ], - "license": "CC-BY-4.0" + ] }, "node_modules/chalk": { "version": "4.1.2", @@ -2205,31 +1766,14 @@ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" } }, - "node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/ci-info": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz", - "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "dev": true, "funding": [ { @@ -2237,34 +1781,21 @@ "url": "https://github.com/sponsors/sibiraj-s" } ], - "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/citty": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz", - "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "consola": "^3.2.3" - } - }, "node_modules/cjs-module-lexer": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.1.0.tgz", - "integrity": "sha512-UX0OwmYRYQQetfrLEZeewIFFI+wSTofC+pMBLNuH3RUuu/xzG1oz84UCEDOSoQlN3fZ4+AzmV50ZYvGqkMh9yA==", - "dev": true, - "license": "MIT" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz", + "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==", + "dev": true }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, - "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -2274,75 +1805,11 @@ "node": ">=12" } }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, - "license": "MIT", "engines": { "iojs": ">= 1.0.0", "node": ">= 0.12.0" @@ -2352,8 +1819,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/color-convert": { "version": "2.0.1", @@ -2372,48 +1838,53 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/command-line-args": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-6.0.1.tgz", - "integrity": "sha512-Jr3eByUjqyK0qd8W0SGFW1nZwqCaNCtbXjRo2cRJC1OYxWl3MZ5t1US3jq+cO4sPavqgw4l9BMGX0CBe+trepg==", - "license": "MIT", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", + "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", "dependencies": { - "array-back": "^6.2.2", - "find-replace": "^5.0.2", + "array-back": "^3.1.0", + "find-replace": "^3.0.0", "lodash.camelcase": "^4.3.0", - "typical": "^7.2.0" + "typical": "^4.0.0" }, "engines": { - "node": ">=12.20" - }, - "peerDependencies": { - "@75lb/nature": "latest" - }, - "peerDependenciesMeta": { - "@75lb/nature": { - "optional": true - } + "node": ">=4.0.0" } }, "node_modules/command-line-usage": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.3.tgz", - "integrity": "sha512-PqMLy5+YGwhMh1wS04mVG44oqDsgyLRSKJBdOo1bnYhMKBW65gZF1dRp2OZRhiTjgUHljy99qkO7bsctLaw35Q==", - "license": "MIT", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.1.tgz", + "integrity": "sha512-NCyznE//MuTjwi3y84QVUGEOT+P5oto1e1Pk/jFPVdPPfsG03qpTIl3yw6etR+v73d0lXsoojRpvbru2sqePxQ==", "dependencies": { "array-back": "^6.2.2", "chalk-template": "^0.4.0", - "table-layout": "^4.1.0", + "table-layout": "^3.0.0", "typical": "^7.1.1" }, "engines": { "node": ">=12.20.0" } }, + "node_modules/command-line-usage/node_modules/array-back": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", + "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", + "engines": { + "node": ">=12.17" + } + }, + "node_modules/command-line-usage/node_modules/typical": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", + "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==", + "engines": { + "node": ">=12.17" + } + }, "node_modules/commist": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/commist/-/commist-3.2.0.tgz", - "integrity": "sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw==", - "license": "MIT" + "integrity": "sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw==" }, "node_modules/compressible": { "version": "2.0.18", @@ -2427,17 +1898,16 @@ } }, "node_modules/compression": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", - "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", - "license": "MIT", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "dependencies": { - "bytes": "3.1.2", - "compressible": "~2.0.18", + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", "debug": "2.6.9", - "negotiator": "~0.6.4", - "on-headers": "~1.1.0", - "safe-buffer": "5.2.1", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", "vary": "~1.1.2" }, "engines": { @@ -2448,8 +1918,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/concat-stream": { "version": "2.0.0", @@ -2458,7 +1927,6 @@ "engines": [ "node >= 6.0" ], - "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", @@ -2470,7 +1938,6 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -2480,23 +1947,6 @@ "node": ">= 6" } }, - "node_modules/confbox": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", - "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/consola": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", - "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": "^14.18.0 || >=16.10.0" - } - }, "node_modules/content-disposition": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", @@ -2508,11 +1958,29 @@ "node": ">= 0.6" } }, + "node_modules/content-disposition/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/content-type": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", "engines": { "node": ">= 0.6" } @@ -2521,13 +1989,12 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "engines": { "node": ">= 0.6" } @@ -2540,24 +2007,32 @@ "node": ">=6.6.0" } }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, "dependencies": { - "object-assign": "^4", - "vary": "^1" + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" }, "engines": { - "node": ">= 0.10" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -2576,11 +2051,10 @@ } }, "node_modules/dedent": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.6.0.tgz", - "integrity": "sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", "dev": true, - "license": "MIT", "peerDependencies": { "babel-plugin-macros": "^3.1.0" }, @@ -2595,28 +2069,10 @@ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/deepmerge-ts": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/deepmerge-ts/-/deepmerge-ts-7.1.5.tgz", - "integrity": "sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==", - "devOptional": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/defu": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", - "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", - "devOptional": true, - "license": "MIT" - }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -2625,41 +2081,28 @@ "node": ">= 0.8" } }, - "node_modules/destr": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", - "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", - "devOptional": true, - "license": "MIT" - }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/dotenv": { - "version": "16.6.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", - "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", - "devOptional": true, - "license": "BSD-2-Clause", + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", @@ -2669,42 +2112,22 @@ "node": ">= 0.4" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, - "license": "MIT" - }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, - "node_modules/effect": { - "version": "3.16.12", - "resolved": "https://registry.npmjs.org/effect/-/effect-3.16.12.tgz", - "integrity": "sha512-N39iBk0K71F9nb442TLbTkjl24FLUzuvx2i1I2RsEAQsdAdUTuUoW0vlfUXgkMTUOnYqKnWcFfqw4hK4Pw27hg==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@standard-schema/spec": "^1.0.0", - "fast-check": "^3.23.1" - } - }, "node_modules/electron-to-chromium": { - "version": "1.5.212", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.212.tgz", - "integrity": "sha512-gE7ErIzSW+d8jALWMcOIgf+IB6lpfsg6NwOhPVwKzDtN2qcBix47vlin4yzSregYDxTCXOUqAZjVY/Z3naS7ww==", - "dev": true, - "license": "ISC" + "version": "1.5.30", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.30.tgz", + "integrity": "sha512-sXI35EBN4lYxzc/pIGorlymYNzDBOqkSlVRe6MkgBsW/hW1tpC/HDJ2fjG7XnjakzfLEuvdmux0Mjs6jHq4UOA==", + "dev": true }, "node_modules/emittery": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -2713,21 +2136,10 @@ } }, "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/empathic": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.0.tgz", - "integrity": "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=14" - } + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/encodeurl": { "version": "2.0.0", @@ -2742,7 +2154,6 @@ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, - "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } @@ -2751,7 +2162,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", "engines": { "node": ">= 0.4" } @@ -2760,7 +2170,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", "engines": { "node": ">= 0.4" } @@ -2769,7 +2178,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "license": "MIT", "dependencies": { "es-errors": "^1.3.0" }, @@ -2782,7 +2190,6 @@ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -2797,7 +2204,6 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -2807,7 +2213,6 @@ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, - "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -2828,7 +2233,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "license": "MIT", "engines": { "node": ">=6" } @@ -2837,7 +2241,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "license": "MIT", "engines": { "node": ">=0.8.x" } @@ -2847,7 +2250,6 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, - "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -2866,55 +2268,43 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/execa/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true, - "license": "ISC" - }, - "node_modules/exit-x": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz", - "integrity": "sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==", - "dev": true, - "license": "MIT", "engines": { "node": ">= 0.8.0" } }, "node_modules/expect": { - "version": "30.1.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.1.2.tgz", - "integrity": "sha512-xvHszRavo28ejws8FpemjhwswGj4w/BetHIL8cU49u4sGyXDw2+p3YbeDbj6xzlxi6kWTjIRSTJ+9sNXPnF0Zg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/expect-utils": "30.1.2", - "@jest/get-type": "30.1.0", - "jest-matcher-utils": "30.1.2", - "jest-message-util": "30.1.0", - "jest-mock": "30.0.5", - "jest-util": "30.0.5" + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/express": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", - "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", - "license": "MIT", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", + "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", "dependencies": { "accepts": "^2.0.0", - "body-parser": "^2.2.1", + "body-parser": "^2.2.0", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", - "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", @@ -2972,6 +2362,25 @@ } } }, + "node_modules/express/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/mime-types": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/express/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -2985,71 +2394,22 @@ "node": ">= 0.6" } }, - "node_modules/exsolve": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz", - "integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/fast-check": { - "version": "3.23.2", - "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.23.2.tgz", - "integrity": "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==", - "devOptional": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ], - "license": "MIT", - "dependencies": { - "pure-rand": "^6.1.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/fast-check/node_modules/pure-rand": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", - "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", - "devOptional": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ], - "license": "MIT" - }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/fast-unique-numbers": { - "version": "9.0.22", - "resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-9.0.22.tgz", - "integrity": "sha512-dBR+30yHAqBGvOuxxQdnn2lTLHCO6r/9B+M4yF8mNrzr3u1yiF+YVJ6u3GTyPN/VRWqaE1FcscZDdBgVKmrmQQ==", - "license": "MIT", + "version": "8.0.13", + "resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-8.0.13.tgz", + "integrity": "sha512-7OnTFAVPefgw2eBJ1xj2PGGR9FwYzSUso9decayHgCDX4sJkHLdcsYTytTg+tYv+wKF3U8gJuSBz2jJpQV4u/g==", "dependencies": { - "@babel/runtime": "^7.27.6", - "tslib": "^2.8.1" + "@babel/runtime": "^7.23.8", + "tslib": "^2.6.2" }, "engines": { - "node": ">=18.2.0" + "node": ">=16.1.0" } }, "node_modules/fb-watchman": { @@ -3057,7 +2417,6 @@ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, - "license": "Apache-2.0", "dependencies": { "bser": "2.1.1" } @@ -3067,7 +2426,6 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, - "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -3113,20 +2471,14 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/find-replace": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-5.0.2.tgz", - "integrity": "sha512-Y45BAiE3mz2QsrN2fb5QEtO4qb44NcS7en/0y9PEVsg351HsLeVclP8QPMH79Le9sH3rs5RSwJu99W0WPZO43Q==", - "license": "MIT", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dependencies": { + "array-back": "^3.0.1" + }, "engines": { - "node": ">=14" - }, - "peerDependencies": { - "@75lb/nature": "latest" - }, - "peerDependenciesMeta": { - "@75lb/nature": { - "optional": true - } + "node": ">=4.0.0" } }, "node_modules/find-up": { @@ -3134,7 +2486,6 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, - "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -3143,23 +2494,6 @@ "node": ">=8" } }, - "node_modules/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -3180,8 +2514,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/fsevents": { "version": "2.3.3", @@ -3189,7 +2522,6 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, - "license": "MIT", "optional": true, "os": [ "darwin" @@ -3202,7 +2534,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3212,7 +2543,6 @@ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -3222,7 +2552,6 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, - "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -3231,7 +2560,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", @@ -3256,7 +2584,6 @@ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=8.0.0" } @@ -3265,7 +2592,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" @@ -3279,7 +2605,6 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -3287,50 +2612,40 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/giget": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/giget/-/giget-2.0.0.tgz", - "integrity": "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "citty": "^0.1.6", - "consola": "^3.4.0", - "defu": "^6.1.4", - "node-fetch-native": "^1.6.6", - "nypm": "^0.6.0", - "pathe": "^2.0.3" - }, - "bin": { - "giget": "dist/cli.mjs" - } - }, "node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, - "license": "ISC", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, - "bin": { - "glob": "dist/esm/bin.mjs" + "engines": { + "node": "*" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -3342,8 +2657,7 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/has-flag": { "version": "4.0.0", @@ -3357,7 +2671,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -3369,7 +2682,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -3380,34 +2692,35 @@ "node_modules/help-me": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", - "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==", - "license": "MIT" + "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==" }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", - "license": "MIT", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dependencies": { - "depd": "~2.0.0", - "inherits": "~2.0.4", - "setprototypeof": "~1.2.0", - "statuses": "~2.0.2", - "toidentifier": "~1.0.1" + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" }, "engines": { "node": ">= 0.8" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" } }, "node_modules/human-signals": { @@ -3415,25 +2728,19 @@ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=10.17.0" } }, "node_modules/iconv-lite": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", - "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", - "license": "MIT", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" } }, "node_modules/ieee754": { @@ -3453,15 +2760,13 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "BSD-3-Clause" + ] }, "node_modules/import-local": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "dev": true, - "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" @@ -3481,7 +2786,6 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.8.19" } @@ -3492,7 +2796,6 @@ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, - "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -3503,25 +2806,6 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "node_modules/ip-address": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", - "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", - "license": "MIT", - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/ip-address/node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "license": "BSD-3-Clause" - }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -3534,15 +2818,28 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "dev": true, - "license": "MIT" + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -3552,7 +2849,6 @@ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -3562,7 +2858,6 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -3577,7 +2872,6 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" }, @@ -3589,15 +2883,13 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=8" } @@ -3607,7 +2899,6 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.23.9", "@babel/parser": "^7.23.9", @@ -3620,11 +2911,10 @@ } }, "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -3637,7 +2927,6 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", @@ -3648,26 +2937,24 @@ } }, "node_modules/istanbul-lib-source-maps": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", - "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.23", "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0" + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" }, "engines": { "node": ">=10" } }, "node_modules/istanbul-lib-source-maps/node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, - "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -3684,15 +2971,13 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/istanbul-reports": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", - "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -3701,39 +2986,22 @@ "node": ">=8" } }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/jest": { - "version": "30.1.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-30.1.3.tgz", - "integrity": "sha512-Ry+p2+NLk6u8Agh5yVqELfUJvRfV51hhVBRIB5yZPY7mU0DGBmOuFG5GebZbMbm86cdQNK0fhJuDX8/1YorISQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/core": "30.1.3", - "@jest/types": "30.0.5", - "import-local": "^3.2.0", - "jest-cli": "30.1.3" + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" }, "bin": { "jest": "bin/jest.js" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" @@ -3745,75 +3013,73 @@ } }, "node_modules/jest-changed-files": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.0.5.tgz", - "integrity": "sha512-bGl2Ntdx0eAwXuGpdLdVYVr5YQHnSZlQ0y9HVDu565lCUAe9sj6JOtBbMmBBikGIegne9piDDIOeiLVoqTkz4A==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", "dev": true, - "license": "MIT", "dependencies": { - "execa": "^5.1.1", - "jest-util": "30.0.5", + "execa": "^5.0.0", + "jest-util": "^29.7.0", "p-limit": "^3.1.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-circus": { - "version": "30.1.3", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.1.3.tgz", - "integrity": "sha512-Yf3dnhRON2GJT4RYzM89t/EXIWNxKTpWTL9BfF3+geFetWP4XSvJjiU1vrWplOiUkmq8cHLiwuhz+XuUp9DscA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/environment": "30.1.2", - "@jest/expect": "30.1.2", - "@jest/test-result": "30.1.3", - "@jest/types": "30.0.5", + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "chalk": "^4.1.2", + "chalk": "^4.0.0", "co": "^4.6.0", - "dedent": "^1.6.0", - "is-generator-fn": "^2.1.0", - "jest-each": "30.1.0", - "jest-matcher-utils": "30.1.2", - "jest-message-util": "30.1.0", - "jest-runtime": "30.1.3", - "jest-snapshot": "30.1.2", - "jest-util": "30.0.5", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", "p-limit": "^3.1.0", - "pretty-format": "30.0.5", - "pure-rand": "^7.0.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", "slash": "^3.0.0", - "stack-utils": "^2.0.6" + "stack-utils": "^2.0.3" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-cli": { - "version": "30.1.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.1.3.tgz", - "integrity": "sha512-G8E2Ol3OKch1DEeIBl41NP7OiC6LBhfg25Btv+idcusmoUSpqUkbrneMqbW9lVpI/rCKb/uETidb7DNteheuAQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/core": "30.1.3", - "@jest/test-result": "30.1.3", - "@jest/types": "30.0.5", - "chalk": "^4.1.2", - "exit-x": "^0.2.2", - "import-local": "^3.2.0", - "jest-config": "30.1.3", - "jest-util": "30.0.5", - "jest-validate": "30.1.0", - "yargs": "^17.7.2" + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" }, "bin": { "jest": "bin/jest.js" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" @@ -3825,211 +3091,204 @@ } }, "node_modules/jest-config": { - "version": "30.1.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.1.3.tgz", - "integrity": "sha512-M/f7gqdQEPgZNA181Myz+GXCe8jXcJsGjCMXUzRj22FIXsZOyHNte84e0exntOvdPaeh9tA0w+B8qlP2fAezfw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/core": "^7.27.4", - "@jest/get-type": "30.1.0", - "@jest/pattern": "30.0.1", - "@jest/test-sequencer": "30.1.3", - "@jest/types": "30.0.5", - "babel-jest": "30.1.2", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "deepmerge": "^4.3.1", - "glob": "^10.3.10", - "graceful-fs": "^4.2.11", - "jest-circus": "30.1.3", - "jest-docblock": "30.0.1", - "jest-environment-node": "30.1.2", - "jest-regex-util": "30.0.1", - "jest-resolve": "30.1.3", - "jest-runner": "30.1.3", - "jest-util": "30.0.5", - "jest-validate": "30.1.0", - "micromatch": "^4.0.8", + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "30.0.5", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "@types/node": "*", - "esbuild-register": ">=3.4.0", "ts-node": ">=9.0.0" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, - "esbuild-register": { - "optional": true - }, "ts-node": { "optional": true } } }, "node_modules/jest-diff": { - "version": "30.1.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.1.2.tgz", - "integrity": "sha512-4+prq+9J61mOVXCa4Qp8ZjavdxzrWQXrI80GNxP8f4tkI2syPuPrJgdRPZRrfUTRvIoUwcmNLbqEJy9W800+NQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/diff-sequences": "30.0.1", - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "pretty-format": "30.0.5" + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-docblock": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.0.1.tgz", - "integrity": "sha512-/vF78qn3DYphAaIc3jy4gA7XSAz167n9Bm/wn/1XhTLW7tTBIzXtCJpb/vcmc73NIIeeohCbdL94JasyXUZsGA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", "dev": true, - "license": "MIT", "dependencies": { - "detect-newline": "^3.1.0" + "detect-newline": "^3.0.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-each": { - "version": "30.1.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.1.0.tgz", - "integrity": "sha512-A+9FKzxPluqogNahpCv04UJvcZ9B3HamqpDNWNKDjtxVRYB8xbZLFuCr8JAJFpNp83CA0anGQFlpQna9Me+/tQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/get-type": "30.1.0", - "@jest/types": "30.0.5", - "chalk": "^4.1.2", - "jest-util": "30.0.5", - "pretty-format": "30.0.5" + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-environment-node": { - "version": "30.1.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.1.2.tgz", - "integrity": "sha512-w8qBiXtqGWJ9xpJIA98M0EIoq079GOQRQUyse5qg1plShUCQ0Ek1VTTcczqKrn3f24TFAgFtT+4q3aOXvjbsuA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/environment": "30.1.2", - "@jest/fake-timers": "30.1.2", - "@jest/types": "30.0.5", + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "30.0.5", - "jest-util": "30.0.5", - "jest-validate": "30.1.0" + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-haste-map": { - "version": "30.1.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.1.0.tgz", - "integrity": "sha512-JLeM84kNjpRkggcGpQLsV7B8W4LNUWz7oDNVnY1Vjj22b5/fAb3kk3htiD+4Na8bmJmjJR7rBtS2Rmq/NEcADg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/types": "30.0.5", + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", "@types/node": "*", - "anymatch": "^3.1.3", - "fb-watchman": "^2.0.2", - "graceful-fs": "^4.2.11", - "jest-regex-util": "30.0.1", - "jest-util": "30.0.5", - "jest-worker": "30.1.0", - "micromatch": "^4.0.8", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", "walker": "^1.0.8" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "optionalDependencies": { - "fsevents": "^2.3.3" + "fsevents": "^2.3.2" } }, "node_modules/jest-leak-detector": { - "version": "30.1.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.1.0.tgz", - "integrity": "sha512-AoFvJzwxK+4KohH60vRuHaqXfWmeBATFZpzpmzNmYTtmRMiyGPVhkXpBqxUQunw+dQB48bDf4NpUs6ivVbRv1g==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/get-type": "30.1.0", - "pretty-format": "30.0.5" + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "30.1.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.1.2.tgz", - "integrity": "sha512-7ai16hy4rSbDjvPTuUhuV8nyPBd6EX34HkBsBcBX2lENCuAQ0qKCPb/+lt8OSWUa9WWmGYLy41PrEzkwRwoGZQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "jest-diff": "30.1.2", - "pretty-format": "30.0.5" + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-message-util": { - "version": "30.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.1.0.tgz", - "integrity": "sha512-HizKDGG98cYkWmaLUHChq4iN+oCENohQLb7Z5guBPumYs+/etonmNFlg1Ps6yN9LTPyZn+M+b/9BbnHx3WTMDg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@jest/types": "30.0.5", - "@types/stack-utils": "^2.0.3", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "micromatch": "^4.0.8", - "pretty-format": "30.0.5", + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", "slash": "^3.0.0", - "stack-utils": "^2.0.6" + "stack-utils": "^2.0.3" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-mock": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.0.5.tgz", - "integrity": "sha512-Od7TyasAAQX/6S+QCbN6vZoWOMwlTtzzGuxJku1GhGanAjz9y+QsQkpScDmETvdc9aSXyJ/Op4rhpMYBWW91wQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/types": "30.0.5", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-util": "30.0.5" + "jest-util": "^29.7.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-pnp-resolver": { @@ -4037,7 +3296,6 @@ "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" }, @@ -4051,156 +3309,148 @@ } }, "node_modules/jest-regex-util": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", - "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", "dev": true, - "license": "MIT", "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-resolve": { - "version": "30.1.3", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.1.3.tgz", - "integrity": "sha512-DI4PtTqzw9GwELFS41sdMK32Ajp3XZQ8iygeDMWkxlRhm7uUTOFSZFVZABFuxr0jvspn8MAYy54NxZCsuCTSOw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", "dev": true, - "license": "MIT", "dependencies": { - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.1.0", - "jest-pnp-resolver": "^1.2.3", - "jest-util": "30.0.5", - "jest-validate": "30.1.0", - "slash": "^3.0.0", - "unrs-resolver": "^1.7.11" + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-resolve-dependencies": { - "version": "30.1.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.1.3.tgz", - "integrity": "sha512-DNfq3WGmuRyHRHfEet+Zm3QOmVFtIarUOQHHryKPc0YL9ROfgWZxl4+aZq/VAzok2SS3gZdniP+dO4zgo59hBg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", "dev": true, - "license": "MIT", "dependencies": { - "jest-regex-util": "30.0.1", - "jest-snapshot": "30.1.2" + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-runner": { - "version": "30.1.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.1.3.tgz", - "integrity": "sha512-dd1ORcxQraW44Uz029TtXj85W11yvLpDuIzNOlofrC8GN+SgDlgY4BvyxJiVeuabA1t6idjNbX59jLd2oplOGQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/console": "30.1.2", - "@jest/environment": "30.1.2", - "@jest/test-result": "30.1.3", - "@jest/transform": "30.1.2", - "@jest/types": "30.0.5", + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "chalk": "^4.1.2", + "chalk": "^4.0.0", "emittery": "^0.13.1", - "exit-x": "^0.2.2", - "graceful-fs": "^4.2.11", - "jest-docblock": "30.0.1", - "jest-environment-node": "30.1.2", - "jest-haste-map": "30.1.0", - "jest-leak-detector": "30.1.0", - "jest-message-util": "30.1.0", - "jest-resolve": "30.1.3", - "jest-runtime": "30.1.3", - "jest-util": "30.0.5", - "jest-watcher": "30.1.3", - "jest-worker": "30.1.0", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", "p-limit": "^3.1.0", "source-map-support": "0.5.13" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-runtime": { - "version": "30.1.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.1.3.tgz", - "integrity": "sha512-WS8xgjuNSphdIGnleQcJ3AKE4tBKOVP+tKhCD0u+Tb2sBmsU8DxfbBpZX7//+XOz81zVs4eFpJQwBNji2Y07DA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/environment": "30.1.2", - "@jest/fake-timers": "30.1.2", - "@jest/globals": "30.1.2", - "@jest/source-map": "30.0.1", - "@jest/test-result": "30.1.3", - "@jest/transform": "30.1.2", - "@jest/types": "30.0.5", + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "chalk": "^4.1.2", - "cjs-module-lexer": "^2.1.0", - "collect-v8-coverage": "^1.0.2", - "glob": "^10.3.10", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.1.0", - "jest-message-util": "30.1.0", - "jest-mock": "30.0.5", - "jest-regex-util": "30.0.1", - "jest-resolve": "30.1.3", - "jest-snapshot": "30.1.2", - "jest-util": "30.0.5", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-snapshot": { - "version": "30.1.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.1.2.tgz", - "integrity": "sha512-4q4+6+1c8B6Cy5pGgFvjDy/Pa6VYRiGu0yQafKkJ9u6wQx4G5PqI2QR6nxTl43yy7IWsINwz6oT4o6tD12a8Dg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/core": "^7.27.4", - "@babel/generator": "^7.27.5", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/plugin-syntax-typescript": "^7.27.1", - "@babel/types": "^7.27.3", - "@jest/expect-utils": "30.1.2", - "@jest/get-type": "30.1.0", - "@jest/snapshot-utils": "30.1.2", - "@jest/transform": "30.1.2", - "@jest/types": "30.0.5", - "babel-preset-current-node-syntax": "^1.1.0", - "chalk": "^4.1.2", - "expect": "30.1.2", - "graceful-fs": "^4.2.11", - "jest-diff": "30.1.2", - "jest-matcher-utils": "30.1.2", - "jest-message-util": "30.1.0", - "jest-util": "30.0.5", - "pretty-format": "30.0.5", - "semver": "^7.7.2", - "synckit": "^0.11.8" + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -4209,52 +3459,37 @@ } }, "node_modules/jest-util": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.0.5.tgz", - "integrity": "sha512-pvyPWssDZR0FlfMxCBoc0tvM8iUEskaRFALUtGQYzVEAqisAztmy+R8LnU14KT4XA0H/a5HMVTXat1jLne010g==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/types": "30.0.5", + "@jest/types": "^29.6.3", "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-util/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-validate": { - "version": "30.1.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.1.0.tgz", - "integrity": "sha512-7P3ZlCFW/vhfQ8pE7zW6Oi4EzvuB4sgR72Q1INfW9m0FGo0GADYlPwIkf4CyPq7wq85g+kPMtPOHNAdWHeBOaA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/get-type": "30.1.0", - "@jest/types": "30.0.5", - "camelcase": "^6.3.0", - "chalk": "^4.1.2", + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", "leven": "^3.1.0", - "pretty-format": "30.0.5" + "pretty-format": "^29.7.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-validate/node_modules/camelcase": { @@ -4262,7 +3497,6 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -4271,40 +3505,37 @@ } }, "node_modules/jest-watcher": { - "version": "30.1.3", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.1.3.tgz", - "integrity": "sha512-6jQUZCP1BTL2gvG9E4YF06Ytq4yMb4If6YoQGRR6PpjtqOXSP3sKe2kqwB6SQ+H9DezOfZaSLnmka1NtGm3fCQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/test-result": "30.1.3", - "@jest/types": "30.0.5", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "ansi-escapes": "^4.3.2", - "chalk": "^4.1.2", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", "emittery": "^0.13.1", - "jest-util": "30.0.5", - "string-length": "^4.0.2" + "jest-util": "^29.7.0", + "string-length": "^4.0.1" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-worker": { - "version": "30.1.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.1.0.tgz", - "integrity": "sha512-uvWcSjlwAAgIu133Tt77A05H7RIk3Ho8tZL50bQM2AkvLdluw9NG48lRCl3Dt+MOH719n/0nnb5YxUwcuJiKRA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*", - "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.0.5", + "jest-util": "^29.7.0", "merge-stream": "^2.0.0", - "supports-color": "^8.1.1" + "supports-color": "^8.0.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-worker/node_modules/supports-color": { @@ -4312,7 +3543,6 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -4323,21 +3553,10 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/jiti": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz", - "integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==", - "devOptional": true, - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, "node_modules/js-sdsl": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", - "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/js-sdsl" @@ -4347,15 +3566,13 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/js-yaml": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", - "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -4364,38 +3581,29 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "license": "MIT" - }, "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, - "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=6" + "node": ">=4" } }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, - "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -4403,12 +3611,20 @@ "node": ">=6" } }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -4417,15 +3633,13 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, - "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -4433,6 +3647,11 @@ "node": ">=8" } }, + "node_modules/lodash.assignwith": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz", + "integrity": "sha512-ZznplvbvtjK2gMvnQ1BR/zqPFZmS6jbK4p+6Up4xcRYA7yMIwxHCfbTcrYxXKzzqLsQ05eJPVznEW3tuwV7k1g==" + }, "node_modules/lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", @@ -4444,17 +3663,18 @@ "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" }, "node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "license": "ISC" + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz", + "integrity": "sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==", + "engines": { + "node": "14 || >=16.14" + } }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, - "license": "MIT", "dependencies": { "semver": "^7.5.3" }, @@ -4466,11 +3686,10 @@ } }, "node_modules/make-dir/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -4483,7 +3702,6 @@ "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "tmpl": "1.0.5" } @@ -4492,7 +3710,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", "engines": { "node": ">= 0.4" } @@ -4501,7 +3718,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", - "license": "MIT", "engines": { "node": ">= 0.8" } @@ -4521,15 +3737,13 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, - "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -4539,28 +3753,22 @@ } }, "node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", - "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", - "license": "MIT", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dependencies": { - "mime-db": "^1.54.0" + "mime-db": "1.52.0" }, "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "node": ">= 0.6" } }, "node_modules/mimic-fn": { @@ -4568,68 +3776,52 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "*" } }, "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/mqtt": { - "version": "5.14.1", - "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.14.1.tgz", - "integrity": "sha512-NxkPxE70Uq3Ph7goefQa7ggSsVzHrayCD0OyxlJgITN/EbzlZN+JEPmaAZdxP1LsIT5FamDyILoQTF72W7Nnbw==", - "license": "MIT", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.7.3.tgz", + "integrity": "sha512-v+5la6Q6zjl0AWsI7ICDA/K3hclkNj7CMa0khMugCC+LKPLrQF+sSQb/9ckezZLMvcBC1tXhRzqmcagQoDl9fQ==", "dependencies": { - "@types/readable-stream": "^4.0.21", - "@types/ws": "^8.18.1", + "@types/readable-stream": "^4.0.5", + "@types/ws": "^8.5.9", "commist": "^3.2.0", "concat-stream": "^2.0.0", - "debug": "^4.4.1", + "debug": "^4.3.4", "help-me": "^5.0.0", - "lru-cache": "^10.4.3", + "lru-cache": "^10.0.1", "minimist": "^1.2.8", - "mqtt-packet": "^9.0.2", + "mqtt": "^5.2.0", + "mqtt-packet": "^9.0.0", "number-allocator": "^1.0.14", - "readable-stream": "^4.7.0", - "rfdc": "^1.4.1", - "socks": "^2.8.6", + "readable-stream": "^4.4.2", + "reinterval": "^1.1.0", + "rfdc": "^1.3.0", "split2": "^4.2.0", - "worker-timers": "^8.0.23", - "ws": "^8.18.3" + "worker-timers": "^7.1.4", + "ws": "^8.17.1" }, "bin": { "mqtt": "build/bin/mqtt.js", @@ -4641,10 +3833,9 @@ } }, "node_modules/mqtt-packet": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-9.0.2.tgz", - "integrity": "sha512-MvIY0B8/qjq7bKxdN1eD+nrljoeaai+qjLJgfRn3TiMuz0pamsIWY2bFODPZMSNmabsLANXsLl4EMoWvlaTZWA==", - "license": "MIT", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-9.0.0.tgz", + "integrity": "sha512-8v+HkX+fwbodsWAZIZTI074XIoxVBOmPeggQuDFCGg1SqNcC+uoRMWu7J6QlJPqIUIJXmjNYYHxBBLr1Y/Df4w==", "dependencies": { "bl": "^6.0.8", "debug": "^4.3.4", @@ -4652,12 +3843,11 @@ } }, "node_modules/mqtt-packet/node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "license": "MIT", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dependencies": { - "ms": "^2.1.3" + "ms": "2.1.2" }, "engines": { "node": ">=6.0" @@ -4669,18 +3859,16 @@ } }, "node_modules/mqtt-packet/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/mqtt/node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "license": "MIT", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dependencies": { - "ms": "^2.1.3" + "ms": "2.1.2" }, "engines": { "node": ">=6.0" @@ -4692,75 +3880,46 @@ } }, "node_modules/mqtt/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/napi-postinstall": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.3.tgz", - "integrity": "sha512-uTp172LLXSxuSYHv/kou+f6KW3SMppU9ivthaVTXian9sOt3XM/zHYHpRZiLgQoxeWfYUnslNWQHF1+G71xcow==", - "dev": true, - "license": "MIT", - "bin": { - "napi-postinstall": "lib/cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/napi-postinstall" - } - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/negotiator": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", - "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", - "license": "MIT", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "engines": { "node": ">= 0.6" } }, - "node_modules/node-fetch-native": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", - "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", - "devOptional": true, - "license": "MIT" - }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", - "dev": true, - "license": "MIT" + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -4770,7 +3929,6 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, - "license": "MIT", "dependencies": { "path-key": "^3.0.0" }, @@ -4782,19 +3940,17 @@ "version": "1.0.14", "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz", "integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==", - "license": "MIT", "dependencies": { "debug": "^4.3.1", "js-sdsl": "4.3.0" } }, "node_modules/number-allocator/node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "license": "MIT", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dependencies": { - "ms": "^2.1.3" + "ms": "2.1.2" }, "engines": { "node": ">=6.0" @@ -4806,44 +3962,14 @@ } }, "node_modules/number-allocator/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/nypm": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.2.tgz", - "integrity": "sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "citty": "^0.1.6", - "consola": "^3.4.2", - "pathe": "^2.0.3", - "pkg-types": "^2.3.0", - "tinyexec": "^1.0.1" - }, - "bin": { - "nypm": "dist/cli.mjs" - }, - "engines": { - "node": "^14.16.0 || >=16.10.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4851,13 +3977,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ohash": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", - "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", - "devOptional": true, - "license": "MIT" - }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -4870,10 +3989,9 @@ } }, "node_modules/on-headers": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", - "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", - "license": "MIT", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", "engines": { "node": ">= 0.8" } @@ -4891,7 +4009,6 @@ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, - "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -4907,7 +4024,6 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, - "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -4923,7 +4039,6 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, - "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -4936,7 +4051,6 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, - "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -4952,24 +4066,15 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true, - "license": "BlueOak-1.0.0" - }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -4996,7 +4101,6 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -5006,7 +4110,6 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -5016,27 +4119,15 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true }, "node_modules/path-to-regexp": { "version": "8.2.0", @@ -5046,33 +4137,17 @@ "node": ">=16" } }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/perfect-debounce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", - "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", - "devOptional": true, - "license": "MIT" - }, "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", + "dev": true }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8.6" }, @@ -5081,11 +4156,10 @@ } }, "node_modules/pirates": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", - "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 6" } @@ -5095,7 +4169,6 @@ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, - "license": "MIT", "dependencies": { "find-up": "^4.0.0" }, @@ -5103,31 +4176,18 @@ "node": ">=8" } }, - "node_modules/pkg-types": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz", - "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "confbox": "^0.2.2", - "exsolve": "^1.0.7", - "pathe": "^2.0.3" - } - }, "node_modules/pretty-format": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.0.5.tgz", - "integrity": "sha512-D1tKtYvByrBkFLe2wHJl2bwMJIiT8rW+XA+TiataH79/FszLQMrpGEvzUVkzPau7OCO0Qnrhpe87PqtOAIB8Yw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/schemas": "30.0.5", - "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/pretty-format/node_modules/ansi-styles": { @@ -5135,7 +4195,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -5144,37 +4203,25 @@ } }, "node_modules/prisma": { - "version": "6.16.2", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.16.2.tgz", - "integrity": "sha512-aRvldGE5UUJTtVmFiH3WfNFNiqFlAtePUxcI0UEGlnXCX7DqhiMT5TRYwncHFeA/Reca5W6ToXXyCMTeFPdSXA==", + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.16.1.tgz", + "integrity": "sha512-Z1Uqodk44diztImxALgJJfNl2Uisl9xDRvqybMKEBYJLNKNhDfAHf+ZIJbZyYiBhLMbKU9cYGdDVG5IIXEnL2Q==", "devOptional": true, "hasInstallScript": true, - "license": "Apache-2.0", - "peer": true, "dependencies": { - "@prisma/config": "6.16.2", - "@prisma/engines": "6.16.2" + "@prisma/engines": "5.16.1" }, "bin": { "prisma": "build/index.js" }, "engines": { - "node": ">=18.18" - }, - "peerDependencies": { - "typescript": ">=5.1.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=16.13" } }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "license": "MIT", "engines": { "node": ">= 0.6.0" } @@ -5182,15 +4229,26 @@ "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "license": "MIT" + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } }, "node_modules/protobufjs": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", - "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.3.2.tgz", + "integrity": "sha512-RXyHaACeqXeqAKGLDl68rQKbmObRsTIn4TYVUUug1KfS47YWCo5MacGITEryugIgZqORCvJWEk4l449POg5Txg==", "hasInstallScript": true, - "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -5222,9 +4280,9 @@ } }, "node_modules/pure-rand": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz", - "integrity": "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", "dev": true, "funding": [ { @@ -5235,14 +4293,12 @@ "type": "opencollective", "url": "https://opencollective.com/fast-check" } - ], - "license": "MIT" + ] }, "node_modules/qs": { "version": "6.14.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" }, @@ -5262,43 +4318,37 @@ } }, "node_modules/raw-body": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", - "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", - "license": "MIT", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", + "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", "dependencies": { - "bytes": "~3.1.2", - "http-errors": "~2.0.1", - "iconv-lite": "~0.7.0", - "unpipe": "~1.0.0" + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.6.3", + "unpipe": "1.0.0" }, "engines": { - "node": ">= 0.10" + "node": ">= 0.8" } }, - "node_modules/rc9": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz", - "integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "defu": "^6.1.4", - "destr": "^2.0.3" + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" } }, "node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/readable-stream": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", - "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", - "license": "MIT", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", @@ -5310,36 +4360,47 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/reinterval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", + "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==" }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/resolve-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, - "license": "MIT", "dependencies": { "resolve-from": "^5.0.0" }, @@ -5352,16 +4413,23 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/rfdc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "license": "MIT" + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==" }, "node_modules/router": { "version": "2.2.0", @@ -5400,37 +4468,20 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -5472,6 +4523,25 @@ } } }, + "node_modules/send/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/send/node_modules/mime-types": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -5501,7 +4571,6 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -5514,7 +4583,6 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -5523,7 +4591,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", @@ -5542,7 +4609,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" @@ -5558,7 +4624,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -5576,7 +4641,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -5592,58 +4656,31 @@ } }, "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "license": "MIT", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks": { - "version": "2.8.6", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.6.tgz", - "integrity": "sha512-pe4Y2yzru68lXCb38aAqRf5gvN8YdjP1lok5o0J7BOHljkyCGKVz7H3vpVIXKD27rj2giOJ7DwVyk/GWrPHDWA==", - "license": "MIT", - "dependencies": { - "ip-address": "^9.0.5", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" - } - }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -5653,7 +4690,6 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, - "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -5663,7 +4699,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "license": "ISC", "engines": { "node": ">= 10.x" } @@ -5672,15 +4707,13 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true, - "license": "BSD-3-Clause" + "dev": true }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, - "license": "MIT", "dependencies": { "escape-string-regexp": "^2.0.0" }, @@ -5696,21 +4729,46 @@ "node": ">= 0.8" } }, + "node_modules/stream-read-all": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/stream-read-all/-/stream-read-all-3.0.1.tgz", + "integrity": "sha512-EWZT9XOceBPlVJRrYcykW8jyRSZYbkb/0ZK36uLEmoWVO5gxBOnntNTseNzfREsqxqdfEGQrD8SXQ3QWbBmq8A==", + "engines": { + "node": ">=10" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, - "license": "MIT", "dependencies": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" @@ -5719,54 +4777,11 @@ "node": ">=10" } }, - "node_modules/string-length/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-length/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -5776,59 +4791,11 @@ "node": ">=8" } }, - "node_modules/string-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -5836,22 +4803,11 @@ "node": ">=8" } }, - "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -5861,7 +4817,6 @@ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -5871,7 +4826,6 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" }, @@ -5890,31 +4844,50 @@ "node": ">=8" } }, - "node_modules/synckit": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz", - "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==", + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, - "license": "MIT", - "dependencies": { - "@pkgr/core": "^0.2.9" - }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": ">= 0.4" }, "funding": { - "url": "https://opencollective.com/synckit" + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/table-layout": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-4.1.1.tgz", - "integrity": "sha512-iK5/YhZxq5GO5z8wb0bY1317uDF3Zjpha0QFFLA8/trAoiLbQD0HUbMesEaxyzUgDxi2QlcbM8IvqOlEjgoXBA==", - "license": "MIT", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-3.0.2.tgz", + "integrity": "sha512-rpyNZYRw+/C+dYkcQ3Pr+rLxW4CfHpXjPDnG7lYhdRoUcZTUt+KEsX+94RGp/aVp/MQU35JCITv2T/beY4m+hw==", "dependencies": { + "@75lb/deep-merge": "^1.1.1", "array-back": "^6.2.2", + "command-line-args": "^5.2.1", + "command-line-usage": "^7.0.0", + "stream-read-all": "^3.0.1", + "typical": "^7.1.1", "wordwrapjs": "^5.1.0" }, + "bin": { + "table-layout": "bin/cli.js" + }, + "engines": { + "node": ">=12.17" + } + }, + "node_modules/table-layout/node_modules/array-back": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", + "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", + "engines": { + "node": ">=12.17" + } + }, + "node_modules/table-layout/node_modules/typical": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", + "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==", "engines": { "node": ">=12.17" } @@ -5924,7 +4897,6 @@ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, - "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", @@ -5934,72 +4906,26 @@ "node": ">=8" } }, - "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/test-exclude/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/test-exclude/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tinyexec": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz", - "integrity": "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==", - "devOptional": true, - "license": "MIT" - }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, - "license": "BSD-3-Clause" + "engines": { + "node": ">=4" + } }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -6016,17 +4942,15 @@ } }, "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } @@ -6036,7 +4960,6 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, - "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -6048,7 +4971,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", - "license": "MIT", "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", @@ -6058,19 +4980,36 @@ "node": ">= 0.6" } }, + "node_modules/type-is/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-types": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "license": "MIT" + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" }, "node_modules/typical": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-7.3.0.tgz", - "integrity": "sha512-ya4mg/30vm+DOWfBg4YK3j2WD6TWtRkCbasOJr40CseYENzCUby/7rIvXA99JGsQHeNxLbnXdyLLxKSv3tauFw==", - "license": "MIT", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", "engines": { - "node": ">=12.17" + "node": ">=8" } }, "node_modules/undici-types": { @@ -6082,50 +5021,14 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", "engines": { "node": ">= 0.8" } }, - "node_modules/unrs-resolver": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", - "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "napi-postinstall": "^0.3.0" - }, - "funding": { - "url": "https://opencollective.com/unrs-resolver" - }, - "optionalDependencies": { - "@unrs/resolver-binding-android-arm-eabi": "1.11.1", - "@unrs/resolver-binding-android-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-x64": "1.11.1", - "@unrs/resolver-binding-freebsd-x64": "1.11.1", - "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", - "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", - "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-musl": "1.11.1", - "@unrs/resolver-binding-wasm32-wasi": "1.11.1", - "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", - "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", - "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" - } - }, "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "dev": true, "funding": [ { @@ -6141,10 +5044,9 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { "escalade": "^3.2.0", - "picocolors": "^1.1.1" + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" @@ -6156,15 +5058,13 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/v8-to-istanbul": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", "dev": true, - "license": "ISC", "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", @@ -6187,7 +5087,6 @@ "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, - "license": "Apache-2.0", "dependencies": { "makeerror": "1.0.12" } @@ -6197,7 +5096,6 @@ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -6212,83 +5110,46 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-5.1.0.tgz", "integrity": "sha512-JNjcULU2e4KJwUNv6CHgI46UvDGitb6dGryHajXTDiLgg1/RiGoPSDw4kZfYnwGtEXf2ZMeIewDQgFGzkCB2Sg==", - "license": "MIT", "engines": { "node": ">=12.17" } }, - "node_modules/worker-factory": { - "version": "7.0.44", - "resolved": "https://registry.npmjs.org/worker-factory/-/worker-factory-7.0.44.tgz", - "integrity": "sha512-08AuUfWi+KeZI+KC7nU4pU/9tDeAFvE5NSWk+K9nIfuQc6UlOsZtjjeGVYVEn+DEchyXNJ5i10HCn0xRzFXEQA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.27.6", - "fast-unique-numbers": "^9.0.22", - "tslib": "^2.8.1" - } - }, "node_modules/worker-timers": { - "version": "8.0.23", - "resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-8.0.23.tgz", - "integrity": "sha512-1BnWHNNiu5YEutgF7eVZEqNntAsij2oG0r66xDdScoY3fKGFrok2y0xA8OgG6FA+3srrmAplSY6JN5h9jV5D0w==", - "license": "MIT", + "version": "7.1.8", + "resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-7.1.8.tgz", + "integrity": "sha512-R54psRKYVLuzff7c1OTFcq/4Hue5Vlz4bFtNEIarpSiCYhpifHU3aIQI29S84o1j87ePCYqbmEJPqwBTf+3sfw==", "dependencies": { - "@babel/runtime": "^7.27.6", - "tslib": "^2.8.1", - "worker-timers-broker": "^8.0.9", - "worker-timers-worker": "^9.0.9" + "@babel/runtime": "^7.24.5", + "tslib": "^2.6.2", + "worker-timers-broker": "^6.1.8", + "worker-timers-worker": "^7.0.71" } }, "node_modules/worker-timers-broker": { - "version": "8.0.9", - "resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-8.0.9.tgz", - "integrity": "sha512-WJsd7aIvu2GBTXp7IBGT1NKnt3ZbiJ2wqb7Pl4nFJXC8pek84+X68TJGVvvrqwHgHPNxSlzpU1nadhcW4PDD7A==", - "license": "MIT", + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-6.1.8.tgz", + "integrity": "sha512-FUCJu9jlK3A8WqLTKXM9E6kAmI/dR1vAJ8dHYLMisLNB/n3GuaFIjJ7pn16ZcD1zCOf7P6H62lWIEBi+yz/zQQ==", "dependencies": { - "@babel/runtime": "^7.27.6", - "broker-factory": "^3.1.8", - "fast-unique-numbers": "^9.0.22", - "tslib": "^2.8.1", - "worker-timers-worker": "^9.0.9" + "@babel/runtime": "^7.24.5", + "fast-unique-numbers": "^8.0.13", + "tslib": "^2.6.2", + "worker-timers-worker": "^7.0.71" } }, "node_modules/worker-timers-worker": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-9.0.9.tgz", - "integrity": "sha512-OOKTMdHbzx7FaXCW40RS8RxAqLF/R8xU5/YA7CFasDy+jBA5yQWUusSQJUFFTV2Z9ZOpnR+ZWgte/IuAqOAEVw==", - "license": "MIT", + "version": "7.0.71", + "resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-7.0.71.tgz", + "integrity": "sha512-ks/5YKwZsto1c2vmljroppOKCivB/ma97g9y77MAAz2TBBjPPgpoOiS1qYQKIgvGTr2QYPT3XhJWIB6Rj2MVPQ==", "dependencies": { - "@babel/runtime": "^7.27.6", - "tslib": "^2.8.1", - "worker-factory": "^7.0.44" + "@babel/runtime": "^7.24.5", + "tslib": "^2.6.2" } }, "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -6301,88 +5162,28 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, - "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" + "signal-exit": "^3.0.7" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/ws": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", - "license": "MIT", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "engines": { "node": ">=10.0.0" }, @@ -6404,7 +5205,6 @@ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, - "license": "ISC", "engines": { "node": ">=10" } @@ -6413,15 +5213,13 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, - "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -6440,62 +5238,15 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, - "license": "ISC", "engines": { "node": ">=12" } }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, diff --git a/package.json b/package.json index 989093f..9a58d79 100644 --- a/package.json +++ b/package.json @@ -9,18 +9,16 @@ "author": "", "license": "ISC", "dependencies": { - "@prisma/client": "^6.16.2", - "command-line-args": "^6.0.1", - "command-line-usage": "^7.0.3", - "compression": "^1.8.1", - "cors": "^2.8.5", - "express": "^5.2.1", - "mqtt": "^5.14.1", - "protobufjs": "^7.5.4", - "ws": "^8.18.3" + "@prisma/client": "^5.11.0", + "command-line-args": "^5.2.1", + "command-line-usage": "^7.0.1", + "compression": "^1.7.4", + "express": "^5.0.0", + "mqtt": "^5.3.6", + "protobufjs": "^7.2.6" }, "devDependencies": { - "jest": "^30.1.3", - "prisma": "^6.16.2" + "jest": "^29.7.0", + "prisma": "^5.10.2" } } diff --git a/prisma/migrations/20250328205405_add_ok_to_mqtt_to_node/migration.sql b/prisma/migrations/20250328205405_add_ok_to_mqtt_to_node/migration.sql deleted file mode 100644 index 9bd381c..0000000 --- a/prisma/migrations/20250328205405_add_ok_to_mqtt_to_node/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterTable -ALTER TABLE `nodes` ADD COLUMN `ok_to_mqtt` BOOLEAN NULL; diff --git a/prisma/migrations/20250415153323_add_portnum_to_service_envelopes/migration.sql b/prisma/migrations/20250415153323_add_portnum_to_service_envelopes/migration.sql deleted file mode 100644 index 20c56fe..0000000 --- a/prisma/migrations/20250415153323_add_portnum_to_service_envelopes/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterTable -ALTER TABLE `service_envelopes` ADD COLUMN `portnum` INTEGER NULL; diff --git a/prisma/migrations/20250415184546_add_packet_id_to_service_envelopes/migration.sql b/prisma/migrations/20250415184546_add_packet_id_to_service_envelopes/migration.sql deleted file mode 100644 index e0139d5..0000000 --- a/prisma/migrations/20250415184546_add_packet_id_to_service_envelopes/migration.sql +++ /dev/null @@ -1,5 +0,0 @@ --- AlterTable -ALTER TABLE `service_envelopes` ADD COLUMN `packet_id` BIGINT NULL; - --- CreateIndex -CREATE INDEX `service_envelopes_packet_id_idx` ON `service_envelopes`(`packet_id`); diff --git a/prisma/migrations/20250422203347_add_battery_and_channel_util_stats/migration.sql b/prisma/migrations/20250422203347_add_battery_and_channel_util_stats/migration.sql deleted file mode 100644 index 1bd67b5..0000000 --- a/prisma/migrations/20250422203347_add_battery_and_channel_util_stats/migration.sql +++ /dev/null @@ -1,19 +0,0 @@ --- CreateTable -CREATE TABLE `battery_stats` ( - `id` BIGINT NOT NULL AUTO_INCREMENT, - `recorded_at` DATETIME(3) NULL DEFAULT CURRENT_TIMESTAMP(3), - `avg_battery_level` DECIMAL(5, 2) NULL, - - INDEX `battery_stats_recorded_at_idx`(`recorded_at`), - PRIMARY KEY (`id`) -) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - --- CreateTable -CREATE TABLE `channel_utilization_stats` ( - `id` BIGINT NOT NULL AUTO_INCREMENT, - `recorded_at` DATETIME(3) NULL DEFAULT CURRENT_TIMESTAMP(3), - `avg_channel_utilization` DECIMAL(65, 30) NULL, - - INDEX `channel_utilization_stats_recorded_at_idx`(`recorded_at`), - PRIMARY KEY (`id`) -) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; diff --git a/prisma/migrations/20250426153224_add_node_name_history/migration.sql b/prisma/migrations/20250426153224_add_node_name_history/migration.sql deleted file mode 100644 index b79e839..0000000 --- a/prisma/migrations/20250426153224_add_node_name_history/migration.sql +++ /dev/null @@ -1,16 +0,0 @@ --- CreateTable -CREATE TABLE `name_history` ( - `id` BIGINT NOT NULL AUTO_INCREMENT, - `node_id` BIGINT NOT NULL, - `long_name` VARCHAR(191) NOT NULL, - `short_name` VARCHAR(191) NOT NULL, - `created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), - `updated_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), - - INDEX `name_history_node_id_idx`(`node_id`), - INDEX `name_history_long_name_idx`(`long_name`), - INDEX `name_history_created_at_idx`(`created_at`), - INDEX `name_history_updated_at_idx`(`updated_at`), - UNIQUE INDEX `name_history_node_id_long_name_short_name_key`(`node_id`, `long_name`, `short_name`), - PRIMARY KEY (`id`) -) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; diff --git a/prisma/migrations/20250627090409_add_node_is_backbone/migration.sql b/prisma/migrations/20250627090409_add_node_is_backbone/migration.sql deleted file mode 100644 index e449774..0000000 --- a/prisma/migrations/20250627090409_add_node_is_backbone/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterTable -ALTER TABLE `nodes` ADD COLUMN `is_backbone` BOOLEAN NULL; diff --git a/prisma/migrations/20250805210540_add_node_pulickey_and_unmessagable/migration.sql b/prisma/migrations/20250805210540_add_node_pulickey_and_unmessagable/migration.sql deleted file mode 100644 index 5c2e5ac..0000000 --- a/prisma/migrations/20250805210540_add_node_pulickey_and_unmessagable/migration.sql +++ /dev/null @@ -1,3 +0,0 @@ --- AlterTable -ALTER TABLE `nodes` ADD COLUMN `is_unmessagable` BOOLEAN NULL, - ADD COLUMN `public_key` VARCHAR(191) NULL; diff --git a/prisma/migrations/20250810082255_add_node_max_hops/migration.sql b/prisma/migrations/20250810082255_add_node_max_hops/migration.sql deleted file mode 100644 index b9dc9b4..0000000 --- a/prisma/migrations/20250810082255_add_node_max_hops/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterTable -ALTER TABLE `nodes` ADD COLUMN `max_hops` INTEGER NULL; diff --git a/prisma/migrations/20250813193012_add_node_channel_id/migration.sql b/prisma/migrations/20250813193012_add_node_channel_id/migration.sql deleted file mode 100644 index 9498fea..0000000 --- a/prisma/migrations/20250813193012_add_node_channel_id/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterTable -ALTER TABLE `nodes` ADD COLUMN `channel_id` VARCHAR(191) NULL; diff --git a/prisma/migrations/20250925171652_add_chutil_channel_id/migration.sql b/prisma/migrations/20250925171652_add_chutil_channel_id/migration.sql deleted file mode 100644 index 771f018..0000000 --- a/prisma/migrations/20250925171652_add_chutil_channel_id/migration.sql +++ /dev/null @@ -1,5 +0,0 @@ --- AlterTable -ALTER TABLE `channel_utilization_stats` ADD COLUMN `channel_id` VARCHAR(191) NULL; - --- CreateIndex -CREATE INDEX `channel_utilization_stats_channel_id_idx` ON `channel_utilization_stats`(`channel_id`); diff --git a/prisma/migrations/20250929184048_add_ok_to_mqtt_to_text_messages/migration.sql b/prisma/migrations/20250929184048_add_ok_to_mqtt_to_text_messages/migration.sql deleted file mode 100644 index 5a14c0c..0000000 --- a/prisma/migrations/20250929184048_add_ok_to_mqtt_to_text_messages/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterTable -ALTER TABLE `text_messages` ADD COLUMN `ok_to_mqtt` BOOLEAN NULL; diff --git a/prisma/migrations/20260106151912_add_edges/migration.sql b/prisma/migrations/20260106151912_add_edges/migration.sql deleted file mode 100644 index 113243f..0000000 --- a/prisma/migrations/20260106151912_add_edges/migration.sql +++ /dev/null @@ -1,23 +0,0 @@ --- CreateTable -CREATE TABLE `edges` ( - `id` BIGINT NOT NULL AUTO_INCREMENT, - `from_node_id` BIGINT NOT NULL, - `to_node_id` BIGINT NOT NULL, - `snr` INTEGER NOT NULL, - `from_latitude` INTEGER NULL, - `from_longitude` INTEGER NULL, - `to_latitude` INTEGER NULL, - `to_longitude` INTEGER NULL, - `packet_id` BIGINT NOT NULL, - `channel_id` VARCHAR(191) NULL, - `gateway_id` BIGINT NULL, - `source` VARCHAR(191) NOT NULL, - `created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), - `updated_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), - - INDEX `edges_from_node_id_idx`(`from_node_id`), - INDEX `edges_to_node_id_idx`(`to_node_id`), - INDEX `edges_created_at_idx`(`created_at`), - INDEX `edges_from_node_id_to_node_id_idx`(`from_node_id`, `to_node_id`), - PRIMARY KEY (`id`) -) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 2a908dc..6741657 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -21,8 +21,6 @@ model Node { hardware_model Int role Int is_licensed Boolean? - public_key String? - is_unmessagable Boolean? firmware_version String? region Int? @@ -53,12 +51,6 @@ model Node { // this column tracks when an mqtt gateway node uplinked a packet mqtt_connection_state_updated_at DateTime? - ok_to_mqtt Boolean? - is_backbone Boolean? - max_hops Int? - - channel_id String? - created_at DateTime @default(now()) updated_at DateTime @default(now()) @updatedAt @@ -210,8 +202,6 @@ model ServiceEnvelope { gateway_id BigInt? to BigInt from BigInt - portnum Int? - packet_id BigInt? protobuf Bytes created_at DateTime @default(now()) @@ -220,7 +210,6 @@ model ServiceEnvelope { @@index(created_at) @@index(updated_at) @@index(gateway_id) - @@index(packet_id) @@map("service_envelopes") } @@ -239,7 +228,6 @@ model TextMessage { rx_snr Decimal? rx_rssi Int? hop_limit Int? - ok_to_mqtt Boolean? created_at DateTime @default(now()) updated_at DateTime @default(now()) @updatedAt @@ -308,67 +296,3 @@ model Waypoint { @@index(gateway_id) @@map("waypoints") } - -model NameHistory { - id BigInt @id @default(autoincrement()) - node_id BigInt - long_name String - short_name String - - created_at DateTime @default(now()) - updated_at DateTime @default(now()) @updatedAt - - @@index(node_id) - @@index(long_name) - - @@index(created_at) - @@index(updated_at) - @@map("name_history") - - // We only want to keep track of unique name and node_id combinations - @@unique([node_id, long_name, short_name]) -} - -model BatteryStats { - id BigInt @id @default(autoincrement()) - recorded_at DateTime? @default(now()) - avg_battery_level Decimal? @db.Decimal(5, 2) - - @@index([recorded_at]) - @@map("battery_stats") -} - -model ChannelUtilizationStats { - id BigInt @id @default(autoincrement()) - recorded_at DateTime? @default(now()) - avg_channel_utilization Decimal? - channel_id String? - - @@index([channel_id]) - @@index([recorded_at]) - @@map("channel_utilization_stats") -} - -model Edge { - id BigInt @id @default(autoincrement()) - from_node_id BigInt - to_node_id BigInt - snr Int - from_latitude Int? - from_longitude Int? - to_latitude Int? - to_longitude Int? - packet_id BigInt - channel_id String? - gateway_id BigInt? - source String - - created_at DateTime @default(now()) - updated_at DateTime @default(now()) @updatedAt - - @@index(from_node_id) - @@index(to_node_id) - @@index(created_at) - @@index([from_node_id, to_node_id]) - @@map("edges") -} \ No newline at end of file diff --git a/screenshot.png b/screenshot.png index 25ee627..13d17b2 100644 Binary files a/screenshot.png and b/screenshot.png differ diff --git a/src/admin.js b/src/admin.js index 5889908..e9fbbef 100644 --- a/src/admin.js +++ b/src/admin.js @@ -1,7 +1,6 @@ // node src/admin.js --purge-node-id 123 // node src/admin.js --purge-node-id '!AABBCCDD' -require('./utils/logger'); const commandLineArgs = require("command-line-args"); const commandLineUsage = require("command-line-usage"); diff --git a/src/index.js b/src/index.js index 48dbcc2..bbfeb2a 100644 --- a/src/index.js +++ b/src/index.js @@ -1,13 +1,9 @@ -require('./utils/logger'); +const fs = require("fs"); const path = require('path'); const express = require('express'); const compression = require('compression'); -const protobufjs = require("protobufjs"); const commandLineArgs = require("command-line-args"); const commandLineUsage = require("command-line-usage"); -const cors = require('cors'); - -const statsRoutes = require('./stats.js'); // create prisma db client const { PrismaClient } = require("@prisma/client"); @@ -54,24 +50,21 @@ if(options.help){ // get options and fallback to default values const port = options["port"] ?? 8080; -// load protobufs -const root = new protobufjs.Root(); -root.resolvePath = (origin, target) => path.join(__dirname, "protobufs", target); -root.loadSync('meshtastic/mqtt.proto'); -const HardwareModel = root.lookupEnum("HardwareModel"); -const Role = root.lookupEnum("Config.DeviceConfig.Role"); -const RegionCode = root.lookupEnum("Config.LoRaConfig.RegionCode"); -const ModemPreset = root.lookupEnum("Config.LoRaConfig.ModemPreset"); +// load json +const hardwareModels = JSON.parse(fs.readFileSync(path.join(__dirname, "json/hardware_models.json"), "utf-8")); +const roles = JSON.parse(fs.readFileSync(path.join(__dirname, "json/roles.json"), "utf-8")); +const regionCodes = JSON.parse(fs.readFileSync(path.join(__dirname, "json/region_codes.json"), "utf-8")); +const modemPresets = JSON.parse(fs.readFileSync(path.join(__dirname, "json/modem_presets.json"), "utf-8")); // appends extra info for node objects returned from api function formatNodeInfo(node) { return { ...node, node_id_hex: "!" + node.node_id.toString(16), - hardware_model_name: HardwareModel.valuesById[node.hardware_model] ?? null, - role_name: Role.valuesById[node.role] ?? null, - region_name: RegionCode.valuesById[node.region] ?? null, - modem_preset_name: ModemPreset.valuesById[node.modem_preset] ?? null, + hardware_model_name: hardwareModels[node.hardware_model] ?? null, + role_name: roles[node.role] ?? null, + region_name: regionCodes[node.region] ?? null, + modem_preset_name: modemPresets[node.modem_preset] ?? null, }; } @@ -80,9 +73,6 @@ const app = express(); // enable compression app.use(compression()); -// Apply CORS only to API routes -app.use('/api', cors()); - // serve files inside the public folder from / app.use('/', express.static(path.join(__dirname, 'public'))); @@ -90,9 +80,6 @@ app.get('/', async (req, res) => { res.sendFile(path.join(__dirname, 'public/index.html')); }); -// stats API in separate file -app.use('/api/v1/stats', statsRoutes); - app.get('/api', async (req, res) => { const links = [ @@ -147,23 +134,6 @@ app.get('/api', async (req, res) => { "path": "/api/v1/nodes/:nodeId/traceroutes", "description": "Trace routes for a meshtastic node", }, - { - "path": "/api/v1/traceroutes", - "description": "Recent traceroute edges across all nodes", - "params": { - "time_from": "Only include traceroutes updated after this unix timestamp (milliseconds)", - "time_to": "Only include traceroutes updated before this unix timestamp (milliseconds)" - } - }, - { - "path": "/api/v1/connections", - "description": "Aggregated edges between nodes from traceroutes", - "params": { - "node_id": "Only include connections involving this node id", - "time_from": "Only include edges created after this unix timestamp (milliseconds)", - "time_to": "Only include edges created before this unix timestamp (milliseconds)" - } - }, { "path": "/api/v1/nodes/:nodeId/position-history", "description": "Position history for a meshtastic node", @@ -229,10 +199,6 @@ app.get('/api/v1/nodes', async (req, res) => { where: { role: role, hardware_model: hardwareModel, - // Since we removed retention; only include nodes that have been updated in the last 30 days - updated_at: { - gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) // within last 30 days - } }, }); @@ -588,313 +554,6 @@ app.get('/api/v1/nodes/:nodeId/traceroutes', async (req, res) => { } }); -// Aggregated recent traceroute edges (global), filtered by updated_at -// Returns deduplicated edges with the latest SNR and timestamp. -// GET /api/v1/nodes/traceroutes?time_from=...&time_to=... -app.get('/api/v1/traceroutes', async (req, res) => { - try { - - const timeFrom = req.query.time_from ? parseInt(req.query.time_from) : undefined; - const timeTo = req.query.time_to ? parseInt(req.query.time_to) : undefined; - - // Pull recent traceroutes within the time window. We only want replies (want_response=false) - // and those that were actually gated to MQTT (gateway_id not null) - const traces = await prisma.traceRoute.findMany({ - where: { - want_response: false, - gateway_id: { not: null }, - updated_at: { - gte: timeFrom ? new Date(timeFrom) : undefined, - lte: timeTo ? new Date(timeTo) : undefined, - }, - }, - orderBy: { id: 'desc' }, - take: 5000, // cap to keep response bounded; UI can page/adjust time window if needed - }); - - // Normalize JSON fields that may be strings (depending on driver) - const normalized = traces.map((t) => { - const trace = { ...t }; - if (typeof trace.route === 'string') { - try { trace.route = JSON.parse(trace.route); } catch(_) {} - } - if (typeof trace.route_back === 'string') { - try { trace.route_back = JSON.parse(trace.route_back); } catch(_) {} - } - if (typeof trace.snr_towards === 'string') { - try { trace.snr_towards = JSON.parse(trace.snr_towards); } catch(_) {} - } - if (typeof trace.snr_back === 'string') { - try { trace.snr_back = JSON.parse(trace.snr_back); } catch(_) {} - } - return trace; - }); - - // Build edges from both forward (towards) and reverse (back) paths. - // Forward path: to → route[] → from, using snr_towards - // Reverse path: from → route_back[] → to, using snr_back - const edgeKey = (a, b) => `${String(a)}->${String(b)}`; - const edges = new Map(); - - function upsertEdgesFromPath(trace, pathNodes, pathSnrs) { - for (let i = 0; i < pathNodes.length - 1; i++) { - const hopFrom = pathNodes[i]; - const hopTo = pathNodes[i + 1]; - const snr = typeof (pathSnrs && pathSnrs[i]) === 'number' ? pathSnrs[i] : null; - - // Skip edges without SNR data - if (snr === null) continue; - - const key = edgeKey(hopFrom, hopTo); - const existing = edges.get(key); - if (!existing) { - edges.set(key, { - from: hopFrom, - to: hopTo, - snr: snr, - updated_at: trace.updated_at, - channel_id: trace.channel_id ?? null, - gateway_id: trace.gateway_id ?? null, - traceroute_from: trace.from, // original initiator - traceroute_to: trace.to, // original target - }); - } else if (new Date(trace.updated_at) > new Date(existing.updated_at)) { - existing.snr = snr; - existing.updated_at = trace.updated_at; - existing.channel_id = trace.channel_id ?? existing.channel_id; - existing.gateway_id = trace.gateway_id ?? existing.gateway_id; - existing.traceroute_from = trace.from; - existing.traceroute_to = trace.to; - } - } - } - - for (const tr of normalized) { - // Forward path - const forwardPath = []; - if (tr.to != null) forwardPath.push(Number(tr.to)); - if (Array.isArray(tr.route)) { - for (const hop of tr.route) { - if (hop != null) forwardPath.push(Number(hop)); - } - } - if (tr.from != null) forwardPath.push(Number(tr.from)); - const forwardSnrs = Array.isArray(tr.snr_towards) ? tr.snr_towards : []; - upsertEdgesFromPath(tr, forwardPath, forwardSnrs); - - // Reverse path - const reversePath = []; - if (tr.from != null) reversePath.push(Number(tr.from)); - if (Array.isArray(tr.route_back)) { - for (const hop of tr.route_back) { - if (hop != null) reversePath.push(Number(hop)); - } - } - if (tr.to != null) reversePath.push(Number(tr.to)); - const reverseSnrs = Array.isArray(tr.snr_back) ? tr.snr_back : []; - upsertEdgesFromPath(tr, reversePath, reverseSnrs); - } - - res.json({ - traceroute_edges: Array.from(edges.values()), - }); - - } catch (err) { - console.error(err); - res.status(500).json({ - message: "Something went wrong, try again later.", - }); - } -}); - -// Aggregated edges endpoint -// GET /api/v1/connections?node_id=...&time_from=...&time_to=... -app.get('/api/v1/connections', async (req, res) => { - try { - const nodeId = req.query.node_id ? parseInt(req.query.node_id) : undefined; - const timeFrom = req.query.time_from ? parseInt(req.query.time_from) : undefined; - const timeTo = req.query.time_to ? parseInt(req.query.time_to) : undefined; - - // Query edges from database - const edges = await prisma.edge.findMany({ - where: { - created_at: { - ...(timeFrom && { gte: new Date(timeFrom) }), - ...(timeTo && { lte: new Date(timeTo) }), - }, - // Only include edges where both nodes have positions - from_latitude: { not: null }, - from_longitude: { not: null }, - to_latitude: { not: null }, - to_longitude: { not: null }, - // If node_id is provided, filter edges where either from_node_id or to_node_id matches - ...(nodeId !== undefined && { - OR: [ - { from_node_id: nodeId }, - { to_node_id: nodeId }, - ], - }), - }, - orderBy: [ - { created_at: 'desc' }, - { packet_id: 'desc' }, - ], - }); - - // Collect all unique node IDs from edges - const nodeIds = new Set(); - for (const edge of edges) { - nodeIds.add(edge.from_node_id); - nodeIds.add(edge.to_node_id); - } - - // Fetch current positions for all nodes - const nodes = await prisma.node.findMany({ - where: { - node_id: { in: Array.from(nodeIds) }, - }, - select: { - node_id: true, - latitude: true, - longitude: true, - }, - }); - - // Create a map of current node positions - const nodePositions = new Map(); - for (const node of nodes) { - nodePositions.set(node.node_id, { - latitude: node.latitude, - longitude: node.longitude, - }); - } - - // Filter edges: only include edges where both nodes are still at the same location - const validEdges = edges.filter(edge => { - const fromCurrentPos = nodePositions.get(edge.from_node_id); - const toCurrentPos = nodePositions.get(edge.to_node_id); - - // Skip if either node doesn't exist or doesn't have a current position - if (!fromCurrentPos || !toCurrentPos || - fromCurrentPos.latitude === null || fromCurrentPos.longitude === null || - toCurrentPos.latitude === null || toCurrentPos.longitude === null) { - return false; - } - - // Check if stored positions match current positions - const fromMatches = fromCurrentPos.latitude === edge.from_latitude && - fromCurrentPos.longitude === edge.from_longitude; - const toMatches = toCurrentPos.latitude === edge.to_latitude && - toCurrentPos.longitude === edge.to_longitude; - - return fromMatches && toMatches; - }); - - // Normalize node pairs: always use min/max to treat A->B and B->A as same connection - const connectionsMap = new Map(); - - for (const edge of validEdges) { - const nodeA = edge.from_node_id < edge.to_node_id ? edge.from_node_id : edge.to_node_id; - const nodeB = edge.from_node_id < edge.to_node_id ? edge.to_node_id : edge.from_node_id; - const key = `${nodeA}-${nodeB}`; - - if (!connectionsMap.has(key)) { - connectionsMap.set(key, { - node_a: nodeA, - node_b: nodeB, - direction_ab: [], // A -> B edges - direction_ba: [], // B -> A edges - }); - } - - const connection = connectionsMap.get(key); - const isAB = edge.from_node_id === nodeA; - - // Add edge to appropriate direction - if (isAB) { - connection.direction_ab.push({ - snr: edge.snr, - snr_db: edge.snr / 4, // Convert to dB - created_at: edge.created_at, - packet_id: edge.packet_id, - source: edge.source, - }); - } else { - connection.direction_ba.push({ - snr: edge.snr, - snr_db: edge.snr / 4, - created_at: edge.created_at, - packet_id: edge.packet_id, - source: edge.source, - }); - } - } - - // Aggregate each connection - const connections = Array.from(connectionsMap.values()).map(conn => { - // Deduplicate edges by packet_id for each direction (keep first occurrence, which is most recent) - const dedupeByPacketId = (edges) => { - const seen = new Set(); - return edges.filter(edge => { - if (seen.has(edge.packet_id)) { - return false; - } - seen.add(edge.packet_id); - return true; - }); - }; - - const deduplicatedAB = dedupeByPacketId(conn.direction_ab); - const deduplicatedBA = dedupeByPacketId(conn.direction_ba); - - // Calculate average SNR for A->B (using deduplicated edges) - const avgSnrAB = deduplicatedAB.length > 0 - ? deduplicatedAB.reduce((sum, e) => sum + e.snr_db, 0) / deduplicatedAB.length - : null; - - // Calculate average SNR for B->A (using deduplicated edges) - const avgSnrBA = deduplicatedBA.length > 0 - ? deduplicatedBA.reduce((sum, e) => sum + e.snr_db, 0) / deduplicatedBA.length - : null; - - // Get last 5 edges for each direction (already sorted by created_at DESC, packet_id DESC, now deduplicated) - const last5AB = deduplicatedAB.slice(0, 5); - const last5BA = deduplicatedBA.slice(0, 5); - - // Determine worst average SNR - const worstAvgSnrDb = [avgSnrAB, avgSnrBA] - .filter(v => v !== null) - .reduce((min, val) => val < min ? val : min, Infinity); - - return { - node_a: conn.node_a, - node_b: conn.node_b, - direction_ab: { - avg_snr_db: avgSnrAB, - last_5_edges: last5AB, - total_count: deduplicatedAB.length, // Use deduplicated count - }, - direction_ba: { - avg_snr_db: avgSnrBA, - last_5_edges: last5BA, - total_count: deduplicatedBA.length, // Use deduplicated count - }, - worst_avg_snr_db: worstAvgSnrDb !== Infinity ? worstAvgSnrDb : null, - }; - }).filter(conn => conn.worst_avg_snr_db !== null); // Only return connections with at least one direction - - res.json({ - connections: connections, - }); - - } catch (err) { - console.error(err); - res.status(500).json({ - message: "Something went wrong, try again later.", - }); - } -}); - app.get('/api/v1/nodes/:nodeId/position-history', async (req, res) => { try { @@ -984,6 +643,42 @@ app.get('/api/v1/nodes/:nodeId/position-history', async (req, res) => { } }); +app.get('/api/v1/stats/hardware-models', async (req, res) => { + try { + + // get nodes from db + const results = await prisma.node.groupBy({ + by: ['hardware_model'], + orderBy: { + _count: { + hardware_model: 'desc', + }, + }, + _count: { + hardware_model: true, + }, + }); + + const hardwareModelStats = results.map((result) => { + return { + count: result._count.hardware_model, + hardware_model: result.hardware_model, + hardware_model_name: hardwareModels[result.hardware_model] ?? "UNKNOWN", + }; + }); + + res.json({ + hardware_model_stats: hardwareModelStats, + }); + + } catch(err) { + console.error(err); + res.status(500).json({ + message: "Something went wrong, try again later.", + }); + } +}); + app.get('/api/v1/text-messages', async (req, res) => { try { @@ -1110,29 +805,8 @@ app.get('/api/v1/waypoints', async (req, res) => { } }); - // start express server const listener = app.listen(port, () => { const port = listener.address().port; console.log(`Server running at http://127.0.0.1:${port}`); }); - -// Graceful shutdown handlers -function gracefulShutdown(signal) { - console.log(`Received ${signal}. Starting graceful shutdown...`); - - // Stop accepting new connections - listener.close(async (err) => { - console.log('HTTP server closed'); - await prisma.$disconnect(); - console.log('Database connections closed'); - console.log('Graceful shutdown completed'); - process.exit(0); - }); -} - -// Handle SIGTERM (Docker, systemd, etc.) -process.on('SIGTERM', () => gracefulShutdown('SIGTERM')); - -// Handle SIGINT (Ctrl+C) -process.on('SIGINT', () => gracefulShutdown('SIGINT')); diff --git a/src/json/hardware_models.json b/src/json/hardware_models.json new file mode 100644 index 0000000..6f4187f --- /dev/null +++ b/src/json/hardware_models.json @@ -0,0 +1,108 @@ +{ + "0": "UNSET", + "1": "TLORA_V2", + "2": "TLORA_V1", + "3": "TLORA_V2_1_1P6", + "4": "TBEAM", + "5": "HELTEC_V2_0", + "6": "TBEAM_V0P7", + "7": "T_ECHO", + "8": "TLORA_V1_1P3", + "9": "RAK4631", + "10": "HELTEC_V2_1", + "11": "HELTEC_V1", + "12": "LILYGO_TBEAM_S3_CORE", + "13": "RAK11200", + "14": "NANO_G1", + "15": "TLORA_V2_1_1P8", + "16": "TLORA_T3_S3", + "17": "NANO_G1_EXPLORER", + "18": "NANO_G2_ULTRA", + "19": "LORA_TYPE", + "20": "WIPHONE", + "21": "WIO_WM1110", + "22": "RAK2560", + "23": "HELTEC_HRU_3601", + "24": "HELTEC_WIRELESS_BRIDGE", + "25": "STATION_G1", + "26": "RAK11310", + "27": "SENSELORA_RP2040", + "28": "SENSELORA_S3", + "29": "CANARYONE", + "30": "RP2040_LORA", + "31": "STATION_G2", + "32": "LORA_RELAY_V1", + "33": "NRF52840DK", + "34": "PPR", + "35": "GENIEBLOCKS", + "36": "NRF52_UNKNOWN", + "37": "PORTDUINO", + "38": "ANDROID_SIM", + "39": "DIY_V1", + "40": "NRF52840_PCA10059", + "41": "DR_DEV", + "42": "M5STACK", + "43": "HELTEC_V3", + "44": "HELTEC_WSL_V3", + "45": "BETAFPV_2400_TX", + "46": "BETAFPV_900_NANO_TX", + "47": "RPI_PICO", + "48": "HELTEC_WIRELESS_TRACKER", + "49": "HELTEC_WIRELESS_PAPER", + "50": "T_DECK", + "51": "T_WATCH_S3", + "52": "PICOMPUTER_S3", + "53": "HELTEC_HT62", + "54": "EBYTE_ESP32_S3", + "55": "ESP32_S3_PICO", + "56": "CHATTER_2", + "57": "HELTEC_WIRELESS_PAPER_V1_0", + "58": "HELTEC_WIRELESS_TRACKER_V1_0", + "59": "UNPHONE", + "60": "TD_LORAC", + "61": "CDEBYTE_EORA_S3", + "62": "TWC_MESH_V4", + "63": "NRF52_PROMICRO_DIY", + "64": "RADIOMASTER_900_BANDIT_NANO", + "65": "HELTEC_CAPSULE_SENSOR_V3", + "66": "HELTEC_VISION_MASTER_T190", + "67": "HELTEC_VISION_MASTER_E213", + "68": "HELTEC_VISION_MASTER_E290", + "69": "HELTEC_MESH_NODE_T114", + "70": "SENSECAP_INDICATOR", + "71": "TRACKER_T1000_E", + "72": "RAK3172", + "73": "WIO_E5", + "74": "RADIOMASTER_900_BANDIT", + "75": "ME25LS01_4Y10TD", + "76": "RP2040_FEATHER_RFM95", + "77": "M5STACK_COREBASIC", + "78": "M5STACK_CORE2", + "79": "RPI_PICO2", + "80": "M5STACK_CORES3", + "81": "SEEED_XIAO_S3", + "82": "MS24SF1", + "83": "TLORA_C6", + "84": "WISMESH_TAP", + "85": "ROUTASTIC", + "86": "MESH_TAB", + "87": "MESHLINK", + "88": "XIAO_NRF52_KIT", + "89": "THINKNODE_M1", + "90": "THINKNODE_M2", + "91": "T_ETH_ELITE", + "92": "HELTEC_SENSOR_HUB", + "93": "RESERVED_FRIED_CHICKEN", + "94": "HELTEC_MESH_POCKET", + "95": "SEEED_SOLAR_NODE", + "96": "NOMADSTAR_METEOR_PRO", + "97": "CROWPANEL", + "98": "LINK_32", + "99": "SEEED_WIO_TRACKER_L1", + "100": "SEEED_WIO_TRACKER_L1_EINK", + "101": "QWANTZ_TINY_ARMS", + "102": "T_DECK_PRO", + "103": "T_LORA_PAGER", + "104": "GAT562_MESH_TRIAL_TRACKER", + "255": "PRIVATE_HW" +} diff --git a/src/json/modem_presets.json b/src/json/modem_presets.json new file mode 100644 index 0000000..75c1ba4 --- /dev/null +++ b/src/json/modem_presets.json @@ -0,0 +1,11 @@ +{ + "0": "LONG_FAST", + "1": "LONG_SLOW", + "2": "VERY_LONG_SLOW", + "3": "MEDIUM_SLOW", + "4": "MEDIUM_FAST", + "5": "SHORT_SLOW", + "6": "SHORT_FAST", + "7": "LONG_MODERATE", + "8": "SHORT_TURBO" +} diff --git a/src/json/region_codes.json b/src/json/region_codes.json new file mode 100644 index 0000000..d63c276 --- /dev/null +++ b/src/json/region_codes.json @@ -0,0 +1,24 @@ +{ + "0": "UNSET", + "1": "US", + "2": "EU_433", + "3": "EU_868", + "4": "CN", + "5": "JP", + "6": "ANZ", + "7": "KR", + "8": "TW", + "9": "RU", + "10": "IN", + "11": "NZ_865", + "12": "TH", + "13": "LORA_24", + "14": "UA_433", + "15": "UA_868", + "16": "MY_433", + "17": "MY_919", + "18": "SG_923", + "19": "PH_433", + "20": "PH_868", + "21": "PH_915" +} diff --git a/src/json/roles.json b/src/json/roles.json new file mode 100644 index 0000000..1fe96fd --- /dev/null +++ b/src/json/roles.json @@ -0,0 +1,14 @@ +{ + "0": "CLIENT", + "1": "CLIENT_MUTE", + "2": "ROUTER", + "3": "ROUTER_CLIENT", + "4": "REPEATER", + "5": "TRACKER", + "6": "SENSOR", + "7": "TAK", + "8": "CLIENT_HIDDEN", + "9": "LOST_AND_FOUND", + "10": "TAK_TRACKER", + "11": "ROUTER_LATE" +} diff --git a/src/mqtt.js b/src/mqtt.js index 67cb9dd..f7b2b25 100644 --- a/src/mqtt.js +++ b/src/mqtt.js @@ -1,4 +1,4 @@ -require('./utils/logger'); +const fs = require("fs"); const crypto = require("crypto"); const path = require("path"); const mqtt = require("mqtt"); @@ -22,6 +22,11 @@ const optionsList = [ type: Boolean, description: 'Display this usage guide.' }, + { + name: "protobufs-path", + type: String, + description: "Path to Protobufs (e.g: ../../protobufs)", + }, { name: "mqtt-broker-url", type: String, @@ -207,6 +212,7 @@ if(options.help){ } // get options and fallback to default values +const protobufsPath = options["protobufs-path"] ?? path.join(path.dirname(__filename), "external/protobufs"); const mqttBrokerUrl = options["mqtt-broker-url"] ?? "mqtt://mqtt.meshtastic.org"; const mqttUsername = options["mqtt-username"] ?? "meshdev"; const mqttPassword = options["mqtt-password"] ?? "large4cats"; @@ -223,7 +229,6 @@ const collectNeighbourInfo = options["collect-neighbour-info"] ?? false; const collectMapReports = options["collect-map-reports"] ?? false; const decryptionKeys = options["decryption-keys"] ?? [ "1PG7OiApB1nwvP+rz05pAQ==", // add default "AQ==" decryption key - "PjG/mVAqnannyvqmuYAwd0LZa1AV+wkcUQlacmexEXY=", // Årsta mesh? länkad av [x/0!] divideByZero i meshen ]; const dropPacketsNotOkToMqtt = options["drop-packets-not-ok-to-mqtt"] ?? false; const dropPortnumsWithoutBitfield = options["drop-portnums-without-bitfield"] ?? null; @@ -242,6 +247,25 @@ const purgeTextMessagesAfterSeconds = options["purge-text-messages-after-seconds const purgeTraceroutesAfterSeconds = options["purge-traceroutes-after-seconds"] ?? null; const purgeWaypointsAfterSeconds = options["purge-waypoints-after-seconds"] ?? null; +// ensure protobufs exist +if(!fs.existsSync(path.join(protobufsPath, "meshtastic/mqtt.proto"))){ + console.error([ + "ERROR: MQTT Collector requires Meshtastic protobufs.", + "", + "This project is licensed under the MIT license to allow end users to do as they wish.", + "Unfortunately, the Meshtastic protobuf schema files are licensed under GPLv3, which means they can not be bundled in this project due to license conflicts.", + "https://github.com/liamcottle/meshtastic-map/issues/102", + "https://github.com/meshtastic/protobufs/issues/695", + "", + "If you clone and install the Meshtastic protobufs as described below, your use of those files will be subject to the GPLv3 license.", + "This does not change the license of this project being MIT. Only the parts you add from the Meshtastic project are covered under GPLv3.", + "", + "To use the MQTT Collector, please clone the Meshtastic protobufs into src/external/protobufs", + "git clone https://github.com/meshtastic/protobufs src/external/protobufs", + ].join("\n")); + return; +} + // create mqtt client const client = mqtt.connect(mqttBrokerUrl, { username: mqttUsername, @@ -251,7 +275,7 @@ const client = mqtt.connect(mqttBrokerUrl, { // load protobufs const root = new protobufjs.Root(); -root.resolvePath = (origin, target) => path.join(__dirname, "protobufs", target); +root.resolvePath = (origin, target) => path.join(protobufsPath, target); root.loadSync('meshtastic/mqtt.proto'); const Data = root.lookupType("Data"); const ServiceEnvelope = root.lookupType("ServiceEnvelope"); @@ -264,9 +288,8 @@ const User = root.lookupType("User"); const Waypoint = root.lookupType("Waypoint"); // run automatic purge if configured -let purgeInterval = null; if(purgeIntervalSeconds){ - purgeInterval = setInterval(async () => { + setInterval(async () => { await purgeUnheardNodes(); await purgeOldDeviceMetrics(); await purgeOldEnvironmentMetrics(); @@ -742,13 +765,6 @@ client.on("message", async (topic, message) => { } } - - // check if bitfield is available, then set ok-to-mqtt - // else leave undefined to let Prisma ignore it. - let isOkToMqtt - if(bitfield != null){ - isOkToMqtt = Boolean(bitfield & BITFIELD_OK_TO_MQTT_MASK); - } // create service envelope in db if(collectServiceEnvelopes){ @@ -760,8 +776,6 @@ client.on("message", async (topic, message) => { gateway_id: envelope.gatewayId ? convertHexIdToNumericId(envelope.gatewayId) : null, to: envelope.packet.to, from: envelope.packet.from, - portnum: portnum, - packet_id: envelope.packet.id, protobuf: message, }, }); @@ -826,7 +840,6 @@ client.on("message", async (topic, message) => { rx_snr: envelope.packet.rxSnr, rx_rssi: envelope.packet.rxRssi, hop_limit: envelope.packet.hopLimit, - ok_to_mqtt: isOkToMqtt, }, }); } catch (e) { @@ -948,19 +961,6 @@ client.on("message", async (topic, message) => { hardware_model: user.hwModel, is_licensed: user.isLicensed === true, role: user.role, - is_unmessagable: user.isUnmessagable, - ok_to_mqtt: isOkToMqtt, - max_hops: envelope.packet.hopStart, - channel_id: envelope.channelId, - - firmware_version: '<2.5.0', - ...(user.publicKey != '' && { - firmware_version: '>2.5.0', - public_key: user.publicKey?.toString("base64"), - }), - ...(user.isUnmessagable != null && { - firmware_version: '>2.6.8', - }), }, update: { long_name: user.longName, @@ -968,57 +968,12 @@ client.on("message", async (topic, message) => { hardware_model: user.hwModel, is_licensed: user.isLicensed === true, role: user.role, - is_unmessagable: user.isUnmessagable, - ok_to_mqtt: isOkToMqtt, - max_hops: envelope.packet.hopStart, - channel_id: envelope.channelId, - - firmware_version: '<2.5.0', - ...(user.publicKey != '' && { - firmware_version: '>2.5.0', - public_key: user.publicKey?.toString("base64"), - }), - ...(user.isUnmessagable != null && { - firmware_version: '>2.6.8', - }), }, }); } catch (e) { - // Ignore MySQL error 1020 "Record has changed since last read" - this is a race condition - // that occurs when multiple packets arrive concurrently for the same node - const errorMessage = e.message || String(e); - if (!errorMessage.includes('Record has changed since last read')) { - console.error(e); - } + console.error(e); } - // Keep track of the names a node has been using. - try { - await prisma.NameHistory.upsert({ - where: { - node_id_long_name_short_name: { - node_id: envelope.packet.from, - long_name: user.longName, - short_name: user.shortName, - } - }, - create: { - node_id: envelope.packet.from, - long_name: user.longName, - short_name: user.shortName, - }, - update: { - updated_at: new Date(), - } - }); - } catch (e) { - // Ignore MySQL error 1020 "Record has changed since last read" - this is a race condition - // that occurs when multiple packets arrive concurrently for the same node - const errorMessage = e.message || String(e); - if (!errorMessage.includes('Record has changed since last read')) { - console.error(e); - } - } } else if(portnum === 8) { @@ -1094,70 +1049,6 @@ client.on("message", async (topic, message) => { console.error(e); } - // Extract edges from neighbour info - try { - const toNodeId = envelope.packet.from; - const neighbors = neighbourInfo.neighbors || []; - const packetId = envelope.packet.id; - const channelId = envelope.channelId; - const gatewayId = envelope.gatewayId ? convertHexIdToNumericId(envelope.gatewayId) : null; - const edgesToCreate = []; - - for(const neighbour of neighbors) { - // Skip if no node ID - if(!neighbour.nodeId) { - continue; - } - - // Skip if SNR is invalid (0 or null/undefined) - // Note: SNR can be negative, so we check for 0 specifically - if(neighbour.snr === 0 || neighbour.snr == null) { - continue; - } - - const fromNodeId = neighbour.nodeId; - const snr = neighbour.snr; - - // Fetch node positions from Node table - const [fromNode, toNode] = await Promise.all([ - prisma.node.findUnique({ - where: { node_id: fromNodeId }, - select: { latitude: true, longitude: true }, - }), - prisma.node.findUnique({ - where: { node_id: toNodeId }, - select: { latitude: true, longitude: true }, - }), - ]); - - // Create edge record - edgesToCreate.push({ - from_node_id: fromNodeId, - to_node_id: toNodeId, - snr: snr, - from_latitude: fromNode?.latitude ?? null, - from_longitude: fromNode?.longitude ?? null, - to_latitude: toNode?.latitude ?? null, - to_longitude: toNode?.longitude ?? null, - packet_id: packetId, - channel_id: channelId, - gateway_id: gatewayId, - source: "NEIGHBORINFO_APP", - }); - } - - // Bulk insert edges - if(edgesToCreate.length > 0) { - await prisma.edge.createMany({ - data: edgesToCreate, - skipDuplicates: true, // Skip if exact duplicate exists - }); - } - } catch (e) { - // Log error but don't crash - edge extraction is non-critical - console.error("Error extracting edges from neighbour info:", e); - } - // don't store all neighbour infos, but we want to update the existing node above if(!collectNeighbourInfo){ return; @@ -1400,160 +1291,6 @@ client.on("message", async (topic, message) => { console.error(e); } - // Extract edges from traceroute (only for response packets) - if(!envelope.packet.decoded.wantResponse) { - try { - const route = routeDiscovery.route || []; - const snrTowards = routeDiscovery.snrTowards || []; - const originNodeId = envelope.packet.to; - const destinationNodeId = envelope.packet.from; - const packetId = envelope.packet.id; - const channelId = envelope.channelId; - const gatewayId = envelope.gatewayId ? convertHexIdToNumericId(envelope.gatewayId) : null; - - // Determine number of edges: route.length + 1 - const numEdges = route.length + 1; - const edgesToCreate = []; - - // Extract edges from the route path - for(let i = 0; i < numEdges; i++) { - // Get SNR for this edge - if(i >= snrTowards.length) { - // Array length mismatch - skip this edge - continue; - } - - const snr = snrTowards[i]; - - // Skip if SNR is -128 (no SNR recorded) - if(snr === -128) { - continue; - } - - // Determine from_node and to_node - let fromNodeId, toNodeId; - - if(route.length === 0) { - // Empty route: direct connection (to -> from) - fromNodeId = originNodeId; - toNodeId = destinationNodeId; - } else if(i === 0) { - // First edge: origin -> route[0] - fromNodeId = originNodeId; - toNodeId = route[0]; - } else if(i === route.length) { - // Last edge: route[route.length-1] -> destination - fromNodeId = route[route.length - 1]; - toNodeId = destinationNodeId; - } else { - // Middle edge: route[i-1] -> route[i] - fromNodeId = route[i - 1]; - toNodeId = route[i]; - } - - // Fetch node positions from Node table - const [fromNode, toNode] = await Promise.all([ - prisma.node.findUnique({ - where: { node_id: fromNodeId }, - select: { latitude: true, longitude: true }, - }), - prisma.node.findUnique({ - where: { node_id: toNodeId }, - select: { latitude: true, longitude: true }, - }), - ]); - - // Create edge record (skip if nodes don't exist, but still create edge with null positions) - edgesToCreate.push({ - from_node_id: fromNodeId, - to_node_id: toNodeId, - snr: snr, - from_latitude: fromNode?.latitude ?? null, - from_longitude: fromNode?.longitude ?? null, - to_latitude: toNode?.latitude ?? null, - to_longitude: toNode?.longitude ?? null, - packet_id: packetId, - channel_id: channelId, - gateway_id: gatewayId, - source: "TRACEROUTE_APP", - }); - } - - // Extract edges from route_back path - const routeBack = routeDiscovery.routeBack || []; - const snrBack = routeDiscovery.snrBack || []; - - if(routeBack.length > 0) { - // Number of edges in route_back equals route_back.length - for(let i = 0; i < routeBack.length; i++) { - // Get SNR for this edge - if(i >= snrBack.length) { - // Array length mismatch - skip this edge - continue; - } - - const snr = snrBack[i]; - - // Skip if SNR is -128 (no SNR recorded) - if(snr === -128) { - continue; - } - - // Determine from_node and to_node - let fromNodeId, toNodeId; - - if(i === 0) { - // First edge: from -> route_back[0] - fromNodeId = destinationNodeId; // 'from' in the packet - toNodeId = routeBack[0]; - } else { - // Subsequent edges: route_back[i-1] -> route_back[i] - fromNodeId = routeBack[i - 1]; - toNodeId = routeBack[i]; - } - - // Fetch node positions from Node table - const [fromNode, toNode] = await Promise.all([ - prisma.node.findUnique({ - where: { node_id: fromNodeId }, - select: { latitude: true, longitude: true }, - }), - prisma.node.findUnique({ - where: { node_id: toNodeId }, - select: { latitude: true, longitude: true }, - }), - ]); - - // Create edge record - edgesToCreate.push({ - from_node_id: fromNodeId, - to_node_id: toNodeId, - snr: snr, - from_latitude: fromNode?.latitude ?? null, - from_longitude: fromNode?.longitude ?? null, - to_latitude: toNode?.latitude ?? null, - to_longitude: toNode?.longitude ?? null, - packet_id: packetId, - channel_id: channelId, - gateway_id: gatewayId, - source: "TRACEROUTE_APP", - }); - } - } - - // Bulk insert edges - if(edgesToCreate.length > 0) { - await prisma.edge.createMany({ - data: edgesToCreate, - skipDuplicates: true, // Skip if exact duplicate exists - }); - } - } catch (e) { - // Log error but don't crash - edge extraction is non-critical - console.error("Error extracting edges from traceroute:", e); - } - } - } else if(portnum === 73) { @@ -1658,7 +1395,6 @@ client.on("message", async (topic, message) => { || portnum === 0 // ignore UNKNOWN_APP || portnum === 1 // ignore TEXT_MESSAGE_APP || portnum === 5 // ignore ROUTING_APP - || portnum === 6 // ignore ADMIN_APP || portnum === 34 // ignore PAXCOUNTER_APP || portnum === 65 // ignore STORE_FORWARD_APP || portnum === 66 // ignore RANGE_TEST_APP @@ -1675,32 +1411,6 @@ client.on("message", async (topic, message) => { } } catch(e) { - console.log("error", e); + // ignore errors } }); - -// Graceful shutdown handlers -function gracefulShutdown(signal) { - console.log(`Received ${signal}. Starting graceful shutdown...`); - - // Clear the purge interval if it exists - if(purgeInterval) { - clearInterval(purgeInterval); - console.log('Purge interval cleared'); - } - - // Close MQTT client - client.end(false, async () => { - console.log('MQTT client disconnected'); - await prisma.$disconnect(); - console.log('Database connections closed'); - console.log('Graceful shutdown completed'); - process.exit(0); - }); -} - -// Handle SIGTERM (Docker, systemd, etc.) -process.on('SIGTERM', () => gracefulShutdown('SIGTERM')); - -// Handle SIGINT (Ctrl+C) -process.on('SIGINT', () => gracefulShutdown('SIGINT')); diff --git a/src/protobufs b/src/protobufs deleted file mode 160000 index c2e45a3..0000000 --- a/src/protobufs +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c2e45a3fc9cda6aedb72ad3b5b88fcccfa78073e diff --git a/src/public/assets/css/styles.css b/src/public/assets/css/styles.css deleted file mode 100644 index 8811cad..0000000 --- a/src/public/assets/css/styles.css +++ /dev/null @@ -1,115 +0,0 @@ -/* used to prevent ui flicker before vuejs loads */ -[v-cloak] { - display: none; -} - -.icon-longfast { - background-color: #009016; - border-radius: 25px; - border: 1px solid #2C2D3C; -} - -.icon-mediumfast { - background-color: #326be7; - border-radius: 25px; - border: 1px solid #2C2D3C; -} - -.icon-shortslow { - background-color: #0077e6; - border-radius: 25px; - border: 1px solid #2C2D3C; -} - -.icon-mqtt-connected { - background-color: #2563eb; /* Change to use same color as disconnected // #16a34a; */ - border-radius: 25px; - border: 1px solid #2C2D3C; -} - -.icon-mqtt-disconnected { - background-color: #2563eb; - border-radius: 25px; - border: 1px solid #2C2D3C; -} - -.icon-offline { - background-color: #e2286c; - border-radius: 25px; - border: 1px solid #2C2D3C; -} - -.icon-position-history { - background-color: #a855f7; - border-radius: 25px; - border: 1px solid #2C2D3C; -} - -.icon-traceroute-start { - background-color: #16a34a; /* green */ - border-radius: 25px; - border: 1px solid #2C2D3C; -} - -.icon-traceroute-end { - background-color: #dc2626; /* red */ - border-radius: 25px; - border: 1px solid #2C2D3C; -} - -.waypoint-label { - font-size: 26px; - background-color: transparent; -} - -.link { - color: #2563eb; -} - -.link:hover { - text-decoration: underline; -} - -.tooltip { - position: relative; - display: inline-block; -} - -.tooltip .tooltip-text { - visibility: hidden; - width: 80px; - background-color: black; - color: #fff; - text-align: center; - padding: 4px 0; - border-radius: 6px; - position: absolute; - z-index: 10000; - top: 100%; - left: 50%; - margin-top: 8px; - margin-left: -40px; /* Use half of the width (120/2 = 60), to center the tooltip */ -} - -.tooltip .tooltip-text::after { - content: " "; - position: absolute; - bottom: 100%; /* At the top of the tooltip */ - left: 50%; - margin-left: -5px; - border-width: 5px; - border-style: solid; - border-color: transparent transparent black transparent; -} - -.tooltip:hover .tooltip-text { - visibility: visible; -} - -.z-search { - z-index: 1001; -} - -.z-sidebar { - z-index: 1002; -} \ No newline at end of file diff --git a/src/public/assets/js/app.js b/src/public/assets/js/app.js deleted file mode 100644 index 86b4542..0000000 --- a/src/public/assets/js/app.js +++ /dev/null @@ -1,956 +0,0 @@ -Vue.createApp({ - data() { - return { - - isShowingAnnouncement: this.shouldShowAnnouncement(), - - configNodesMaxAgeInSeconds: window.getConfigNodesMaxAgeInSeconds(), - configNodesOfflineAgeInSeconds: window.getConfigNodesOfflineAgeInSeconds(), - configWaypointsMaxAgeInSeconds: window.getConfigWaypointsMaxAgeInSeconds(), - configConnectionsMaxDistanceInMeters: window.getConfigConnectionsMaxDistanceInMeters(), - configZoomLevelGoToNode: window.getConfigZoomLevelGoToNode(), - configAutoUpdatePositionInUrl: window.getConfigAutoUpdatePositionInUrl(), - configEnableMapAnimations: window.getConfigEnableMapAnimations(), - configTemperatureFormat: window.getConfigTemperatureFormat(), - configConnectionsTimePeriodInSeconds: window.getConfigConnectionsTimePeriodInSeconds(), - configConnectionsColoredLines: window.getConfigConnectionsColoredLines(), - configConnectionsBidirectionalOnly: window.getConfigConnectionsBidirectionalOnly(), - configConnectionsMinSnrDb: window.getConfigConnectionsMinSnrDb(), - configConnectionsBidirectionalMinSnr: window.getConfigConnectionsBidirectionalMinSnr(), - - isShowingHardwareModels: false, - hardwareModelStats: null, - - isShowingInfoModal: this.shouldShowInfoModal(), - isShowingMobileSearch: false, - isShowingSettings: false, - - nodes: [], - searchText: "", - - selectedNode: null, - selectedNodeDeviceMetrics: [], - selectedNodeEnvironmentMetrics: [], - selectedNodePowerMetrics: [], - selectedNodeMqttMetrics: [], - selectedNodeTraceroutes: [], - - deviceMetricsTimeRange: "7d", - environmentMetricsTimeRange: "7d", - powerMetricsTimeRange: "7d", - - isPositionHistoryModalExpanded: true, - positionHistoryDateTimeFrom: null, - positionHistoryDateTimeTo: null, - selectedNodePositionHistory: [], - selectedNodeToShowPositionHistory: null, - selectedNodePositionHistoryMarkers: [], - selectedNodePositionHistoryPolyLines: [], - - selectedTraceRoute: null, - tracerouteEdges: [], - - selectedNodeToShowConnections: null, - - moment: window.moment, - - }; - }, - mounted: function() { - - // load data - this.loadHardwareModelStats(); - - // handle map click callback from outside of vue - window._onMapClick = () => { - this.searchText = ""; - this.isShowingMobileSearch = false; - }; - - // handle node callback from outside of vue - window._onNodeClick = (node) => { - this.selectedNode = node; - this.loadNodeDeviceMetrics(node.node_id); - this.loadNodeEnvironmentMetrics(node.node_id); - this.loadNodePowerMetrics(node.node_id); - this.loadNodeMqttMetrics(node.node_id); - this.loadNodeTraceroutes(node.node_id); - //this.loadNodePositionHistory(node.node_id); - }; - - // handle node callback from outside of vue - window._onShowNodeConnectionsClick = (node) => { - this.selectedNodeToShowConnections = node; - }; - - // handle nodes updated callback from outside of vue - window._onNodesUpdated = (nodes) => { - this.nodes = nodes; - }; - - }, - methods: { - getAnnouncementId: function() { - // change this when making a new announcement - return "1"; - }, - shouldShowAnnouncement: function() { - const lastSeenAnnouncementId = window.localStorage.getItem("last-seen-announcement-id"); - return lastSeenAnnouncementId?.toString() !== this.getAnnouncementId(); - }, - dismissAnnouncement: function() { - window.localStorage.setItem("last-seen-announcement-id", this.getAnnouncementId()); - this.isShowingAnnouncement = false; - }, - shouldShowInfoModal: function() { - return !window.getConfigHasSeenInfoModal() - && !window.isMobile(); - }, - loadHardwareModelStats: function() { - window.axios.get('/api/v1/stats/hardware-models').then((response) => { - this.hardwareModelStats = response.data.hardware_model_stats; - }).catch((error) => { - // do nothing - }); - }, - loadNodeDeviceMetrics: function(nodeId) { - - // calculate unix timestamps in milliseconds for supported time ranges - const oneDayAgoInMilliseconds = new Date().getTime() - (86400 * 1000); - const threeDaysAgoInMilliseconds = new Date().getTime() - (259200 * 1000); - const sevenDaysAgoInMilliseconds = new Date().getTime() - (604800 * 1000); - const thirtyDaysAgoInMilliseconds = new Date().getTime() - (259200 * 1000 * 10); - - // determine how long back to load device metrics from - var timeFrom = threeDaysAgoInMilliseconds; - switch(this.deviceMetricsTimeRange){ - case "1d": { - timeFrom = oneDayAgoInMilliseconds; - break; - } - case "3d": { - timeFrom = threeDaysAgoInMilliseconds; - break; - } - case "7d": { - timeFrom = sevenDaysAgoInMilliseconds; - break; - } - case "30d": { - timeFrom = thirtyDaysAgoInMilliseconds; - break; - } - } - - window.axios.get(`/api/v1/nodes/${nodeId}/device-metrics`, { - params: { - time_from: timeFrom, - }, - }).then((response) => { - // reverse response, as it's newest to oldest, but we want oldest to newest - this.selectedNodeDeviceMetrics = response.data.device_metrics.reverse(); - this.renderDeviceMetricCharts(); - }).catch(() => { - this.selectedNodeDeviceMetrics = []; - this.renderDeviceMetricCharts(); - }); - }, - loadNodeEnvironmentMetrics: function(nodeId) { - - // calculate unix timestamps in milliseconds for supported time ranges - const oneDayAgoInMilliseconds = new Date().getTime() - (86400 * 1000); - const threeDaysAgoInMilliseconds = new Date().getTime() - (259200 * 1000); - const sevenDaysAgoInMilliseconds = new Date().getTime() - (604800 * 1000); - const thirtyDaysAgoInMilliseconds = new Date().getTime() - (259200 * 1000 * 10); - - // determine how long back to load environment metrics from - var timeFrom = threeDaysAgoInMilliseconds; - switch(this.environmentMetricsTimeRange){ - case "1d": { - timeFrom = oneDayAgoInMilliseconds; - break; - } - case "3d": { - timeFrom = threeDaysAgoInMilliseconds; - break; - } - case "7d": { - timeFrom = sevenDaysAgoInMilliseconds; - break; - } - case "30d": { - timeFrom = thirtyDaysAgoInMilliseconds; - break; - } - } - - window.axios.get(`/api/v1/nodes/${nodeId}/environment-metrics`, { - params: { - time_from: timeFrom, - }, - }).then((response) => { - // reverse response, as it's newest to oldest, but we want oldest to newest - this.selectedNodeEnvironmentMetrics = response.data.environment_metrics.reverse(); - this.renderEnvironmentMetricCharts(); - }).catch(() => { - this.selectedNodeEnvironmentMetrics = []; - this.renderEnvironmentMetricCharts(); - }); - }, - loadNodePowerMetrics: function(nodeId) { - - // calculate unix timestamps in milliseconds for supported time ranges - const oneDayAgoInMilliseconds = new Date().getTime() - (86400 * 1000); - const threeDaysAgoInMilliseconds = new Date().getTime() - (259200 * 1000); - const sevenDaysAgoInMilliseconds = new Date().getTime() - (604800 * 1000); - const thirtyDaysAgoInMilliseconds = new Date().getTime() - (259200 * 1000 * 10); - - // determine how long back to load power metrics from - var timeFrom = threeDaysAgoInMilliseconds; - switch(this.powerMetricsTimeRange){ - case "1d": { - timeFrom = oneDayAgoInMilliseconds; - break; - } - case "3d": { - timeFrom = threeDaysAgoInMilliseconds; - break; - } - case "7d": { - timeFrom = sevenDaysAgoInMilliseconds; - break; - } - case "30d": { - timeFrom = thirtyDaysAgoInMilliseconds; - break; - } - } - - window.axios.get(`/api/v1/nodes/${nodeId}/power-metrics`, { - params: { - time_from: timeFrom, - }, - }).then((response) => { - // reverse response, as it's newest to oldest, but we want oldest to newest - this.selectedNodePowerMetrics = response.data.power_metrics.reverse(); - this.renderPowerMetricCharts(); - }).catch(() => { - this.selectedNodePowerMetrics = []; - this.renderPowerMetricCharts(); - }); - }, - loadNodeMqttMetrics: function(nodeId) { - this.selectedNodeMqttMetrics = []; - window.axios.get(`/api/v1/nodes/${nodeId}/mqtt-metrics`).then((response) => { - this.selectedNodeMqttMetrics = response.data.mqtt_metrics; - }).catch(() => { - // do nothing - }); - }, - loadNodeTraceroutes: function(nodeId) { - this.selectedNodeTraceroutes = []; - window.axios.get(`/api/v1/nodes/${nodeId}/traceroutes`, { - params: { - count: 5, - }, - }).then((response) => { - this.selectedNodeTraceroutes = response.data.traceroutes; - }).catch(() => { - // do nothing - }); - }, - loadNodePositionHistory: function(nodeId) { - this.selectedNodePositionHistory = []; - window.axios.get(`/api/v1/nodes/${nodeId}/position-history`, { - params: { - // parse from datetime-local format, and send as unix timestamp in milliseconds - time_from: moment(this.positionHistoryDateTimeFrom, "YYYY-MM-DDTHH:mm").format("x"), - time_to: moment(this.positionHistoryDateTimeTo, "YYYY-MM-DDTHH:mm").format("x"), - }, - }).then((response) => { - this.selectedNodePositionHistory = response.data.position_history; - if(this.selectedNodeToShowPositionHistory != null){ - clearAllPositionHistory(); - onPositionHistoryUpdated(response.data.position_history); - } - - }).catch(() => { - // do nothing - }); - }, - renderDeviceMetricCharts: function() { - try { - this.updateDeviceMetricsChart(); - } catch(e) { - console.log(e); - } - }, - updateDeviceMetricsChart: function() { - - // destroy existing chart - const chartElementId = "deviceMetricsChart"; - const existingChart = window.Chart.getChart(chartElementId); - if(existingChart != null){ - existingChart.destroy(); - } - - // get chart element - const chartElement = window.document.getElementById(chartElementId); - if(!chartElement){ - return; - } - - // create chart data - const labels = []; - const batteryMetrics = []; - const channelUtilizationMetrics = []; - const airUtilTxMetrics = []; - for(const deviceMetric of this.selectedNodeDeviceMetrics){ - labels.push(moment(deviceMetric.created_at)); - batteryMetrics.push(deviceMetric.battery_level); - channelUtilizationMetrics.push(deviceMetric.channel_utilization); - airUtilTxMetrics.push(deviceMetric.air_util_tx); - } - - // create chart - new window.Chart(chartElement, { - type: 'line', - data: { - labels: labels, - datasets: [ - { - label: 'Battery Level', - borderColor: '#3b82f6', - backgroundColor: '#3b82f6', - pointStyle: false, // no points - fill: false, - data: batteryMetrics, - }, - { - label: 'Channel Util', - borderColor: '#22c55e', - backgroundColor: '#22c55e', - showLine: false, // no lines between points - fill: false, - data: channelUtilizationMetrics, - }, - { - label: 'Air Util TX', - borderColor: '#f97316', - backgroundColor: '#f97316', - showLine: false, // no lines between points - fill: false, - data: airUtilTxMetrics, - - }, - ], - }, - options: { - responsive: true, - borderWidth: 2, - elements: { - point: { - radius: 2, - }, - }, - scales: { - x: { - position: 'top', - type: 'time', - time: { - unit: 'day', - displayFormats: { - day: 'MMM DD', // Jan 01 - }, - }, - }, - y: { - min: 0, - max: 101, // 101 is "Plugged In", need to include for tooltip to work - ticks: { - callback: (label) => `${label}%`, - }, - }, - }, - plugins: { - legend: { - display: false, - }, - tooltip: { - mode: "index", - intersect: false, - callbacks: { - label: (item) => { - return `${item.dataset.label}: ${item.formattedValue}%`; - }, - }, - }, - }, - } - }); - - }, - renderEnvironmentMetricCharts: function() { - try { - this.updateEnvironmentMetricsChart(); - } catch(e) { - console.log(e); - } - }, - updateEnvironmentMetricsChart: function() { - - // destroy existing chart - const chartElementId = "environmentMetricsChart"; - const existingChart = window.Chart.getChart(chartElementId); - if(existingChart != null){ - existingChart.destroy(); - } - - // get chart element - const chartElement = window.document.getElementById(chartElementId); - if(!chartElement){ - return; - } - - // create chart data - const labels = []; - const temperatureMetrics = []; - const relativeHumidityMetrics = []; - const barometricPressureMetrics = []; - const iaqMetrics = []; - for(const deviceMetric of this.selectedNodeEnvironmentMetrics){ - labels.push(moment(deviceMetric.created_at)); - temperatureMetrics.push(deviceMetric.temperature); - relativeHumidityMetrics.push(deviceMetric.relative_humidity); - barometricPressureMetrics.push(deviceMetric.barometric_pressure); - iaqMetrics.push(deviceMetric.iaq); - } - - // create chart - new window.Chart(chartElement, { - type: 'line', - data: { - labels: labels, - datasets: [ - { - label: 'Temperature', - suffix: '°C', - borderColor: '#3b82f6', - backgroundColor: '#3b82f6', - pointStyle: false, // no points - fill: false, - data: temperatureMetrics, - yAxisID: 'y', - }, - { - label: 'Humidity', - suffix: '%', - borderColor: '#22c55e', - backgroundColor: '#22c55e', - pointStyle: false, // no points - fill: false, - data: relativeHumidityMetrics, - yAxisID: 'y', - }, - { - label: 'Pressure', - suffix: 'hPa', - borderColor: '#f97316', - backgroundColor: '#f97316', - pointStyle: false, // no points - fill: false, - data: barometricPressureMetrics, - yAxisID: 'y1', - - }, - { - label: 'IAQ', - suffix: 'IAQ', - borderColor: '#f472b6', - backgroundColor: '#f472b6', - pointStyle: false, // no points - fill: false, - data: iaqMetrics, - yAxisID: 'yIAQ', - - }, - ], - }, - options: { - responsive: true, - borderWidth: 2, - spanGaps: 1000 * 60 * 60 * 24, // only show lines between metrics with a 24 hour or less gap - elements: { - point: { - radius: 2, - }, - }, - scales: { - x: { - position: 'top', - type: 'time', - time: { - unit: 'day', - displayFormats: { - day: 'MMM DD', // Jan 01 - }, - }, - }, - y: { - min: -20, - max: 100, - }, - y1: { - min: 800, - max: 1100, - ticks: { - stepSize: 10, - callback: (label) => `${label} hPa`, - }, - position: 'right', - grid: { - drawOnChartArea: false, // only want the grid lines for one axis to show up - }, - }, - yIAQ: { - type: 'linear', - display: false, - }, - }, - plugins: { - legend: { - display: false, - }, - tooltip: { - mode: "index", - intersect: false, - callbacks: { - label: (item) => { - return `${item.dataset.label}: ${item.formattedValue}${item.dataset.suffix}`; - }, - }, - }, - }, - } - }); - - }, - renderPowerMetricCharts: function() { - try { - this.updatePowerMetricsChart(); - } catch(e) { - console.log(e); - } - }, - updatePowerMetricsChart: function() { - - // destroy existing chart - const chartElementId = "powerMetricsChart"; - const existingChart = window.Chart.getChart(chartElementId); - if(existingChart != null){ - existingChart.destroy(); - } - - // get chart element - const chartElement = window.document.getElementById(chartElementId); - if(!chartElement){ - return; - } - - // create chart data - const labels = []; - const channel1VoltageReadings = []; - const channel2VoltageReadings = []; - const channel3VoltageReadings = []; - const channel1CurrentReadings = []; - const channel2CurrentReadings = []; - const channel3CurrentReadings = []; - for(const powerMetric of this.selectedNodePowerMetrics){ - labels.push(moment(powerMetric.created_at)); - channel1VoltageReadings.push(powerMetric.ch1_voltage); - channel2VoltageReadings.push(powerMetric.ch2_voltage); - channel3VoltageReadings.push(powerMetric.ch3_voltage); - channel1CurrentReadings.push(powerMetric.ch1_current); - channel2CurrentReadings.push(powerMetric.ch2_current); - channel3CurrentReadings.push(powerMetric.ch3_current); - } - - // create chart - new window.Chart(chartElement, { - type: 'line', - data: { - labels: labels, - datasets: [ - { - label: 'Ch1 Voltage', - suffix: "V", - borderColor: '#3b82f6', - backgroundColor: '#3b82f6', - pointStyle: false, // no points - fill: false, - data: channel1VoltageReadings, - yAxisID: 'y', - }, - { - label: 'Ch2 Voltage', - suffix: "V", - borderColor: '#22c55e', - backgroundColor: '#22c55e', - pointStyle: false, // no points - fill: false, - data: channel2VoltageReadings, - yAxisID: 'y', - }, - { - label: 'Ch3 Voltage', - suffix: "V", - borderColor: '#f97316', - backgroundColor: '#f97316', - pointStyle: false, // no points - fill: false, - data: channel3VoltageReadings, - yAxisID: 'y', - }, - { - label: 'Ch1 Current', - suffix: "mA", - borderColor: '#93c5fd', - backgroundColor: '#93c5fd', - pointStyle: false, // no points - fill: false, - data: channel1CurrentReadings, - yAxisID: 'y1', - }, - { - label: 'Ch2 Current', - suffix: "mA", - borderColor: '#86efac', - backgroundColor: '#86efac', - pointStyle: false, // no points - fill: false, - data: channel2CurrentReadings, - yAxisID: 'y1', - }, - { - label: 'Ch3 Current', - suffix: "mA", - borderColor: '#fdba74', - backgroundColor: '#fdba74', - pointStyle: false, // no points - fill: false, - data: channel3CurrentReadings, - yAxisID: 'y1', - }, - ], - }, - options: { - responsive: true, - borderWidth: 2, - spanGaps: 1000 * 60 * 60 * 3, // only show lines between metrics with a 3 hour or less gap - elements: { - point: { - radius: 2, - }, - }, - scales: { - x: { - position: 'top', - type: 'time', - time: { - unit: 'day', - displayFormats: { - day: 'MMM DD', // Jan 01 - }, - }, - }, - y: { - min: 0, - suggestedMax: 6, - ticks: { - callback: (label) => `${label}V`, - }, - }, - y1: { - suggestedMin: -50, - suggestedMax: 50, - ticks: { - stepSize: 50, - callback: (label) => `${label}mA`, - }, - position: 'right', - grid: { - drawOnChartArea: false, // only want the grid lines for one axis to show up - }, - }, - }, - plugins: { - legend: { - display: false, - }, - tooltip: { - mode: "index", - intersect: false, - callbacks: { - label: (item) => { - return `${item.dataset.label}: ${item.formattedValue}${item.dataset.suffix}`; - }, - }, - }, - }, - } - }); - - }, - showTraceRoute: function(traceroute) { - this.selectedTraceRoute = traceroute; - }, - findNodeById: function(id) { - return window.findNodeById(id); - }, - findNodeMarkerById: function(id) { - return window.findNodeMarkerById(id); - }, - onSearchResultNodeClick: function(node) { - - // clear search - this.searchText = ""; - - // hide search - this.isShowingMobileSearch = false; - - // go to node - if(window.goToNode(node.node_id)){ - return; - } - - // fallback to showing node details since we can't go to the node - window.showNodeDetails(node.node_id); - - }, - dismissInfoModal: function() { - this.isShowingInfoModal = false; - window.setConfigHasSeenInfoModal(true); - }, - getRegionFrequencyRange: function(regionName) { - return window.getRegionFrequencyRange(regionName); - }, - showNodePositionHistory: function(nodeId) { - - // find node - const node = findNodeById(nodeId); - if(!node){ - return; - } - - // update ui - this.selectedNode = null; - this.selectedNodeToShowPositionHistory = node; - this.isPositionHistoryModalExpanded = true; - - // close node info tooltip as position history shows under it - window.closeAllTooltips(); - - // reset default time range when opening position history ui - // YYYY-MM-DDTHH:mm is the format expected by the datetime-local input type - this.positionHistoryDateTimeFrom = moment().subtract(1, "hours").format('YYYY-MM-DDTHH:mm'); - this.positionHistoryDateTimeTo = moment().format('YYYY-MM-DDTHH:mm'); - - // load position history - this.loadNodePositionHistory(nodeId); - - }, - onPositionHistoryQuickRangeClick: function(range) { - - // update position history time range - switch(range){ - case "1h": { - this.positionHistoryDateTimeFrom = moment().subtract(1, "hours").format('YYYY-MM-DDTHH:mm'); - this.positionHistoryDateTimeTo = moment().format('YYYY-MM-DDTHH:mm'); - break; - } - case "24h": { - this.positionHistoryDateTimeFrom = moment().subtract(24, "hours").format('YYYY-MM-DDTHH:mm'); - this.positionHistoryDateTimeTo = moment().format('YYYY-MM-DDTHH:mm'); - break; - } - case "7d": { - this.positionHistoryDateTimeFrom = moment().subtract(7, "days").format('YYYY-MM-DDTHH:mm'); - this.positionHistoryDateTimeTo = moment().format('YYYY-MM-DDTHH:mm'); - break; - } - } - - // reload position history - const node = this.selectedNodeToShowPositionHistory; - if(node){ - this.loadNodePositionHistory(node.node_id); - } - - }, - getShareLinkForNode: function(nodeId) { - return window.location.origin + `/?node_id=${nodeId}`; - }, - copyShareLinkForNode: function(nodeId) { - - // make sure copy to clipboard is supported - if(!navigator.clipboard || !navigator.clipboard.writeText){ - alert("Clipboard not supported. Site must be served via https on iOS."); - return; - } - - // copy share link to clipboard - const url = this.getShareLinkForNode(nodeId); - navigator.clipboard.writeText(url); - - // tell user we copied it - alert("Link copied to clipboard!"); - - }, - dismissShowingNodeConnections: function() { - window._onHideNodeConnectionsClick(); - this.selectedNodeToShowConnections = null; - }, - dismissShowingNodePositionHistory: function() { - this.selectedNodePositionHistory = []; - this.selectedNodeToShowPositionHistory = null; - this.selectedNodePositionHistoryMarkers = []; - this.selectedNodePositionHistoryPolyLines = []; - cleanUpPositionHistory(); - }, - formatUptimeSeconds: function(secondsToFormat) { - secondsToFormat = Number(secondsToFormat); - var days = Math.floor(secondsToFormat / (3600 * 24)); - var hours = Math.floor((secondsToFormat % (3600 * 24)) / 3600); - var minutes = Math.floor((secondsToFormat % 3600) / 60); - var seconds = Math.floor(secondsToFormat % 60); - var daysPlural = days === 1 ? 'day' : 'days'; - return `${days} ${daysPlural} ${hours}h ${minutes}m ${seconds}s`; - }, - formatTemperature: function(celsius) { - switch(this.configTemperatureFormat){ - case "celsius": { - return `${Number(celsius).toFixed(0)}°C`; - } - case "fahrenheit": { - const fahrenheit = this.celsiusToFahrenheit(celsius); - return `${fahrenheit.toFixed(0)}°F`; - } - } - }, - convertTemperature: function(celsius) { - switch(this.configTemperatureFormat){ - case "celsius": { - return celsius; - } - case "fahrenheit": { - return this.celsiusToFahrenheit(celsius); - } - } - }, - getTemperatureUnit: function() { - switch(this.configTemperatureFormat){ - case "celsius": return "°C"; - case "fahrenheit": return "°F"; - } - }, - celsiusToFahrenheit: function(celsius) { - return (celsius * 9/5) + 32; - }, - getNodeColour(nodeId) { - // convert node id to a hex colour - return "#" + (nodeId & 0x00FFFFFF).toString(16).padStart(6, '0'); - }, - getNodeTextColour(nodeId) { - - // extract rgb components - const r = (nodeId & 0xFF0000) >> 16; - const g = (nodeId & 0x00FF00) >> 8; - const b = nodeId & 0x0000FF; - - // calculate brightness - const brightness = ((r * 0.299) + (g * 0.587) + (b * 0.114)) / 255; - - // determine text color based on brightness - return brightness > 0.5 ? "#000000" : "#FFFFFF"; - - }, - }, - computed: { - searchedNodes() { - - // search nodes - const nodes = this.nodes.filter((node) => { - const matchesId = node.node_id?.toLowerCase()?.includes(this.searchText.toLowerCase()); - const matchesHexId = node.node_id_hex?.toLowerCase()?.includes(this.searchText.toLowerCase()); - const matchesLongName = node.long_name?.toLowerCase()?.includes(this.searchText.toLowerCase()); - const matchesShortName = node.short_name?.toLowerCase()?.includes(this.searchText.toLowerCase()); - return matchesId || matchesHexId || matchesLongName || matchesShortName; - }); - - // order alphabetically by long name - nodes.sort((nodeA, nodeB) => { - const nodeALongName = nodeA.long_name || ""; - const nodeBLongName = nodeB.long_name || ""; - return nodeALongName.localeCompare(nodeBLongName); - }); - - // only return the first 500 results to avoid ui lag... - return nodes.slice(0, 500); - - }, - selectedNodeLatestPowerMetric() { - const [ latestPowerMetric ] = this.selectedNodePowerMetrics.slice(-1); - return latestPowerMetric; - }, - }, - watch: { - configNodesMaxAgeInSeconds() { - window.setConfigNodesMaxAgeInSeconds(this.configNodesMaxAgeInSeconds); - }, - configNodesOfflineAgeInSeconds() { - window.setConfigNodesOfflineAgeInSeconds(this.configNodesOfflineAgeInSeconds); - }, - configWaypointsMaxAgeInSeconds() { - window.setConfigWaypointsMaxAgeInSeconds(this.configWaypointsMaxAgeInSeconds); - }, - configConnectionsMaxDistanceInMeters() { - window.setConfigConnectionsMaxDistanceInMeters(this.configConnectionsMaxDistanceInMeters); - }, - configZoomLevelGoToNode() { - window.setConfigZoomLevelGoToNode(this.configZoomLevelGoToNode); - }, - configAutoUpdatePositionInUrl() { - window.setConfigAutoUpdatePositionInUrl(this.configAutoUpdatePositionInUrl); - }, - configEnableMapAnimations() { - window.setConfigEnableMapAnimations(this.configEnableMapAnimations); - }, - configTemperatureFormat() { - window.setConfigTemperatureFormat(this.configTemperatureFormat); - }, - configConnectionsTimePeriodInSeconds() { - window.setConfigConnectionsTimePeriodInSeconds(this.configConnectionsTimePeriodInSeconds); - }, - configConnectionsColoredLines() { - window.setConfigConnectionsColoredLines(this.configConnectionsColoredLines); - }, - configConnectionsBidirectionalOnly() { - window.setConfigConnectionsBidirectionalOnly(this.configConnectionsBidirectionalOnly); - }, - configConnectionsMinSnrDb() { - window.setConfigConnectionsMinSnrDb(this.configConnectionsMinSnrDb); - }, - configConnectionsBidirectionalMinSnr() { - window.setConfigConnectionsBidirectionalMinSnr(this.configConnectionsBidirectionalMinSnr); - }, - deviceMetricsTimeRange() { - this.loadNodeDeviceMetrics(this.selectedNode.node_id); - }, - environmentMetricsTimeRange() { - this.loadNodeEnvironmentMetrics(this.selectedNode.node_id); - }, - powerMetricsTimeRange() { - this.loadNodePowerMetrics(this.selectedNode.node_id); - }, - }, -}).mount('#app'); \ No newline at end of file diff --git a/src/public/assets/js/config.js b/src/public/assets/js/config.js deleted file mode 100644 index 5866a4c..0000000 --- a/src/public/assets/js/config.js +++ /dev/null @@ -1,199 +0,0 @@ -function getConfigHasSeenInfoModal() { - return localStorage.getItem("config_has_seen_info_modal") === "true"; -} - -function setConfigHasSeenInfoModal(value) { - return localStorage.setItem("config_has_seen_info_modal", value); -} - -function getConfigAutoUpdatePositionInUrl() { - // use user preference, or enable by default - const value = localStorage.getItem("config_auto_update_position_in_url"); - return value === "true" || value == null; -} - -function setConfigAutoUpdatePositionInUrl(value) { - return localStorage.setItem("config_auto_update_position_in_url", value); -} - -function getConfigEnableMapAnimations() { - - const value = localStorage.getItem("config_enable_map_animations"); - - // enable animations by default - if(value === null){ - return true; - } - - return value === "true"; - -} - -function setConfigEnableMapAnimations(value) { - return localStorage.setItem("config_enable_map_animations", value); -} - -function getConfigTemperatureFormat() { - return localStorage.getItem("config_temperature_format") || "celsius"; -} - -function setConfigTemperatureFormat(format) { - return localStorage.setItem("config_temperature_format", format); -} - -function getConfigMapSelectedTileLayer() { - return localStorage.getItem("config_map_selected_tile_layer") || "Thunderforest Neighbourhood"; -} - -function setConfigMapSelectedTileLayer(layer) { - return localStorage.setItem("config_map_selected_tile_layer", layer); -} - -function getConfigMapEnabledOverlayLayers() { - - try { - const value = localStorage.getItem("config_map_enabled_overlay_layers"); - if(value){ - return JSON.parse(value); - } - } catch(e) {} - - // overlays enabled by default - return ["Legend", "Position History", "Traceroutes"]; - -} - -function setConfigMapEnabledOverlayLayers(layers) { - return localStorage.setItem("config_map_enabled_overlay_layers", JSON.stringify(layers)); -} - -function getConfigNodesMaxAgeInSeconds() { - const value = localStorage.getItem("config_nodes_max_age_in_seconds"); - return value != null ? parseInt(value) : null; -} - -function setConfigNodesMaxAgeInSeconds(value) { - if(value != null){ - return localStorage.setItem("config_nodes_max_age_in_seconds", value); - } else { - return localStorage.removeItem("config_nodes_max_age_in_seconds"); - } -} - -function getConfigNodesOfflineAgeInSeconds() { - const value = localStorage.getItem("config_nodes_offline_age_in_seconds"); - return value != null ? parseInt(value) : 10800; -} - -function setConfigNodesOfflineAgeInSeconds(value) { - if(value != null){ - return localStorage.setItem("config_nodes_offline_age_in_seconds", value); - } else { - return localStorage.removeItem("config_nodes_offline_age_in_seconds"); - } -} - -function getConfigWaypointsMaxAgeInSeconds() { - const value = localStorage.getItem("config_waypoints_max_age_in_seconds"); - return value != null ? parseInt(value) : null; -} - -function setConfigWaypointsMaxAgeInSeconds(value) { - if(value != null){ - return localStorage.setItem("config_waypoints_max_age_in_seconds", value); - } else { - return localStorage.removeItem("config_waypoints_max_age_in_seconds"); - } -} - -function getConfigConnectionsMaxDistanceInMeters() { - const value = localStorage.getItem("config_connections_max_distance_in_meters"); - // default to 70km (70,000 meters) - return value != null ? parseInt(value) : 70000; -} - -function setConfigConnectionsMaxDistanceInMeters(value) { - return localStorage.setItem("config_connections_max_distance_in_meters", value); -} - -function getConfigZoomLevelGoToNode() { - const value = localStorage.getItem("config_zoom_level_go_to_node"); - const parsedValue = value != null ? parseInt(value) : null; - return parsedValue || 15; -} - -function setConfigZoomLevelGoToNode(value) { - return localStorage.setItem("config_zoom_level_go_to_node", value); -} - -function getConfigConnectionsTimePeriodInSeconds() { - const value = localStorage.getItem("config_connections_time_period_in_seconds"); - // default to 7 days if unset - return value != null ? parseInt(value) : 604800; -} - -function setConfigConnectionsTimePeriodInSeconds(value) { - return localStorage.setItem("config_connections_time_period_in_seconds", value); -} - -function getConfigConnectionsColoredLines() { - const value = localStorage.getItem("config_connections_colored_lines"); - // disable colored lines by default - if(value === null){ - return false; - } - return value === "true"; -} - -function setConfigConnectionsColoredLines(value) { - return localStorage.setItem("config_connections_colored_lines", value); -} - -function getConfigConnectionsBidirectionalOnly() { - const value = localStorage.getItem("config_connections_bidirectional_only"); - // disable bidirectional filter by default - if(value === null){ - return false; - } - return value === "true"; -} - -function setConfigConnectionsBidirectionalOnly(value) { - return localStorage.setItem("config_connections_bidirectional_only", value); -} - -function getConfigConnectionsMinSnrDb() { - const value = localStorage.getItem("config_connections_min_snr_db"); - // default to null (unset) - if(value === null || value === ""){ - return null; - } - const parsed = parseFloat(value); - return isNaN(parsed) ? null : parsed; -} - -function setConfigConnectionsMinSnrDb(value) { - if(value === null || value === "" || value === undefined){ - return localStorage.removeItem("config_connections_min_snr_db"); - } - // Convert to string for localStorage (handles both number and string inputs) - const stringValue = typeof value === "number" ? value.toString() : String(value); - return localStorage.setItem("config_connections_min_snr_db", stringValue); -} - -function getConfigConnectionsBidirectionalMinSnr() { - const value = localStorage.getItem("config_connections_bidirectional_min_snr"); - // disable bidirectional minimum SNR by default - if(value === null){ - return false; - } - return value === "true"; -} - -function setConfigConnectionsBidirectionalMinSnr(value) { - return localStorage.setItem("config_connections_bidirectional_min_snr", value); -} - -function isMobile() { - return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); -} \ No newline at end of file diff --git a/src/public/assets/js/map.js b/src/public/assets/js/map.js deleted file mode 100644 index e25c067..0000000 --- a/src/public/assets/js/map.js +++ /dev/null @@ -1,1692 +0,0 @@ -// global state -var nodes = []; -var nodeMarkers = {}; -var selectedNodeOutlineCircle = null; -var waypoints = []; - -// set map bounds to be a little more than full size to prevent panning off screen -var bounds = [ - [-100, 70], // top left - [100, 500], // bottom right -]; - -// create map positioned over NRW -if(!isMobile()){ - var map = L.map('map', { - maxBounds: bounds, - }).setView([ - 51.1, - 366.82, - ], 9); -} else { - var map = L.map('map', { - maxBounds: bounds, - }).setView([ - 51.1, - 366.82, - ], 8); -} - -// remove leaflet link -map.attributionControl.setPrefix(''); - -var openThunderforestLandscapeMapTileLayer = L.tileLayer('https://tiles.nixware.dev/landscape/{z}/{x}/{y}.png', { - maxZoom: 22, - attribution: 'Tiles © Gravitystorm Limited | Data from Meshtastic', -}); - -var openThunderforestAtlasMapTileLayer = L.tileLayer('https://tiles.nixware.dev/atlas/{z}/{x}/{y}.png', { - maxZoom: 22, - attribution: 'Tiles © Gravitystorm Limited | Data from Meshtastic', -}); - -var openThunderforestNeighbourhoodMapTileLayer = L.tileLayer('https://tiles.nixware.dev/neighbourhood/{z}/{x}/{y}.png', { - maxZoom: 22, - attribution: 'Tiles © Gravitystorm Limited | Data from Meshtastic', -}); - -var openStreetMapTileLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { - maxZoom: 22, // increase from 18 to 22 - attribution: 'Tiles © OpenStreetMap | Data from Meshtastic', -}); - -var openTopoMapTileLayer = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', { - maxZoom: 17, // open topo map doesn't have tiles closer than this - attribution: 'Tiles © OpenStreetMap | Data from Meshtastic', -}); - -var esriWorldImageryTileLayer = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', { - maxZoom: 21, // esri doesn't have tiles closer than this - attribution: 'Tiles © Esri | Data from Meshtastic' -}); - -var googleSatelliteTileLayer = L.tileLayer('https://{s}.google.com/vt/lyrs=s&x={x}&y={y}&z={z}', { - maxZoom: 21, - subdomains: ['mt0', 'mt1', 'mt2', 'mt3'], - attribution: 'Tiles © Google | Data from Meshtastic' -}); - -var googleHybridTileLayer = L.tileLayer('https://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}', { - maxZoom: 21, - subdomains: ['mt0', 'mt1', 'mt2', 'mt3'], - attribution: 'Tiles © Google | Data from Meshtastic' -}); - -var tileLayers = { - "Thunderforest Neighbourhood": openThunderforestNeighbourhoodMapTileLayer, - "Thunderforest Landscape": openThunderforestLandscapeMapTileLayer, - "Thunderforest Atlas": openThunderforestAtlasMapTileLayer, - "OpenStreetMap": openStreetMapTileLayer, - "OpenTopoMap": openTopoMapTileLayer, - "Esri Satellite": esriWorldImageryTileLayer, - "Google Satellite": googleSatelliteTileLayer, - "Google Hybrid": googleHybridTileLayer, -}; - -// use tile layer based on config -const selectedTileLayerName = getConfigMapSelectedTileLayer(); -const selectedTileLayer = tileLayers[selectedTileLayerName] || openThunderforestNeighbourhoodMapTileLayer; -selectedTileLayer.addTo(map); - -// create layer groups -var nodesLayerGroup = new L.LayerGroup(); -var backboneConnectionsLayerGroup = new L.LayerGroup(); -var nodeConnectionsLayerGroup = new L.LayerGroup(); -var nodesClusteredLayerGroup = L.markerClusterGroup({ - showCoverageOnHover: false, - disableClusteringAtZoom: 10, // zoom level where node clustering is disabled -}); -var nodesRouterLayerGroup = L.markerClusterGroup({ - showCoverageOnHover: false, - disableClusteringAtZoom: 10, // zoom level where node clustering is disabled -}); -var nodesBackboneLayerGroup = new L.LayerGroup(); -//var nodesMediumFastLayerGroup = new L.LayerGroup(); -var nodesShortSlowLayerGroup = new L.LayerGroup(); -var nodesLongFastLayerGroup = new L.LayerGroup(); -var waypointsLayerGroup = new L.LayerGroup(); -var nodePositionHistoryLayerGroup = new L.LayerGroup(); -var traceroutesLayerGroup = new L.LayerGroup(); -var connectionsLayerGroup = new L.LayerGroup(); - -// create icons -var iconMqttConnected = L.divIcon({ - className: 'icon-mqtt-connected', - iconSize: [16, 16], // increase from 12px to 16px to make hover easier -}); - -var iconLongFast = L.divIcon({ - className: 'icon-longfast', - iconSize: [16, 16], // increase from 12px to 16px to make hover easier -}); - -/*var iconMediumFast = L.divIcon({ - className: 'icon-mediumfast', - iconSize: [16, 16], // increase from 12px to 16px to make hover easier -});*/ - -var iconShortSlow = L.divIcon({ - className: 'icon-shortslow', - iconSize: [16, 16], -}); - -var iconMqttDisconnected = L.divIcon({ - className: 'icon-mqtt-disconnected', - iconSize: [16, 16], // increase from 12px to 16px to make hover easier -}); - -var iconOffline = L.divIcon({ - className: 'icon-offline', - iconSize: [16, 16], // increase from 12px to 16px to make hover easier -}); - -var iconPositionHistory = L.divIcon({ - className: 'icon-position-history', - iconSize: [16, 16], // increase from 12px to 16px to make hover easier -}); - -var iconTracerouteStart = L.divIcon({ - className: 'icon-traceroute-start', - iconSize: [16, 16], -}); - -var iconTracerouteEnd = L.divIcon({ - className: 'icon-traceroute-end', - iconSize: [16, 16], -}); - -// create legend -var legendLayerGroup = new L.LayerGroup(); -var legend = L.control({position: 'bottomleft'}); -legend.onAdd = function (map) { - var div = L.DomUtil.create('div', 'leaflet-control-layers'); - div.style.backgroundColor = 'white'; - div.style.padding = '12px'; - div.innerHTML = `
Legend
` - + `
ShortSlow
` - //+ `
MediumFast
` - + `
LongFast
` - + `
Offline Too Long
` - + `
Traceroute
`; - return div; -}; - -// handle baselayerchange to update tile layer preference -map.on('baselayerchange', function(event) { - setConfigMapSelectedTileLayer(event.name); -}); - -// handle adding/remove legend on map (can't use L.Control as an overlay, so we toggle an empty L.LayerGroup) -map.on('overlayadd overlayremove', function(event) { - if(event.name === "Legend"){ - if(event.type === "overlayadd"){ - map.addControl(legend); - } else if(event.type === "overlayremove"){ - map.removeControl(legend); - } - } -}); - -// add layers to control ui -L.control.groupedLayers(tileLayers, { - "Nodes": { - "All": nodesLayerGroup, - "Routers": nodesRouterLayerGroup, - "Backbone": nodesBackboneLayerGroup, - "ShortSlow": nodesShortSlowLayerGroup, - //"MediumFast": nodesMediumFastLayerGroup, - "LongFast": nodesLongFastLayerGroup, - "Clustered": nodesClusteredLayerGroup, - "None": new L.LayerGroup(), - }, - "Overlays": { - "Legend": legendLayerGroup, - "Backbone Connections": backboneConnectionsLayerGroup, - "Connections": connectionsLayerGroup, - "Waypoints": waypointsLayerGroup, - "Position History": nodePositionHistoryLayerGroup, - "Traceroutes": traceroutesLayerGroup, - }, -}, { - // make the "Nodes" group exclusive (use radio inputs instead of checkbox) - exclusiveGroups: ["Nodes"], -}).addTo(map); - -// enable base layers -nodesLayerGroup.addTo(map); - -// enable overlay layers based on config -const enabledOverlayLayers = getConfigMapEnabledOverlayLayers(); -if(enabledOverlayLayers.includes("Legend")){ - legendLayerGroup.addTo(map); -} -if(enabledOverlayLayers.includes("Backbone Connection")){ - backboneConnectionsLayerGroup.addTo(map); -} -if(enabledOverlayLayers.includes("Connections")){ - connectionsLayerGroup.addTo(map); -} -if(enabledOverlayLayers.includes("Waypoints")){ - waypointsLayerGroup.addTo(map); -} -if(enabledOverlayLayers.includes("Position History")){ - nodePositionHistoryLayerGroup.addTo(map); -} -if(enabledOverlayLayers.includes("Traceroutes")){ - traceroutesLayerGroup.addTo(map); -} - -map.on('overlayadd', function(event) { - // update config when map overlay is added - const layerName = event.name; - const enabledOverlayLayers = getConfigMapEnabledOverlayLayers(); - if(!enabledOverlayLayers.includes(layerName)){ - enabledOverlayLayers.push(layerName); - } - setConfigMapEnabledOverlayLayers(enabledOverlayLayers); - - // clear traceroutes layer when traceroutes overlay is added - if (layerName === "Traceroutes") { - traceroutesLayerGroup.clearLayers(); - } -}); - -// update config when map overlay is removed -map.on('overlayremove', function(event) { - const layerName = event.name; - const enabledOverlayLayers = getConfigMapEnabledOverlayLayers().filter(function(enabledOverlayLayer) { - return enabledOverlayLayer !== layerName; - }); - setConfigMapEnabledOverlayLayers(enabledOverlayLayers); -}); - -// handle map clicks -map.on('click', function() { - - // remove outline when map clicked - clearNodeOutline(); - - // send callback to vue - window._onMapClick(); - -}); - -// close all tooltips and popups when clicking map -map.on("click", function(event) { - - // do nothing when clicking inside tooltip - const clickedElement = event.originalEvent.target; - if(elementOrAnyAncestorHasClass(clickedElement, "leaflet-tooltip")){ - return; - } - - closeAllTooltips(); - closeAllPopups(); - -}); - -function isValidLatLng(lat, lng) { - - if(isNaN(lat) || isNaN(lng)){ - return false; - } - - return true; - -} - -function findNodeById(id) { - - // find node by id - var node = nodes.find((node) => node.node_id.toString() === id.toString()); - if(node){ - return node; - } - - return null; - -} - -function findNodeMarkerById(id) { - - // find node marker by id - var nodeMarker = nodeMarkers[id]; - if(nodeMarker){ - return nodeMarker; - } - - return null; - -} - -function goToNode(id, animate, zoom){ - - // find node - var node = findNodeById(id); - if(!node){ - alert("Could not find node: " + id); - return false; - } - - // find node marker by id - var nodeMarker = findNodeMarkerById(id); - if(!nodeMarker){ - return false; - } - - // close all popups and tooltips - closeAllPopups(); - closeAllTooltips(); - - // select node - showNodeOutline(id); - - // fly to node marker - const shouldAnimate = animate != null ? animate : true; - map.flyTo(nodeMarker.getLatLng(), zoom || getConfigZoomLevelGoToNode(), { - animate: getConfigEnableMapAnimations() ? shouldAnimate : false, - }); - - // open tooltip for node - map.openTooltip(getTooltipContentForNode(node), nodeMarker.getLatLng(), { - interactive: true, // allow clicking buttons inside tooltip - permanent: true, // don't auto dismiss when clicking buttons inside tooltip - }); - - // successfully went to node - return true; - -} - -function goToRandomNode() { - if(nodes.length > 0){ - const randomNode = nodes[Math.floor(Math.random() * nodes.length)]; - if(randomNode){ - - // go to node - if(window.goToNode(randomNode.node_id)){ - return; - } - - // fallback to showing node details since we can't go to the node - window.showNodeDetails(randomNode.node_id); - - } - } -} - -function clearAllNodes() { - nodesLayerGroup.clearLayers(); - nodesClusteredLayerGroup.clearLayers(); - nodesRouterLayerGroup.clearLayers(); - nodesBackboneLayerGroup.clearLayers(); - nodesShortSlowLayerGroup.clearLayers(); - //nodesMediumFastLayerGroup.clearLayers(); - nodesLongFastLayerGroup.clearLayers(); -} - -function clearAllBackboneConnections() { - backboneConnectionsLayerGroup.clearLayers(); -} - -function clearAllWaypoints() { - waypointsLayerGroup.clearLayers(); -} - -function clearAllTraceroutes() { - traceroutesLayerGroup.clearLayers(); -} - -function clearAllConnections() { - connectionsLayerGroup.clearLayers(); - backboneConnectionsLayerGroup.clearLayers(); -} - -function closeAllPopups() { - map.eachLayer(function(layer) { - if(layer.options.pane === "popupPane"){ - layer.removeFrom(map); - } - }); -} - -function closeAllTooltips() { - map.eachLayer(function(layer) { - if(layer.options.pane === "tooltipPane"){ - layer.removeFrom(map); - } - }); -} - -function clearAllPositionHistory() { - nodePositionHistoryLayerGroup.clearLayers(); -} - -function clearNodeOutline() { - if(selectedNodeOutlineCircle){ - selectedNodeOutlineCircle.removeFrom(map); - selectedNodeOutlineCircle = null; - } -} - -function showNodeOutline(id) { - - // remove any existing node circle - clearNodeOutline(); - - // find node marker by id - const nodeMarker = nodeMarkers[id]; - if(!nodeMarker){ - return; - } - - // find node by id - const node = findNodeById(id); - if(!node){ - return; - } - - // add position precision circle around node - if(node.position_precision != null && node.position_precision > 0 && node.position_precision < 32){ - selectedNodeOutlineCircle = L.circle(nodeMarker.getLatLng(), { - radius: getPositionPrecisionInMeters(node.position_precision), - }).addTo(map); - } - -} - -function showNodeDetails(id) { - - // find node - const node = findNodeById(id); - if(!node){ - return; - } - - // fire callback to vuejs handler - window._onNodeClick(node); - -} - -function getColourForSnr(snr) { - if(snr >= -4) return "#16a34a"; // good - if(snr > -8) return "#fff200"; // medium-good - if(snr > -12) return "#ff9f1c"; // medium - return "#dc2626"; // bad -} - -function getSignalBarsIndicator(snrDb) { - if(snrDb == null) return ''; - - // Determine number of bars based on SNR - let bars = 0; - if(snrDb >= -4) bars = 4; // good - else if(snrDb > -8) bars = 3; // medium-good - else if(snrDb > -12) bars = 2; // medium - else bars = 1; // bad - - const color = getColourForSnr(snrDb); - - // Create 4 bars with increasing height - let indicator = ''; - - // Bar heights: 4px, 6px, 8px, 10px - const barHeights = [4, 6, 8, 10]; - const barWidth = 2; - - for (let i = 0; i < 4; i++) { - const height = barHeights[i]; - const isActive = i < bars; - const barColor = isActive ? color : '#d1d5db'; // gray for inactive bars - indicator += ``; - } - - indicator += ''; - return indicator; -} - -function cleanUpNodeConnections() { - - // close tooltips and popups - closeAllPopups(); - closeAllTooltips(); - - // setup node connections layer - nodeConnectionsLayerGroup.clearLayers(); - nodeConnectionsLayerGroup.removeFrom(map); - nodeConnectionsLayerGroup.addTo(map); - -} - -function getTerrainProfileImage(node1, node2) { - - // line colour between nodes - const lineColour = "0000FF"; // blue - - // node 1 (left side of image) - const node1MarkerColour = "0000FF"; // blue - const node1Latitude = node1.latitude; - const node1Longitude = node1.longitude; - const node1ElevationMSL = node1.altitude ?? ""; - - // node 2 (right side of image) - const node2MarkerColour = "0000FF"; // blue - const node2Latitude = node2.latitude; - const node2Longitude = node2.longitude; - const node2ElevationMSL = node2.altitude ?? ""; - - // generate terrain profile image url - return "https://heywhatsthat.com/bin/profile-0904.cgi?" + new URLSearchParams({ - src: "meshtastic.liamcottle.net", - axes: 1, // include grid lines and a scale - metric: 1, // show metric units - curvature: 1, - width: 500, - height: 200, - pt0: `${node1Latitude},${node1Longitude},${lineColour},${node1ElevationMSL},${node1MarkerColour}`, - pt1: `${node2Latitude},${node2Longitude},${lineColour},${node2ElevationMSL},${node2MarkerColour}`, - }).toString(); - -} - -async function showNodeConnections(id) { - - cleanUpNodeConnections(); - - // find node - const node = findNodeById(id); - if(!node){ - return; - } - - // find node marker - const nodeMarker = findNodeMarkerById(node.node_id); - if(!nodeMarker){ - return; - } - - // show overlay for node connections - window._onShowNodeConnectionsClick(node); - - // Fetch connections for this node - const connectionsTimePeriodSec = getConfigConnectionsTimePeriodInSeconds(); - const connectionsTimeFrom = connectionsTimePeriodSec ? (Date.now() - connectionsTimePeriodSec * 1000) : undefined; - const connectionsParams = new URLSearchParams(); - connectionsParams.set('node_id', id); - if (connectionsTimeFrom) connectionsParams.set('time_from', connectionsTimeFrom); - - try { - const response = await window.axios.get(`/api/v1/connections?${connectionsParams.toString()}`); - const connections = response.data.connections ?? []; - - for (const connection of connections) { - // Convert to numbers for comparison since API returns strings - const nodeA = parseInt(connection.node_a, 10); - const nodeB = parseInt(connection.node_b, 10); - - const otherNodeId = nodeA === id ? nodeB : nodeA; - const otherNode = findNodeById(otherNodeId); - const otherNodeMarker = findNodeMarkerById(otherNodeId); - - if (!otherNode || !otherNodeMarker) continue; - - // Apply bidirectional filter - const configConnectionsBidirectionalOnly = getConfigConnectionsBidirectionalOnly(); - if(configConnectionsBidirectionalOnly){ - const hasDirectionAB = connection.direction_ab && connection.direction_ab.avg_snr_db != null; - const hasDirectionBA = connection.direction_ba && connection.direction_ba.avg_snr_db != null; - if(!hasDirectionAB || !hasDirectionBA){ - continue; - } - } - - // Apply minimum SNR filter - const configConnectionsMinSnrDb = getConfigConnectionsMinSnrDb(); - if(configConnectionsMinSnrDb != null){ - const snrAB = connection.direction_ab && connection.direction_ab.avg_snr_db != null ? connection.direction_ab.avg_snr_db : null; - const snrBA = connection.direction_ba && connection.direction_ba.avg_snr_db != null ? connection.direction_ba.avg_snr_db : null; - - const configConnectionsBidirectionalMinSnr = getConfigConnectionsBidirectionalMinSnr(); - let hasSnrAboveThreshold; - - if(configConnectionsBidirectionalMinSnr){ - // Bidirectional mode: ALL existing directions must meet threshold - const directionsToCheck = []; - if(snrAB != null) directionsToCheck.push(snrAB); - if(snrBA != null) directionsToCheck.push(snrBA); - - if(directionsToCheck.length === 0){ - // No SNR data in either direction, skip - hasSnrAboveThreshold = false; - } else { - // All existing directions must be above threshold - hasSnrAboveThreshold = directionsToCheck.every(snr => snr > configConnectionsMinSnrDb); - } - } else { - // Default mode: EITHER direction has SNR above threshold - hasSnrAboveThreshold = (snrAB != null && snrAB > configConnectionsMinSnrDb) || (snrBA != null && snrBA > configConnectionsMinSnrDb); - } - - if(!hasSnrAboveThreshold){ - continue; - } - } - - // Calculate distance - const distanceInMeters = nodeMarker.getLatLng().distanceTo(otherNodeMarker.getLatLng()).toFixed(2); - const configConnectionsMaxDistanceInMeters = getConfigConnectionsMaxDistanceInMeters(); - if(configConnectionsMaxDistanceInMeters != null && parseFloat(distanceInMeters) > configConnectionsMaxDistanceInMeters){ - continue; - } - - let distance = `${distanceInMeters} meters`; - if (distanceInMeters >= 1000) { - const distanceInKilometers = (distanceInMeters / 1000).toFixed(2); - distance = `${distanceInKilometers} kilometers`; - } - - // Determine line color - const configConnectionsColoredLines = getConfigConnectionsColoredLines(); - const worstSnrDb = connection.worst_avg_snr_db; - const lineColor = configConnectionsColoredLines && worstSnrDb != null ? getColourForSnr(worstSnrDb) : '#2563eb'; - - // Create bidirectional line - const line = L.polyline([ - nodeMarker.getLatLng(), - otherNodeMarker.getLatLng(), - ], { - color: lineColor, - opacity: 0.75, - weight: 3, - }).addTo(nodeConnectionsLayerGroup); - - // Generate tooltip using standardized function - const tooltipNodeA = findNodeById(connection.node_a); - const tooltipNodeB = findNodeById(connection.node_b); - const tooltip = generateConnectionTooltip(connection, tooltipNodeA, tooltipNodeB, distance); - - line.bindTooltip(tooltip, { - sticky: true, - opacity: 1, - interactive: true, - }) - .bindPopup(tooltip) - .on('click', function(event) { - event.target.closeTooltip(); - }); - } - } catch (err) { - console.error('Error fetching connections:', err); - } - -} - -function clearMap() { - closeAllPopups(); - closeAllTooltips(); - clearAllNodes(); - clearAllBackboneConnections(); - clearAllWaypoints(); - clearAllTraceroutes(); - clearAllConnections(); - clearNodeOutline(); - cleanUpNodeConnections(); -} - -// returns true if the element or one of its parents has the class classname -function elementOrAnyAncestorHasClass(element, className) { - - // check if element contains class - if(element.classList && element.classList.contains(className)){ - return true; - } - - // check if parent node has the class - if(element.parentNode){ - return elementOrAnyAncestorHasClass(element.parentNode, className); - } - - // couldn't find the class - return false; - -} - -// escape strings for tooltips etc, to prevent html/script injection -// not used in vuejs, as that auto escapes -function escapeString(string) { - return string.replace(//g, ">"); -} - - -function onNodesUpdated(updatedNodes) { - - // clear nodes cache - nodes = []; - - // get config - const now = moment(); - const configNodesMaxAgeInSeconds = getConfigNodesMaxAgeInSeconds(); - const configNodesOfflineAgeInSeconds = getConfigNodesOfflineAgeInSeconds(); - const configConnectionsMaxDistanceInMeters = getConfigConnectionsMaxDistanceInMeters(); - - // add nodes - for(const node of updatedNodes){ - - // skip nodes older than configured node max age - if(configNodesMaxAgeInSeconds){ - const lastUpdatedAgeInMillis = now.diff(moment(node.updated_at)); - if(lastUpdatedAgeInMillis > configNodesMaxAgeInSeconds * 1000){ - continue; - } - } - - // add to cache - nodes.push(node); - - // skip nodes without position - if(!node.latitude || !node.longitude){ - continue; - } - - // fix lat long - node.latitude = node.latitude / 10000000; - node.longitude = node.longitude / 10000000; - - // skip nodes with invalid position - if(!isValidLatLng(node.latitude, node.longitude)){ - continue; - } - - // wrap longitude for shortest path, everything to left of australia should be shown on the right - var longitude = parseFloat(node.longitude); - if(longitude <= 100){ - longitude += 360; - } - - // icon based on channel preset - var icon = iconLongFast; - - if (node.channel_id == "ShortSlow") { - icon = iconShortSlow; - } - - /*if (node.channel_id == "MediumFast") { - icon = iconMediumFast; - }*/ - - // use offline icon for nodes older than configured node offline age - if(configNodesOfflineAgeInSeconds){ - const lastUpdatedAgeInMillis = now.diff(moment(node.updated_at)); - if(lastUpdatedAgeInMillis > configNodesOfflineAgeInSeconds * 1000){ - icon = iconOffline; - } - } - - // determine zIndexOffset: MediumFast (1000), LongFast (-1000), Offline (-2000) - var zIndexOffset = 1000; - if(icon == iconOffline){ - zIndexOffset = -2000; - } else if(node.channel_id == 'LongFast'){ - zIndexOffset = -1000; - } - - // To not have overlapping nodes. - var latJitter = 0; - var lonJitter = 0; - // If position pression > 45m apply random jitter within a small circle to avoid diagonal-only displacement - if (node.position_precision < 19) { - const maxMeters = 40; - const r = maxMeters * Math.sqrt(Math.random()); - const theta = 2 * Math.PI * Math.random(); - const dy = r * Math.sin(theta); - const dx = r * Math.cos(theta); - const metersPerDegLat = 111320; - const metersPerDegLon = 111320 * Math.cos(node.latitude * Math.PI / 180); - latJitter = dy / metersPerDegLat; - lonJitter = metersPerDegLon ? (dx / metersPerDegLon) : 0; - } - - // create node marker - const marker = L.marker([node.latitude + latJitter, longitude + lonJitter], { - icon: icon, - tagName: node.node_id, - // zIndex: offline (-2000) < has channel_id (-1000) < others (1000) - zIndexOffset: zIndexOffset, - }).on('click', function(event) { - // close tooltip on click to prevent tooltip and popup showing at same time - event.target.closeTooltip(); - }); - - // add marker to node layer groups - marker.addTo(nodesLayerGroup); - nodesClusteredLayerGroup.addLayer(marker); - - // add markers for routers and repeaters to routers layer group - if(node.role_name === "ROUTER" - || node.role_name === "ROUTER_CLIENT" - || node.role_name === "ROUTER_LATE" - || node.role_name === "REPEATER"){ - nodesRouterLayerGroup.addLayer(marker); - } - - // add markers for backbone to layer group - if(node.is_backbone) { - nodesBackboneLayerGroup.addLayer(marker); - } - - if(node.channel_id == "ShortSlow") { - nodesShortSlowLayerGroup.addLayer(marker); - } - - // add markers for MediumFast channel to layer group - /*if(node.channel_id == "MediumFast") { - nodesMediumFastLayerGroup.addLayer(marker); - }*/ - - // add markers for LongFast channel to layer group - if(node.channel_id == "LongFast") { - nodesLongFastLayerGroup.addLayer(marker); - } - - // show tooltip on desktop only - if(!isMobile()){ - marker.bindTooltip(getTooltipContentForNode(node), { - interactive: true, - }); - } - - // show node info tooltip when clicking node marker - marker.on("click", function(event) { - - // close all other popups and tooltips - closeAllTooltips(); - closeAllPopups(); - - // find node - const node = findNodeById(event.target.options.tagName); - if(!node){ - return; - } - - // show position precision outline - showNodeOutline(node.node_id); - - // open tooltip for node - map.openTooltip(getTooltipContentForNode(node), event.target.getLatLng(), { - interactive: true, // allow clicking buttons inside tooltip - permanent: true, // don't auto dismiss when clicking buttons inside tooltip - }); - - }); - - // add to cache - nodeMarkers[node.node_id] = marker; - - } - - window._onNodesUpdated(nodes); - -} - -function onWaypointsUpdated(updatedWaypoints) { - - // clear nodes cache - waypoints = []; - - // get config - const now = moment(); - const configWaypointsMaxAgeInSeconds = getConfigWaypointsMaxAgeInSeconds(); - - // add nodes - for(const waypoint of updatedWaypoints){ - - // skip waypoints older than configured waypoint max age - if(configWaypointsMaxAgeInSeconds){ - const lastUpdatedAgeInMillis = now.diff(moment(waypoint.updated_at)); - if(lastUpdatedAgeInMillis > configWaypointsMaxAgeInSeconds * 1000){ - continue; - } - } - - // skip expired waypoints - if(waypoint.expire < Date.now() / 1000){ - continue; - } - - // skip waypoints without position - if(!waypoint.latitude || !waypoint.longitude){ - continue; - } - - // fix lat long - waypoint.latitude = waypoint.latitude / 10000000; - waypoint.longitude = waypoint.longitude / 10000000; - - // skip waypoints with invalid position - if(!isValidLatLng(waypoint.latitude, waypoint.longitude)){ - continue; - } - - // wrap longitude for shortest path, everything to left of australia should be shown on the right - var longitude = parseFloat(waypoint.longitude); - if(longitude <= 100){ - longitude += 360; - } - - // determine emoji to show as marker icon - const emoji = waypoint.icon === 0 ? 128205 : waypoint.icon; - const emojiText = String.fromCodePoint(emoji) - - var tooltip = getTooltipContentForWaypoint(waypoint); - - // create waypoint marker - const marker = L.marker([waypoint.latitude, longitude], { - icon: L.divIcon({ - className: 'waypoint-label', - iconSize: [26, 26], // increase from 12px to 26px - html: emojiText, - }), - }).bindPopup(tooltip).on('click', function(event) { - // close tooltip on click to prevent tooltip and popup showing at same time - event.target.closeTooltip(); - }); - - // show tooltip on desktop only - if(!isMobile()){ - marker.bindTooltip(tooltip, { - interactive: true, - }); - } - - // add marker to waypoints layer groups - marker.addTo(waypointsLayerGroup); - - // add to cache - waypoints.push(waypoint); - - } - -} - - -function generateConnectionTooltip(connection, nodeA, nodeB, distance) { - let tooltip = `Connection`; - tooltip += `
[${escapeString(nodeA.short_name)}] ${escapeString(nodeA.long_name)} <-> [${escapeString(nodeB.short_name)}] ${escapeString(nodeB.long_name)}`; - tooltip += `
Distance: ${distance}`; - tooltip += `
`; - - // Direction A -> B - if (connection.direction_ab.avg_snr_db != null) { - tooltip += `
${escapeString(nodeA.short_name)} -> ${escapeString(nodeB.short_name)}:`; - tooltip += `
SNR: ${connection.direction_ab.avg_snr_db.toFixed(1)}dB ${getSignalBarsIndicator(connection.direction_ab.avg_snr_db)} (Average of ${connection.direction_ab.total_count} edges)`; - if (connection.direction_ab.last_5_edges.length > 0) { - tooltip += `
Last 5 edges:`; - for (const edge of connection.direction_ab.last_5_edges) { - const timeAgo = moment(new Date(edge.created_at)).fromNow(); - const sourceIcon = edge.source === "TRACEROUTE_APP" ? "⇵" : (edge.source === "NEIGHBORINFO_APP" ? "✳" : "?"); - tooltip += `
   ${edge.snr_db.toFixed(1)}dB ${getSignalBarsIndicator(edge.snr_db)} (${timeAgo} by:${sourceIcon})`; - } - } else { - tooltip += `
No recent edges`; - } - } - - // Direction B -> A - if (connection.direction_ba.avg_snr_db != null) { - tooltip += `

${escapeString(nodeB.short_name)} -> ${escapeString(nodeA.short_name)}:`; - tooltip += `
SNR: ${connection.direction_ba.avg_snr_db.toFixed(1)}dB ${getSignalBarsIndicator(connection.direction_ba.avg_snr_db)} (Average of ${connection.direction_ba.total_count} edges)`; - if (connection.direction_ba.last_5_edges.length > 0) { - tooltip += `
Last 5 edges:`; - for (const edge of connection.direction_ba.last_5_edges) { - const timeAgo = moment(new Date(edge.created_at)).fromNow(); - const sourceIcon = edge.source === "TRACEROUTE_APP" ? "⇵" : (edge.source === "NEIGHBORINFO_APP" ? "✳" : "?"); - tooltip += `
   ${edge.snr_db.toFixed(1)}dB ${getSignalBarsIndicator(edge.snr_db)} (${timeAgo} by:${sourceIcon})`; - } - } else { - tooltip += `
No recent edges`; - } - } - - // Add terrain profile image - const terrainImageUrl = getTerrainProfileImage(nodeA, nodeB); - tooltip += `

Terrain images from HeyWhatsThat.com`; - tooltip += `
`; - - return tooltip; -} - -function onConnectionsUpdated(connections) { - // Clear existing connections - clearAllConnections(); - - for (const connection of connections) { - // Find both node markers - const nodeAMarker = findNodeMarkerById(connection.node_a); - const nodeBMarker = findNodeMarkerById(connection.node_b); - - // Skip if either node marker doesn't exist - if (!nodeAMarker || !nodeBMarker) { - continue; - } - - // Find node objects for names and terrain profile - const nodeA = findNodeById(connection.node_a); - const nodeB = findNodeById(connection.node_b); - - if (!nodeA || !nodeB) { - continue; - } - - // Apply bidirectional filter - const configConnectionsBidirectionalOnly = getConfigConnectionsBidirectionalOnly(); - if(configConnectionsBidirectionalOnly){ - const hasDirectionAB = connection.direction_ab && connection.direction_ab.avg_snr_db != null; - const hasDirectionBA = connection.direction_ba && connection.direction_ba.avg_snr_db != null; - if(!hasDirectionAB || !hasDirectionBA){ - continue; - } - } - - // Apply minimum SNR filter - const configConnectionsMinSnrDb = getConfigConnectionsMinSnrDb(); - if(configConnectionsMinSnrDb != null){ - const snrAB = connection.direction_ab && connection.direction_ab.avg_snr_db != null ? connection.direction_ab.avg_snr_db : null; - const snrBA = connection.direction_ba && connection.direction_ba.avg_snr_db != null ? connection.direction_ba.avg_snr_db : null; - - const configConnectionsBidirectionalMinSnr = getConfigConnectionsBidirectionalMinSnr(); - let hasSnrAboveThreshold; - - if(configConnectionsBidirectionalMinSnr){ - // Bidirectional mode: ALL existing directions must meet threshold - const directionsToCheck = []; - if(snrAB != null) directionsToCheck.push(snrAB); - if(snrBA != null) directionsToCheck.push(snrBA); - - if(directionsToCheck.length === 0){ - // No SNR data in either direction, skip - hasSnrAboveThreshold = false; - } else { - // All existing directions must be above threshold - hasSnrAboveThreshold = directionsToCheck.every(snr => snr > configConnectionsMinSnrDb); - } - } else { - // Default mode: EITHER direction has SNR above threshold - hasSnrAboveThreshold = (snrAB != null && snrAB > configConnectionsMinSnrDb) || (snrBA != null && snrBA > configConnectionsMinSnrDb); - } - - if(!hasSnrAboveThreshold){ - continue; - } - } - - // Calculate distance between nodes - const distanceInMeters = nodeAMarker.getLatLng().distanceTo(nodeBMarker.getLatLng()).toFixed(2); - - // Apply distance filter - const configConnectionsMaxDistanceInMeters = getConfigConnectionsMaxDistanceInMeters(); - if(configConnectionsMaxDistanceInMeters != null && parseFloat(distanceInMeters) > configConnectionsMaxDistanceInMeters){ - continue; - } - - let distance = `${distanceInMeters} meters`; - if (distanceInMeters >= 1000) { - const distanceInKilometers = (distanceInMeters / 1000).toFixed(2); - distance = `${distanceInKilometers} kilometers`; - } - - // Determine line color based on worst average SNR (if colored lines enabled) - const configConnectionsColoredLines = getConfigConnectionsColoredLines(); - const worstSnrDb = connection.worst_avg_snr_db; - const lineColor = configConnectionsColoredLines && worstSnrDb != null ? getColourForSnr(worstSnrDb) : '#2563eb'; - - // Create polyline (bidirectional, no arrows) - const line = L.polyline([ - nodeAMarker.getLatLng(), - nodeBMarker.getLatLng(), - ], { - color: lineColor, - opacity: 0.75, - weight: 3, - }).addTo(connectionsLayerGroup); - - // Generate tooltip - const tooltip = generateConnectionTooltip(connection, nodeA, nodeB, distance); - - // Bind tooltip and popup - line.bindTooltip(tooltip, { - sticky: true, - opacity: 1, - interactive: true, - }) - .bindPopup(tooltip) - .on('click', function(event) { - // close tooltip on click to prevent tooltip and popup showing at same time - event.target.closeTooltip(); - }); - - // If both nodes are backbone nodes, also add to backbone layer group - if (nodeA.is_backbone && nodeB.is_backbone) { - const backboneLine = L.polyline([ - nodeAMarker.getLatLng(), - nodeBMarker.getLatLng(), - ], { - color: lineColor, - opacity: 0.75, - weight: 3, - }).addTo(backboneConnectionsLayerGroup); - - backboneLine.bindTooltip(tooltip, { - sticky: true, - opacity: 1, - interactive: true, - }) - .bindPopup(tooltip) - .on('click', function(event) { - event.target.closeTooltip(); - }); - } - } -} - -function onPositionHistoryUpdated(updatedPositionHistories) { - - let positionHistoryLinesCords = []; - - // add nodes - for(const positionHistory of updatedPositionHistories) { - - // skip position history without position - if(!positionHistory.latitude || !positionHistory.longitude){ - continue; - } - - // find node this position is for - const node = findNodeById(positionHistory.node_id); - if(!node){ - continue; - } - - // fix lat long - positionHistory.latitude = positionHistory.latitude / 10000000; - positionHistory.longitude = positionHistory.longitude / 10000000; - - // skip position history with invalid position - if(!isValidLatLng(positionHistory.latitude, positionHistory.longitude)){ - continue; - } - - // wrap longitude for shortest path, everything to left of australia should be shown on the right - var longitude = parseFloat(positionHistory.longitude); - if(longitude <= 100){ - longitude += 360; - } - - positionHistoryLinesCords.push([positionHistory.latitude, longitude]); - - let tooltip = ""; - if(positionHistory.type === "position"){ - tooltip += `Position`; - } else if(positionHistory.type === "map_report"){ - tooltip += `Map Report`; - } - tooltip += `
[${escapeString(node.short_name)}] ${escapeString(node.long_name)}`; - tooltip += `
${positionHistory.latitude}, ${positionHistory.longitude}`; - tooltip += `
Heard on: ${moment(new Date(positionHistory.created_at)).format("YYYY-MM-DD HH:mm")}`; - - // add gateway info if available - if(positionHistory.gateway_id){ - const gatewayNode = findNodeById(positionHistory.gateway_id); - const gatewayNodeInfo = gatewayNode ? `[${gatewayNode.short_name}] ${gatewayNode.long_name}` : "???"; - tooltip += `
Heard by: ${gatewayNodeInfo}`; - } - - // create position history marker - const marker = L.marker([positionHistory.latitude, longitude],{ - icon: iconPositionHistory, - }).bindTooltip(tooltip).bindPopup(tooltip).on('click', function(event) { - // close tooltip on click to prevent tooltip and popup showing at same time - event.target.closeTooltip(); - }); - - // add marker to position history layer group - marker.addTo(nodePositionHistoryLayerGroup); - - } - - // show lines between position history markers - L.polyline(positionHistoryLinesCords, { - color: "#a855f7", - opacity: 1, - }).addTo(nodePositionHistoryLayerGroup); - -} - -function cleanUpPositionHistory() { - - // close tooltips and popups - closeAllPopups(); - closeAllTooltips(); - - // setup node position history layer - nodePositionHistoryLayerGroup.clearLayers(); - nodePositionHistoryLayerGroup.removeFrom(map); - nodePositionHistoryLayerGroup.addTo(map); - -} - -function setLoading(loading){ - var reloadButton = document.getElementById("reload-button"); - if(loading){ - reloadButton.classList.add("animate-spin"); - } else { - reloadButton.classList.remove("animate-spin"); - } -} - -async function reload(goToNodeId, zoom) { - - // show loading - setLoading(true); - - // clear previous data - clearMap(); - - // fetch nodes - await window.axios.get('/api/v1/nodes').then(async (response) => { - - // update nodes - onNodesUpdated(response.data.nodes); - - // hide loading - setLoading(false); - - // go to node id if provided - if(goToNodeId){ - - // go to node - if(window.goToNode(goToNodeId, false, zoom)){ - return; - } - - // fallback to showing node details since we can't go to the node - window.showNodeDetails(goToNodeId); - - } - - }); - - // fetch waypoints (after awaiting nodes, so we can use nodes cache in waypoint tooltips) - await window.axios.get('/api/v1/waypoints').then(async (response) => { - onWaypointsUpdated(response.data.waypoints); - }); - - // fetch connections (edges) - const connectionsTimePeriodSec = getConfigConnectionsTimePeriodInSeconds(); - const connectionsTimeFrom = connectionsTimePeriodSec ? (Date.now() - connectionsTimePeriodSec * 1000) : undefined; - const connectionsParams = new URLSearchParams(); - if (connectionsTimeFrom) connectionsParams.set('time_from', connectionsTimeFrom); - await window.axios.get(`/api/v1/connections?${connectionsParams.toString()}`).then(async (response) => { - onConnectionsUpdated(response.data.connections ?? []); - }).catch(() => { - onConnectionsUpdated([]); - }); - -} - -function getRegionFrequencyRange(regionName) { - - // determine lora frequency range based on region_name - // https://github.com/meshtastic/firmware/blob/a4c22321fca6fc8da7bab157c3812055603512ba/src/mesh/RadioInterface.cpp#L21 - const regionNameToLoraFrequencyRange = { - "US": "902-928 MHz", - "EU_433": "433-434 MHz", - "EU_868": "869.4-869.65 MHz", - "CN": "470-510 MHz", - "JP": "920.8-927.8 MHz", - "ANZ": "915-928 MHz", - "RU": "868.7-869.2 MHz", - "KR": "920-923 MHz", - "TW": "920-925 MHz", - "IN": "865-867 MHz", - "NZ_865": "864-868 MHz", - "TH": "920-925 MHz", - "UA_433": "433-434.7 MHz", - "UA_868": "868-868.6 MHz", - "MY_433": "433-435 MHz", - "MY_919": "919-924 MHz", - "SG_923": "917-925 MHz", - "LORA_24": "2.4-2.4835 GHz", - "UNSET": "902-928 MHz", - } - - return regionNameToLoraFrequencyRange[regionName] ?? null; - -} - -function getPositionPrecisionInMeters(positionPrecision) { - switch(positionPrecision){ - case 2: return 5976446; - case 3: return 2988223; - case 4: return 1494111; - case 5: return 747055; - case 6: return 373527; - case 7: return 186763; - case 8: return 93381; - case 9: return 46690; - case 10: return 23345; - case 11: return 11672; // Android LOW_PRECISION - case 12: return 5836; - case 13: return 2918; - case 14: return 1459; - case 15: return 729; - case 16: return 364; // Android MED_PRECISION - case 17: return 182; - case 18: return 91; - case 19: return 45; - case 20: return 22; - case 21: return 11; - case 22: return 5; - case 23: return 2; - case 24: return 1; - case 32: return 0; // Android HIGH_PRECISION - } - return null; -} - -function formatPositionPrecision(positionPrecision) { - - // get position precision in meters - const positionPrecisionInMeters = getPositionPrecisionInMeters(positionPrecision); - if(positionPrecisionInMeters == null){ - return "?"; - } - - // format kilometers - if(positionPrecisionInMeters > 1000){ - const positionPrecisionInKilometers = Math.ceil(positionPrecisionInMeters / 1000); - return `±${positionPrecisionInKilometers}km`; - } - - // format meters - return `±${positionPrecisionInMeters}m`; - -} - -function getTooltipContentForNode(node) { - - var loraFrequencyRange = getRegionFrequencyRange(node.region_name); - - var tooltip = `` + - `${escapeString(node.long_name)}` + - `
Short Name: ${escapeString(node.short_name)}` + - (node.num_online_local_nodes != null ? `
Local Nodes Online: ${node.num_online_local_nodes}` : '') + - (node.position_precision != null && node.position_precision !== 32 ? `
Position Precision: ${formatPositionPrecision(node.position_precision)}` : '') + - `

Role: ${node.role_name}` + - `
Hardware: ${node.hardware_model_name}` + - (node.firmware_version != null ? `
Firmware: ${node.firmware_version}` : '') + - `
OK to MQTT: ${node.ok_to_mqtt}`; - - if(node.battery_level){ - if(node.battery_level > 100){ - tooltip += `
Battery: ${node.battery_level > 100 ? 'Plugged In' : node.battery_level}`; - } else { - tooltip += `
Battery: ${node.battery_level}%`; - } - } - - if(node.voltage){ - tooltip += `
Voltage: ${Number(node.voltage).toFixed(2)}V`; - } - - if(node.channel_utilization){ - tooltip += `
Ch Util: ${Number(node.channel_utilization).toFixed(2)}%`; - } - - if(node.air_util_tx){ - tooltip += `
Air Util: ${Number(node.air_util_tx).toFixed(2)}%`; - } - - // ignore alt above 42949000 due to https://github.com/meshtastic/firmware/issues/3109 - if(node.altitude && node.altitude < 42949000){ - tooltip += `
Altitude: ${node.altitude}m`; - } - - // bottom info - tooltip += `

ID: ${node.node_id}`; - tooltip += `
Hex ID: ${node.node_id_hex}`; - tooltip += `
Updated: ${moment(new Date(node.updated_at)).fromNow()}`; - tooltip += (node.mqtt_connection_state_updated_at ? `
MQTT Updated: ${moment(new Date(node.mqtt_connection_state_updated_at)).fromNow()}` : ''); - tooltip += (node.neighbours_updated_at ? `
Neighbours Updated: ${moment(new Date(node.neighbours_updated_at)).fromNow()}` : ''); - tooltip += (node.position_updated_at ? `
Position Updated: ${moment(new Date(node.position_updated_at)).fromNow()}` : ''); - - // show details button - tooltip += `

`; - tooltip += `
`; - tooltip += ``; - - return tooltip; - -} - -function getTooltipContentForWaypoint(waypoint) { - - // get from node name - var fromNode = findNodeById(waypoint.from); - - var tooltip = `${escapeString(waypoint.name)}` + - (waypoint.description ? `
${escapeString(waypoint.description)}` : '') + - `

Expires: ${moment(new Date(waypoint.expire * 1000)).fromNow()}` + - `
Lat/Lng: ${waypoint.latitude}, ${waypoint.longitude}` + - `

From ID: ${waypoint.from}` + - `
From Hex ID: !${Number(waypoint.from).toString(16)}`; - - // show node name this waypoint is from, if possible - if(fromNode != null){ - tooltip += `
From Node: ${escapeString(fromNode.long_name) || 'Unnamed Node'}`; - } else { - tooltip += `
From Node: ???`; - } - - // bottom info - tooltip += `

ID: ${waypoint.waypoint_id}`; - tooltip += `
Updated: ${moment(new Date(waypoint.updated_at)).fromNow()}`; - - return tooltip; - -} - -window._onHideNodeConnectionsClick = function() { - cleanUpNodeConnections(); -}; - -// parse url params -var queryParams = new URLSearchParams(location.search); -var queryNodeId = queryParams.get('node_id'); -var queryLat = queryParams.get('lat'); -var queryLng = queryParams.get('lng'); -var queryZoom = queryParams.get('zoom'); - -// go to lat/lng if provided -if(queryLat && queryLng){ - const zoomLevel = queryZoom || getConfigZoomLevelGoToNode(); - map.flyTo([queryLat, queryLng], zoomLevel, { - animate: false, - }); -} - -// auto update url when lat/lng/zoom changes -map.on("moveend zoomend", function() { - - // check if user enabled auto updating position in url - const autoUpdatePositionInUrl = getConfigAutoUpdatePositionInUrl(); - if(!autoUpdatePositionInUrl){ - return; - } - - // get map info - const latLng = map.getCenter(); - const zoom = map.getZoom(); - - // construct new url - const url = new URL(window.location.href); - url.searchParams.set("lat", latLng.lat); - url.searchParams.set("lng", latLng.lng); - url.searchParams.set("zoom", zoom); - - // update current url - if(window.history.replaceState){ - window.history.replaceState(null, null, url.toString()); - } - -}); - -// reload and go to provided node id -reload(queryNodeId, queryZoom); - -// WebSocket connection for real-time messages -var ws = null; -var tracerouteCooldown = {}; // Track last traceroute time per from node (for 20s cooldown) -var activeTracerouteKeys = new Set(); // Track active traceroute visualizations to prevent duplicates -var tracerouteLines = {}; // Track lines for each traceroute route key for cleanup - -function connectWebSocket() { - // Determine WebSocket URL - use same hostname as current page, port 8081 - const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; - // Heuristic: if running on localhost, use port 8081; otherwise use /ws path via Nginx - const isLocalhost = location.hostname === 'localhost' || location.hostname === '127.0.0.1'; - const wsUrl = isLocalhost - ? `${wsProtocol}//${location.hostname}:8081` - : `${wsProtocol}//${location.host}/ws`; - - console.log('Connecting to WebSocket:', wsUrl); - ws = new WebSocket(wsUrl); - - ws.onopen = function() { - console.log('WebSocket connected'); - }; - - ws.onmessage = function(event) { - try { - const message = JSON.parse(event.data); - handleWebSocketMessage(message); - } catch (e) { - console.error('Error parsing WebSocket message:', e); - } - }; - - ws.onerror = function(error) { - console.error('WebSocket error:', error); - }; - - ws.onclose = function() { - console.log('WebSocket disconnected, reconnecting in 5 seconds...'); - setTimeout(connectWebSocket, 5000); - }; -} - -function handleWebSocketMessage(message) { - if (message.type === 'traceroute') { - handleTraceroute(message.data); - } -} - -function handleTraceroute(data) { - // Only visualize traceroutes where want_response is false (the reply coming back) - if (data.want_response) { - return; - } - - // When want_response is false, from and to are swapped from the original request - // The path goes from 'to' (original sender) through route to 'from' (original destination) - const originalSender = data.to; // This was the original sender - const originalDestination = data.from; // This was the original destination - const route = data.route || []; - const snrTowards = data.snr_towards || []; - - // Deduplicate: ignore traceroutes from the same original sender for 20 seconds - const now = Date.now(); - if (tracerouteCooldown[originalSender] && (now - tracerouteCooldown[originalSender]) < 20000) { - return; // Still in cooldown period - } - - // Create unique key for this traceroute path to prevent duplicate visualizations - // Use original sender (to), original destination (from), and route to create unique key - // (ignoring gateway_id since multiple gateways can receive same route) - const routeKey = `${originalSender}-${originalDestination}-${route.join('-')}`; - if (activeTracerouteKeys.has(routeKey)) { - return; // Already visualizing this route - } - - // Mark as active and set cooldown - activeTracerouteKeys.add(routeKey); - tracerouteCooldown[originalSender] = now; - - // Build the complete path: to (original sender) -> route[0] -> route[1] -> ... -> from (original destination) - const path = [originalSender]; // Start from original sender - if (route.length > 0) { - path.push(...route); - } - path.push(originalDestination); // End at original destination - - // Visualize the traceroute with animated hops - visualizeTraceroute(path, snrTowards, routeKey); -} - -function visualizeTraceroute(path, snrTowards, routeKey) { - // Verify all nodes in path exist on map - const pathMarkers = []; - for (const nodeId of path) { - const marker = findNodeMarkerById(nodeId); - if (!marker) { - // Node not on map, skip this traceroute - activeTracerouteKeys.delete(routeKey); - return; - } - pathMarkers.push(marker); - } - - // Store lines and overlays for this route key for cleanup - const routeElements = { - lines: [], - startOverlay: null, - endOverlay: null, - }; - tracerouteLines[routeKey] = routeElements; - - // Color starting node (first in path) green and destination node (last in path) red - const startMarker = pathMarkers[0]; - const endMarker = pathMarkers[pathMarkers.length - 1]; - - const startOverlay = L.marker(startMarker.getLatLng(), { - icon: iconTracerouteStart, - zIndexOffset: 10000, // Ensure it's on top - }).addTo(traceroutesLayerGroup); - - const endOverlay = L.marker(endMarker.getLatLng(), { - icon: iconTracerouteEnd, - zIndexOffset: 10000, // Ensure it's on top - }).addTo(traceroutesLayerGroup); - - // Store overlays for cleanup - routeElements.startOverlay = startOverlay; - routeElements.endOverlay = endOverlay; - - // Animate each hop sequentially - let hopIndex = 0; - const animateNextHop = () => { - if (hopIndex >= pathMarkers.length - 1) { - // All hops animated, cleanup after delay - setTimeout(() => { - if (tracerouteLines[routeKey]) { - const routeElements = tracerouteLines[routeKey]; - // Remove all lines - if (routeElements.lines) { - routeElements.lines.forEach(line => { - line.remove(); - }); - } - // Remove node overlays - if (routeElements.startOverlay) { - routeElements.startOverlay.remove(); - } - if (routeElements.endOverlay) { - routeElements.endOverlay.remove(); - } - delete tracerouteLines[routeKey]; - } - activeTracerouteKeys.delete(routeKey); - }, 2500); - return; - } - - const fromMarker = pathMarkers[hopIndex]; - const toMarker = pathMarkers[hopIndex + 1]; - const snr = hopIndex < snrTowards.length ? snrTowards[hopIndex] : null; - - // Use orange color for all traceroute lines - const lineColor = '#f97316'; // orange - - // Create animated polyline for this hop with orange dotted style - const line = L.polyline([fromMarker.getLatLng(), toMarker.getLatLng()], { - color: lineColor, - weight: 4, - opacity: 0, // Start invisible - // dashArray: '10, 5', // Dotted line style - zIndexOffset: 10000, - }).addTo(traceroutesLayerGroup); - - // Fade in animation - line.setStyle({ opacity: 1.0 }); - tracerouteLines[routeKey].lines.push(line); - - // Animate next hop after 700ms delay - hopIndex++; - setTimeout(animateNextHop, 700); - }; - - // Start animation - animateNextHop(); -} - -// Connect WebSocket when page loads -connectWebSocket(); \ No newline at end of file diff --git a/src/public/images/devices/HELTEC_MESH_POCKET.png b/src/public/images/devices/HELTEC_MESH_POCKET.png deleted file mode 100644 index ae7a797..0000000 Binary files a/src/public/images/devices/HELTEC_MESH_POCKET.png and /dev/null differ diff --git a/src/public/images/devices/HELTEC_MESH_SOLAR.png b/src/public/images/devices/HELTEC_MESH_SOLAR.png deleted file mode 100644 index a6575ef..0000000 Binary files a/src/public/images/devices/HELTEC_MESH_SOLAR.png and /dev/null differ diff --git a/src/public/images/devices/HELTEC_V4.png b/src/public/images/devices/HELTEC_V4.png deleted file mode 100644 index 6dd4c49..0000000 Binary files a/src/public/images/devices/HELTEC_V4.png and /dev/null differ diff --git a/src/public/images/devices/HELTEC_VISION_MASTER_E213.png b/src/public/images/devices/HELTEC_VISION_MASTER_E213.png deleted file mode 100644 index 5000861..0000000 Binary files a/src/public/images/devices/HELTEC_VISION_MASTER_E213.png and /dev/null differ diff --git a/src/public/images/devices/PORTDUINO.png b/src/public/images/devices/PORTDUINO.png deleted file mode 100644 index 0ccea0d..0000000 Binary files a/src/public/images/devices/PORTDUINO.png and /dev/null differ diff --git a/src/public/images/devices/RP2040_LORA.png b/src/public/images/devices/RP2040_LORA.png index e83fa3a..60bd69b 100644 Binary files a/src/public/images/devices/RP2040_LORA.png and b/src/public/images/devices/RP2040_LORA.png differ diff --git a/src/public/images/devices/SEEED_SOLAR_NODE.png b/src/public/images/devices/SEEED_SOLAR_NODE.png deleted file mode 100644 index 7f894bc..0000000 Binary files a/src/public/images/devices/SEEED_SOLAR_NODE.png and /dev/null differ diff --git a/src/public/images/devices/SEEED_WIO_TRACKER_L1.png b/src/public/images/devices/SEEED_WIO_TRACKER_L1.png deleted file mode 100644 index e432076..0000000 Binary files a/src/public/images/devices/SEEED_WIO_TRACKER_L1.png and /dev/null differ diff --git a/src/public/images/devices/SEEED_XIAO_S3.png b/src/public/images/devices/SEEED_XIAO_S3.png index cceedfd..d87288a 100644 Binary files a/src/public/images/devices/SEEED_XIAO_S3.png and b/src/public/images/devices/SEEED_XIAO_S3.png differ diff --git a/src/public/images/devices/THINKNODE_M1.png b/src/public/images/devices/THINKNODE_M1.png deleted file mode 100644 index 7995026..0000000 Binary files a/src/public/images/devices/THINKNODE_M1.png and /dev/null differ diff --git a/src/public/images/devices/T_ETH_ELITE.png b/src/public/images/devices/T_ETH_ELITE.png deleted file mode 100644 index 3a25fbc..0000000 Binary files a/src/public/images/devices/T_ETH_ELITE.png and /dev/null differ diff --git a/src/public/images/devices/XIAO_NRF52_KIT.png b/src/public/images/devices/XIAO_NRF52_KIT.png deleted file mode 100644 index f3cc2eb..0000000 Binary files a/src/public/images/devices/XIAO_NRF52_KIT.png and /dev/null differ diff --git a/src/public/index.html b/src/public/index.html index ff76890..a3ebcec 100644 --- a/src/public/index.html +++ b/src/public/index.html @@ -3,15 +3,15 @@ - DL4AX Meshtastic Map - + Meshtastic Map + - - + + @@ -48,8 +48,95 @@ - - + @@ -58,8 +145,32 @@
+ +
+ + +
+
Introducing MeshCore
+
+ Looking for a new mesh project to tinker with? Check out MeshCore +
+
+ + + + +
+ -
+
@@ -73,8 +184,16 @@
-
- + + + +
+
Meshtastic Map
+
+ Created by Liam Cottle +
@@ -112,6 +231,16 @@ + +
+ + + +
+
+ + + +
+
+
+
+ + + + + +
+ + +
+ +

Meshtastic Map

+

Created by Liam Cottle

+ +
+ + +
+ 👋 Welcome to my open source map of Meshtastic nodes heard on MQTT. +
+ + +
+
Features
+
+
    +
  • The map shows nodes that have sent a valid position to MQTT.
  • +
  • Position packets must be unencrypted, or encrypted with the default key.
  • +
  • Use the search bar to find nodes by ID or name.
  • +
  • Hover over nodes (on desktop) to see basic details.
  • +
  • Click a node to see info such as telemetry graphs and traceroutes.
  • +
  • Use the top right layers panel to show neighbours and waypoints.
  • +
  • Use the settings button to configure the map to your liking.
  • +
  • Have a feature request, or found a bug? Open an issue on GitHub.
  • +
+
+
+ + +
+
FAQ
+
+
+
How do I add my node to the map?
+
Your node, or a node that hears your node must uplink to our MQTT server.
+
Your position packet must be unencrypted, or encrypted with the default key.
+
If your node has v2.5 firmware or newer, you must enable "OK to MQTT".
+
Use the MQTT server details below to uplink to this map.
+
+
+
What MQTT server should I use?
+
    +
  • Address: mqtt.meshtastic.liamcottle.net
  • +
  • Username: uplink
  • +
  • Password: uplink
  • +
  • Encryption Enabled: Yes
  • +
  • JSON Output: No
  • +
  • TLS Enabled: No
  • +
+
Please note, nodes can only uplink to this server. Downlink is disabled.
+
We suggest running dedicated nodes for uplinking to the map.
+
+
+
How do I remove my node from the map?
+
Nodes that have not been heard for 7 days are automatically removed.
+
Disable position reporting in your node to prevent it coming back.
+
Use custom encryption keys so the public can't see your position data.
+
If your node has v2.5 firmware or newer, we ignore packets if "OK to MQTT" is disabled.
+
To have your node removed now, please contact me.
+
+
+
How do I see neighbours a node heard?
+
Open the top right layers panel and enable neighbours.
+
Some neighbours are from MQTT, this is patched in latest firmware.
+
+
+
Why is my node showing up in the wrong place?
+
This public map obfuscates your position packets for v2.4 firmware and older.
+
Nodes on v2.4 and older have their positions obfuscated to 2 decimal places.
+
Nodes on v2.5 and newer, with "OK to MQTT" enabled, will show positions with your configured precision.
+
Nodes on v2.5 and newer, with "OK to MQTT" disabled, will not update their positions.
+
+
+
+ + +
+
Legal
+
+
This project is not affiliated with or endorsed by the Meshtastic project.
+
The Meshtastic logo is the trademark of Meshtastic LLC.
+
Map tiles provided by OpenStreetMap
+
+
+ + + + +
+ +
+
+
+
+ + +
+ + +
+
LoRa Config
+
    + + +
  • +
    Region
    +
    + {{ selectedNode.region_name }} ({{ getRegionFrequencyRange(selectedNode.region_name) }}) + ??? +
    +
  • + + +
  • +
    Modem Preset
    +
    + {{ selectedNode.modem_preset_name }} + ??? +
    +
  • + + +
  • +
    Has Default Channel
    +
    + {{ selectedNode.has_default_channel ? "Yes" : "No" }} + ??? +
    +
  • + +
+
+
@@ -442,7 +805,6 @@ -
@@ -533,7 +895,6 @@ -
@@ -558,10 +919,6 @@
Pressure
-
-
-
IAQ
-
@@ -607,7 +964,6 @@ - @@ -1046,6 +1402,29 @@ + +
+ +
Nodes that have not uplinked to MQTT in this time will show as blue icons. Reload to update map.
+ +
+
@@ -1092,66 +1471,11 @@
- +
- -
Edges from traceroutes and neighbour info within this time period are shown in the Connections layer. Reload to update map.
- -
- - -
-
-
- -
- -
-
Colors the connection lines by the average SNR in the worst direction. Reload to update map.
-
- - -
-
-
- -
- -
-
Only show connections where data flows in both directions. Reload to update map.
-
- - -
- -
Only show connections where at least one direction has SNR above this threshold. Leave empty to show all connections. Reload to update map.
- -
-
- -
- -
-
If checked, all existing directions must meet the minimum SNR threshold (both directions if bidirectional, single direction if unidirectional).
-
- - -
- -
Connections further than this are hidden. Reload to update map.
- + +
Neighbours further than this are hidden. Reload to update map.
+
@@ -1192,6 +1516,7 @@
Map will animate flying to nodes.
+ @@ -1201,7 +1526,7 @@ - +