diff --git a/.eslintrc.js b/.eslintrc.js
deleted file mode 100644
index 97db310c..00000000
--- a/.eslintrc.js
+++ /dev/null
@@ -1,41 +0,0 @@
-module.exports = {
- parser: '@typescript-eslint/parser',
- env: {
- browser: true,
- commonjs: true,
- es6: true,
- node: true,
- },
- extends: [
- 'plugin:@typescript-eslint/recommended',
- 'plugin:prettier/recommended',
- 'prettier',
- ],
- plugins: ['@typescript-eslint', 'prettier', 'simple-import-sort'],
- globals: {
- Atomics: 'readonly',
- SharedArrayBuffer: 'readonly',
- },
- parserOptions: {
- ecmaVersion: 2020,
- sourceType: 'module',
- allowImportExportEverywhere: true,
- },
- rules: {
- 'prettier/prettier': 'off',
- 'linebreak-style': ['error', 'unix'],
- quotes: ['error', 'single', { avoidEscape: true }],
- semi: ['error', 'never'],
- 'no-prototype-builtins': 'off',
- '@typescript-eslint/no-this-alias': 'off',
- '@typescript-eslint/no-var-requires': 'off',
- '@typescript-eslint/no-explicit-any': 'off',
- '@typescript-eslint/ban-ts-comment': 'off',
- 'simple-import-sort/imports': 'error',
- 'simple-import-sort/exports': 'error',
- '@typescript-eslint/no-unused-vars': [
- 'error',
- { argsIgnorePattern: '^_', destructuredArrayIgnorePattern: '^_' },
- ],
- },
-}
diff --git a/.gitattributes b/.gitattributes
index 21256661..94f480de 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1 +1 @@
-* text=auto
\ No newline at end of file
+* text=auto eol=lf
\ No newline at end of file
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index ed13afb1..da62bbc1 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -11,6 +11,9 @@
#
name: "CodeQL"
+env:
+ HUSKY: 0
+
on:
push:
branches: [ master, dev ]
diff --git a/.github/workflows/publish-dev.yml b/.github/workflows/publish-dev.yml
index d721b4f5..06c3fb79 100644
--- a/.github/workflows/publish-dev.yml
+++ b/.github/workflows/publish-dev.yml
@@ -1,5 +1,8 @@
name: Dev publish
+env:
+ HUSKY: 0
+
on:
push:
branches:
@@ -16,7 +19,7 @@ jobs:
- run: |
npm ci
npm run build
- npm run test
+ npm run test:ci
publish-npm:
needs: build
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index a9cb6519..802a66a8 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -1,5 +1,8 @@
name: Release publish
+env:
+ HUSKY: 0
+
on:
push:
branches:
@@ -16,7 +19,7 @@ jobs:
- run: |
npm ci
npm run build
- npm run test
+ npm run test:ci
publish-npm:
needs: build
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 3360dfb1..89eddaa2 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -1,13 +1,19 @@
name: Tests
-on: [ pull_request ]
+env:
+ HUSKY: 0
+
+on:
+ push:
+ pull_request:
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
+ fail-fast: false
matrix:
- node_version: [ 18, 20, 22 ]
+ node-version: [ 20, 22, 24 ]
os: [ ubuntu-latest, windows-latest, macOS-latest ]
steps:
- uses: actions/checkout@v4
@@ -17,7 +23,8 @@ jobs:
- name: build and test
run: |
npm ci
+ npm run lint
npm run build
- npm run test
+ npm run test:ci
env:
CI: true
diff --git a/.gitignore b/.gitignore
index b24ae2ac..d64e1dc1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -175,9 +175,6 @@ typings/
# Optional npm cache directory
.npm
-# Optional eslint cache
-.eslintcache
-
# Optional REPL history
.node_repl_history
diff --git a/.husky/pre-commit b/.husky/pre-commit
index 36404cc6..ba1caafd 100644
--- a/.husky/pre-commit
+++ b/.husky/pre-commit
@@ -1,9 +1 @@
-#!/usr/bin/env sh
-
-# .husky/pre-commit
-# ...
-[ -n "$CI" ] && exit 0
-
-. "$(dirname -- "$0")/_/husky.sh"
-
-npm run prettier && npm test && npm run eslint
+npm run format && npm test
\ No newline at end of file
diff --git a/.prettierrc.js b/.prettierrc.js
deleted file mode 100644
index a3a46860..00000000
--- a/.prettierrc.js
+++ /dev/null
@@ -1,8 +0,0 @@
-module.exports = {
- tabWidth: 4,
- useTabs: false,
- semi: false,
- singleQuote: true,
- trailingComma: 'es5',
- endOfLine: 'lf',
-}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cfdec49b..53f19930 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,6 @@
#### ⚠️ CAUTION ⚠️
-##### Before upgrading make sure that you are using the latest version of [Node-RED](https://nodered.org/docs/getting-started/local) and latest LTS version of [Node.js](https://nodejs.org/en/download/)
+##### Before upgrading make sure that you are using the latest version of [Node-RED](https://nodered.org/docs/getting-started/local) and the latest LTS version of [Node.js](https://nodejs.org/en/download/)
# Changelog
@@ -9,11 +9,26 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [2.0.0] - 2025-11-22
+
+Lost backward compatibility for Camera Service and MDNS Custom Configuration.
+
+### Changed
+
+- Updated hap-nodejs [0.12.3 to 2.0.2](https://github.com/homebridge/HAP-NodeJS/blob/latest/CHANGELOG.md) (features
+ and bug fixes)
+- Dependencies upgrade
+- Node `18` no longer supported, use Node
+ 24 [#578](https://github.com/NRCHKB/node-red-contrib-homekit-bridged/issues/578)! Or at least 20.
+- Due to a major upgrade of hap-nodejs, some breaking changes might be present, including Camera Service and MDNS Custom
+ Configuration.
+
## [1.7.3] - 2025-01-16
### Changed
-- Updated hap-nodejs [0.12.3-beta.18 to 0.12.3](https://github.com/homebridge/HAP-NodeJS/blob/latest/CHANGELOG.md) (features
+- Updated hap-nodejs [0.12.3-beta.18 to 0.12.3](https://github.com/homebridge/HAP-NodeJS/blob/latest/CHANGELOG.md) (
+ features
and bug fixes)
- Dependencies upgrade
@@ -31,7 +46,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
### Fixed
-- Fix bad listeners detachment for characteristics [#563](https://github.com/NRCHKB/node-red-contrib-homekit-bridged/issues/563)
+- Fix bad listeners detachment for
+ characteristics [#563](https://github.com/NRCHKB/node-red-contrib-homekit-bridged/issues/563)
## [1.7.0] - 2024-09-19
@@ -43,11 +59,13 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
### Added
- Adaptive Lighting support [#335](https://github.com/NRCHKB/node-red-contrib-homekit-bridged/issues/335)
-- By default, registered Eve.app Characteristics for power management - for existing setup, requires old custom characteristics file to be removed
+- By default, registered Eve.app Characteristics for power management - for existing setup, requires old custom
+ characteristics file to be removed
### Changed
-- Updated hap-nodejs [0.11.1 to 0.12.3-beta.18](https://github.com/homebridge/HAP-NodeJS/blob/latest/CHANGELOG.md) (features
+- Updated hap-nodejs [0.11.1 to 0.12.3-beta.18](https://github.com/homebridge/HAP-NodeJS/blob/latest/CHANGELOG.md) (
+ features
and bug fixes)
- Dependencies upgrade
- Node `10`, `12` and `16` no longer supported, use Node 20! Or at least 18
diff --git a/biome.json b/biome.json
new file mode 100644
index 00000000..2da45fb7
--- /dev/null
+++ b/biome.json
@@ -0,0 +1,51 @@
+{
+ "$schema": "https://biomejs.dev/schemas/2.3.7/schema.json",
+ "vcs": {
+ "enabled": true,
+ "clientKind": "git",
+ "useIgnoreFile": true
+ },
+ "files": {
+ "ignoreUnknown": false,
+ "includes": [
+ "src/**",
+ "examples/**",
+ "docs/**",
+ "*.md",
+ "*.json",
+ "*.yml",
+ ".husky/**"
+ ]
+ },
+ "formatter": {
+ "enabled": true,
+ "indentStyle": "space"
+ },
+ "linter": {
+ "enabled": true,
+ "rules": {
+ "recommended": true,
+ "suspicious": {
+ "noExplicitAny": "off"
+ },
+ "complexity": {
+ "useArrowFunction": "warn"
+ }
+ }
+ },
+ "javascript": {
+ "formatter": {
+ "quoteStyle": "single",
+ "semicolons": "asNeeded",
+ "trailingCommas": "none"
+ }
+ },
+ "assist": {
+ "enabled": true,
+ "actions": {
+ "source": {
+ "organizeImports": "on"
+ }
+ }
+ }
+}
diff --git a/examples/demo/01 - ALL Demos single import.json b/examples/demo/01 - ALL Demos single import.json
index 8076caf8..21bad810 100644
--- a/examples/demo/01 - ALL Demos single import.json
+++ b/examples/demo/01 - ALL Demos single import.json
@@ -83,12 +83,7 @@
"outputs": 2,
"x": 500,
"y": 1600,
- "wires": [
- [
- "b7778e52.220a5"
- ],
- []
- ]
+ "wires": [["b7778e52.220a5"], []]
},
{
"id": "c717b796.0735b8",
@@ -105,11 +100,7 @@
"payloadType": "json",
"x": 220,
"y": 1700,
- "wires": [
- [
- "fd8aff55.91d41"
- ]
- ]
+ "wires": [["fd8aff55.91d41"]]
},
{
"id": "f56a2f96.509c1",
@@ -135,11 +126,7 @@
"payloadType": "json",
"x": 200,
"y": 1600,
- "wires": [
- [
- "fd8aff55.91d41"
- ]
- ]
+ "wires": [["fd8aff55.91d41"]]
},
{
"id": "d945ba75.897998",
@@ -165,11 +152,7 @@
"payloadType": "json",
"x": 200,
"y": 1640,
- "wires": [
- [
- "fd8aff55.91d41"
- ]
- ]
+ "wires": [["fd8aff55.91d41"]]
},
{
"id": "409001a1.3e7a78",
@@ -279,12 +262,7 @@
"outputs": 2,
"x": 490,
"y": 720,
- "wires": [
- [
- "d838176b.dbaf7"
- ],
- []
- ]
+ "wires": [["d838176b.dbaf7"], []]
},
{
"id": "ee1452a5.08edd",
@@ -306,11 +284,7 @@
"payloadType": "json",
"x": 420,
"y": 640,
- "wires": [
- [
- "7bf880d4.3cd4d"
- ]
- ]
+ "wires": [["7bf880d4.3cd4d"]]
},
{
"id": "c6ed2a2a.90a01",
@@ -332,11 +306,7 @@
"payloadType": "json",
"x": 190,
"y": 640,
- "wires": [
- [
- "7bf880d4.3cd4d"
- ]
- ]
+ "wires": [["7bf880d4.3cd4d"]]
},
{
"id": "8cdfae2b.2f2ce8",
@@ -358,11 +328,7 @@
"payloadType": "json",
"x": 200,
"y": 720,
- "wires": [
- [
- "7bf880d4.3cd4d"
- ]
- ]
+ "wires": [["7bf880d4.3cd4d"]]
},
{
"id": "1758401b.6c62e8",
@@ -384,11 +350,7 @@
"payloadType": "json",
"x": 190,
"y": 680,
- "wires": [
- [
- "7bf880d4.3cd4d"
- ]
- ]
+ "wires": [["7bf880d4.3cd4d"]]
},
{
"id": "3a57bebe.a3b222",
@@ -461,12 +423,7 @@
"outputs": 2,
"x": 460,
"y": 540,
- "wires": [
- [
- "379657db.a99df8"
- ],
- []
- ]
+ "wires": [["379657db.a99df8"], []]
},
{
"id": "379657db.a99df8",
@@ -504,11 +461,7 @@
"payloadType": "json",
"x": 400,
"y": 500,
- "wires": [
- [
- "459254fe.49c72c"
- ]
- ]
+ "wires": [["459254fe.49c72c"]]
},
{
"id": "253b3550.729caa",
@@ -530,11 +483,7 @@
"payloadType": "json",
"x": 190,
"y": 500,
- "wires": [
- [
- "459254fe.49c72c"
- ]
- ]
+ "wires": [["459254fe.49c72c"]]
},
{
"id": "b9bc7f3d.51acf",
@@ -556,11 +505,7 @@
"payloadType": "json",
"x": 190,
"y": 540,
- "wires": [
- [
- "459254fe.49c72c"
- ]
- ]
+ "wires": [["459254fe.49c72c"]]
},
{
"id": "60e44fde.c914f8",
@@ -613,11 +558,7 @@
"payloadType": "json",
"x": 190,
"y": 100,
- "wires": [
- [
- "5302e4aa.1b466c"
- ]
- ]
+ "wires": [["5302e4aa.1b466c"]]
},
{
"id": "5302e4aa.1b466c",
@@ -662,13 +603,7 @@
"outputs": 2,
"x": 370,
"y": 100,
- "wires": [
- [
- "bfe1c73d.c165a8",
- "9739d842.a402f"
- ],
- []
- ]
+ "wires": [["bfe1c73d.c165a8", "9739d842.a402f"], []]
},
{
"id": "bfe1c73d.c165a8",
@@ -699,19 +634,8 @@
"finalize": "",
"x": 530,
"y": 100,
- "wires": [
- [
- "664dadf9.85d0d4",
- "d7cd8a56.628178"
- ],
- [
- "3de34c4c.1871a4"
- ]
- ],
- "outputLabels": [
- "On",
- "Off"
- ]
+ "wires": [["664dadf9.85d0d4", "d7cd8a56.628178"], ["3de34c4c.1871a4"]],
+ "outputLabels": ["On", "Off"]
},
{
"id": "87048a6e.df64e8",
@@ -733,11 +657,7 @@
"payloadType": "json",
"x": 190,
"y": 140,
- "wires": [
- [
- "5302e4aa.1b466c"
- ]
- ]
+ "wires": [["5302e4aa.1b466c"]]
},
{
"id": "db412cea.4a62f8",
@@ -759,11 +679,7 @@
"payloadType": "json",
"x": 190,
"y": 180,
- "wires": [
- [
- "5302e4aa.1b466c"
- ]
- ]
+ "wires": [["5302e4aa.1b466c"]]
},
{
"id": "46418e19.aa6d6",
@@ -771,16 +687,10 @@
"z": "eeb8b00c.2c18c",
"g": "60e44fde.c914f8",
"name": "",
- "links": [
- "ee8894e4.f1855"
- ],
+ "links": ["ee8894e4.f1855"],
"x": 315,
"y": 180,
- "wires": [
- [
- "5302e4aa.1b466c"
- ]
- ]
+ "wires": [["5302e4aa.1b466c"]]
},
{
"id": "664dadf9.85d0d4",
@@ -801,11 +711,7 @@
"outputs": 1,
"x": 730,
"y": 100,
- "wires": [
- [
- "ee8894e4.f1855"
- ]
- ]
+ "wires": [["ee8894e4.f1855"]]
},
{
"id": "d7cd8a56.628178",
@@ -826,11 +732,7 @@
"outputs": 1,
"x": 730,
"y": 140,
- "wires": [
- [
- "ee8894e4.f1855"
- ]
- ]
+ "wires": [["ee8894e4.f1855"]]
},
{
"id": "3de34c4c.1871a4",
@@ -851,11 +753,7 @@
"outputs": 1,
"x": 730,
"y": 180,
- "wires": [
- [
- "ee8894e4.f1855"
- ]
- ]
+ "wires": [["ee8894e4.f1855"]]
},
{
"id": "ee8894e4.f1855",
@@ -863,9 +761,7 @@
"z": "eeb8b00c.2c18c",
"g": "60e44fde.c914f8",
"name": "",
- "links": [
- "46418e19.aa6d6"
- ],
+ "links": ["46418e19.aa6d6"],
"x": 875,
"y": 140,
"wires": []
@@ -945,10 +841,7 @@
"outputs": 2,
"x": 750,
"y": 1040,
- "wires": [
- [],
- []
- ]
+ "wires": [[], []]
},
{
"id": "79889759.8219c",
@@ -963,11 +856,7 @@
"finalize": "",
"x": 460,
"y": 1200,
- "wires": [
- [
- "2e6738a6.ef5dd8"
- ]
- ]
+ "wires": [["2e6738a6.ef5dd8"]]
},
{
"id": "7f53465b.356a68",
@@ -982,11 +871,7 @@
"finalize": "",
"x": 470,
"y": 1080,
- "wires": [
- [
- "2e6738a6.ef5dd8"
- ]
- ]
+ "wires": [["2e6738a6.ef5dd8"]]
},
{
"id": "97aff586.786ff8",
@@ -1012,11 +897,7 @@
"payloadType": "json",
"x": 480,
"y": 1040,
- "wires": [
- [
- "2e6738a6.ef5dd8"
- ]
- ]
+ "wires": [["2e6738a6.ef5dd8"]]
},
{
"id": "659ff3da.236404",
@@ -1038,11 +919,7 @@
"payloadType": "num",
"x": 220,
"y": 1200,
- "wires": [
- [
- "79889759.8219c"
- ]
- ]
+ "wires": [["79889759.8219c"]]
},
{
"id": "e6105066.f8911",
@@ -1059,11 +936,7 @@
"payloadType": "num",
"x": 210,
"y": 1040,
- "wires": [
- [
- "7f53465b.356a68"
- ]
- ]
+ "wires": [["7f53465b.356a68"]]
},
{
"id": "b433a780.665a7",
@@ -1085,11 +958,7 @@
"payloadType": "str",
"x": 200,
"y": 1240,
- "wires": [
- [
- "79889759.8219c"
- ]
- ]
+ "wires": [["79889759.8219c"]]
},
{
"id": "d4b30334.a19e58",
@@ -1111,11 +980,7 @@
"payloadType": "str",
"x": 220,
"y": 1080,
- "wires": [
- [
- "7f53465b.356a68"
- ]
- ]
+ "wires": [["7f53465b.356a68"]]
},
{
"id": "b0eeeb34.2dde8",
@@ -1137,11 +1002,7 @@
"payloadType": "str",
"x": 230,
"y": 1120,
- "wires": [
- [
- "7f53465b.356a68"
- ]
- ]
+ "wires": [["7f53465b.356a68"]]
},
{
"id": "a875cc7.a4c42b",
@@ -1217,10 +1078,7 @@
"outputs": 2,
"x": 740,
"y": 1340,
- "wires": [
- [],
- []
- ]
+ "wires": [[], []]
},
{
"id": "2f9bc0d.42a73c",
@@ -1237,11 +1095,7 @@
"payloadType": "json",
"x": 200,
"y": 1460,
- "wires": [
- [
- "a5194c26.18c628"
- ]
- ]
+ "wires": [["a5194c26.18c628"]]
},
{
"id": "dfca0b2d.8b8e8",
@@ -1258,11 +1112,7 @@
"payloadType": "json",
"x": 220,
"y": 1500,
- "wires": [
- [
- "a5194c26.18c628"
- ]
- ]
+ "wires": [["a5194c26.18c628"]]
},
{
"id": "d74a610c.09a36",
@@ -1279,11 +1129,7 @@
"payloadType": "json",
"x": 560,
"y": 1460,
- "wires": [
- [
- "a5194c26.18c628"
- ]
- ]
+ "wires": [["a5194c26.18c628"]]
},
{
"id": "c15b6468.ae2eb8",
@@ -1300,11 +1146,7 @@
"payloadType": "json",
"x": 560,
"y": 1500,
- "wires": [
- [
- "a5194c26.18c628"
- ]
- ]
+ "wires": [["a5194c26.18c628"]]
},
{
"id": "6f7bc7fa.7f4f6",
@@ -1330,11 +1172,7 @@
"payloadType": "json",
"x": 220,
"y": 1400,
- "wires": [
- [
- "a5194c26.18c628"
- ]
- ]
+ "wires": [["a5194c26.18c628"]]
},
{
"id": "99b55eb3.e31bf8",
@@ -1355,11 +1193,7 @@
"outputs": 1,
"x": 430,
"y": 1340,
- "wires": [
- [
- "a5194c26.18c628"
- ]
- ]
+ "wires": [["a5194c26.18c628"]]
},
{
"id": "508d9ccf.29e404",
@@ -1385,11 +1219,7 @@
"payloadType": "json",
"x": 190,
"y": 1340,
- "wires": [
- [
- "99b55eb3.e31bf8"
- ]
- ]
+ "wires": [["99b55eb3.e31bf8"]]
},
{
"id": "ab48426e.25466",
@@ -1465,10 +1295,7 @@
"outputs": 2,
"x": 750,
"y": 820,
- "wires": [
- [],
- []
- ]
+ "wires": [[], []]
},
{
"id": "3611c654.8a42f2",
@@ -1483,11 +1310,7 @@
"finalize": "",
"x": 480,
"y": 820,
- "wires": [
- [
- "88892b4.8a61bd8"
- ]
- ]
+ "wires": [["88892b4.8a61bd8"]]
},
{
"id": "62cafcb0.8ade9c",
@@ -1504,11 +1327,7 @@
"payloadType": "json",
"x": 550,
"y": 860,
- "wires": [
- [
- "88892b4.8a61bd8"
- ]
- ]
+ "wires": [["88892b4.8a61bd8"]]
},
{
"id": "a0171cdb.f209b",
@@ -1525,11 +1344,7 @@
"payloadType": "json",
"x": 550,
"y": 900,
- "wires": [
- [
- "88892b4.8a61bd8"
- ]
- ]
+ "wires": [["88892b4.8a61bd8"]]
},
{
"id": "6f7de764.a6a688",
@@ -1546,11 +1361,7 @@
"payloadType": "json",
"x": 520,
"y": 940,
- "wires": [
- [
- "88892b4.8a61bd8"
- ]
- ]
+ "wires": [["88892b4.8a61bd8"]]
},
{
"id": "8758b463.afb0f",
@@ -1572,11 +1383,7 @@
"payloadType": "num",
"x": 190,
"y": 820,
- "wires": [
- [
- "3611c654.8a42f2"
- ]
- ]
+ "wires": [["3611c654.8a42f2"]]
},
{
"id": "69e8161b.74b7a",
@@ -1598,11 +1405,7 @@
"payloadType": "str",
"x": 200,
"y": 860,
- "wires": [
- [
- "3611c654.8a42f2"
- ]
- ]
+ "wires": [["3611c654.8a42f2"]]
},
{
"id": "40010b09.c73cdc",
@@ -1624,11 +1427,7 @@
"payloadType": "str",
"x": 220,
"y": 900,
- "wires": [
- [
- "3611c654.8a42f2"
- ]
- ]
+ "wires": [["3611c654.8a42f2"]]
},
{
"id": "b3b5156e.cdf988",
@@ -1703,10 +1502,7 @@
"outputs": 2,
"x": 750,
"y": 280,
- "wires": [
- [],
- []
- ]
+ "wires": [[], []]
},
{
"id": "a70b3192.dfb4f",
@@ -1728,11 +1524,7 @@
"payloadType": "json",
"x": 230,
"y": 280,
- "wires": [
- [
- "560fc866.6de558"
- ]
- ]
+ "wires": [["560fc866.6de558"]]
},
{
"id": "d5708f5.036c87",
@@ -1754,11 +1546,7 @@
"payloadType": "date",
"x": 220,
"y": 380,
- "wires": [
- [
- "90b692e4.b9f6c"
- ]
- ]
+ "wires": [["90b692e4.b9f6c"]]
},
{
"id": "90b692e4.b9f6c",
@@ -1773,11 +1561,7 @@
"finalize": "",
"x": 470,
"y": 380,
- "wires": [
- [
- "5cd5342a.cfd72c"
- ]
- ]
+ "wires": [["5cd5342a.cfd72c"]]
},
{
"id": "54bfafbc.396898",
@@ -1799,11 +1583,7 @@
"payloadType": "json",
"x": 500,
"y": 320,
- "wires": [
- [
- "8088a797.e1a7c"
- ]
- ]
+ "wires": [["8088a797.e1a7c"]]
},
{
"id": "560fc866.6de558",
@@ -1818,11 +1598,7 @@
"finalize": "",
"x": 500,
"y": 280,
- "wires": [
- [
- "8088a797.e1a7c"
- ]
- ]
+ "wires": [["8088a797.e1a7c"]]
},
{
"id": "61e113b2.dbb714",
@@ -1835,9 +1611,7 @@
"fill": "#bfdbef",
"label": true
},
- "nodes": [
- "5cd5342a.cfd72c"
- ],
+ "nodes": ["5cd5342a.cfd72c"],
"x": 654,
"y": 339,
"w": 172,
@@ -1888,10 +1662,7 @@
"outputs": 2,
"x": 740,
"y": 380,
- "wires": [
- [],
- []
- ]
+ "wires": [[], []]
},
{
"id": "c869b0a5.e4def8",
@@ -1981,12 +1752,7 @@
"outputs": 2,
"x": 510,
"y": 1800,
- "wires": [
- [
- "dadd634c.ae2258"
- ],
- []
- ]
+ "wires": [["dadd634c.ae2258"], []]
},
{
"id": "992f4930.012aa",
@@ -2012,11 +1778,7 @@
"payloadType": "json",
"x": 460,
"y": 1880,
- "wires": [
- [
- "753e3777.49a1d"
- ]
- ]
+ "wires": [["753e3777.49a1d"]]
},
{
"id": "2497a466.aa0e84",
@@ -2042,11 +1804,7 @@
"payloadType": "json",
"x": 190,
"y": 1800,
- "wires": [
- [
- "753e3777.49a1d"
- ]
- ]
+ "wires": [["753e3777.49a1d"]]
},
{
"id": "c53b76fb.7a3cc8",
@@ -2072,11 +1830,7 @@
"payloadType": "json",
"x": 190,
"y": 1840,
- "wires": [
- [
- "753e3777.49a1d"
- ]
- ]
+ "wires": [["753e3777.49a1d"]]
},
{
"id": "6c9646ee.1f3a18",
@@ -2102,11 +1856,7 @@
"payloadType": "json",
"x": 200,
"y": 1880,
- "wires": [
- [
- "753e3777.49a1d"
- ]
- ]
+ "wires": [["753e3777.49a1d"]]
},
{
"id": "1e42a8f3.cf008f",
@@ -2132,10 +1882,6 @@
"payloadType": "json",
"x": 190,
"y": 1920,
- "wires": [
- [
- "753e3777.49a1d"
- ]
- ]
+ "wires": [["753e3777.49a1d"]]
}
]
diff --git a/examples/demo/02 - Air Purifier.json b/examples/demo/02 - Air Purifier.json
index b1e44f20..647e7eaa 100644
--- a/examples/demo/02 - Air Purifier.json
+++ b/examples/demo/02 - Air Purifier.json
@@ -1,331 +1,282 @@
[
- {
- "id": "60e44fde.c914f8",
- "type": "group",
- "z": "60b06629.a2ebd",
- "name": "Air Purifier: input power state, output commands device",
- "style": {
- "stroke": "#999999",
- "fill": "none",
- "label": true,
- "label-position": "nw",
- "color": "#a4a4a4"
- },
- "nodes": [
- "8dea49.4a770db8",
- "5302e4aa.1b466c",
- "bfe1c73d.c165a8",
- "9739d842.a402f",
- "87048a6e.df64e8",
- "db412cea.4a62f8",
- "46418e19.aa6d6",
- "664dadf9.85d0d4",
- "d7cd8a56.628178",
- "3de34c4c.1871a4",
- "ee8894e4.f1855"
- ],
- "x": 14,
- "y": 119,
- "w": 822,
- "h": 162,
- "info": "Turning the device on or off will send:\n`{\"Active\":[0, 1]}`\n\nAfter changing power state, the device will be \"Turning on\" or \"Turning off\" until a current state is sent of:\n`{\"CurrentAirPurifierState\":[0, 1, 2]}`\n0: off
\n1: idle
\n2: on
\n\nThere will be a slider in the home app for sending `RotationSpeed`\n\nThere will be a switch on Home app for \"Oscillate\" which sends:\n`{\"SwingMode\":[0,1]}`\n\nChanging mode to manual to auto will send payload:\n`{\"TargetAirPurifierState\":[0, 1]}`\n\nChild lock will send \n`{\"LockPhysicalControls\": [0, 1]}`\n\n"
+ {
+ "id": "60e44fde.c914f8",
+ "type": "group",
+ "z": "60b06629.a2ebd",
+ "name": "Air Purifier: input power state, output commands device",
+ "style": {
+ "stroke": "#999999",
+ "fill": "none",
+ "label": true,
+ "label-position": "nw",
+ "color": "#a4a4a4"
},
- {
- "id": "8dea49.4a770db8",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "60e44fde.c914f8",
- "name": "off",
- "props": [
- {
- "p": "payload"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"CurrentAirPurifierState\":0}",
- "payloadType": "json",
- "x": 110,
- "y": 160,
- "wires": [
- [
- "5302e4aa.1b466c"
- ]
- ]
- },
- {
- "id": "5302e4aa.1b466c",
- "type": "homekit-service",
- "z": "60b06629.a2ebd",
- "g": "60e44fde.c914f8",
- "isParent": true,
- "bridge": "409001a1.3e7a78",
- "parentService": "",
- "name": "Air purifier",
- "serviceName": "AirPurifier",
- "topic": "",
- "filter": false,
- "manufacturer": "Purity",
- "model": "Air",
- "serialNo": "23",
- "firmwareRev": "1.0.0",
- "hardwareRev": "1.0.0",
- "softwareRev": "1.0.0",
- "cameraConfigVideoProcessor": "ffmpeg",
- "cameraConfigSource": "",
- "cameraConfigStillImageSource": "",
- "cameraConfigMaxStreams": 2,
- "cameraConfigMaxWidth": 1280,
- "cameraConfigMaxHeight": 720,
- "cameraConfigMaxFPS": 10,
- "cameraConfigMaxBitrate": 300,
- "cameraConfigVideoCodec": "libx264",
- "cameraConfigAudioCodec": "libfdk_aac",
- "cameraConfigAudio": false,
- "cameraConfigPacketSize": 1316,
- "cameraConfigVerticalFlip": false,
- "cameraConfigHorizontalFlip": false,
- "cameraConfigMapVideo": "0:0",
- "cameraConfigMapAudio": "0:1",
- "cameraConfigVideoFilter": "scale=1280:720",
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
- "cameraConfigDebug": false,
- "cameraConfigSnapshotOutput": "disabled",
- "cameraConfigInterfaceName": "",
- "characteristicProperties": "{\n \"SwingMode\":true,\n \"RotationSpeed\":true,\n \"LockPhysicalControls\":true\n}",
- "outputs": 2,
- "x": 290,
- "y": 160,
- "wires": [
- [
- "bfe1c73d.c165a8",
- "9739d842.a402f"
- ],
- []
- ]
- },
- {
- "id": "bfe1c73d.c165a8",
- "type": "debug",
- "z": "60b06629.a2ebd",
- "g": "60e44fde.c914f8",
- "name": "Purifier output",
- "active": true,
- "tosidebar": true,
- "console": false,
- "tostatus": false,
- "complete": "true",
- "targetType": "full",
- "x": 420,
- "y": 240,
- "wires": []
- },
- {
- "id": "9739d842.a402f",
- "type": "function",
- "z": "60b06629.a2ebd",
- "g": "60e44fde.c914f8",
- "name": "on/off",
- "func": "if (msg.hap !== undefined && msg.hap.context !== undefined){\n if (msg.payload.Active === 1){\n return [msg,null];\n }\n if (msg.payload.Active === 0){\n return [null,msg];\n }\n}\nreturn;",
- "outputs": 2,
- "noerr": 0,
- "initialize": "",
- "finalize": "",
- "x": 450,
- "y": 160,
- "wires": [
- [
- "664dadf9.85d0d4",
- "d7cd8a56.628178"
- ],
- [
- "3de34c4c.1871a4"
- ]
- ],
- "outputLabels": [
- "On",
- "Off"
- ]
- },
- {
- "id": "87048a6e.df64e8",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "60e44fde.c914f8",
- "name": "idle",
- "props": [
- {
- "p": "payload"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"CurrentAirPurifierState\":1}",
- "payloadType": "json",
- "x": 110,
- "y": 200,
- "wires": [
- [
- "5302e4aa.1b466c"
- ]
- ]
- },
- {
- "id": "db412cea.4a62f8",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "60e44fde.c914f8",
- "name": "on",
- "props": [
- {
- "p": "payload"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"CurrentAirPurifierState\":2}",
- "payloadType": "json",
- "x": 110,
- "y": 240,
- "wires": [
- [
- "5302e4aa.1b466c"
- ]
- ]
- },
- {
- "id": "46418e19.aa6d6",
- "type": "link in",
- "z": "60b06629.a2ebd",
- "g": "60e44fde.c914f8",
- "name": "",
- "links": [
- "ee8894e4.f1855"
- ],
- "x": 235,
- "y": 240,
- "wires": [
- [
- "5302e4aa.1b466c"
- ]
- ]
- },
- {
- "id": "664dadf9.85d0d4",
- "type": "trigger",
- "z": "60b06629.a2ebd",
- "g": "60e44fde.c914f8",
- "name": "5 sec to idle",
- "op1": "",
- "op2": "{\"CurrentAirPurifierState\":1}",
- "op1type": "nul",
- "op2type": "json",
- "duration": "5",
- "extend": false,
- "units": "s",
- "reset": "",
- "bytopic": "all",
- "topic": "topic",
- "outputs": 1,
- "x": 650,
- "y": 160,
- "wires": [
- [
- "ee8894e4.f1855"
- ]
- ]
- },
- {
- "id": "d7cd8a56.628178",
- "type": "trigger",
- "z": "60b06629.a2ebd",
- "g": "60e44fde.c914f8",
- "name": "10 sec to on",
- "op1": "",
- "op2": "{\"CurrentAirPurifierState\":2}",
- "op1type": "nul",
- "op2type": "json",
- "duration": "10",
- "extend": false,
- "units": "s",
- "reset": "",
- "bytopic": "all",
- "topic": "topic",
- "outputs": 1,
- "x": 650,
- "y": 200,
- "wires": [
- [
- "ee8894e4.f1855"
- ]
- ]
- },
- {
- "id": "3de34c4c.1871a4",
- "type": "trigger",
- "z": "60b06629.a2ebd",
- "g": "60e44fde.c914f8",
- "name": "5 sec to off",
- "op1": "",
- "op2": "{\"CurrentAirPurifierState\":0}",
- "op1type": "nul",
- "op2type": "json",
- "duration": "5",
- "extend": false,
- "units": "s",
- "reset": "",
- "bytopic": "all",
- "topic": "topic",
- "outputs": 1,
- "x": 650,
- "y": 240,
- "wires": [
- [
- "ee8894e4.f1855"
- ]
- ]
- },
- {
- "id": "ee8894e4.f1855",
- "type": "link out",
- "z": "60b06629.a2ebd",
- "g": "60e44fde.c914f8",
- "name": "",
- "links": [
- "46418e19.aa6d6"
- ],
- "x": 795,
- "y": 200,
- "wires": []
- },
- {
- "id": "409001a1.3e7a78",
- "type": "homekit-bridge",
- "z": "",
- "bridgeName": "Demo 1",
- "pinCode": "153-10-538",
- "port": "",
- "allowInsecureRequest": false,
- "manufacturer": "NRCHKB",
- "model": "Demo",
- "serialNo": "1.1.2",
- "customMdnsConfig": false,
- "mdnsMulticast": true,
- "mdnsInterface": "",
- "mdnsPort": "",
- "mdnsIp": "",
- "mdnsTtl": "",
- "mdnsLoopback": true,
- "mdnsReuseAddr": true,
- "allowMessagePassthrough": true
- }
+ "nodes": [
+ "8dea49.4a770db8",
+ "5302e4aa.1b466c",
+ "bfe1c73d.c165a8",
+ "9739d842.a402f",
+ "87048a6e.df64e8",
+ "db412cea.4a62f8",
+ "46418e19.aa6d6",
+ "664dadf9.85d0d4",
+ "d7cd8a56.628178",
+ "3de34c4c.1871a4",
+ "ee8894e4.f1855"
+ ],
+ "x": 14,
+ "y": 119,
+ "w": 822,
+ "h": 162,
+ "info": "Turning the device on or off will send:\n`{\"Active\":[0, 1]}`\n\nAfter changing power state, the device will be \"Turning on\" or \"Turning off\" until a current state is sent of:\n`{\"CurrentAirPurifierState\":[0, 1, 2]}`\n0: off
\n1: idle
\n2: on
\n\nThere will be a slider in the home app for sending `RotationSpeed`\n\nThere will be a switch on Home app for \"Oscillate\" which sends:\n`{\"SwingMode\":[0,1]}`\n\nChanging mode to manual to auto will send payload:\n`{\"TargetAirPurifierState\":[0, 1]}`\n\nChild lock will send \n`{\"LockPhysicalControls\": [0, 1]}`\n\n"
+ },
+ {
+ "id": "8dea49.4a770db8",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "60e44fde.c914f8",
+ "name": "off",
+ "props": [
+ {
+ "p": "payload"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"CurrentAirPurifierState\":0}",
+ "payloadType": "json",
+ "x": 110,
+ "y": 160,
+ "wires": [["5302e4aa.1b466c"]]
+ },
+ {
+ "id": "5302e4aa.1b466c",
+ "type": "homekit-service",
+ "z": "60b06629.a2ebd",
+ "g": "60e44fde.c914f8",
+ "isParent": true,
+ "bridge": "409001a1.3e7a78",
+ "parentService": "",
+ "name": "Air purifier",
+ "serviceName": "AirPurifier",
+ "topic": "",
+ "filter": false,
+ "manufacturer": "Purity",
+ "model": "Air",
+ "serialNo": "23",
+ "firmwareRev": "1.0.0",
+ "hardwareRev": "1.0.0",
+ "softwareRev": "1.0.0",
+ "cameraConfigVideoProcessor": "ffmpeg",
+ "cameraConfigSource": "",
+ "cameraConfigStillImageSource": "",
+ "cameraConfigMaxStreams": 2,
+ "cameraConfigMaxWidth": 1280,
+ "cameraConfigMaxHeight": 720,
+ "cameraConfigMaxFPS": 10,
+ "cameraConfigMaxBitrate": 300,
+ "cameraConfigVideoCodec": "libx264",
+ "cameraConfigAudioCodec": "libfdk_aac",
+ "cameraConfigAudio": false,
+ "cameraConfigPacketSize": 1316,
+ "cameraConfigVerticalFlip": false,
+ "cameraConfigHorizontalFlip": false,
+ "cameraConfigMapVideo": "0:0",
+ "cameraConfigMapAudio": "0:1",
+ "cameraConfigVideoFilter": "scale=1280:720",
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
+ "cameraConfigDebug": false,
+ "cameraConfigSnapshotOutput": "disabled",
+ "cameraConfigInterfaceName": "",
+ "characteristicProperties": "{\n \"SwingMode\":true,\n \"RotationSpeed\":true,\n \"LockPhysicalControls\":true\n}",
+ "outputs": 2,
+ "x": 290,
+ "y": 160,
+ "wires": [["bfe1c73d.c165a8", "9739d842.a402f"], []]
+ },
+ {
+ "id": "bfe1c73d.c165a8",
+ "type": "debug",
+ "z": "60b06629.a2ebd",
+ "g": "60e44fde.c914f8",
+ "name": "Purifier output",
+ "active": true,
+ "tosidebar": true,
+ "console": false,
+ "tostatus": false,
+ "complete": "true",
+ "targetType": "full",
+ "x": 420,
+ "y": 240,
+ "wires": []
+ },
+ {
+ "id": "9739d842.a402f",
+ "type": "function",
+ "z": "60b06629.a2ebd",
+ "g": "60e44fde.c914f8",
+ "name": "on/off",
+ "func": "if (msg.hap !== undefined && msg.hap.context !== undefined){\n if (msg.payload.Active === 1){\n return [msg,null];\n }\n if (msg.payload.Active === 0){\n return [null,msg];\n }\n}\nreturn;",
+ "outputs": 2,
+ "noerr": 0,
+ "initialize": "",
+ "finalize": "",
+ "x": 450,
+ "y": 160,
+ "wires": [["664dadf9.85d0d4", "d7cd8a56.628178"], ["3de34c4c.1871a4"]],
+ "outputLabels": ["On", "Off"]
+ },
+ {
+ "id": "87048a6e.df64e8",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "60e44fde.c914f8",
+ "name": "idle",
+ "props": [
+ {
+ "p": "payload"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"CurrentAirPurifierState\":1}",
+ "payloadType": "json",
+ "x": 110,
+ "y": 200,
+ "wires": [["5302e4aa.1b466c"]]
+ },
+ {
+ "id": "db412cea.4a62f8",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "60e44fde.c914f8",
+ "name": "on",
+ "props": [
+ {
+ "p": "payload"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"CurrentAirPurifierState\":2}",
+ "payloadType": "json",
+ "x": 110,
+ "y": 240,
+ "wires": [["5302e4aa.1b466c"]]
+ },
+ {
+ "id": "46418e19.aa6d6",
+ "type": "link in",
+ "z": "60b06629.a2ebd",
+ "g": "60e44fde.c914f8",
+ "name": "",
+ "links": ["ee8894e4.f1855"],
+ "x": 235,
+ "y": 240,
+ "wires": [["5302e4aa.1b466c"]]
+ },
+ {
+ "id": "664dadf9.85d0d4",
+ "type": "trigger",
+ "z": "60b06629.a2ebd",
+ "g": "60e44fde.c914f8",
+ "name": "5 sec to idle",
+ "op1": "",
+ "op2": "{\"CurrentAirPurifierState\":1}",
+ "op1type": "nul",
+ "op2type": "json",
+ "duration": "5",
+ "extend": false,
+ "units": "s",
+ "reset": "",
+ "bytopic": "all",
+ "topic": "topic",
+ "outputs": 1,
+ "x": 650,
+ "y": 160,
+ "wires": [["ee8894e4.f1855"]]
+ },
+ {
+ "id": "d7cd8a56.628178",
+ "type": "trigger",
+ "z": "60b06629.a2ebd",
+ "g": "60e44fde.c914f8",
+ "name": "10 sec to on",
+ "op1": "",
+ "op2": "{\"CurrentAirPurifierState\":2}",
+ "op1type": "nul",
+ "op2type": "json",
+ "duration": "10",
+ "extend": false,
+ "units": "s",
+ "reset": "",
+ "bytopic": "all",
+ "topic": "topic",
+ "outputs": 1,
+ "x": 650,
+ "y": 200,
+ "wires": [["ee8894e4.f1855"]]
+ },
+ {
+ "id": "3de34c4c.1871a4",
+ "type": "trigger",
+ "z": "60b06629.a2ebd",
+ "g": "60e44fde.c914f8",
+ "name": "5 sec to off",
+ "op1": "",
+ "op2": "{\"CurrentAirPurifierState\":0}",
+ "op1type": "nul",
+ "op2type": "json",
+ "duration": "5",
+ "extend": false,
+ "units": "s",
+ "reset": "",
+ "bytopic": "all",
+ "topic": "topic",
+ "outputs": 1,
+ "x": 650,
+ "y": 240,
+ "wires": [["ee8894e4.f1855"]]
+ },
+ {
+ "id": "ee8894e4.f1855",
+ "type": "link out",
+ "z": "60b06629.a2ebd",
+ "g": "60e44fde.c914f8",
+ "name": "",
+ "links": ["46418e19.aa6d6"],
+ "x": 795,
+ "y": 200,
+ "wires": []
+ },
+ {
+ "id": "409001a1.3e7a78",
+ "type": "homekit-bridge",
+ "z": "",
+ "bridgeName": "Demo 1",
+ "pinCode": "153-10-538",
+ "port": "",
+ "allowInsecureRequest": false,
+ "manufacturer": "NRCHKB",
+ "model": "Demo",
+ "serialNo": "1.1.2",
+ "customMdnsConfig": false,
+ "mdnsMulticast": true,
+ "mdnsInterface": "",
+ "mdnsPort": "",
+ "mdnsIp": "",
+ "mdnsTtl": "",
+ "mdnsLoopback": true,
+ "mdnsReuseAddr": true,
+ "allowMessagePassthrough": true
+ }
]
diff --git a/examples/demo/03 - Air Quality sensor with Battery.json b/examples/demo/03 - Air Quality sensor with Battery.json
index 88cbee76..597488da 100644
--- a/examples/demo/03 - Air Quality sensor with Battery.json
+++ b/examples/demo/03 - Air Quality sensor with Battery.json
@@ -1,286 +1,258 @@
[
- {
- "id": "b3b5156e.cdf988",
- "type": "group",
- "z": "eeb8b00c.2c18c",
- "name": "Air Quality with Battery: input only sensor",
- "style": {
- "stroke": "#999999",
- "fill": "none",
- "label": true,
- "label-position": "nw",
- "color": "#a4a4a4"
- },
- "nodes": [
- "8088a797.e1a7c",
- "a70b3192.dfb4f",
- "d5708f5.036c87",
- "90b692e4.b9f6c",
- "54bfafbc.396898",
- "560fc866.6de558",
- "61e113b2.dbb714"
- ],
- "x": 94,
- "y": 239,
- "w": 758,
- "h": 208,
- "info": "# Air Quality Sensor\n\nThis sensor will inject random values for all of the air quality metrics available in the HomeKit spec. It will also inject random values for a linked battery service.\n\nWatch the input and Home app to learn how to see how things are working."
+ {
+ "id": "b3b5156e.cdf988",
+ "type": "group",
+ "z": "eeb8b00c.2c18c",
+ "name": "Air Quality with Battery: input only sensor",
+ "style": {
+ "stroke": "#999999",
+ "fill": "none",
+ "label": true,
+ "label-position": "nw",
+ "color": "#a4a4a4"
},
- {
- "id": "8088a797.e1a7c",
- "type": "homekit-service",
- "z": "eeb8b00c.2c18c",
- "g": "b3b5156e.cdf988",
- "isParent": true,
- "hostType": "0",
- "bridge": "409001a1.3e7a78",
- "accessoryId": "",
- "parentService": "",
- "name": "Air Quality",
- "serviceName": "AirQualitySensor",
- "topic": "",
- "filter": false,
- "manufacturer": "Quality",
- "model": "Battery",
- "serialNo": "777",
- "firmwareRev": "8.3",
- "hardwareRev": "2.1",
- "softwareRev": "1.0.0",
- "cameraConfigVideoProcessor": "ffmpeg",
- "cameraConfigSource": "",
- "cameraConfigStillImageSource": "",
- "cameraConfigMaxStreams": 2,
- "cameraConfigMaxWidth": 1280,
- "cameraConfigMaxHeight": 720,
- "cameraConfigMaxFPS": 10,
- "cameraConfigMaxBitrate": 300,
- "cameraConfigVideoCodec": "libx264",
- "cameraConfigAudioCodec": "libfdk_aac",
- "cameraConfigAudio": false,
- "cameraConfigPacketSize": 1316,
- "cameraConfigVerticalFlip": false,
- "cameraConfigHorizontalFlip": false,
- "cameraConfigMapVideo": "0:0",
- "cameraConfigMapAudio": "0:1",
- "cameraConfigVideoFilter": "scale=1280:720",
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
- "cameraConfigDebug": false,
- "cameraConfigSnapshotOutput": "disabled",
- "cameraConfigInterfaceName": "",
- "characteristicProperties": "{ \"AirQuality\":true, \"PM2_5Density\":true, \"PM10Density\":true}",
- "waitForSetupMsg": false,
- "outputs": 2,
- "x": 750,
- "y": 280,
- "wires": [
- [],
- []
- ]
+ "nodes": [
+ "8088a797.e1a7c",
+ "a70b3192.dfb4f",
+ "d5708f5.036c87",
+ "90b692e4.b9f6c",
+ "54bfafbc.396898",
+ "560fc866.6de558",
+ "61e113b2.dbb714"
+ ],
+ "x": 94,
+ "y": 239,
+ "w": 758,
+ "h": 208,
+ "info": "# Air Quality Sensor\n\nThis sensor will inject random values for all of the air quality metrics available in the HomeKit spec. It will also inject random values for a linked battery service.\n\nWatch the input and Home app to learn how to see how things are working."
+ },
+ {
+ "id": "8088a797.e1a7c",
+ "type": "homekit-service",
+ "z": "eeb8b00c.2c18c",
+ "g": "b3b5156e.cdf988",
+ "isParent": true,
+ "hostType": "0",
+ "bridge": "409001a1.3e7a78",
+ "accessoryId": "",
+ "parentService": "",
+ "name": "Air Quality",
+ "serviceName": "AirQualitySensor",
+ "topic": "",
+ "filter": false,
+ "manufacturer": "Quality",
+ "model": "Battery",
+ "serialNo": "777",
+ "firmwareRev": "8.3",
+ "hardwareRev": "2.1",
+ "softwareRev": "1.0.0",
+ "cameraConfigVideoProcessor": "ffmpeg",
+ "cameraConfigSource": "",
+ "cameraConfigStillImageSource": "",
+ "cameraConfigMaxStreams": 2,
+ "cameraConfigMaxWidth": 1280,
+ "cameraConfigMaxHeight": 720,
+ "cameraConfigMaxFPS": 10,
+ "cameraConfigMaxBitrate": 300,
+ "cameraConfigVideoCodec": "libx264",
+ "cameraConfigAudioCodec": "libfdk_aac",
+ "cameraConfigAudio": false,
+ "cameraConfigPacketSize": 1316,
+ "cameraConfigVerticalFlip": false,
+ "cameraConfigHorizontalFlip": false,
+ "cameraConfigMapVideo": "0:0",
+ "cameraConfigMapAudio": "0:1",
+ "cameraConfigVideoFilter": "scale=1280:720",
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
+ "cameraConfigDebug": false,
+ "cameraConfigSnapshotOutput": "disabled",
+ "cameraConfigInterfaceName": "",
+ "characteristicProperties": "{ \"AirQuality\":true, \"PM2_5Density\":true, \"PM10Density\":true}",
+ "waitForSetupMsg": false,
+ "outputs": 2,
+ "x": 750,
+ "y": 280,
+ "wires": [[], []]
+ },
+ {
+ "id": "a70b3192.dfb4f",
+ "type": "inject",
+ "z": "eeb8b00c.2c18c",
+ "g": "b3b5156e.cdf988",
+ "name": "Air quality random",
+ "props": [
+ {
+ "p": "payload"
+ }
+ ],
+ "repeat": "15",
+ "crontab": "",
+ "once": true,
+ "onceDelay": "5",
+ "topic": "",
+ "payload": "{}",
+ "payloadType": "json",
+ "x": 230,
+ "y": 280,
+ "wires": [["560fc866.6de558"]]
+ },
+ {
+ "id": "d5708f5.036c87",
+ "type": "inject",
+ "z": "eeb8b00c.2c18c",
+ "g": "b3b5156e.cdf988",
+ "name": "Battery random",
+ "props": [
+ {
+ "p": "payload"
+ }
+ ],
+ "repeat": "30",
+ "crontab": "",
+ "once": true,
+ "onceDelay": "5",
+ "topic": "",
+ "payload": "",
+ "payloadType": "date",
+ "x": 220,
+ "y": 380,
+ "wires": [["90b692e4.b9f6c"]]
+ },
+ {
+ "id": "90b692e4.b9f6c",
+ "type": "function",
+ "z": "eeb8b00c.2c18c",
+ "g": "b3b5156e.cdf988",
+ "name": "Batt",
+ "func": "// Define random battery level\nconst level = Math.floor(Math.random() * Math.floor(100))\nvar newMsg = {\n payload: {\n \"BatteryLevel\": level\n }\n};\n\n// Show \"Low Battery\" if less than 10%\nif (level < 10)newMsg.payload.StatusLowBattery = 1;\nelse newMsg.payload.StatusLowBattery = 0;\n\n// Show \"Charging\" if greater than 60%\nif (level > 60) newMsg.payload.ChargingState = 1;\nelse newMsg.payload.ChargingState = 0;\n\nreturn newMsg;",
+ "outputs": 1,
+ "noerr": 0,
+ "initialize": "",
+ "finalize": "",
+ "x": 470,
+ "y": 380,
+ "wires": [["5cd5342a.cfd72c"]]
+ },
+ {
+ "id": "54bfafbc.396898",
+ "type": "inject",
+ "z": "eeb8b00c.2c18c",
+ "g": "b3b5156e.cdf988",
+ "name": "NO RESPONSE",
+ "props": [
+ {
+ "p": "payload"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"AirQuality\":\"NO_RESPONSE\"}",
+ "payloadType": "json",
+ "x": 500,
+ "y": 320,
+ "wires": [["8088a797.e1a7c"]]
+ },
+ {
+ "id": "560fc866.6de558",
+ "type": "function",
+ "z": "eeb8b00c.2c18c",
+ "g": "b3b5156e.cdf988",
+ "name": "Random values",
+ "func": "var newMsg = {\n \"payload\":{\n \"AirQuality\":Math.floor(Math.random() * Math.floor(5)),\n \"PM2_5Density\":Math.floor(Math.random() * Math.floor(1000)),\n \"PM10Density\":Math.floor(Math.random() * Math.floor(1000)),\n \"OzoneDensity\":Math.floor(Math.random() * Math.floor(1000)),\n \"NitrogenDioxideDensity\":Math.floor(Math.random() * Math.floor(1000)),\n \"SulphurDioxideDensity\": Math.floor(Math.random() * Math.floor(1000))\n }\n}\n\n\n\nreturn newMsg;",
+ "outputs": 1,
+ "noerr": 0,
+ "initialize": "",
+ "finalize": "",
+ "x": 500,
+ "y": 280,
+ "wires": [["8088a797.e1a7c"]]
+ },
+ {
+ "id": "61e113b2.dbb714",
+ "type": "group",
+ "z": "eeb8b00c.2c18c",
+ "g": "b3b5156e.cdf988",
+ "name": "LINKED",
+ "style": {
+ "stroke": "#0070c0",
+ "fill": "#bfdbef",
+ "label": true
},
- {
- "id": "a70b3192.dfb4f",
- "type": "inject",
- "z": "eeb8b00c.2c18c",
- "g": "b3b5156e.cdf988",
- "name": "Air quality random",
- "props": [
- {
- "p": "payload"
- }
- ],
- "repeat": "15",
- "crontab": "",
- "once": true,
- "onceDelay": "5",
- "topic": "",
- "payload": "{}",
- "payloadType": "json",
- "x": 230,
- "y": 280,
- "wires": [
- [
- "560fc866.6de558"
- ]
- ]
- },
- {
- "id": "d5708f5.036c87",
- "type": "inject",
- "z": "eeb8b00c.2c18c",
- "g": "b3b5156e.cdf988",
- "name": "Battery random",
- "props": [
- {
- "p": "payload"
- }
- ],
- "repeat": "30",
- "crontab": "",
- "once": true,
- "onceDelay": "5",
- "topic": "",
- "payload": "",
- "payloadType": "date",
- "x": 220,
- "y": 380,
- "wires": [
- [
- "90b692e4.b9f6c"
- ]
- ]
- },
- {
- "id": "90b692e4.b9f6c",
- "type": "function",
- "z": "eeb8b00c.2c18c",
- "g": "b3b5156e.cdf988",
- "name": "Batt",
- "func": "// Define random battery level\nconst level = Math.floor(Math.random() * Math.floor(100))\nvar newMsg = {\n payload: {\n \"BatteryLevel\": level\n }\n};\n\n// Show \"Low Battery\" if less than 10%\nif (level < 10)newMsg.payload.StatusLowBattery = 1;\nelse newMsg.payload.StatusLowBattery = 0;\n\n// Show \"Charging\" if greater than 60%\nif (level > 60) newMsg.payload.ChargingState = 1;\nelse newMsg.payload.ChargingState = 0;\n\nreturn newMsg;",
- "outputs": 1,
- "noerr": 0,
- "initialize": "",
- "finalize": "",
- "x": 470,
- "y": 380,
- "wires": [
- [
- "5cd5342a.cfd72c"
- ]
- ]
- },
- {
- "id": "54bfafbc.396898",
- "type": "inject",
- "z": "eeb8b00c.2c18c",
- "g": "b3b5156e.cdf988",
- "name": "NO RESPONSE",
- "props": [
- {
- "p": "payload"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"AirQuality\":\"NO_RESPONSE\"}",
- "payloadType": "json",
- "x": 500,
- "y": 320,
- "wires": [
- [
- "8088a797.e1a7c"
- ]
- ]
- },
- {
- "id": "560fc866.6de558",
- "type": "function",
- "z": "eeb8b00c.2c18c",
- "g": "b3b5156e.cdf988",
- "name": "Random values",
- "func": "var newMsg = {\n \"payload\":{\n \"AirQuality\":Math.floor(Math.random() * Math.floor(5)),\n \"PM2_5Density\":Math.floor(Math.random() * Math.floor(1000)),\n \"PM10Density\":Math.floor(Math.random() * Math.floor(1000)),\n \"OzoneDensity\":Math.floor(Math.random() * Math.floor(1000)),\n \"NitrogenDioxideDensity\":Math.floor(Math.random() * Math.floor(1000)),\n \"SulphurDioxideDensity\": Math.floor(Math.random() * Math.floor(1000))\n }\n}\n\n\n\nreturn newMsg;",
- "outputs": 1,
- "noerr": 0,
- "initialize": "",
- "finalize": "",
- "x": 500,
- "y": 280,
- "wires": [
- [
- "8088a797.e1a7c"
- ]
- ]
- },
- {
- "id": "61e113b2.dbb714",
- "type": "group",
- "z": "eeb8b00c.2c18c",
- "g": "b3b5156e.cdf988",
- "name": "LINKED",
- "style": {
- "stroke": "#0070c0",
- "fill": "#bfdbef",
- "label": true
- },
- "nodes": [
- "5cd5342a.cfd72c"
- ],
- "x": 654,
- "y": 339,
- "w": 172,
- "h": 82
- },
- {
- "id": "5cd5342a.cfd72c",
- "type": "homekit-service",
- "z": "eeb8b00c.2c18c",
- "g": "61e113b2.dbb714",
- "isParent": false,
- "hostType": "0",
- "bridge": "",
- "accessoryId": "",
- "parentService": "8088a797.e1a7c",
- "name": "Battery",
- "serviceName": "Battery",
- "topic": "Air Quality",
- "filter": false,
- "manufacturer": "Default Manufacturer",
- "model": "Default Model",
- "serialNo": "Default Serial Number",
- "firmwareRev": "1.0.0",
- "hardwareRev": "1.0.0",
- "softwareRev": "1.0.0",
- "cameraConfigVideoProcessor": "ffmpeg",
- "cameraConfigSource": "",
- "cameraConfigStillImageSource": "",
- "cameraConfigMaxStreams": 2,
- "cameraConfigMaxWidth": 1280,
- "cameraConfigMaxHeight": 720,
- "cameraConfigMaxFPS": 10,
- "cameraConfigMaxBitrate": 300,
- "cameraConfigVideoCodec": "libx264",
- "cameraConfigAudioCodec": "libfdk_aac",
- "cameraConfigAudio": false,
- "cameraConfigPacketSize": 1316,
- "cameraConfigVerticalFlip": false,
- "cameraConfigHorizontalFlip": false,
- "cameraConfigMapVideo": "0:0",
- "cameraConfigMapAudio": "0:1",
- "cameraConfigVideoFilter": "scale=1280:720",
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
- "cameraConfigDebug": false,
- "cameraConfigSnapshotOutput": "disabled",
- "cameraConfigInterfaceName": "",
- "characteristicProperties": "{}",
- "waitForSetupMsg": false,
- "outputs": 2,
- "x": 740,
- "y": 380,
- "wires": [
- [],
- []
- ]
- },
- {
- "id": "409001a1.3e7a78",
- "type": "homekit-bridge",
- "bridgeName": "Demo 1",
- "pinCode": "153-10-538",
- "port": "",
- "allowInsecureRequest": false,
- "manufacturer": "NRCHKB",
- "model": "Demo",
- "serialNo": "1.1.2",
- "customMdnsConfig": false,
- "mdnsMulticast": true,
- "mdnsInterface": "",
- "mdnsPort": "",
- "mdnsIp": "",
- "mdnsTtl": "",
- "mdnsLoopback": true,
- "mdnsReuseAddr": true,
- "allowMessagePassthrough": true
- }
+ "nodes": ["5cd5342a.cfd72c"],
+ "x": 654,
+ "y": 339,
+ "w": 172,
+ "h": 82
+ },
+ {
+ "id": "5cd5342a.cfd72c",
+ "type": "homekit-service",
+ "z": "eeb8b00c.2c18c",
+ "g": "61e113b2.dbb714",
+ "isParent": false,
+ "hostType": "0",
+ "bridge": "",
+ "accessoryId": "",
+ "parentService": "8088a797.e1a7c",
+ "name": "Battery",
+ "serviceName": "Battery",
+ "topic": "Air Quality",
+ "filter": false,
+ "manufacturer": "Default Manufacturer",
+ "model": "Default Model",
+ "serialNo": "Default Serial Number",
+ "firmwareRev": "1.0.0",
+ "hardwareRev": "1.0.0",
+ "softwareRev": "1.0.0",
+ "cameraConfigVideoProcessor": "ffmpeg",
+ "cameraConfigSource": "",
+ "cameraConfigStillImageSource": "",
+ "cameraConfigMaxStreams": 2,
+ "cameraConfigMaxWidth": 1280,
+ "cameraConfigMaxHeight": 720,
+ "cameraConfigMaxFPS": 10,
+ "cameraConfigMaxBitrate": 300,
+ "cameraConfigVideoCodec": "libx264",
+ "cameraConfigAudioCodec": "libfdk_aac",
+ "cameraConfigAudio": false,
+ "cameraConfigPacketSize": 1316,
+ "cameraConfigVerticalFlip": false,
+ "cameraConfigHorizontalFlip": false,
+ "cameraConfigMapVideo": "0:0",
+ "cameraConfigMapAudio": "0:1",
+ "cameraConfigVideoFilter": "scale=1280:720",
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
+ "cameraConfigDebug": false,
+ "cameraConfigSnapshotOutput": "disabled",
+ "cameraConfigInterfaceName": "",
+ "characteristicProperties": "{}",
+ "waitForSetupMsg": false,
+ "outputs": 2,
+ "x": 740,
+ "y": 380,
+ "wires": [[], []]
+ },
+ {
+ "id": "409001a1.3e7a78",
+ "type": "homekit-bridge",
+ "bridgeName": "Demo 1",
+ "pinCode": "153-10-538",
+ "port": "",
+ "allowInsecureRequest": false,
+ "manufacturer": "NRCHKB",
+ "model": "Demo",
+ "serialNo": "1.1.2",
+ "customMdnsConfig": false,
+ "mdnsMulticast": true,
+ "mdnsInterface": "",
+ "mdnsPort": "",
+ "mdnsIp": "",
+ "mdnsTtl": "",
+ "mdnsLoopback": true,
+ "mdnsReuseAddr": true,
+ "allowMessagePassthrough": true
+ }
]
diff --git a/examples/demo/04 - Dimmable Bulb.json b/examples/demo/04 - Dimmable Bulb.json
index 587c4be0..d181b54f 100644
--- a/examples/demo/04 - Dimmable Bulb.json
+++ b/examples/demo/04 - Dimmable Bulb.json
@@ -1,192 +1,175 @@
[
- {
- "id": "3a57bebe.a3b222",
- "type": "group",
- "z": "60b06629.a2ebd",
- "name": "Dimmable Bulb: input from device, output to device",
- "style": {
- "stroke": "#999999",
- "fill": "none",
- "label": true,
- "label-position": "nw",
- "color": "#a4a4a4"
- },
- "nodes": [
- "459254fe.49c72c",
- "379657db.a99df8",
- "52a07047.03ce7",
- "253b3550.729caa",
- "b9bc7f3d.51acf"
- ],
- "x": 14,
- "y": 519,
- "w": 752,
- "h": 122,
- "info": "# Dimmable Bulb\n\nThis is a dimmable bulb. The Characteristic Properties enable brightness. It is a white bulb which can be adjusted from 0 to 100% brightness."
+ {
+ "id": "3a57bebe.a3b222",
+ "type": "group",
+ "z": "60b06629.a2ebd",
+ "name": "Dimmable Bulb: input from device, output to device",
+ "style": {
+ "stroke": "#999999",
+ "fill": "none",
+ "label": true,
+ "label-position": "nw",
+ "color": "#a4a4a4"
},
- {
- "id": "459254fe.49c72c",
- "type": "homekit-service",
- "z": "60b06629.a2ebd",
- "g": "3a57bebe.a3b222",
- "isParent": true,
- "bridge": "409001a1.3e7a78",
- "parentService": "",
- "name": "Dimmable",
- "serviceName": "Lightbulb",
- "topic": "",
- "filter": false,
- "manufacturer": "Garrett",
- "model": "Dummy",
- "serialNo": "Default Serial Number",
- "firmwareRev": "1.1.9",
- "hardwareRev": "1.0.0",
- "softwareRev": "1.0.0",
- "cameraConfigVideoProcessor": "ffmpeg",
- "cameraConfigSource": "",
- "cameraConfigStillImageSource": "",
- "cameraConfigMaxStreams": 2,
- "cameraConfigMaxWidth": 1280,
- "cameraConfigMaxHeight": 720,
- "cameraConfigMaxFPS": 10,
- "cameraConfigMaxBitrate": 300,
- "cameraConfigVideoCodec": "libx264",
- "cameraConfigAudioCodec": "libfdk_aac",
- "cameraConfigAudio": false,
- "cameraConfigPacketSize": 1316,
- "cameraConfigVerticalFlip": false,
- "cameraConfigHorizontalFlip": false,
- "cameraConfigMapVideo": "0:0",
- "cameraConfigMapAudio": "0:1",
- "cameraConfigVideoFilter": "scale=1280:720",
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
- "cameraConfigDebug": false,
- "cameraConfigSnapshotOutput": "disabled",
- "cameraConfigInterfaceName": "",
- "characteristicProperties": "{\n \"Brightness\":true\n}",
- "outputs": 2,
- "x": 380,
- "y": 600,
- "wires": [
- [
- "379657db.a99df8"
- ],
- []
- ]
- },
- {
- "id": "379657db.a99df8",
- "type": "debug",
- "z": "60b06629.a2ebd",
- "g": "3a57bebe.a3b222",
- "name": "Dimmable light output",
- "active": true,
- "tosidebar": true,
- "console": false,
- "tostatus": false,
- "complete": "payload",
- "targetType": "msg",
- "x": 620,
- "y": 600,
- "wires": []
- },
- {
- "id": "52a07047.03ce7",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "3a57bebe.a3b222",
- "name": "NO RESPONSE",
- "props": [
- {
- "p": "payload"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"On\":\"NO_RESPONSE\"}",
- "payloadType": "json",
- "x": 320,
- "y": 560,
- "wires": [
- [
- "459254fe.49c72c"
- ]
- ]
- },
- {
- "id": "253b3550.729caa",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "3a57bebe.a3b222",
- "name": "ON",
- "props": [
- {
- "p": "payload"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"On\":true}",
- "payloadType": "json",
- "x": 110,
- "y": 560,
- "wires": [
- [
- "459254fe.49c72c"
- ]
- ]
- },
- {
- "id": "b9bc7f3d.51acf",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "3a57bebe.a3b222",
- "name": "OFF",
- "props": [
- {
- "p": "payload"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"On\":false}",
- "payloadType": "json",
- "x": 110,
- "y": 600,
- "wires": [
- [
- "459254fe.49c72c"
- ]
- ]
- },
- {
- "id": "409001a1.3e7a78",
- "type": "homekit-bridge",
- "z": "",
- "bridgeName": "Demo 1",
- "pinCode": "153-10-538",
- "port": "",
- "allowInsecureRequest": false,
- "manufacturer": "NRCHKB",
- "model": "Demo",
- "serialNo": "1.1.2",
- "customMdnsConfig": false,
- "mdnsMulticast": true,
- "mdnsInterface": "",
- "mdnsPort": "",
- "mdnsIp": "",
- "mdnsTtl": "",
- "mdnsLoopback": true,
- "mdnsReuseAddr": true,
- "allowMessagePassthrough": true
- }
+ "nodes": [
+ "459254fe.49c72c",
+ "379657db.a99df8",
+ "52a07047.03ce7",
+ "253b3550.729caa",
+ "b9bc7f3d.51acf"
+ ],
+ "x": 14,
+ "y": 519,
+ "w": 752,
+ "h": 122,
+ "info": "# Dimmable Bulb\n\nThis is a dimmable bulb. The Characteristic Properties enable brightness. It is a white bulb which can be adjusted from 0 to 100% brightness."
+ },
+ {
+ "id": "459254fe.49c72c",
+ "type": "homekit-service",
+ "z": "60b06629.a2ebd",
+ "g": "3a57bebe.a3b222",
+ "isParent": true,
+ "bridge": "409001a1.3e7a78",
+ "parentService": "",
+ "name": "Dimmable",
+ "serviceName": "Lightbulb",
+ "topic": "",
+ "filter": false,
+ "manufacturer": "Garrett",
+ "model": "Dummy",
+ "serialNo": "Default Serial Number",
+ "firmwareRev": "1.1.9",
+ "hardwareRev": "1.0.0",
+ "softwareRev": "1.0.0",
+ "cameraConfigVideoProcessor": "ffmpeg",
+ "cameraConfigSource": "",
+ "cameraConfigStillImageSource": "",
+ "cameraConfigMaxStreams": 2,
+ "cameraConfigMaxWidth": 1280,
+ "cameraConfigMaxHeight": 720,
+ "cameraConfigMaxFPS": 10,
+ "cameraConfigMaxBitrate": 300,
+ "cameraConfigVideoCodec": "libx264",
+ "cameraConfigAudioCodec": "libfdk_aac",
+ "cameraConfigAudio": false,
+ "cameraConfigPacketSize": 1316,
+ "cameraConfigVerticalFlip": false,
+ "cameraConfigHorizontalFlip": false,
+ "cameraConfigMapVideo": "0:0",
+ "cameraConfigMapAudio": "0:1",
+ "cameraConfigVideoFilter": "scale=1280:720",
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
+ "cameraConfigDebug": false,
+ "cameraConfigSnapshotOutput": "disabled",
+ "cameraConfigInterfaceName": "",
+ "characteristicProperties": "{\n \"Brightness\":true\n}",
+ "outputs": 2,
+ "x": 380,
+ "y": 600,
+ "wires": [["379657db.a99df8"], []]
+ },
+ {
+ "id": "379657db.a99df8",
+ "type": "debug",
+ "z": "60b06629.a2ebd",
+ "g": "3a57bebe.a3b222",
+ "name": "Dimmable light output",
+ "active": true,
+ "tosidebar": true,
+ "console": false,
+ "tostatus": false,
+ "complete": "payload",
+ "targetType": "msg",
+ "x": 620,
+ "y": 600,
+ "wires": []
+ },
+ {
+ "id": "52a07047.03ce7",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "3a57bebe.a3b222",
+ "name": "NO RESPONSE",
+ "props": [
+ {
+ "p": "payload"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"On\":\"NO_RESPONSE\"}",
+ "payloadType": "json",
+ "x": 320,
+ "y": 560,
+ "wires": [["459254fe.49c72c"]]
+ },
+ {
+ "id": "253b3550.729caa",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "3a57bebe.a3b222",
+ "name": "ON",
+ "props": [
+ {
+ "p": "payload"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"On\":true}",
+ "payloadType": "json",
+ "x": 110,
+ "y": 560,
+ "wires": [["459254fe.49c72c"]]
+ },
+ {
+ "id": "b9bc7f3d.51acf",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "3a57bebe.a3b222",
+ "name": "OFF",
+ "props": [
+ {
+ "p": "payload"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"On\":false}",
+ "payloadType": "json",
+ "x": 110,
+ "y": 600,
+ "wires": [["459254fe.49c72c"]]
+ },
+ {
+ "id": "409001a1.3e7a78",
+ "type": "homekit-bridge",
+ "z": "",
+ "bridgeName": "Demo 1",
+ "pinCode": "153-10-538",
+ "port": "",
+ "allowInsecureRequest": false,
+ "manufacturer": "NRCHKB",
+ "model": "Demo",
+ "serialNo": "1.1.2",
+ "customMdnsConfig": false,
+ "mdnsMulticast": true,
+ "mdnsInterface": "",
+ "mdnsPort": "",
+ "mdnsIp": "",
+ "mdnsTtl": "",
+ "mdnsLoopback": true,
+ "mdnsReuseAddr": true,
+ "allowMessagePassthrough": true
+ }
]
diff --git a/examples/demo/05 - Color Bulb (HSV).json b/examples/demo/05 - Color Bulb (HSV).json
index 1b55fac1..e5604c39 100644
--- a/examples/demo/05 - Color Bulb (HSV).json
+++ b/examples/demo/05 - Color Bulb (HSV).json
@@ -1,219 +1,198 @@
[
- {
- "id": "384e0889.1fdae",
- "type": "group",
- "z": "60b06629.a2ebd",
- "name": "Color Bulb: input from device, output to device",
- "style": {
- "stroke": "#999999",
- "fill": "none",
- "label": true,
- "label-position": "nw",
- "color": "#a4a4a4"
- },
- "nodes": [
- "d838176b.dbaf7",
- "7bf880d4.3cd4d",
- "ee1452a5.08edd",
- "c6ed2a2a.90a01",
- "8cdfae2b.2f2ce8",
- "1758401b.6c62e8"
- ],
- "x": 14,
- "y": 659,
- "w": 752,
- "h": 162,
- "info": "# Color Bulb\n\nThis is a color bulb. It accepts and sends out Hue, Saturation, Value, and On/off state.\n\nHue is the color\n\nSaturation is how deep the color is\n\nValue is brightness\n\nOn is power state"
+ {
+ "id": "384e0889.1fdae",
+ "type": "group",
+ "z": "60b06629.a2ebd",
+ "name": "Color Bulb: input from device, output to device",
+ "style": {
+ "stroke": "#999999",
+ "fill": "none",
+ "label": true,
+ "label-position": "nw",
+ "color": "#a4a4a4"
},
- {
- "id": "d838176b.dbaf7",
- "type": "debug",
- "z": "60b06629.a2ebd",
- "g": "384e0889.1fdae",
- "name": "Color light output",
- "active": true,
- "tosidebar": true,
- "console": false,
- "tostatus": false,
- "complete": "payload",
- "targetType": "msg",
- "x": 630,
- "y": 780,
- "wires": []
- },
- {
- "id": "7bf880d4.3cd4d",
- "type": "homekit-service",
- "z": "60b06629.a2ebd",
- "g": "384e0889.1fdae",
- "isParent": true,
- "bridge": "409001a1.3e7a78",
- "parentService": "",
- "name": "Color",
- "serviceName": "Lightbulb",
- "topic": "",
- "filter": false,
- "manufacturer": "Garrett",
- "model": "Color",
- "serialNo": "42",
- "firmwareRev": "1.2",
- "hardwareRev": "1.0.0",
- "softwareRev": "1.0.0",
- "cameraConfigVideoProcessor": "ffmpeg",
- "cameraConfigSource": "",
- "cameraConfigStillImageSource": "",
- "cameraConfigMaxStreams": 2,
- "cameraConfigMaxWidth": 1280,
- "cameraConfigMaxHeight": 720,
- "cameraConfigMaxFPS": 10,
- "cameraConfigMaxBitrate": 300,
- "cameraConfigVideoCodec": "libx264",
- "cameraConfigAudioCodec": "libfdk_aac",
- "cameraConfigAudio": false,
- "cameraConfigPacketSize": 1316,
- "cameraConfigVerticalFlip": false,
- "cameraConfigHorizontalFlip": false,
- "cameraConfigMapVideo": "0:0",
- "cameraConfigMapAudio": "0:1",
- "cameraConfigVideoFilter": "scale=1280:720",
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
- "cameraConfigDebug": false,
- "cameraConfigSnapshotOutput": "disabled",
- "cameraConfigInterfaceName": "",
- "characteristicProperties": "{\n \"Brightness\":true,\n \"Hue\":true,\n \"Saturation\":true\n}",
- "outputs": 2,
- "x": 410,
- "y": 780,
- "wires": [
- [
- "d838176b.dbaf7"
- ],
- []
- ]
- },
- {
- "id": "ee1452a5.08edd",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "384e0889.1fdae",
- "name": "NO RESPONSE",
- "props": [
- {
- "p": "payload"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"On\":\"NO_RESPONSE\"}",
- "payloadType": "json",
- "x": 340,
- "y": 700,
- "wires": [
- [
- "7bf880d4.3cd4d"
- ]
- ]
- },
- {
- "id": "c6ed2a2a.90a01",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "384e0889.1fdae",
- "name": "ON",
- "props": [
- {
- "p": "payload"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"On\":true}",
- "payloadType": "json",
- "x": 110,
- "y": 700,
- "wires": [
- [
- "7bf880d4.3cd4d"
- ]
- ]
- },
- {
- "id": "8cdfae2b.2f2ce8",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "384e0889.1fdae",
- "name": "Reset HSV",
- "props": [
- {
- "p": "payload"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"Brightness\":50,\"Hue\":50,\"Saturation\":50}",
- "payloadType": "json",
- "x": 120,
- "y": 780,
- "wires": [
- [
- "7bf880d4.3cd4d"
- ]
- ]
- },
- {
- "id": "1758401b.6c62e8",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "384e0889.1fdae",
- "name": "OFF",
- "props": [
- {
- "p": "payload"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"On\":false}",
- "payloadType": "json",
- "x": 110,
- "y": 740,
- "wires": [
- [
- "7bf880d4.3cd4d"
- ]
- ]
- },
- {
- "id": "409001a1.3e7a78",
- "type": "homekit-bridge",
- "z": "",
- "bridgeName": "Demo 1",
- "pinCode": "153-10-538",
- "port": "",
- "allowInsecureRequest": false,
- "manufacturer": "NRCHKB",
- "model": "Demo",
- "serialNo": "1.1.2",
- "customMdnsConfig": false,
- "mdnsMulticast": true,
- "mdnsInterface": "",
- "mdnsPort": "",
- "mdnsIp": "",
- "mdnsTtl": "",
- "mdnsLoopback": true,
- "mdnsReuseAddr": true,
- "allowMessagePassthrough": true
- }
+ "nodes": [
+ "d838176b.dbaf7",
+ "7bf880d4.3cd4d",
+ "ee1452a5.08edd",
+ "c6ed2a2a.90a01",
+ "8cdfae2b.2f2ce8",
+ "1758401b.6c62e8"
+ ],
+ "x": 14,
+ "y": 659,
+ "w": 752,
+ "h": 162,
+ "info": "# Color Bulb\n\nThis is a color bulb. It accepts and sends out Hue, Saturation, Value, and On/off state.\n\nHue is the color\n\nSaturation is how deep the color is\n\nValue is brightness\n\nOn is power state"
+ },
+ {
+ "id": "d838176b.dbaf7",
+ "type": "debug",
+ "z": "60b06629.a2ebd",
+ "g": "384e0889.1fdae",
+ "name": "Color light output",
+ "active": true,
+ "tosidebar": true,
+ "console": false,
+ "tostatus": false,
+ "complete": "payload",
+ "targetType": "msg",
+ "x": 630,
+ "y": 780,
+ "wires": []
+ },
+ {
+ "id": "7bf880d4.3cd4d",
+ "type": "homekit-service",
+ "z": "60b06629.a2ebd",
+ "g": "384e0889.1fdae",
+ "isParent": true,
+ "bridge": "409001a1.3e7a78",
+ "parentService": "",
+ "name": "Color",
+ "serviceName": "Lightbulb",
+ "topic": "",
+ "filter": false,
+ "manufacturer": "Garrett",
+ "model": "Color",
+ "serialNo": "42",
+ "firmwareRev": "1.2",
+ "hardwareRev": "1.0.0",
+ "softwareRev": "1.0.0",
+ "cameraConfigVideoProcessor": "ffmpeg",
+ "cameraConfigSource": "",
+ "cameraConfigStillImageSource": "",
+ "cameraConfigMaxStreams": 2,
+ "cameraConfigMaxWidth": 1280,
+ "cameraConfigMaxHeight": 720,
+ "cameraConfigMaxFPS": 10,
+ "cameraConfigMaxBitrate": 300,
+ "cameraConfigVideoCodec": "libx264",
+ "cameraConfigAudioCodec": "libfdk_aac",
+ "cameraConfigAudio": false,
+ "cameraConfigPacketSize": 1316,
+ "cameraConfigVerticalFlip": false,
+ "cameraConfigHorizontalFlip": false,
+ "cameraConfigMapVideo": "0:0",
+ "cameraConfigMapAudio": "0:1",
+ "cameraConfigVideoFilter": "scale=1280:720",
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
+ "cameraConfigDebug": false,
+ "cameraConfigSnapshotOutput": "disabled",
+ "cameraConfigInterfaceName": "",
+ "characteristicProperties": "{\n \"Brightness\":true,\n \"Hue\":true,\n \"Saturation\":true\n}",
+ "outputs": 2,
+ "x": 410,
+ "y": 780,
+ "wires": [["d838176b.dbaf7"], []]
+ },
+ {
+ "id": "ee1452a5.08edd",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "384e0889.1fdae",
+ "name": "NO RESPONSE",
+ "props": [
+ {
+ "p": "payload"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"On\":\"NO_RESPONSE\"}",
+ "payloadType": "json",
+ "x": 340,
+ "y": 700,
+ "wires": [["7bf880d4.3cd4d"]]
+ },
+ {
+ "id": "c6ed2a2a.90a01",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "384e0889.1fdae",
+ "name": "ON",
+ "props": [
+ {
+ "p": "payload"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"On\":true}",
+ "payloadType": "json",
+ "x": 110,
+ "y": 700,
+ "wires": [["7bf880d4.3cd4d"]]
+ },
+ {
+ "id": "8cdfae2b.2f2ce8",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "384e0889.1fdae",
+ "name": "Reset HSV",
+ "props": [
+ {
+ "p": "payload"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"Brightness\":50,\"Hue\":50,\"Saturation\":50}",
+ "payloadType": "json",
+ "x": 120,
+ "y": 780,
+ "wires": [["7bf880d4.3cd4d"]]
+ },
+ {
+ "id": "1758401b.6c62e8",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "384e0889.1fdae",
+ "name": "OFF",
+ "props": [
+ {
+ "p": "payload"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"On\":false}",
+ "payloadType": "json",
+ "x": 110,
+ "y": 740,
+ "wires": [["7bf880d4.3cd4d"]]
+ },
+ {
+ "id": "409001a1.3e7a78",
+ "type": "homekit-bridge",
+ "z": "",
+ "bridgeName": "Demo 1",
+ "pinCode": "153-10-538",
+ "port": "",
+ "allowInsecureRequest": false,
+ "manufacturer": "NRCHKB",
+ "model": "Demo",
+ "serialNo": "1.1.2",
+ "customMdnsConfig": false,
+ "mdnsMulticast": true,
+ "mdnsInterface": "",
+ "mdnsPort": "",
+ "mdnsIp": "",
+ "mdnsTtl": "",
+ "mdnsLoopback": true,
+ "mdnsReuseAddr": true,
+ "allowMessagePassthrough": true
+ }
]
diff --git a/examples/demo/06 - Fan (simple, 3 speeds).json b/examples/demo/06 - Fan (simple, 3 speeds).json
index f38ccab7..17f9b7b8 100644
--- a/examples/demo/06 - Fan (simple, 3 speeds).json
+++ b/examples/demo/06 - Fan (simple, 3 speeds).json
@@ -1,268 +1,243 @@
[
- {
- "id": "c869b0a5.e4def8",
- "type": "group",
- "z": "60b06629.a2ebd",
- "name": "Fan Simplified: input from device, output to device",
- "style": {
- "stroke": "#999999",
- "fill": "none",
- "label": true,
- "label-position": "nw",
- "color": "#a4a4a4"
- },
- "nodes": [
- "dadd634c.ae2258",
- "753e3777.49a1d",
- "992f4930.012aa",
- "2497a466.aa0e84",
- "c53b76fb.7a3cc8",
- "6c9646ee.1f3a18",
- "1e42a8f3.cf008f"
- ],
- "x": 14,
- "y": 1819,
- "w": 752,
- "h": 202,
- "info": "# Fan Simple\n\nThis example is for a 3-speed fan.\n\nSpeeds are:
\nLow = 33
\nMedium = 66
\nHigh = 99
\n\nValues outside of this are restricted and will not work. The home app will \"snap\" to these values. Siri will respond to \"set fan to low/medium/high\" with the corresponding value."
+ {
+ "id": "c869b0a5.e4def8",
+ "type": "group",
+ "z": "60b06629.a2ebd",
+ "name": "Fan Simplified: input from device, output to device",
+ "style": {
+ "stroke": "#999999",
+ "fill": "none",
+ "label": true,
+ "label-position": "nw",
+ "color": "#a4a4a4"
},
- {
- "id": "dadd634c.ae2258",
- "type": "debug",
- "z": "60b06629.a2ebd",
- "g": "c869b0a5.e4def8",
- "name": "Fan output",
- "active": true,
- "tosidebar": true,
- "console": false,
- "tostatus": false,
- "complete": "payload",
- "targetType": "msg",
- "statusVal": "",
- "statusType": "auto",
- "x": 650,
- "y": 1860,
- "wires": []
- },
- {
- "id": "753e3777.49a1d",
- "type": "homekit-service",
- "z": "60b06629.a2ebd",
- "g": "c869b0a5.e4def8",
- "isParent": true,
- "bridge": "409001a1.3e7a78",
- "parentService": "",
- "name": "Fan Speeds",
- "serviceName": "Fan",
- "topic": "",
- "filter": false,
- "manufacturer": "Gman",
- "model": "Default Model",
- "serialNo": "CRX1",
- "firmwareRev": "1.0.0",
- "hardwareRev": "1.0.0",
- "softwareRev": "1.0.0",
- "cameraConfigVideoProcessor": "ffmpeg",
- "cameraConfigSource": "",
- "cameraConfigStillImageSource": "",
- "cameraConfigMaxStreams": 2,
- "cameraConfigMaxWidth": 1280,
- "cameraConfigMaxHeight": 720,
- "cameraConfigMaxFPS": 10,
- "cameraConfigMaxBitrate": 300,
- "cameraConfigVideoCodec": "libx264",
- "cameraConfigAudioCodec": "libfdk_aac",
- "cameraConfigAudio": false,
- "cameraConfigPacketSize": 1316,
- "cameraConfigVerticalFlip": false,
- "cameraConfigHorizontalFlip": false,
- "cameraConfigMapVideo": "0:0",
- "cameraConfigMapAudio": "0:1",
- "cameraConfigVideoFilter": "scale=1280:720",
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
- "cameraConfigDebug": false,
- "cameraConfigSnapshotOutput": "disabled",
- "cameraConfigInterfaceName": "",
- "characteristicProperties": "{\n \"RotationSpeed\": {\n \"minValue\":0,\n \"maxValue\":99,\n \"minStep\":33\n }\n}",
- "outputs": 2,
- "x": 430,
- "y": 1860,
- "wires": [
- [
- "dadd634c.ae2258"
- ],
- []
- ]
- },
- {
- "id": "992f4930.012aa",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "c869b0a5.e4def8",
- "name": "NO RESPONSE",
- "props": [
- {
- "p": "payload"
- },
- {
- "p": "topic",
- "vt": "str"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"On\":\"NO_RESPONSE\"}",
- "payloadType": "json",
- "x": 380,
- "y": 1940,
- "wires": [
- [
- "753e3777.49a1d"
- ]
- ]
- },
- {
- "id": "2497a466.aa0e84",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "c869b0a5.e4def8",
- "name": "OFF",
- "props": [
- {
- "p": "payload"
- },
- {
- "p": "topic",
- "vt": "str"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"On\":false}",
- "payloadType": "json",
- "x": 110,
- "y": 1860,
- "wires": [
- [
- "753e3777.49a1d"
- ]
- ]
- },
- {
- "id": "c53b76fb.7a3cc8",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "c869b0a5.e4def8",
- "name": "Low",
- "props": [
- {
- "p": "payload"
- },
- {
- "p": "topic",
- "vt": "str"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"On\":true,\"RotationSpeed\":33}",
- "payloadType": "json",
- "x": 110,
- "y": 1900,
- "wires": [
- [
- "753e3777.49a1d"
- ]
- ]
- },
- {
- "id": "6c9646ee.1f3a18",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "c869b0a5.e4def8",
- "name": "Medium",
- "props": [
- {
- "p": "payload"
- },
- {
- "p": "topic",
- "vt": "str"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"On\":true,\"RotationSpeed\":66}",
- "payloadType": "json",
- "x": 120,
- "y": 1940,
- "wires": [
- [
- "753e3777.49a1d"
- ]
- ]
- },
- {
- "id": "1e42a8f3.cf008f",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "c869b0a5.e4def8",
- "name": "High",
- "props": [
- {
- "p": "payload"
- },
- {
- "p": "topic",
- "vt": "str"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"On\":true,\"RotationSpeed\":99}",
- "payloadType": "json",
- "x": 110,
- "y": 1980,
- "wires": [
- [
- "753e3777.49a1d"
- ]
- ]
- },
- {
- "id": "409001a1.3e7a78",
- "type": "homekit-bridge",
- "z": "",
- "bridgeName": "Demo 1",
- "pinCode": "153-10-538",
- "port": "",
- "allowInsecureRequest": false,
- "manufacturer": "NRCHKB",
- "model": "Demo",
- "serialNo": "1.1.2",
- "customMdnsConfig": false,
- "mdnsMulticast": true,
- "mdnsInterface": "",
- "mdnsPort": "",
- "mdnsIp": "",
- "mdnsTtl": "",
- "mdnsLoopback": true,
- "mdnsReuseAddr": true,
- "allowMessagePassthrough": true
- }
+ "nodes": [
+ "dadd634c.ae2258",
+ "753e3777.49a1d",
+ "992f4930.012aa",
+ "2497a466.aa0e84",
+ "c53b76fb.7a3cc8",
+ "6c9646ee.1f3a18",
+ "1e42a8f3.cf008f"
+ ],
+ "x": 14,
+ "y": 1819,
+ "w": 752,
+ "h": 202,
+ "info": "# Fan Simple\n\nThis example is for a 3-speed fan.\n\nSpeeds are:
\nLow = 33
\nMedium = 66
\nHigh = 99
\n\nValues outside of this are restricted and will not work. The home app will \"snap\" to these values. Siri will respond to \"set fan to low/medium/high\" with the corresponding value."
+ },
+ {
+ "id": "dadd634c.ae2258",
+ "type": "debug",
+ "z": "60b06629.a2ebd",
+ "g": "c869b0a5.e4def8",
+ "name": "Fan output",
+ "active": true,
+ "tosidebar": true,
+ "console": false,
+ "tostatus": false,
+ "complete": "payload",
+ "targetType": "msg",
+ "statusVal": "",
+ "statusType": "auto",
+ "x": 650,
+ "y": 1860,
+ "wires": []
+ },
+ {
+ "id": "753e3777.49a1d",
+ "type": "homekit-service",
+ "z": "60b06629.a2ebd",
+ "g": "c869b0a5.e4def8",
+ "isParent": true,
+ "bridge": "409001a1.3e7a78",
+ "parentService": "",
+ "name": "Fan Speeds",
+ "serviceName": "Fan",
+ "topic": "",
+ "filter": false,
+ "manufacturer": "Gman",
+ "model": "Default Model",
+ "serialNo": "CRX1",
+ "firmwareRev": "1.0.0",
+ "hardwareRev": "1.0.0",
+ "softwareRev": "1.0.0",
+ "cameraConfigVideoProcessor": "ffmpeg",
+ "cameraConfigSource": "",
+ "cameraConfigStillImageSource": "",
+ "cameraConfigMaxStreams": 2,
+ "cameraConfigMaxWidth": 1280,
+ "cameraConfigMaxHeight": 720,
+ "cameraConfigMaxFPS": 10,
+ "cameraConfigMaxBitrate": 300,
+ "cameraConfigVideoCodec": "libx264",
+ "cameraConfigAudioCodec": "libfdk_aac",
+ "cameraConfigAudio": false,
+ "cameraConfigPacketSize": 1316,
+ "cameraConfigVerticalFlip": false,
+ "cameraConfigHorizontalFlip": false,
+ "cameraConfigMapVideo": "0:0",
+ "cameraConfigMapAudio": "0:1",
+ "cameraConfigVideoFilter": "scale=1280:720",
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
+ "cameraConfigDebug": false,
+ "cameraConfigSnapshotOutput": "disabled",
+ "cameraConfigInterfaceName": "",
+ "characteristicProperties": "{\n \"RotationSpeed\": {\n \"minValue\":0,\n \"maxValue\":99,\n \"minStep\":33\n }\n}",
+ "outputs": 2,
+ "x": 430,
+ "y": 1860,
+ "wires": [["dadd634c.ae2258"], []]
+ },
+ {
+ "id": "992f4930.012aa",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "c869b0a5.e4def8",
+ "name": "NO RESPONSE",
+ "props": [
+ {
+ "p": "payload"
+ },
+ {
+ "p": "topic",
+ "vt": "str"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"On\":\"NO_RESPONSE\"}",
+ "payloadType": "json",
+ "x": 380,
+ "y": 1940,
+ "wires": [["753e3777.49a1d"]]
+ },
+ {
+ "id": "2497a466.aa0e84",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "c869b0a5.e4def8",
+ "name": "OFF",
+ "props": [
+ {
+ "p": "payload"
+ },
+ {
+ "p": "topic",
+ "vt": "str"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"On\":false}",
+ "payloadType": "json",
+ "x": 110,
+ "y": 1860,
+ "wires": [["753e3777.49a1d"]]
+ },
+ {
+ "id": "c53b76fb.7a3cc8",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "c869b0a5.e4def8",
+ "name": "Low",
+ "props": [
+ {
+ "p": "payload"
+ },
+ {
+ "p": "topic",
+ "vt": "str"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"On\":true,\"RotationSpeed\":33}",
+ "payloadType": "json",
+ "x": 110,
+ "y": 1900,
+ "wires": [["753e3777.49a1d"]]
+ },
+ {
+ "id": "6c9646ee.1f3a18",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "c869b0a5.e4def8",
+ "name": "Medium",
+ "props": [
+ {
+ "p": "payload"
+ },
+ {
+ "p": "topic",
+ "vt": "str"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"On\":true,\"RotationSpeed\":66}",
+ "payloadType": "json",
+ "x": 120,
+ "y": 1940,
+ "wires": [["753e3777.49a1d"]]
+ },
+ {
+ "id": "1e42a8f3.cf008f",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "c869b0a5.e4def8",
+ "name": "High",
+ "props": [
+ {
+ "p": "payload"
+ },
+ {
+ "p": "topic",
+ "vt": "str"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"On\":true,\"RotationSpeed\":99}",
+ "payloadType": "json",
+ "x": 110,
+ "y": 1980,
+ "wires": [["753e3777.49a1d"]]
+ },
+ {
+ "id": "409001a1.3e7a78",
+ "type": "homekit-bridge",
+ "z": "",
+ "bridgeName": "Demo 1",
+ "pinCode": "153-10-538",
+ "port": "",
+ "allowInsecureRequest": false,
+ "manufacturer": "NRCHKB",
+ "model": "Demo",
+ "serialNo": "1.1.2",
+ "customMdnsConfig": false,
+ "mdnsMulticast": true,
+ "mdnsInterface": "",
+ "mdnsPort": "",
+ "mdnsIp": "",
+ "mdnsTtl": "",
+ "mdnsLoopback": true,
+ "mdnsReuseAddr": true,
+ "allowMessagePassthrough": true
+ }
]
diff --git a/examples/demo/07 - Fan (with speed, oscillate, rotation direction).json b/examples/demo/07 - Fan (with speed, oscillate, rotation direction).json
index 7d4542a6..0b2df4c1 100644
--- a/examples/demo/07 - Fan (with speed, oscillate, rotation direction).json
+++ b/examples/demo/07 - Fan (with speed, oscillate, rotation direction).json
@@ -1,195 +1,178 @@
[
- {
- "id": "2c464315.51c50c",
- "type": "group",
- "z": "60b06629.a2ebd",
- "name": "Fan Full Example: input from device, output to device",
- "style": {
- "stroke": "#999999",
- "fill": "none",
- "label": true,
- "label-position": "nw",
- "color": "#a4a4a4"
- },
- "nodes": [
- "b7778e52.220a5",
- "fd8aff55.91d41",
- "c717b796.0735b8",
- "f56a2f96.509c1",
- "d945ba75.897998"
- ],
- "x": 14,
- "y": 1619,
- "w": 752,
- "h": 182,
- "info": "# Fan V2\n\nThis example shows a fan. The inputs from node red are to turn the fan on, off, or set \"No Response\".\n\nThe outputs going to \"Fan output\" will show:\n\nOn / off state
\nRotation speed
\nSwing mode on / off (oscillate)
\nRotation direction (clockwise/counterclockwise)"
+ {
+ "id": "2c464315.51c50c",
+ "type": "group",
+ "z": "60b06629.a2ebd",
+ "name": "Fan Full Example: input from device, output to device",
+ "style": {
+ "stroke": "#999999",
+ "fill": "none",
+ "label": true,
+ "label-position": "nw",
+ "color": "#a4a4a4"
},
- {
- "id": "b7778e52.220a5",
- "type": "debug",
- "z": "60b06629.a2ebd",
- "g": "2c464315.51c50c",
- "name": "Fan output",
- "active": true,
- "tosidebar": true,
- "console": false,
- "tostatus": false,
- "complete": "payload",
- "targetType": "msg",
- "x": 650,
- "y": 1660,
- "wires": []
- },
- {
- "id": "fd8aff55.91d41",
- "type": "homekit-service",
- "z": "60b06629.a2ebd",
- "g": "2c464315.51c50c",
- "isParent": true,
- "bridge": "409001a1.3e7a78",
- "parentService": "",
- "name": "Fan V2",
- "serviceName": "Fanv2",
- "topic": "",
- "filter": false,
- "manufacturer": "Default Manufacturer",
- "model": "Default Model",
- "serialNo": "Default Serial Number",
- "firmwareRev": "1.0.0",
- "hardwareRev": "1.0.0",
- "softwareRev": "1.0.0",
- "cameraConfigVideoProcessor": "ffmpeg",
- "cameraConfigSource": "",
- "cameraConfigStillImageSource": "",
- "cameraConfigMaxStreams": 2,
- "cameraConfigMaxWidth": 1280,
- "cameraConfigMaxHeight": 720,
- "cameraConfigMaxFPS": 10,
- "cameraConfigMaxBitrate": 300,
- "cameraConfigVideoCodec": "libx264",
- "cameraConfigAudioCodec": "libfdk_aac",
- "cameraConfigAudio": false,
- "cameraConfigPacketSize": 1316,
- "cameraConfigVerticalFlip": false,
- "cameraConfigHorizontalFlip": false,
- "cameraConfigMapVideo": "0:0",
- "cameraConfigMapAudio": "0:1",
- "cameraConfigVideoFilter": "scale=1280:720",
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
- "cameraConfigDebug": false,
- "cameraConfigSnapshotOutput": "disabled",
- "cameraConfigInterfaceName": "",
- "characteristicProperties": "{\n \"RotationSpeed\":true,\n \"RotationDirection\":true,\n \"SwingMode\":true\n}",
- "outputs": 2,
- "x": 420,
- "y": 1660,
- "wires": [
- [
- "b7778e52.220a5"
- ],
- []
- ]
- },
- {
- "id": "c717b796.0735b8",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "2c464315.51c50c",
- "name": "NO RESPONSE",
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"Active\":\"NO_RESPONSE\"}",
- "payloadType": "json",
- "x": 140,
- "y": 1760,
- "wires": [
- [
- "fd8aff55.91d41"
- ]
- ]
- },
- {
- "id": "f56a2f96.509c1",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "2c464315.51c50c",
- "name": "ON",
- "props": [
- {
- "p": "payload"
- },
- {
- "p": "topic",
- "vt": "str"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"Active\":true}",
- "payloadType": "json",
- "x": 120,
- "y": 1660,
- "wires": [
- [
- "fd8aff55.91d41"
- ]
- ]
- },
- {
- "id": "d945ba75.897998",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "2c464315.51c50c",
- "name": "OFF",
- "props": [
- {
- "p": "payload"
- },
- {
- "p": "topic",
- "vt": "str"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"Active\":false}",
- "payloadType": "json",
- "x": 120,
- "y": 1700,
- "wires": [
- [
- "fd8aff55.91d41"
- ]
- ]
- },
- {
- "id": "409001a1.3e7a78",
- "type": "homekit-bridge",
- "z": "",
- "bridgeName": "Demo 1",
- "pinCode": "153-10-538",
- "port": "",
- "allowInsecureRequest": false,
- "manufacturer": "NRCHKB",
- "model": "Demo",
- "serialNo": "1.1.2",
- "customMdnsConfig": false,
- "mdnsMulticast": true,
- "mdnsInterface": "",
- "mdnsPort": "",
- "mdnsIp": "",
- "mdnsTtl": "",
- "mdnsLoopback": true,
- "mdnsReuseAddr": true,
- "allowMessagePassthrough": true
- }
+ "nodes": [
+ "b7778e52.220a5",
+ "fd8aff55.91d41",
+ "c717b796.0735b8",
+ "f56a2f96.509c1",
+ "d945ba75.897998"
+ ],
+ "x": 14,
+ "y": 1619,
+ "w": 752,
+ "h": 182,
+ "info": "# Fan V2\n\nThis example shows a fan. The inputs from node red are to turn the fan on, off, or set \"No Response\".\n\nThe outputs going to \"Fan output\" will show:\n\nOn / off state
\nRotation speed
\nSwing mode on / off (oscillate)
\nRotation direction (clockwise/counterclockwise)"
+ },
+ {
+ "id": "b7778e52.220a5",
+ "type": "debug",
+ "z": "60b06629.a2ebd",
+ "g": "2c464315.51c50c",
+ "name": "Fan output",
+ "active": true,
+ "tosidebar": true,
+ "console": false,
+ "tostatus": false,
+ "complete": "payload",
+ "targetType": "msg",
+ "x": 650,
+ "y": 1660,
+ "wires": []
+ },
+ {
+ "id": "fd8aff55.91d41",
+ "type": "homekit-service",
+ "z": "60b06629.a2ebd",
+ "g": "2c464315.51c50c",
+ "isParent": true,
+ "bridge": "409001a1.3e7a78",
+ "parentService": "",
+ "name": "Fan V2",
+ "serviceName": "Fanv2",
+ "topic": "",
+ "filter": false,
+ "manufacturer": "Default Manufacturer",
+ "model": "Default Model",
+ "serialNo": "Default Serial Number",
+ "firmwareRev": "1.0.0",
+ "hardwareRev": "1.0.0",
+ "softwareRev": "1.0.0",
+ "cameraConfigVideoProcessor": "ffmpeg",
+ "cameraConfigSource": "",
+ "cameraConfigStillImageSource": "",
+ "cameraConfigMaxStreams": 2,
+ "cameraConfigMaxWidth": 1280,
+ "cameraConfigMaxHeight": 720,
+ "cameraConfigMaxFPS": 10,
+ "cameraConfigMaxBitrate": 300,
+ "cameraConfigVideoCodec": "libx264",
+ "cameraConfigAudioCodec": "libfdk_aac",
+ "cameraConfigAudio": false,
+ "cameraConfigPacketSize": 1316,
+ "cameraConfigVerticalFlip": false,
+ "cameraConfigHorizontalFlip": false,
+ "cameraConfigMapVideo": "0:0",
+ "cameraConfigMapAudio": "0:1",
+ "cameraConfigVideoFilter": "scale=1280:720",
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
+ "cameraConfigDebug": false,
+ "cameraConfigSnapshotOutput": "disabled",
+ "cameraConfigInterfaceName": "",
+ "characteristicProperties": "{\n \"RotationSpeed\":true,\n \"RotationDirection\":true,\n \"SwingMode\":true\n}",
+ "outputs": 2,
+ "x": 420,
+ "y": 1660,
+ "wires": [["b7778e52.220a5"], []]
+ },
+ {
+ "id": "c717b796.0735b8",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "2c464315.51c50c",
+ "name": "NO RESPONSE",
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"Active\":\"NO_RESPONSE\"}",
+ "payloadType": "json",
+ "x": 140,
+ "y": 1760,
+ "wires": [["fd8aff55.91d41"]]
+ },
+ {
+ "id": "f56a2f96.509c1",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "2c464315.51c50c",
+ "name": "ON",
+ "props": [
+ {
+ "p": "payload"
+ },
+ {
+ "p": "topic",
+ "vt": "str"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"Active\":true}",
+ "payloadType": "json",
+ "x": 120,
+ "y": 1660,
+ "wires": [["fd8aff55.91d41"]]
+ },
+ {
+ "id": "d945ba75.897998",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "2c464315.51c50c",
+ "name": "OFF",
+ "props": [
+ {
+ "p": "payload"
+ },
+ {
+ "p": "topic",
+ "vt": "str"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"Active\":false}",
+ "payloadType": "json",
+ "x": 120,
+ "y": 1700,
+ "wires": [["fd8aff55.91d41"]]
+ },
+ {
+ "id": "409001a1.3e7a78",
+ "type": "homekit-bridge",
+ "z": "",
+ "bridgeName": "Demo 1",
+ "pinCode": "153-10-538",
+ "port": "",
+ "allowInsecureRequest": false,
+ "manufacturer": "NRCHKB",
+ "model": "Demo",
+ "serialNo": "1.1.2",
+ "customMdnsConfig": false,
+ "mdnsMulticast": true,
+ "mdnsInterface": "",
+ "mdnsPort": "",
+ "mdnsIp": "",
+ "mdnsTtl": "",
+ "mdnsLoopback": true,
+ "mdnsReuseAddr": true,
+ "allowMessagePassthrough": true
+ }
]
diff --git a/examples/demo/08 - CO2 detector.json b/examples/demo/08 - CO2 detector.json
index cefad8e9..686cdfcf 100644
--- a/examples/demo/08 - CO2 detector.json
+++ b/examples/demo/08 - CO2 detector.json
@@ -1,258 +1,227 @@
[
- {
- "id": "ab48426e.25466",
- "type": "group",
- "z": "60b06629.a2ebd",
- "name": "CO2 Sensor: input only sensor",
- "style": {
- "stroke": "#999999",
- "fill": "none",
- "label": true,
- "label-position": "nw",
- "color": "#a4a4a4"
- },
- "nodes": [
- "88892b4.8a61bd8",
- "3611c654.8a42f2",
- "62cafcb0.8ade9c",
- "a0171cdb.f209b",
- "6f7de764.a6a688",
- "8758b463.afb0f",
- "69e8161b.74b7a",
- "40010b09.c73cdc"
- ],
- "x": 14,
- "y": 839,
- "w": 752,
- "h": 202,
- "info": "# CO2 Sensor\n\nThere are three inputs to this example, one for each level of Carbon Dioxide in the air. Options are:\n\n**0 ppm:** this will assume no CO2
\n**Safe level:** this will assume a level between 1 and 999 ppm, inclusive
\n**Dangerous level:** this will assume a level between 1,000 and 100,000, inclusive; this will also trigger an alert"
+ {
+ "id": "ab48426e.25466",
+ "type": "group",
+ "z": "60b06629.a2ebd",
+ "name": "CO2 Sensor: input only sensor",
+ "style": {
+ "stroke": "#999999",
+ "fill": "none",
+ "label": true,
+ "label-position": "nw",
+ "color": "#a4a4a4"
},
- {
- "id": "88892b4.8a61bd8",
- "type": "homekit-service",
- "z": "60b06629.a2ebd",
- "g": "ab48426e.25466",
- "isParent": true,
- "bridge": "409001a1.3e7a78",
- "parentService": "",
- "name": "CO2 Sensor",
- "serviceName": "CarbonDioxideSensor",
- "topic": "",
- "filter": false,
- "manufacturer": "Default Manufacturer",
- "model": "Carbon",
- "serialNo": "Default Serial Number",
- "firmwareRev": "22",
- "hardwareRev": "11",
- "cameraConfigVideoProcessor": "",
- "cameraConfigSource": "",
- "cameraConfigStillImageSource": "",
- "cameraConfigMaxStreams": "",
- "cameraConfigMaxWidth": "",
- "cameraConfigMaxHeight": "",
- "cameraConfigMaxFPS": "",
- "cameraConfigMaxBitrate": "",
- "cameraConfigVideoCodec": "",
- "cameraConfigAudioCodec": "",
- "cameraConfigAudio": false,
- "cameraConfigPacketSize": "",
- "cameraConfigVerticalFlip": false,
- "cameraConfigHorizontalFlip": false,
- "cameraConfigMapVideo": "",
- "cameraConfigMapAudio": "",
- "cameraConfigVideoFilter": "",
- "cameraConfigAdditionalCommandLine": "",
- "cameraConfigDebug": false,
- "cameraConfigSnapshotOutput": "disabled",
- "cameraConfigInterfaceName": "",
- "characteristicProperties": "{\n \"CarbonDioxideLevel\" : true,\n \"CarbonDioxidePeakLevel\": true,\n \"StatusActive\" : true\n}",
- "outputs": 2,
- "x": 670,
- "y": 880,
- "wires": [
- [],
- []
- ]
- },
- {
- "id": "3611c654.8a42f2",
- "type": "function",
- "z": "60b06629.a2ebd",
- "g": "ab48426e.25466",
- "name": "Random values, peak value",
- "func": "// Reset all values to 0 if 0ppm input\nif(msg.payload === 0){\n context.set('lastPeak',0);\n newMsg = {\n payload: {\n \"CarbonDioxideLevel\":0,\n \"CarbonDioxidePeakLevel\":0,\n \"CarbonDioxideDetected\":0\n }\n };\n return newMsg;\n}\n\n// Initialize vars\nvar CurrentLevel = 0;\nvar lastPeak = context.get('lastPeak');\n\n// Set random safe or dangerous levels\nif(msg.payload === \"Safe\"){\n CurrentLevel = Math.floor(Math.random() * (999 - 1 + 1) + 1);\n}\nif(msg.payload === \"Danger\"){\n CurrentLevel = Math.floor(Math.random() * (100000 - 1000 + 1) + 1000);\n}\n\n// Formulate output message\nvar newMsg = {\n payload: {\n \"CarbonDioxideLevel\" : CurrentLevel,\n \"CarbonDioxideDetected\" : 0\n }\n};\n\n// Set new peak level\nif(CurrentLevel > lastPeak){\n lastPeak = CurrentLevel;\n context.set('lastPeak',CurrentLevel);\n newMsg.payload.CarbonDioxidePeakLevel = CurrentLevel;\n}\n\n// Set warning if dangerous\nif (CurrentLevel >= 1000) {\n newMsg.payload.CarbonDioxideDetected = 1;\n} \n\nreturn newMsg;",
- "outputs": 1,
- "noerr": 0,
- "initialize": "// Code added here will be run once\n// whenever the node is deployed.\ncontext.set('lastPeak',0);\n",
- "finalize": "",
- "x": 400,
- "y": 880,
- "wires": [
- [
- "88892b4.8a61bd8"
- ]
- ]
- },
- {
- "id": "62cafcb0.8ade9c",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "ab48426e.25466",
- "name": "Active",
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"StatusActive\":true}",
- "payloadType": "json",
- "x": 470,
- "y": 920,
- "wires": [
- [
- "88892b4.8a61bd8"
- ]
- ]
- },
- {
- "id": "a0171cdb.f209b",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "ab48426e.25466",
- "name": "Inactive",
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"StatusActive\":false}",
- "payloadType": "json",
- "x": 470,
- "y": 960,
- "wires": [
- [
- "88892b4.8a61bd8"
- ]
- ]
- },
- {
- "id": "6f7de764.a6a688",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "ab48426e.25466",
- "name": "NO RESPONSE",
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"CarbonDioxideLevel\":\"NO_RESPONSE\"}",
- "payloadType": "json",
- "x": 440,
- "y": 1000,
- "wires": [
- [
- "88892b4.8a61bd8"
- ]
- ]
- },
- {
- "id": "8758b463.afb0f",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "ab48426e.25466",
- "name": "0 ppm",
- "props": [
- {
- "p": "payload"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "0",
- "payloadType": "num",
- "x": 110,
- "y": 880,
- "wires": [
- [
- "3611c654.8a42f2"
- ]
- ]
- },
- {
- "id": "69e8161b.74b7a",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "ab48426e.25466",
- "name": "Safe Level",
- "props": [
- {
- "p": "payload"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "Safe",
- "payloadType": "str",
- "x": 120,
- "y": 920,
- "wires": [
- [
- "3611c654.8a42f2"
- ]
- ]
- },
- {
- "id": "40010b09.c73cdc",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "ab48426e.25466",
- "name": "Dangerous level",
- "props": [
- {
- "p": "payload"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "Danger",
- "payloadType": "str",
- "x": 140,
- "y": 960,
- "wires": [
- [
- "3611c654.8a42f2"
- ]
- ]
- },
- {
- "id": "409001a1.3e7a78",
- "type": "homekit-bridge",
- "z": "",
- "bridgeName": "Demo 1",
- "pinCode": "153-10-538",
- "port": "",
- "allowInsecureRequest": false,
- "manufacturer": "NRCHKB",
- "model": "Demo",
- "serialNo": "1.1.2",
- "customMdnsConfig": false,
- "mdnsMulticast": true,
- "mdnsInterface": "",
- "mdnsPort": "",
- "mdnsIp": "",
- "mdnsTtl": "",
- "mdnsLoopback": true,
- "mdnsReuseAddr": true,
- "allowMessagePassthrough": true
- }
+ "nodes": [
+ "88892b4.8a61bd8",
+ "3611c654.8a42f2",
+ "62cafcb0.8ade9c",
+ "a0171cdb.f209b",
+ "6f7de764.a6a688",
+ "8758b463.afb0f",
+ "69e8161b.74b7a",
+ "40010b09.c73cdc"
+ ],
+ "x": 14,
+ "y": 839,
+ "w": 752,
+ "h": 202,
+ "info": "# CO2 Sensor\n\nThere are three inputs to this example, one for each level of Carbon Dioxide in the air. Options are:\n\n**0 ppm:** this will assume no CO2
\n**Safe level:** this will assume a level between 1 and 999 ppm, inclusive
\n**Dangerous level:** this will assume a level between 1,000 and 100,000, inclusive; this will also trigger an alert"
+ },
+ {
+ "id": "88892b4.8a61bd8",
+ "type": "homekit-service",
+ "z": "60b06629.a2ebd",
+ "g": "ab48426e.25466",
+ "isParent": true,
+ "bridge": "409001a1.3e7a78",
+ "parentService": "",
+ "name": "CO2 Sensor",
+ "serviceName": "CarbonDioxideSensor",
+ "topic": "",
+ "filter": false,
+ "manufacturer": "Default Manufacturer",
+ "model": "Carbon",
+ "serialNo": "Default Serial Number",
+ "firmwareRev": "22",
+ "hardwareRev": "11",
+ "cameraConfigVideoProcessor": "",
+ "cameraConfigSource": "",
+ "cameraConfigStillImageSource": "",
+ "cameraConfigMaxStreams": "",
+ "cameraConfigMaxWidth": "",
+ "cameraConfigMaxHeight": "",
+ "cameraConfigMaxFPS": "",
+ "cameraConfigMaxBitrate": "",
+ "cameraConfigVideoCodec": "",
+ "cameraConfigAudioCodec": "",
+ "cameraConfigAudio": false,
+ "cameraConfigPacketSize": "",
+ "cameraConfigVerticalFlip": false,
+ "cameraConfigHorizontalFlip": false,
+ "cameraConfigMapVideo": "",
+ "cameraConfigMapAudio": "",
+ "cameraConfigVideoFilter": "",
+ "cameraConfigAdditionalCommandLine": "",
+ "cameraConfigDebug": false,
+ "cameraConfigSnapshotOutput": "disabled",
+ "cameraConfigInterfaceName": "",
+ "characteristicProperties": "{\n \"CarbonDioxideLevel\" : true,\n \"CarbonDioxidePeakLevel\": true,\n \"StatusActive\" : true\n}",
+ "outputs": 2,
+ "x": 670,
+ "y": 880,
+ "wires": [[], []]
+ },
+ {
+ "id": "3611c654.8a42f2",
+ "type": "function",
+ "z": "60b06629.a2ebd",
+ "g": "ab48426e.25466",
+ "name": "Random values, peak value",
+ "func": "// Reset all values to 0 if 0ppm input\nif(msg.payload === 0){\n context.set('lastPeak',0);\n newMsg = {\n payload: {\n \"CarbonDioxideLevel\":0,\n \"CarbonDioxidePeakLevel\":0,\n \"CarbonDioxideDetected\":0\n }\n };\n return newMsg;\n}\n\n// Initialize vars\nvar CurrentLevel = 0;\nvar lastPeak = context.get('lastPeak');\n\n// Set random safe or dangerous levels\nif(msg.payload === \"Safe\"){\n CurrentLevel = Math.floor(Math.random() * (999 - 1 + 1) + 1);\n}\nif(msg.payload === \"Danger\"){\n CurrentLevel = Math.floor(Math.random() * (100000 - 1000 + 1) + 1000);\n}\n\n// Formulate output message\nvar newMsg = {\n payload: {\n \"CarbonDioxideLevel\" : CurrentLevel,\n \"CarbonDioxideDetected\" : 0\n }\n};\n\n// Set new peak level\nif(CurrentLevel > lastPeak){\n lastPeak = CurrentLevel;\n context.set('lastPeak',CurrentLevel);\n newMsg.payload.CarbonDioxidePeakLevel = CurrentLevel;\n}\n\n// Set warning if dangerous\nif (CurrentLevel >= 1000) {\n newMsg.payload.CarbonDioxideDetected = 1;\n} \n\nreturn newMsg;",
+ "outputs": 1,
+ "noerr": 0,
+ "initialize": "// Code added here will be run once\n// whenever the node is deployed.\ncontext.set('lastPeak',0);\n",
+ "finalize": "",
+ "x": 400,
+ "y": 880,
+ "wires": [["88892b4.8a61bd8"]]
+ },
+ {
+ "id": "62cafcb0.8ade9c",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "ab48426e.25466",
+ "name": "Active",
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"StatusActive\":true}",
+ "payloadType": "json",
+ "x": 470,
+ "y": 920,
+ "wires": [["88892b4.8a61bd8"]]
+ },
+ {
+ "id": "a0171cdb.f209b",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "ab48426e.25466",
+ "name": "Inactive",
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"StatusActive\":false}",
+ "payloadType": "json",
+ "x": 470,
+ "y": 960,
+ "wires": [["88892b4.8a61bd8"]]
+ },
+ {
+ "id": "6f7de764.a6a688",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "ab48426e.25466",
+ "name": "NO RESPONSE",
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"CarbonDioxideLevel\":\"NO_RESPONSE\"}",
+ "payloadType": "json",
+ "x": 440,
+ "y": 1000,
+ "wires": [["88892b4.8a61bd8"]]
+ },
+ {
+ "id": "8758b463.afb0f",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "ab48426e.25466",
+ "name": "0 ppm",
+ "props": [
+ {
+ "p": "payload"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "0",
+ "payloadType": "num",
+ "x": 110,
+ "y": 880,
+ "wires": [["3611c654.8a42f2"]]
+ },
+ {
+ "id": "69e8161b.74b7a",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "ab48426e.25466",
+ "name": "Safe Level",
+ "props": [
+ {
+ "p": "payload"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "Safe",
+ "payloadType": "str",
+ "x": 120,
+ "y": 920,
+ "wires": [["3611c654.8a42f2"]]
+ },
+ {
+ "id": "40010b09.c73cdc",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "ab48426e.25466",
+ "name": "Dangerous level",
+ "props": [
+ {
+ "p": "payload"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "Danger",
+ "payloadType": "str",
+ "x": 140,
+ "y": 960,
+ "wires": [["3611c654.8a42f2"]]
+ },
+ {
+ "id": "409001a1.3e7a78",
+ "type": "homekit-bridge",
+ "z": "",
+ "bridgeName": "Demo 1",
+ "pinCode": "153-10-538",
+ "port": "",
+ "allowInsecureRequest": false,
+ "manufacturer": "NRCHKB",
+ "model": "Demo",
+ "serialNo": "1.1.2",
+ "customMdnsConfig": false,
+ "mdnsMulticast": true,
+ "mdnsInterface": "",
+ "mdnsPort": "",
+ "mdnsIp": "",
+ "mdnsTtl": "",
+ "mdnsLoopback": true,
+ "mdnsReuseAddr": true,
+ "allowMessagePassthrough": true
+ }
]
diff --git a/examples/demo/09 - CO (carbon monoxide) example.json b/examples/demo/09 - CO (carbon monoxide) example.json
index 983c94fb..5bf71f6e 100644
--- a/examples/demo/09 - CO (carbon monoxide) example.json
+++ b/examples/demo/09 - CO (carbon monoxide) example.json
@@ -1,293 +1,258 @@
[
- {
- "id": "6eaa9b9e.282734",
- "type": "group",
- "z": "60b06629.a2ebd",
- "name": "CO plus CO2 Sensor: input only sensor",
- "style": {
- "stroke": "#999999",
- "fill": "none",
- "label": true,
- "label-position": "nw",
- "color": "#a4a4a4"
- },
- "nodes": [
- "2e6738a6.ef5dd8",
- "79889759.8219c",
- "7f53465b.356a68",
- "97aff586.786ff8",
- "659ff3da.236404",
- "e6105066.f8911",
- "b433a780.665a7",
- "d4b30334.a19e58",
- "b0eeeb34.2dde8"
- ],
- "x": 14,
- "y": 1059,
- "w": 752,
- "h": 282,
- "info": "# Combined Sensor\nThis is a sensor which will display both Carbon Monoxide (poisonous, deadly gas) and Carbon Dioxide (what humans exhale) levels.\n\n# CO Sensor\n\nThere are three inputs to this example, one for each level of Carbon Monoxide in the air. Options are:\n\n**0 ppm:** this will assume no CO in the air
\n**Low level:** this will assume a level between 1 and 35 ppm, inclusive. This level is generally assumed to not cause problems in healthy adults
\n**Dangerous level:** this will assume a level between 35 and 5000, inclusive; this will also trigger an alert in Home app\n\n## IF YOU HAVE A CARBON MONOXIDE DETECTOR EVER READING ABOVE 35 PPM, PLEASE EVACUATE THE AREA AND SEEK FRESH AIR IMMEDIATELY TO AVOID RISK OF DEATH ##\n\n# CO2 Sensor\n\nThere are three inputs to this example, one for each level of Carbon Dioxide in the air. Options are:\n\n**0 ppm:** this will assume no CO2 in the air
\n**CO2 Level:** this will assume a level between 1 and 100,000 ppm, inclusive
\n**Dangerous level:** this will assume a level between 1,000 and 100,000, inclusive\n\n"
+ {
+ "id": "6eaa9b9e.282734",
+ "type": "group",
+ "z": "60b06629.a2ebd",
+ "name": "CO plus CO2 Sensor: input only sensor",
+ "style": {
+ "stroke": "#999999",
+ "fill": "none",
+ "label": true,
+ "label-position": "nw",
+ "color": "#a4a4a4"
},
- {
- "id": "2e6738a6.ef5dd8",
- "type": "homekit-service",
- "z": "60b06629.a2ebd",
- "g": "6eaa9b9e.282734",
- "isParent": true,
- "bridge": "409001a1.3e7a78",
- "parentService": "",
- "name": "CO detector",
- "serviceName": "CarbonMonoxideSensor",
- "topic": "",
- "filter": false,
- "manufacturer": "MONOxide",
- "model": "1",
- "serialNo": "2",
- "firmwareRev": "2",
- "hardwareRev": "2",
- "softwareRev": "1.0.0",
- "cameraConfigVideoProcessor": "ffmpeg",
- "cameraConfigSource": "",
- "cameraConfigStillImageSource": "",
- "cameraConfigMaxStreams": 2,
- "cameraConfigMaxWidth": 1280,
- "cameraConfigMaxHeight": 720,
- "cameraConfigMaxFPS": 10,
- "cameraConfigMaxBitrate": 300,
- "cameraConfigVideoCodec": "libx264",
- "cameraConfigAudioCodec": "libfdk_aac",
- "cameraConfigAudio": false,
- "cameraConfigPacketSize": 1316,
- "cameraConfigVerticalFlip": false,
- "cameraConfigHorizontalFlip": false,
- "cameraConfigMapVideo": "0:0",
- "cameraConfigMapAudio": "0:1",
- "cameraConfigVideoFilter": "scale=1280:720",
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
- "cameraConfigDebug": false,
- "cameraConfigSnapshotOutput": "disabled",
- "cameraConfigInterfaceName": "",
- "characteristicProperties": "{\n \"CarbonMonoxideLevel\":{\n \"maxValue\":5000\n },\n \"CarbonMonoxidePeakLevel\":{\n \"maxValue\":5000\n },\n \"CarbonDioxideLevel\":true,\n \"CarbonDioxidePeakLevel\":true\n}",
- "outputs": 2,
- "x": 670,
- "y": 1100,
- "wires": [
- [],
- []
- ]
- },
- {
- "id": "79889759.8219c",
- "type": "function",
- "z": "60b06629.a2ebd",
- "g": "6eaa9b9e.282734",
- "name": "Carbon DIoxide",
- "func": "if(msg.payload === 0){\n context.set('lastPeak',0);\n newMsg = {\n payload: {\n \"CarbonDioxideLevel\":0\n }\n }\n return newMsg;\n}\n\n// Initialize vars\nvar CurrentLevel = 0;\nvar lastPeak = context.get('lastPeak');\n\n// Set random level\nif(msg.payload === \"CO2\"){\n CurrentLevel = Math.floor(Math.random() * (100000 - 1 + 1) + 1);\n}\n\n\n// Formulate output message\nvar newMsg = {\n payload: {\n \"CarbonDioxideLevel\" : CurrentLevel\n }\n};\n\n// Set new peak level\nif(CurrentLevel > lastPeak){\n lastPeak = CurrentLevel;\n context.set('lastPeak',CurrentLevel);\n newMsg.payload.CarbonDioxidePeakLevel = CurrentLevel;\n}\n\nreturn newMsg;",
- "outputs": 1,
- "noerr": 0,
- "initialize": "// Code added here will be run once\n// whenever the node is deployed.\ncontext.set('lastPeak',0);",
- "finalize": "",
- "x": 380,
- "y": 1260,
- "wires": [
- [
- "2e6738a6.ef5dd8"
- ]
- ]
- },
- {
- "id": "7f53465b.356a68",
- "type": "function",
- "z": "60b06629.a2ebd",
- "g": "6eaa9b9e.282734",
- "name": "Carbon MONoxide",
- "func": "// Reset all values to 0 if 0ppm input\nif(msg.payload === 0){\n context.set('lastPeak',0);\n newMsg = {\n payload: {\n \"CarbonMonoxideLevel\":0,\n \"CarbonMonoxidePeakLevel\":0,\n \"CarbonMonoxideDetected\":0\n }\n };\n return newMsg;\n}\n\n// Initialize vars\nvar CurrentLevel = 0;\nvar lastPeak = context.get('lastPeak');\n\n// Set random Low or Dangerous levels\nif(msg.payload === \"Low\"){\n CurrentLevel = Math.floor(Math.random() * (35 - 1 + 1) + 1);\n}\nif(msg.payload === \"Danger\"){\n CurrentLevel = Math.floor(Math.random() * (5000 - 35 + 1) + 35);\n}\n\n// Formulate output message\nvar newMsg = {\n payload: {\n \"CarbonMonoxideLevel\" : CurrentLevel,\n \"CarbonMonoxideDetected\" : 0\n }\n};\n\n// Set new peak level\nif(CurrentLevel > lastPeak){\n lastPeak = CurrentLevel;\n context.set('lastPeak',CurrentLevel);\n newMsg.payload.CarbonMonoxidePeakLevel = CurrentLevel;\n}\n\n// Set warning if dangerous\nif (CurrentLevel >= 35) {\n newMsg.payload.CarbonMonoxideDetected = 1;\n} \n\nreturn newMsg;",
- "outputs": 1,
- "noerr": 0,
- "initialize": "",
- "finalize": "",
- "x": 390,
- "y": 1140,
- "wires": [
- [
- "2e6738a6.ef5dd8"
- ]
- ]
- },
- {
- "id": "97aff586.786ff8",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "6eaa9b9e.282734",
- "name": "NO RESPONSE",
- "props": [
- {
- "p": "payload"
- },
- {
- "p": "topic",
- "vt": "str"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"CarbonMonoxideLevel\":\"NO_RESPONSE\"}",
- "payloadType": "json",
- "x": 400,
- "y": 1100,
- "wires": [
- [
- "2e6738a6.ef5dd8"
- ]
- ]
- },
- {
- "id": "659ff3da.236404",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "6eaa9b9e.282734",
- "name": "Clear CO2 Peak",
- "props": [
- {
- "p": "payload"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "0",
- "payloadType": "num",
- "x": 140,
- "y": 1260,
- "wires": [
- [
- "79889759.8219c"
- ]
- ]
- },
- {
- "id": "e6105066.f8911",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "6eaa9b9e.282734",
- "name": "0 ppm",
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "0",
- "payloadType": "num",
- "x": 130,
- "y": 1100,
- "wires": [
- [
- "7f53465b.356a68"
- ]
- ]
- },
- {
- "id": "b433a780.665a7",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "6eaa9b9e.282734",
- "name": "CO2 Level",
- "props": [
- {
- "p": "payload"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "CO2",
- "payloadType": "str",
- "x": 120,
- "y": 1300,
- "wires": [
- [
- "79889759.8219c"
- ]
- ]
- },
- {
- "id": "d4b30334.a19e58",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "6eaa9b9e.282734",
- "name": "Low level",
- "props": [
- {
- "p": "payload"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "Low",
- "payloadType": "str",
- "x": 140,
- "y": 1140,
- "wires": [
- [
- "7f53465b.356a68"
- ]
- ]
- },
- {
- "id": "b0eeeb34.2dde8",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "6eaa9b9e.282734",
- "name": "Danger level",
- "props": [
- {
- "p": "payload"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "Danger",
- "payloadType": "str",
- "x": 150,
- "y": 1180,
- "wires": [
- [
- "7f53465b.356a68"
- ]
- ]
- },
- {
- "id": "409001a1.3e7a78",
- "type": "homekit-bridge",
- "z": "",
- "bridgeName": "Demo 1",
- "pinCode": "153-10-538",
- "port": "",
- "allowInsecureRequest": false,
- "manufacturer": "NRCHKB",
- "model": "Demo",
- "serialNo": "1.1.2",
- "customMdnsConfig": false,
- "mdnsMulticast": true,
- "mdnsInterface": "",
- "mdnsPort": "",
- "mdnsIp": "",
- "mdnsTtl": "",
- "mdnsLoopback": true,
- "mdnsReuseAddr": true,
- "allowMessagePassthrough": true
- }
+ "nodes": [
+ "2e6738a6.ef5dd8",
+ "79889759.8219c",
+ "7f53465b.356a68",
+ "97aff586.786ff8",
+ "659ff3da.236404",
+ "e6105066.f8911",
+ "b433a780.665a7",
+ "d4b30334.a19e58",
+ "b0eeeb34.2dde8"
+ ],
+ "x": 14,
+ "y": 1059,
+ "w": 752,
+ "h": 282,
+ "info": "# Combined Sensor\nThis is a sensor which will display both Carbon Monoxide (poisonous, deadly gas) and Carbon Dioxide (what humans exhale) levels.\n\n# CO Sensor\n\nThere are three inputs to this example, one for each level of Carbon Monoxide in the air. Options are:\n\n**0 ppm:** this will assume no CO in the air
\n**Low level:** this will assume a level between 1 and 35 ppm, inclusive. This level is generally assumed to not cause problems in healthy adults
\n**Dangerous level:** this will assume a level between 35 and 5000, inclusive; this will also trigger an alert in Home app\n\n## IF YOU HAVE A CARBON MONOXIDE DETECTOR EVER READING ABOVE 35 PPM, PLEASE EVACUATE THE AREA AND SEEK FRESH AIR IMMEDIATELY TO AVOID RISK OF DEATH ##\n\n# CO2 Sensor\n\nThere are three inputs to this example, one for each level of Carbon Dioxide in the air. Options are:\n\n**0 ppm:** this will assume no CO2 in the air
\n**CO2 Level:** this will assume a level between 1 and 100,000 ppm, inclusive
\n**Dangerous level:** this will assume a level between 1,000 and 100,000, inclusive\n\n"
+ },
+ {
+ "id": "2e6738a6.ef5dd8",
+ "type": "homekit-service",
+ "z": "60b06629.a2ebd",
+ "g": "6eaa9b9e.282734",
+ "isParent": true,
+ "bridge": "409001a1.3e7a78",
+ "parentService": "",
+ "name": "CO detector",
+ "serviceName": "CarbonMonoxideSensor",
+ "topic": "",
+ "filter": false,
+ "manufacturer": "MONOxide",
+ "model": "1",
+ "serialNo": "2",
+ "firmwareRev": "2",
+ "hardwareRev": "2",
+ "softwareRev": "1.0.0",
+ "cameraConfigVideoProcessor": "ffmpeg",
+ "cameraConfigSource": "",
+ "cameraConfigStillImageSource": "",
+ "cameraConfigMaxStreams": 2,
+ "cameraConfigMaxWidth": 1280,
+ "cameraConfigMaxHeight": 720,
+ "cameraConfigMaxFPS": 10,
+ "cameraConfigMaxBitrate": 300,
+ "cameraConfigVideoCodec": "libx264",
+ "cameraConfigAudioCodec": "libfdk_aac",
+ "cameraConfigAudio": false,
+ "cameraConfigPacketSize": 1316,
+ "cameraConfigVerticalFlip": false,
+ "cameraConfigHorizontalFlip": false,
+ "cameraConfigMapVideo": "0:0",
+ "cameraConfigMapAudio": "0:1",
+ "cameraConfigVideoFilter": "scale=1280:720",
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
+ "cameraConfigDebug": false,
+ "cameraConfigSnapshotOutput": "disabled",
+ "cameraConfigInterfaceName": "",
+ "characteristicProperties": "{\n \"CarbonMonoxideLevel\":{\n \"maxValue\":5000\n },\n \"CarbonMonoxidePeakLevel\":{\n \"maxValue\":5000\n },\n \"CarbonDioxideLevel\":true,\n \"CarbonDioxidePeakLevel\":true\n}",
+ "outputs": 2,
+ "x": 670,
+ "y": 1100,
+ "wires": [[], []]
+ },
+ {
+ "id": "79889759.8219c",
+ "type": "function",
+ "z": "60b06629.a2ebd",
+ "g": "6eaa9b9e.282734",
+ "name": "Carbon DIoxide",
+ "func": "if(msg.payload === 0){\n context.set('lastPeak',0);\n newMsg = {\n payload: {\n \"CarbonDioxideLevel\":0\n }\n }\n return newMsg;\n}\n\n// Initialize vars\nvar CurrentLevel = 0;\nvar lastPeak = context.get('lastPeak');\n\n// Set random level\nif(msg.payload === \"CO2\"){\n CurrentLevel = Math.floor(Math.random() * (100000 - 1 + 1) + 1);\n}\n\n\n// Formulate output message\nvar newMsg = {\n payload: {\n \"CarbonDioxideLevel\" : CurrentLevel\n }\n};\n\n// Set new peak level\nif(CurrentLevel > lastPeak){\n lastPeak = CurrentLevel;\n context.set('lastPeak',CurrentLevel);\n newMsg.payload.CarbonDioxidePeakLevel = CurrentLevel;\n}\n\nreturn newMsg;",
+ "outputs": 1,
+ "noerr": 0,
+ "initialize": "// Code added here will be run once\n// whenever the node is deployed.\ncontext.set('lastPeak',0);",
+ "finalize": "",
+ "x": 380,
+ "y": 1260,
+ "wires": [["2e6738a6.ef5dd8"]]
+ },
+ {
+ "id": "7f53465b.356a68",
+ "type": "function",
+ "z": "60b06629.a2ebd",
+ "g": "6eaa9b9e.282734",
+ "name": "Carbon MONoxide",
+ "func": "// Reset all values to 0 if 0ppm input\nif(msg.payload === 0){\n context.set('lastPeak',0);\n newMsg = {\n payload: {\n \"CarbonMonoxideLevel\":0,\n \"CarbonMonoxidePeakLevel\":0,\n \"CarbonMonoxideDetected\":0\n }\n };\n return newMsg;\n}\n\n// Initialize vars\nvar CurrentLevel = 0;\nvar lastPeak = context.get('lastPeak');\n\n// Set random Low or Dangerous levels\nif(msg.payload === \"Low\"){\n CurrentLevel = Math.floor(Math.random() * (35 - 1 + 1) + 1);\n}\nif(msg.payload === \"Danger\"){\n CurrentLevel = Math.floor(Math.random() * (5000 - 35 + 1) + 35);\n}\n\n// Formulate output message\nvar newMsg = {\n payload: {\n \"CarbonMonoxideLevel\" : CurrentLevel,\n \"CarbonMonoxideDetected\" : 0\n }\n};\n\n// Set new peak level\nif(CurrentLevel > lastPeak){\n lastPeak = CurrentLevel;\n context.set('lastPeak',CurrentLevel);\n newMsg.payload.CarbonMonoxidePeakLevel = CurrentLevel;\n}\n\n// Set warning if dangerous\nif (CurrentLevel >= 35) {\n newMsg.payload.CarbonMonoxideDetected = 1;\n} \n\nreturn newMsg;",
+ "outputs": 1,
+ "noerr": 0,
+ "initialize": "",
+ "finalize": "",
+ "x": 390,
+ "y": 1140,
+ "wires": [["2e6738a6.ef5dd8"]]
+ },
+ {
+ "id": "97aff586.786ff8",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "6eaa9b9e.282734",
+ "name": "NO RESPONSE",
+ "props": [
+ {
+ "p": "payload"
+ },
+ {
+ "p": "topic",
+ "vt": "str"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"CarbonMonoxideLevel\":\"NO_RESPONSE\"}",
+ "payloadType": "json",
+ "x": 400,
+ "y": 1100,
+ "wires": [["2e6738a6.ef5dd8"]]
+ },
+ {
+ "id": "659ff3da.236404",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "6eaa9b9e.282734",
+ "name": "Clear CO2 Peak",
+ "props": [
+ {
+ "p": "payload"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "0",
+ "payloadType": "num",
+ "x": 140,
+ "y": 1260,
+ "wires": [["79889759.8219c"]]
+ },
+ {
+ "id": "e6105066.f8911",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "6eaa9b9e.282734",
+ "name": "0 ppm",
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "0",
+ "payloadType": "num",
+ "x": 130,
+ "y": 1100,
+ "wires": [["7f53465b.356a68"]]
+ },
+ {
+ "id": "b433a780.665a7",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "6eaa9b9e.282734",
+ "name": "CO2 Level",
+ "props": [
+ {
+ "p": "payload"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "CO2",
+ "payloadType": "str",
+ "x": 120,
+ "y": 1300,
+ "wires": [["79889759.8219c"]]
+ },
+ {
+ "id": "d4b30334.a19e58",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "6eaa9b9e.282734",
+ "name": "Low level",
+ "props": [
+ {
+ "p": "payload"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "Low",
+ "payloadType": "str",
+ "x": 140,
+ "y": 1140,
+ "wires": [["7f53465b.356a68"]]
+ },
+ {
+ "id": "b0eeeb34.2dde8",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "6eaa9b9e.282734",
+ "name": "Danger level",
+ "props": [
+ {
+ "p": "payload"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "Danger",
+ "payloadType": "str",
+ "x": 150,
+ "y": 1180,
+ "wires": [["7f53465b.356a68"]]
+ },
+ {
+ "id": "409001a1.3e7a78",
+ "type": "homekit-bridge",
+ "z": "",
+ "bridgeName": "Demo 1",
+ "pinCode": "153-10-538",
+ "port": "",
+ "allowInsecureRequest": false,
+ "manufacturer": "NRCHKB",
+ "model": "Demo",
+ "serialNo": "1.1.2",
+ "customMdnsConfig": false,
+ "mdnsMulticast": true,
+ "mdnsInterface": "",
+ "mdnsPort": "",
+ "mdnsIp": "",
+ "mdnsTtl": "",
+ "mdnsLoopback": true,
+ "mdnsReuseAddr": true,
+ "allowMessagePassthrough": true
+ }
]
diff --git a/examples/demo/10 - Door window contact sensor.json b/examples/demo/10 - Door window contact sensor.json
index 10de5934..32fd056b 100644
--- a/examples/demo/10 - Door window contact sensor.json
+++ b/examples/demo/10 - Door window contact sensor.json
@@ -1,268 +1,237 @@
[
- {
- "id": "a875cc7.a4c42b",
- "type": "group",
- "z": "60b06629.a2ebd",
- "name": "Contact Sensor: input only sensor",
- "style": {
- "stroke": "#999999",
- "fill": "none",
- "label": true,
- "label-position": "nw",
- "color": "#a4a4a4"
- },
- "nodes": [
- "a5194c26.18c628",
- "2f9bc0d.42a73c",
- "dfca0b2d.8b8e8",
- "d74a610c.09a36",
- "c15b6468.ae2eb8",
- "6f7bc7fa.7f4f6",
- "99b55eb3.e31bf8",
- "508d9ccf.29e404"
- ],
- "x": 14,
- "y": 1359,
- "w": 752,
- "h": 242,
- "info": "# Contact Sensor\n\nThe contact sensor has one inject node to Open the sensor (door, window, etc). Once open, a ten second timer will run then set it back to closed.\n\nAdditional inputs are for \"No Response\", \"Tampered\", and \"Battery\". Note that this battery will not show a battery level but only a good/low battery status."
+ {
+ "id": "a875cc7.a4c42b",
+ "type": "group",
+ "z": "60b06629.a2ebd",
+ "name": "Contact Sensor: input only sensor",
+ "style": {
+ "stroke": "#999999",
+ "fill": "none",
+ "label": true,
+ "label-position": "nw",
+ "color": "#a4a4a4"
},
- {
- "id": "a5194c26.18c628",
- "type": "homekit-service",
- "z": "60b06629.a2ebd",
- "g": "a875cc7.a4c42b",
- "isParent": true,
- "bridge": "409001a1.3e7a78",
- "parentService": "",
- "name": "Contact Sensor",
- "serviceName": "ContactSensor",
- "topic": "",
- "filter": false,
- "manufacturer": "Full Contact",
- "model": "Door",
- "serialNo": "Sensor",
- "firmwareRev": "1.0.0",
- "hardwareRev": "1.0.0",
- "softwareRev": "1.0.0",
- "cameraConfigVideoProcessor": "ffmpeg",
- "cameraConfigSource": "",
- "cameraConfigStillImageSource": "",
- "cameraConfigMaxStreams": 2,
- "cameraConfigMaxWidth": 1280,
- "cameraConfigMaxHeight": 720,
- "cameraConfigMaxFPS": 10,
- "cameraConfigMaxBitrate": 300,
- "cameraConfigVideoCodec": "libx264",
- "cameraConfigAudioCodec": "libfdk_aac",
- "cameraConfigAudio": false,
- "cameraConfigPacketSize": 1316,
- "cameraConfigVerticalFlip": false,
- "cameraConfigHorizontalFlip": false,
- "cameraConfigMapVideo": "0:0",
- "cameraConfigMapAudio": "0:1",
- "cameraConfigVideoFilter": "scale=1280:720",
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
- "cameraConfigDebug": false,
- "cameraConfigSnapshotOutput": "disabled",
- "cameraConfigInterfaceName": "",
- "characteristicProperties": "{\n \"StatusTampered\":true,\n \"StatusLowBattery\":true\n}",
- "outputs": 2,
- "x": 660,
- "y": 1400,
- "wires": [
- [],
- []
- ]
- },
- {
- "id": "2f9bc0d.42a73c",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "a875cc7.a4c42b",
- "name": "Tampered",
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"StatusTampered\":1}",
- "payloadType": "json",
- "x": 120,
- "y": 1520,
- "wires": [
- [
- "a5194c26.18c628"
- ]
- ]
- },
- {
- "id": "dfca0b2d.8b8e8",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "a875cc7.a4c42b",
- "name": "Clear tampered",
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"StatusTampered\":0}",
- "payloadType": "json",
- "x": 140,
- "y": 1560,
- "wires": [
- [
- "a5194c26.18c628"
- ]
- ]
- },
- {
- "id": "d74a610c.09a36",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "a875cc7.a4c42b",
- "name": "Low batt",
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"StatusLowBattery\":1}",
- "payloadType": "json",
- "x": 480,
- "y": 1520,
- "wires": [
- [
- "a5194c26.18c628"
- ]
- ]
- },
- {
- "id": "c15b6468.ae2eb8",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "a875cc7.a4c42b",
- "name": "Good batt",
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"StatusLowBattery\":0}",
- "payloadType": "json",
- "x": 480,
- "y": 1560,
- "wires": [
- [
- "a5194c26.18c628"
- ]
- ]
- },
- {
- "id": "6f7bc7fa.7f4f6",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "a875cc7.a4c42b",
- "name": "NO RESPONSE",
- "props": [
- {
- "p": "payload"
- },
- {
- "p": "topic",
- "vt": "str"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"ContactSensorState\":\"NO_RESPONSE\"}",
- "payloadType": "json",
- "x": 140,
- "y": 1460,
- "wires": [
- [
- "a5194c26.18c628"
- ]
- ]
- },
- {
- "id": "99b55eb3.e31bf8",
- "type": "trigger",
- "z": "60b06629.a2ebd",
- "g": "a875cc7.a4c42b",
- "name": "10 Sec open",
- "op1": "",
- "op2": "{\"ContactSensorState\":0}",
- "op1type": "pay",
- "op2type": "json",
- "duration": "10",
- "extend": false,
- "units": "s",
- "reset": "",
- "bytopic": "all",
- "topic": "topic",
- "outputs": 1,
- "x": 350,
- "y": 1400,
- "wires": [
- [
- "a5194c26.18c628"
- ]
- ]
- },
- {
- "id": "508d9ccf.29e404",
- "type": "inject",
- "z": "60b06629.a2ebd",
- "g": "a875cc7.a4c42b",
- "name": "Open",
- "props": [
- {
- "p": "payload"
- },
- {
- "p": "topic",
- "vt": "str"
- }
- ],
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": "1",
- "topic": "",
- "payload": "{\"ContactSensorState\":1}",
- "payloadType": "json",
- "x": 110,
- "y": 1400,
- "wires": [
- [
- "99b55eb3.e31bf8"
- ]
- ]
- },
- {
- "id": "409001a1.3e7a78",
- "type": "homekit-bridge",
- "z": "",
- "bridgeName": "Demo 1",
- "pinCode": "153-10-538",
- "port": "",
- "allowInsecureRequest": false,
- "manufacturer": "NRCHKB",
- "model": "Demo",
- "serialNo": "1.1.2",
- "customMdnsConfig": false,
- "mdnsMulticast": true,
- "mdnsInterface": "",
- "mdnsPort": "",
- "mdnsIp": "",
- "mdnsTtl": "",
- "mdnsLoopback": true,
- "mdnsReuseAddr": true,
- "allowMessagePassthrough": true
- }
+ "nodes": [
+ "a5194c26.18c628",
+ "2f9bc0d.42a73c",
+ "dfca0b2d.8b8e8",
+ "d74a610c.09a36",
+ "c15b6468.ae2eb8",
+ "6f7bc7fa.7f4f6",
+ "99b55eb3.e31bf8",
+ "508d9ccf.29e404"
+ ],
+ "x": 14,
+ "y": 1359,
+ "w": 752,
+ "h": 242,
+ "info": "# Contact Sensor\n\nThe contact sensor has one inject node to Open the sensor (door, window, etc). Once open, a ten second timer will run then set it back to closed.\n\nAdditional inputs are for \"No Response\", \"Tampered\", and \"Battery\". Note that this battery will not show a battery level but only a good/low battery status."
+ },
+ {
+ "id": "a5194c26.18c628",
+ "type": "homekit-service",
+ "z": "60b06629.a2ebd",
+ "g": "a875cc7.a4c42b",
+ "isParent": true,
+ "bridge": "409001a1.3e7a78",
+ "parentService": "",
+ "name": "Contact Sensor",
+ "serviceName": "ContactSensor",
+ "topic": "",
+ "filter": false,
+ "manufacturer": "Full Contact",
+ "model": "Door",
+ "serialNo": "Sensor",
+ "firmwareRev": "1.0.0",
+ "hardwareRev": "1.0.0",
+ "softwareRev": "1.0.0",
+ "cameraConfigVideoProcessor": "ffmpeg",
+ "cameraConfigSource": "",
+ "cameraConfigStillImageSource": "",
+ "cameraConfigMaxStreams": 2,
+ "cameraConfigMaxWidth": 1280,
+ "cameraConfigMaxHeight": 720,
+ "cameraConfigMaxFPS": 10,
+ "cameraConfigMaxBitrate": 300,
+ "cameraConfigVideoCodec": "libx264",
+ "cameraConfigAudioCodec": "libfdk_aac",
+ "cameraConfigAudio": false,
+ "cameraConfigPacketSize": 1316,
+ "cameraConfigVerticalFlip": false,
+ "cameraConfigHorizontalFlip": false,
+ "cameraConfigMapVideo": "0:0",
+ "cameraConfigMapAudio": "0:1",
+ "cameraConfigVideoFilter": "scale=1280:720",
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
+ "cameraConfigDebug": false,
+ "cameraConfigSnapshotOutput": "disabled",
+ "cameraConfigInterfaceName": "",
+ "characteristicProperties": "{\n \"StatusTampered\":true,\n \"StatusLowBattery\":true\n}",
+ "outputs": 2,
+ "x": 660,
+ "y": 1400,
+ "wires": [[], []]
+ },
+ {
+ "id": "2f9bc0d.42a73c",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "a875cc7.a4c42b",
+ "name": "Tampered",
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"StatusTampered\":1}",
+ "payloadType": "json",
+ "x": 120,
+ "y": 1520,
+ "wires": [["a5194c26.18c628"]]
+ },
+ {
+ "id": "dfca0b2d.8b8e8",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "a875cc7.a4c42b",
+ "name": "Clear tampered",
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"StatusTampered\":0}",
+ "payloadType": "json",
+ "x": 140,
+ "y": 1560,
+ "wires": [["a5194c26.18c628"]]
+ },
+ {
+ "id": "d74a610c.09a36",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "a875cc7.a4c42b",
+ "name": "Low batt",
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"StatusLowBattery\":1}",
+ "payloadType": "json",
+ "x": 480,
+ "y": 1520,
+ "wires": [["a5194c26.18c628"]]
+ },
+ {
+ "id": "c15b6468.ae2eb8",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "a875cc7.a4c42b",
+ "name": "Good batt",
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"StatusLowBattery\":0}",
+ "payloadType": "json",
+ "x": 480,
+ "y": 1560,
+ "wires": [["a5194c26.18c628"]]
+ },
+ {
+ "id": "6f7bc7fa.7f4f6",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "a875cc7.a4c42b",
+ "name": "NO RESPONSE",
+ "props": [
+ {
+ "p": "payload"
+ },
+ {
+ "p": "topic",
+ "vt": "str"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"ContactSensorState\":\"NO_RESPONSE\"}",
+ "payloadType": "json",
+ "x": 140,
+ "y": 1460,
+ "wires": [["a5194c26.18c628"]]
+ },
+ {
+ "id": "99b55eb3.e31bf8",
+ "type": "trigger",
+ "z": "60b06629.a2ebd",
+ "g": "a875cc7.a4c42b",
+ "name": "10 Sec open",
+ "op1": "",
+ "op2": "{\"ContactSensorState\":0}",
+ "op1type": "pay",
+ "op2type": "json",
+ "duration": "10",
+ "extend": false,
+ "units": "s",
+ "reset": "",
+ "bytopic": "all",
+ "topic": "topic",
+ "outputs": 1,
+ "x": 350,
+ "y": 1400,
+ "wires": [["a5194c26.18c628"]]
+ },
+ {
+ "id": "508d9ccf.29e404",
+ "type": "inject",
+ "z": "60b06629.a2ebd",
+ "g": "a875cc7.a4c42b",
+ "name": "Open",
+ "props": [
+ {
+ "p": "payload"
+ },
+ {
+ "p": "topic",
+ "vt": "str"
+ }
+ ],
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": "1",
+ "topic": "",
+ "payload": "{\"ContactSensorState\":1}",
+ "payloadType": "json",
+ "x": 110,
+ "y": 1400,
+ "wires": [["99b55eb3.e31bf8"]]
+ },
+ {
+ "id": "409001a1.3e7a78",
+ "type": "homekit-bridge",
+ "z": "",
+ "bridgeName": "Demo 1",
+ "pinCode": "153-10-538",
+ "port": "",
+ "allowInsecureRequest": false,
+ "manufacturer": "NRCHKB",
+ "model": "Demo",
+ "serialNo": "1.1.2",
+ "customMdnsConfig": false,
+ "mdnsMulticast": true,
+ "mdnsInterface": "",
+ "mdnsPort": "",
+ "mdnsIp": "",
+ "mdnsTtl": "",
+ "mdnsLoopback": true,
+ "mdnsReuseAddr": true,
+ "allowMessagePassthrough": true
+ }
]
diff --git a/examples/demos (advanced)/01 - Television with inputs and speaker.json b/examples/demos (advanced)/01 - Television with inputs and speaker.json
index a2d0238c..ed6d432e 100644
--- a/examples/demos (advanced)/01 - Television with inputs and speaker.json
+++ b/examples/demos (advanced)/01 - Television with inputs and speaker.json
@@ -1,611 +1,545 @@
[
- {
- "id": "a98abda4.5784d",
- "type": "group",
- "z": "21f36bce.02d864",
- "name": "Television: input from device, output to device",
- "style": {
- "stroke": "#999999",
- "fill": "none",
- "label": true,
- "label-position": "nw",
- "color": "#a4a4a4"
- },
- "nodes": [
- "894d3458.2f07d",
- "87183aa8.418ec",
- "519fe2f2.b4870c",
- "5de4624c.b2aeac",
- "d5812842.bebac",
- "ac7b78f3.2b9328",
- "1d662593.e8434a",
- "405055ca.02f2dc",
- "f164c3c9.de75e8",
- "d35fba0b.560e68",
- "da9f0bd6.b2bbf",
- "b4c4b8b.fc331c8",
- "56282414.102184",
- "f83a84cb.08b19"
- ],
- "x": 14,
- "y": 59,
- "w": 932,
- "h": 488,
- "info": "## Example With Speaker and 4 inputs\n\nThis example will show a television service with 4 inputs and a speaker (volume control). There are two functions that should be used to name your specific devices. These functions are `Setup TV` and `Setup Inputs`.\n\n**Setup TV:**\nThis function will be run 5 seconds after startup or whenever the `TV Setup` inject node is triggered. Change the name on line 1 of the function. The output message is sent to the Television Service to initialize the name and set the TV to `{\"Active\":0}` (TV off).\n\n**Setup Inputs:**\nThis function will be run 6 seconds after startup or whenever the `Source Setup` inject node is triggered. The following variables are available:\n* Lines 5 through 8 will name your sources\n* Lines 24 through 27 will set the input type according to the values in lines 11 through 21\n\n## Setting the HomeKit item based on TV state\n\nThere are various `inject` nodes which can be used to send information from your television ([Vizio API](https://github.com/exiva/Vizio_SmartCast_API), [Onkyo device](https://github.com/estbeetoo/node-red-contrib-eiscp), [Samsung TV](https://github.com/Toxblh/node-red-contrib-samsung-tv-control), [LG TV](https://github.com/hobbyquaker/node-red-contrib-lgtv), etc). It is up to you as the user to set this up according to your hardware. Use the provided `inject` nodes as a template to begin understanding the payloads expected by the Television Service.\n\nPlease note that the Television Speaker and Input Source service items **DO NOT** receive any input after initial configuration.\n\n## Setting TV state based on HomeKit output\n\nThere are two debug nodes provided. These can be used as examples of the output coming from HomeKit nodes to set up your system accordingly.\n\nThe `State and source output` debug node will output the following payloads:\n* `{\"Active\":0/1}` for TV state off/on\n* `{\"Input\":0-3}` for changing inputs from HomeKit\n* `{\"RemoteKey\":various}` for various integers when using the control center remote\n\n\nThe `Volume output` debug node will output the following payloads:\n* `{\"VolumeSelector\":0}` when control center remote press is \"Increase Volume\"\n* `{\"VolumeSelector\":1}` when control center remote press is \"Decrease Volume\"\n\nThe Input Source services will output payloads like `{\"ConfiguredName\":\"Name\"}` if the name is changed from HomeKit. If you would like to change your input names from within HomeKit rather than the `Set up inputs` function, it can be done but is beyond the scope of this example.\n"
+ {
+ "id": "a98abda4.5784d",
+ "type": "group",
+ "z": "21f36bce.02d864",
+ "name": "Television: input from device, output to device",
+ "style": {
+ "stroke": "#999999",
+ "fill": "none",
+ "label": true,
+ "label-position": "nw",
+ "color": "#a4a4a4"
},
- {
- "id": "894d3458.2f07d",
- "type": "inject",
- "z": "21f36bce.02d864",
- "g": "a98abda4.5784d",
- "name": "TV on",
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"Active\":1}",
- "payloadType": "json",
- "x": 110,
- "y": 160,
- "wires": [
- [
- "56282414.102184"
- ]
- ]
+ "nodes": [
+ "894d3458.2f07d",
+ "87183aa8.418ec",
+ "519fe2f2.b4870c",
+ "5de4624c.b2aeac",
+ "d5812842.bebac",
+ "ac7b78f3.2b9328",
+ "1d662593.e8434a",
+ "405055ca.02f2dc",
+ "f164c3c9.de75e8",
+ "d35fba0b.560e68",
+ "da9f0bd6.b2bbf",
+ "b4c4b8b.fc331c8",
+ "56282414.102184",
+ "f83a84cb.08b19"
+ ],
+ "x": 14,
+ "y": 59,
+ "w": 932,
+ "h": 488,
+ "info": "## Example With Speaker and 4 inputs\n\nThis example will show a television service with 4 inputs and a speaker (volume control). There are two functions that should be used to name your specific devices. These functions are `Setup TV` and `Setup Inputs`.\n\n**Setup TV:**\nThis function will be run 5 seconds after startup or whenever the `TV Setup` inject node is triggered. Change the name on line 1 of the function. The output message is sent to the Television Service to initialize the name and set the TV to `{\"Active\":0}` (TV off).\n\n**Setup Inputs:**\nThis function will be run 6 seconds after startup or whenever the `Source Setup` inject node is triggered. The following variables are available:\n* Lines 5 through 8 will name your sources\n* Lines 24 through 27 will set the input type according to the values in lines 11 through 21\n\n## Setting the HomeKit item based on TV state\n\nThere are various `inject` nodes which can be used to send information from your television ([Vizio API](https://github.com/exiva/Vizio_SmartCast_API), [Onkyo device](https://github.com/estbeetoo/node-red-contrib-eiscp), [Samsung TV](https://github.com/Toxblh/node-red-contrib-samsung-tv-control), [LG TV](https://github.com/hobbyquaker/node-red-contrib-lgtv), etc). It is up to you as the user to set this up according to your hardware. Use the provided `inject` nodes as a template to begin understanding the payloads expected by the Television Service.\n\nPlease note that the Television Speaker and Input Source service items **DO NOT** receive any input after initial configuration.\n\n## Setting TV state based on HomeKit output\n\nThere are two debug nodes provided. These can be used as examples of the output coming from HomeKit nodes to set up your system accordingly.\n\nThe `State and source output` debug node will output the following payloads:\n* `{\"Active\":0/1}` for TV state off/on\n* `{\"Input\":0-3}` for changing inputs from HomeKit\n* `{\"RemoteKey\":various}` for various integers when using the control center remote\n\n\nThe `Volume output` debug node will output the following payloads:\n* `{\"VolumeSelector\":0}` when control center remote press is \"Increase Volume\"\n* `{\"VolumeSelector\":1}` when control center remote press is \"Decrease Volume\"\n\nThe Input Source services will output payloads like `{\"ConfiguredName\":\"Name\"}` if the name is changed from HomeKit. If you would like to change your input names from within HomeKit rather than the `Set up inputs` function, it can be done but is beyond the scope of this example.\n"
+ },
+ {
+ "id": "894d3458.2f07d",
+ "type": "inject",
+ "z": "21f36bce.02d864",
+ "g": "a98abda4.5784d",
+ "name": "TV on",
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"Active\":1}",
+ "payloadType": "json",
+ "x": 110,
+ "y": 160,
+ "wires": [["56282414.102184"]]
+ },
+ {
+ "id": "87183aa8.418ec",
+ "type": "inject",
+ "z": "21f36bce.02d864",
+ "g": "a98abda4.5784d",
+ "name": "TV off",
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"Active\":0}",
+ "payloadType": "json",
+ "x": 110,
+ "y": 200,
+ "wires": [["56282414.102184"]]
+ },
+ {
+ "id": "519fe2f2.b4870c",
+ "type": "debug",
+ "z": "21f36bce.02d864",
+ "g": "a98abda4.5784d",
+ "name": "State and source output",
+ "active": true,
+ "tosidebar": true,
+ "console": false,
+ "tostatus": false,
+ "complete": "payload",
+ "targetType": "msg",
+ "x": 790,
+ "y": 140,
+ "wires": []
+ },
+ {
+ "id": "5de4624c.b2aeac",
+ "type": "debug",
+ "z": "21f36bce.02d864",
+ "g": "a98abda4.5784d",
+ "name": "Volume output",
+ "active": true,
+ "tosidebar": true,
+ "console": false,
+ "tostatus": false,
+ "complete": "payload",
+ "targetType": "msg",
+ "statusVal": "",
+ "statusType": "auto",
+ "x": 800,
+ "y": 220,
+ "wires": []
+ },
+ {
+ "id": "d5812842.bebac",
+ "type": "inject",
+ "z": "21f36bce.02d864",
+ "g": "a98abda4.5784d",
+ "name": "TV Setup",
+ "repeat": "",
+ "crontab": "",
+ "once": true,
+ "onceDelay": "5",
+ "topic": "",
+ "payload": "",
+ "payloadType": "date",
+ "x": 120,
+ "y": 100,
+ "wires": [["1d662593.e8434a"]]
+ },
+ {
+ "id": "ac7b78f3.2b9328",
+ "type": "inject",
+ "z": "21f36bce.02d864",
+ "g": "a98abda4.5784d",
+ "name": "Source Setup",
+ "repeat": "",
+ "crontab": "",
+ "once": true,
+ "onceDelay": "6",
+ "topic": "",
+ "payload": "",
+ "payloadType": "date",
+ "x": 140,
+ "y": 480,
+ "wires": [["b4c4b8b.fc331c8"]]
+ },
+ {
+ "id": "1d662593.e8434a",
+ "type": "function",
+ "z": "21f36bce.02d864",
+ "g": "a98abda4.5784d",
+ "name": "Setup TV",
+ "func": "var name = \"Television\";\n\nmsg.payload = {\n \"ConfiguredName\": name,\n \"ActiveIdentifier\" : 0,\n \"SleepDiscoveryMode\" : 0,\n \"Active\" : 0\n};\nreturn msg;",
+ "outputs": 1,
+ "noerr": 0,
+ "x": 300,
+ "y": 100,
+ "wires": [["56282414.102184"]]
+ },
+ {
+ "id": "405055ca.02f2dc",
+ "type": "inject",
+ "z": "21f36bce.02d864",
+ "g": "a98abda4.5784d",
+ "name": "Input 1",
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"ActiveIdentifier\":1}",
+ "payloadType": "json",
+ "x": 110,
+ "y": 320,
+ "wires": [["56282414.102184"]]
+ },
+ {
+ "id": "f164c3c9.de75e8",
+ "type": "inject",
+ "z": "21f36bce.02d864",
+ "g": "a98abda4.5784d",
+ "name": "Input 0",
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"ActiveIdentifier\":0}",
+ "payloadType": "json",
+ "x": 110,
+ "y": 280,
+ "wires": [["56282414.102184"]]
+ },
+ {
+ "id": "d35fba0b.560e68",
+ "type": "inject",
+ "z": "21f36bce.02d864",
+ "g": "a98abda4.5784d",
+ "name": "Input 2",
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"ActiveIdentifier\":2}",
+ "payloadType": "json",
+ "x": 110,
+ "y": 360,
+ "wires": [["56282414.102184"]]
+ },
+ {
+ "id": "da9f0bd6.b2bbf",
+ "type": "inject",
+ "z": "21f36bce.02d864",
+ "g": "a98abda4.5784d",
+ "name": "Input 3",
+ "repeat": "",
+ "crontab": "",
+ "once": false,
+ "onceDelay": 0.1,
+ "topic": "",
+ "payload": "{\"ActiveIdentifier\":3}",
+ "payloadType": "json",
+ "x": 110,
+ "y": 400,
+ "wires": [["56282414.102184"]]
+ },
+ {
+ "id": "b4c4b8b.fc331c8",
+ "type": "function",
+ "z": "21f36bce.02d864",
+ "g": "a98abda4.5784d",
+ "name": "Set up inputs",
+ "func": "// This function will initialize and name inputs\n// it is set to work with 4 inputs\n\n// INPUT SOURCE NAMES\nvar input0 = \"HDMI 1\";\nvar input1 = \"HDMI 2\";\nvar input2 = \"Apple TV\";\nvar input3 = \"Wii U\";\n\n// INPUT SOURCE TYPES\nvar OTHER = 0;\nvar HOME_SCREEN = 1;\nvar TUNER = 2;\nvar HDMI = 3;\nvar COMPOSITE_VIDEO = 4;\nvar S_VIDEO = 5;\nvar COMPONENT_VIDEO = 6;\nvar DVI = 7;\nvar AIRPLAY = 8;\nvar USB = 9;\nvar APPLICATION = 10;\n\n// Configure your input types based on options above\nvar input0type = HDMI;\nvar input1type = HDMI;\nvar input2type = HDMI;\nvar input3type = COMPOSITE_VIDEO;\n\n\n// Duplicate or remove sets if you have more or fewer inputs\nvar msg0={};\nvar msg1={};\nvar msg2={};\nvar msg3={};\n\nmsg0.payload = {\n \"Identifier\": 0,\n \"IsConfigured\" : 1,\n \"ConfiguredName\": input0,\n \"InputSourceType\": input0type\n};\nmsg1.payload = {\n \"Identifier\": 1,\n \"IsConfigured\" : 1,\n \"ConfiguredName\": input1,\n \"InputSourceType\": input1type\n};\nmsg2.payload = {\n \"Identifier\": 2,\n \"IsConfigured\" : 1,\n \"ConfiguredName\": input2,\n \"InputSourceType\": input2type\n};\nmsg3.payload = {\n \"Identifier\": 3,\n \"IsConfigured\" : 1,\n \"ConfiguredName\" : input3,\n \"InputSourceType\" : input3type\n};\nreturn [msg0,msg1,msg2,msg3];",
+ "outputs": 4,
+ "noerr": 0,
+ "x": 330,
+ "y": 460,
+ "wires": [
+ ["cb312294.a7f498"],
+ ["28645f7e.68e9b"],
+ ["3a8efd21.5d57c2"],
+ ["4c751d1f.e9a014"]
+ ]
+ },
+ {
+ "id": "56282414.102184",
+ "type": "homekit-service",
+ "z": "21f36bce.02d864",
+ "g": "a98abda4.5784d",
+ "isParent": true,
+ "bridge": "5257174b.4307a8",
+ "parentService": "",
+ "name": "Television Example",
+ "serviceName": "Television",
+ "topic": "",
+ "filter": false,
+ "manufacturer": "Default Manufacturer",
+ "model": "Default Model",
+ "serialNo": "Default Serial Number",
+ "firmwareRev": "",
+ "hardwareRev": "",
+ "cameraConfigVideoProcessor": "ffmpeg",
+ "cameraConfigSource": "",
+ "cameraConfigStillImageSource": "",
+ "cameraConfigMaxStreams": 2,
+ "cameraConfigMaxWidth": 1280,
+ "cameraConfigMaxHeight": 720,
+ "cameraConfigMaxFPS": 10,
+ "cameraConfigMaxBitrate": 300,
+ "cameraConfigVideoCodec": "libx264",
+ "cameraConfigAudioCodec": "libfdk_aac",
+ "cameraConfigAudio": false,
+ "cameraConfigPacketSize": 1316,
+ "cameraConfigVerticalFlip": false,
+ "cameraConfigHorizontalFlip": false,
+ "cameraConfigMapVideo": "0:0",
+ "cameraConfigMapAudio": "0:1",
+ "cameraConfigVideoFilter": "scale=1280:720",
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
+ "cameraConfigDebug": false,
+ "cameraConfigSnapshotOutput": "disabled",
+ "cameraConfigInterfaceName": "",
+ "characteristicProperties": "{\n \"RemoteKey\":null\n}",
+ "outputs": 2,
+ "x": 530,
+ "y": 140,
+ "wires": [[], ["519fe2f2.b4870c"]]
+ },
+ {
+ "id": "f83a84cb.08b19",
+ "type": "group",
+ "z": "21f36bce.02d864",
+ "g": "a98abda4.5784d",
+ "name": "Linked services",
+ "style": {
+ "stroke": "#0070c0",
+ "fill": "#bfdbef",
+ "label": true
},
- {
- "id": "87183aa8.418ec",
- "type": "inject",
- "z": "21f36bce.02d864",
- "g": "a98abda4.5784d",
- "name": "TV off",
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"Active\":0}",
- "payloadType": "json",
- "x": 110,
- "y": 200,
- "wires": [
- [
- "56282414.102184"
- ]
- ]
- },
- {
- "id": "519fe2f2.b4870c",
- "type": "debug",
- "z": "21f36bce.02d864",
- "g": "a98abda4.5784d",
- "name": "State and source output",
- "active": true,
- "tosidebar": true,
- "console": false,
- "tostatus": false,
- "complete": "payload",
- "targetType": "msg",
- "x": 790,
- "y": 140,
- "wires": []
- },
- {
- "id": "5de4624c.b2aeac",
- "type": "debug",
- "z": "21f36bce.02d864",
- "g": "a98abda4.5784d",
- "name": "Volume output",
- "active": true,
- "tosidebar": true,
- "console": false,
- "tostatus": false,
- "complete": "payload",
- "targetType": "msg",
- "statusVal": "",
- "statusType": "auto",
- "x": 800,
- "y": 220,
- "wires": []
- },
- {
- "id": "d5812842.bebac",
- "type": "inject",
- "z": "21f36bce.02d864",
- "g": "a98abda4.5784d",
- "name": "TV Setup",
- "repeat": "",
- "crontab": "",
- "once": true,
- "onceDelay": "5",
- "topic": "",
- "payload": "",
- "payloadType": "date",
- "x": 120,
- "y": 100,
- "wires": [
- [
- "1d662593.e8434a"
- ]
- ]
- },
- {
- "id": "ac7b78f3.2b9328",
- "type": "inject",
- "z": "21f36bce.02d864",
- "g": "a98abda4.5784d",
- "name": "Source Setup",
- "repeat": "",
- "crontab": "",
- "once": true,
- "onceDelay": "6",
- "topic": "",
- "payload": "",
- "payloadType": "date",
- "x": 140,
- "y": 480,
- "wires": [
- [
- "b4c4b8b.fc331c8"
- ]
- ]
- },
- {
- "id": "1d662593.e8434a",
- "type": "function",
- "z": "21f36bce.02d864",
- "g": "a98abda4.5784d",
- "name": "Setup TV",
- "func": "var name = \"Television\";\n\nmsg.payload = {\n \"ConfiguredName\": name,\n \"ActiveIdentifier\" : 0,\n \"SleepDiscoveryMode\" : 0,\n \"Active\" : 0\n};\nreturn msg;",
- "outputs": 1,
- "noerr": 0,
- "x": 300,
- "y": 100,
- "wires": [
- [
- "56282414.102184"
- ]
- ]
- },
- {
- "id": "405055ca.02f2dc",
- "type": "inject",
- "z": "21f36bce.02d864",
- "g": "a98abda4.5784d",
- "name": "Input 1",
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"ActiveIdentifier\":1}",
- "payloadType": "json",
- "x": 110,
- "y": 320,
- "wires": [
- [
- "56282414.102184"
- ]
- ]
- },
- {
- "id": "f164c3c9.de75e8",
- "type": "inject",
- "z": "21f36bce.02d864",
- "g": "a98abda4.5784d",
- "name": "Input 0",
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"ActiveIdentifier\":0}",
- "payloadType": "json",
- "x": 110,
- "y": 280,
- "wires": [
- [
- "56282414.102184"
- ]
- ]
- },
- {
- "id": "d35fba0b.560e68",
- "type": "inject",
- "z": "21f36bce.02d864",
- "g": "a98abda4.5784d",
- "name": "Input 2",
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"ActiveIdentifier\":2}",
- "payloadType": "json",
- "x": 110,
- "y": 360,
- "wires": [
- [
- "56282414.102184"
- ]
- ]
- },
- {
- "id": "da9f0bd6.b2bbf",
- "type": "inject",
- "z": "21f36bce.02d864",
- "g": "a98abda4.5784d",
- "name": "Input 3",
- "repeat": "",
- "crontab": "",
- "once": false,
- "onceDelay": 0.1,
- "topic": "",
- "payload": "{\"ActiveIdentifier\":3}",
- "payloadType": "json",
- "x": 110,
- "y": 400,
- "wires": [
- [
- "56282414.102184"
- ]
- ]
- },
- {
- "id": "b4c4b8b.fc331c8",
- "type": "function",
- "z": "21f36bce.02d864",
- "g": "a98abda4.5784d",
- "name": "Set up inputs",
- "func": "// This function will initialize and name inputs\n// it is set to work with 4 inputs\n\n// INPUT SOURCE NAMES\nvar input0 = \"HDMI 1\";\nvar input1 = \"HDMI 2\";\nvar input2 = \"Apple TV\";\nvar input3 = \"Wii U\";\n\n// INPUT SOURCE TYPES\nvar OTHER = 0;\nvar HOME_SCREEN = 1;\nvar TUNER = 2;\nvar HDMI = 3;\nvar COMPOSITE_VIDEO = 4;\nvar S_VIDEO = 5;\nvar COMPONENT_VIDEO = 6;\nvar DVI = 7;\nvar AIRPLAY = 8;\nvar USB = 9;\nvar APPLICATION = 10;\n\n// Configure your input types based on options above\nvar input0type = HDMI;\nvar input1type = HDMI;\nvar input2type = HDMI;\nvar input3type = COMPOSITE_VIDEO;\n\n\n// Duplicate or remove sets if you have more or fewer inputs\nvar msg0={};\nvar msg1={};\nvar msg2={};\nvar msg3={};\n\nmsg0.payload = {\n \"Identifier\": 0,\n \"IsConfigured\" : 1,\n \"ConfiguredName\": input0,\n \"InputSourceType\": input0type\n};\nmsg1.payload = {\n \"Identifier\": 1,\n \"IsConfigured\" : 1,\n \"ConfiguredName\": input1,\n \"InputSourceType\": input1type\n};\nmsg2.payload = {\n \"Identifier\": 2,\n \"IsConfigured\" : 1,\n \"ConfiguredName\": input2,\n \"InputSourceType\": input2type\n};\nmsg3.payload = {\n \"Identifier\": 3,\n \"IsConfigured\" : 1,\n \"ConfiguredName\" : input3,\n \"InputSourceType\" : input3type\n};\nreturn [msg0,msg1,msg2,msg3];",
- "outputs": 4,
- "noerr": 0,
- "x": 330,
- "y": 460,
- "wires": [
- [
- "cb312294.a7f498"
- ],
- [
- "28645f7e.68e9b"
- ],
- [
- "3a8efd21.5d57c2"
- ],
- [
- "4c751d1f.e9a014"
- ]
- ]
- },
- {
- "id": "56282414.102184",
- "type": "homekit-service",
- "z": "21f36bce.02d864",
- "g": "a98abda4.5784d",
- "isParent": true,
- "bridge": "5257174b.4307a8",
- "parentService": "",
- "name": "Television Example",
- "serviceName": "Television",
- "topic": "",
- "filter": false,
- "manufacturer": "Default Manufacturer",
- "model": "Default Model",
- "serialNo": "Default Serial Number",
- "firmwareRev": "",
- "hardwareRev": "",
- "cameraConfigVideoProcessor": "ffmpeg",
- "cameraConfigSource": "",
- "cameraConfigStillImageSource": "",
- "cameraConfigMaxStreams": 2,
- "cameraConfigMaxWidth": 1280,
- "cameraConfigMaxHeight": 720,
- "cameraConfigMaxFPS": 10,
- "cameraConfigMaxBitrate": 300,
- "cameraConfigVideoCodec": "libx264",
- "cameraConfigAudioCodec": "libfdk_aac",
- "cameraConfigAudio": false,
- "cameraConfigPacketSize": 1316,
- "cameraConfigVerticalFlip": false,
- "cameraConfigHorizontalFlip": false,
- "cameraConfigMapVideo": "0:0",
- "cameraConfigMapAudio": "0:1",
- "cameraConfigVideoFilter": "scale=1280:720",
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
- "cameraConfigDebug": false,
- "cameraConfigSnapshotOutput": "disabled",
- "cameraConfigInterfaceName": "",
- "characteristicProperties": "{\n \"RemoteKey\":null\n}",
- "outputs": 2,
- "x": 530,
- "y": 140,
- "wires": [
- [],
- [
- "519fe2f2.b4870c"
- ]
- ]
- },
- {
- "id": "f83a84cb.08b19",
- "type": "group",
- "z": "21f36bce.02d864",
- "g": "a98abda4.5784d",
- "name": "Linked services",
- "style": {
- "stroke": "#0070c0",
- "fill": "#bfdbef",
- "label": true
- },
- "nodes": [
- "1b32678b.2eedf",
- "cb312294.a7f498",
- "28645f7e.68e9b",
- "3a8efd21.5d57c2",
- "4c751d1f.e9a014"
- ],
- "x": 434,
- "y": 179,
- "w": 232,
- "h": 342
- },
- {
- "id": "1b32678b.2eedf",
- "type": "homekit-service",
- "z": "21f36bce.02d864",
- "g": "f83a84cb.08b19",
- "isParent": false,
- "bridge": "5257174b.4307a8",
- "parentService": "56282414.102184",
- "name": "Television Speaker",
- "serviceName": "TelevisionSpeaker",
- "topic": "Television Example",
- "filter": false,
- "manufacturer": "Default Manufacturer",
- "model": "Default Model",
- "serialNo": "Default Serial Number",
- "firmwareRev": "",
- "hardwareRev": "",
- "cameraConfigVideoProcessor": "ffmpeg",
- "cameraConfigSource": "",
- "cameraConfigStillImageSource": "",
- "cameraConfigMaxStreams": 2,
- "cameraConfigMaxWidth": 1280,
- "cameraConfigMaxHeight": 720,
- "cameraConfigMaxFPS": 10,
- "cameraConfigMaxBitrate": 300,
- "cameraConfigVideoCodec": "libx264",
- "cameraConfigAudioCodec": "libfdk_aac",
- "cameraConfigAudio": false,
- "cameraConfigPacketSize": 1316,
- "cameraConfigVerticalFlip": false,
- "cameraConfigHorizontalFlip": false,
- "cameraConfigMapVideo": "0:0",
- "cameraConfigMapAudio": "0:1",
- "cameraConfigVideoFilter": "scale=1280:720",
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
- "cameraConfigDebug": false,
- "cameraConfigSnapshotOutput": "disabled",
- "cameraConfigInterfaceName": "",
- "characteristicProperties": "{\n \"VolumeControlType\":1,\n \"VolumeSelector\":true\n}",
- "outputs": 2,
- "x": 550,
- "y": 220,
- "wires": [
- [],
- [
- "5de4624c.b2aeac"
- ]
- ]
- },
- {
- "id": "cb312294.a7f498",
- "type": "homekit-service",
- "z": "21f36bce.02d864",
- "g": "f83a84cb.08b19",
- "isParent": false,
- "bridge": "",
- "parentService": "56282414.102184",
- "name": "Input 0",
- "serviceName": "InputSource",
- "topic": "Television Example",
- "filter": false,
- "manufacturer": "Default Manufacturer",
- "model": "Default Model",
- "serialNo": "Default Serial Number",
- "firmwareRev": "",
- "hardwareRev": "",
- "cameraConfigVideoProcessor": "ffmpeg",
- "cameraConfigSource": "",
- "cameraConfigStillImageSource": "",
- "cameraConfigMaxStreams": 2,
- "cameraConfigMaxWidth": 1280,
- "cameraConfigMaxHeight": 720,
- "cameraConfigMaxFPS": 10,
- "cameraConfigMaxBitrate": 300,
- "cameraConfigVideoCodec": "libx264",
- "cameraConfigAudioCodec": "libfdk_aac",
- "cameraConfigAudio": false,
- "cameraConfigPacketSize": 1316,
- "cameraConfigVerticalFlip": false,
- "cameraConfigHorizontalFlip": false,
- "cameraConfigMapVideo": "0:0",
- "cameraConfigMapAudio": "0:1",
- "cameraConfigVideoFilter": "scale=1280:720",
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
- "cameraConfigDebug": false,
- "cameraConfigSnapshotOutput": "disabled",
- "cameraConfigInterfaceName": "",
- "characteristicProperties": "{}",
- "outputs": 2,
- "x": 580,
- "y": 300,
- "wires": [
- [],
- []
- ]
- },
- {
- "id": "28645f7e.68e9b",
- "type": "homekit-service",
- "z": "21f36bce.02d864",
- "g": "f83a84cb.08b19",
- "isParent": false,
- "bridge": "",
- "parentService": "56282414.102184",
- "name": "Input 1",
- "serviceName": "InputSource",
- "topic": "Television Example",
- "filter": false,
- "manufacturer": "Default Manufacturer",
- "model": "Default Model",
- "serialNo": "Default Serial Number",
- "firmwareRev": "",
- "hardwareRev": "",
- "cameraConfigVideoProcessor": "ffmpeg",
- "cameraConfigSource": "",
- "cameraConfigStillImageSource": "",
- "cameraConfigMaxStreams": 2,
- "cameraConfigMaxWidth": 1280,
- "cameraConfigMaxHeight": 720,
- "cameraConfigMaxFPS": 10,
- "cameraConfigMaxBitrate": 300,
- "cameraConfigVideoCodec": "libx264",
- "cameraConfigAudioCodec": "libfdk_aac",
- "cameraConfigAudio": false,
- "cameraConfigPacketSize": 1316,
- "cameraConfigVerticalFlip": false,
- "cameraConfigHorizontalFlip": false,
- "cameraConfigMapVideo": "0:0",
- "cameraConfigMapAudio": "0:1",
- "cameraConfigVideoFilter": "scale=1280:720",
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
- "cameraConfigDebug": false,
- "cameraConfigSnapshotOutput": "disabled",
- "cameraConfigInterfaceName": "",
- "characteristicProperties": "{}",
- "outputs": 2,
- "x": 580,
- "y": 360,
- "wires": [
- [],
- []
- ]
- },
- {
- "id": "3a8efd21.5d57c2",
- "type": "homekit-service",
- "z": "21f36bce.02d864",
- "g": "f83a84cb.08b19",
- "isParent": false,
- "bridge": "",
- "parentService": "56282414.102184",
- "name": "Input 2",
- "serviceName": "InputSource",
- "topic": "Television Example",
- "filter": false,
- "manufacturer": "Default Manufacturer",
- "model": "Default Model",
- "serialNo": "Default Serial Number",
- "firmwareRev": "",
- "hardwareRev": "",
- "cameraConfigVideoProcessor": "ffmpeg",
- "cameraConfigSource": "",
- "cameraConfigStillImageSource": "",
- "cameraConfigMaxStreams": 2,
- "cameraConfigMaxWidth": 1280,
- "cameraConfigMaxHeight": 720,
- "cameraConfigMaxFPS": 10,
- "cameraConfigMaxBitrate": 300,
- "cameraConfigVideoCodec": "libx264",
- "cameraConfigAudioCodec": "libfdk_aac",
- "cameraConfigAudio": false,
- "cameraConfigPacketSize": 1316,
- "cameraConfigVerticalFlip": false,
- "cameraConfigHorizontalFlip": false,
- "cameraConfigMapVideo": "0:0",
- "cameraConfigMapAudio": "0:1",
- "cameraConfigVideoFilter": "scale=1280:720",
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
- "cameraConfigDebug": false,
- "cameraConfigSnapshotOutput": "disabled",
- "cameraConfigInterfaceName": "",
- "characteristicProperties": "{}",
- "outputs": 2,
- "x": 580,
- "y": 420,
- "wires": [
- [],
- []
- ]
- },
- {
- "id": "4c751d1f.e9a014",
- "type": "homekit-service",
- "z": "21f36bce.02d864",
- "g": "f83a84cb.08b19",
- "isParent": false,
- "bridge": "",
- "parentService": "56282414.102184",
- "name": "Input 3",
- "serviceName": "InputSource",
- "topic": "Television Example",
- "filter": false,
- "manufacturer": "Default Manufacturer",
- "model": "Default Model",
- "serialNo": "Default Serial Number",
- "firmwareRev": "",
- "hardwareRev": "",
- "cameraConfigVideoProcessor": "ffmpeg",
- "cameraConfigSource": "",
- "cameraConfigStillImageSource": "",
- "cameraConfigMaxStreams": 2,
- "cameraConfigMaxWidth": 1280,
- "cameraConfigMaxHeight": 720,
- "cameraConfigMaxFPS": 10,
- "cameraConfigMaxBitrate": 300,
- "cameraConfigVideoCodec": "libx264",
- "cameraConfigAudioCodec": "libfdk_aac",
- "cameraConfigAudio": false,
- "cameraConfigPacketSize": 1316,
- "cameraConfigVerticalFlip": false,
- "cameraConfigHorizontalFlip": false,
- "cameraConfigMapVideo": "0:0",
- "cameraConfigMapAudio": "0:1",
- "cameraConfigVideoFilter": "scale=1280:720",
- "cameraConfigAdditionalCommandLine": "-tune zerolatency",
- "cameraConfigDebug": false,
- "cameraConfigSnapshotOutput": "disabled",
- "cameraConfigInterfaceName": "",
- "characteristicProperties": "{}",
- "outputs": 2,
- "x": 580,
- "y": 480,
- "wires": [
- [],
- []
- ]
- },
- {
- "id": "5257174b.4307a8",
- "type": "homekit-bridge",
- "z": "",
- "bridgeName": "Demo TV",
- "pinCode": "111-11-111",
- "port": "",
- "allowInsecureRequest": false,
- "manufacturer": "NRCHKB",
- "model": "Demo",
- "serialNo": "1.1.2",
- "customMdnsConfig": false,
- "mdnsMulticast": true,
- "mdnsInterface": "",
- "mdnsPort": "",
- "mdnsIp": "",
- "mdnsTtl": "",
- "mdnsLoopback": true,
- "mdnsReuseAddr": true,
- "allowMessagePassthrough": false
- }
+ "nodes": [
+ "1b32678b.2eedf",
+ "cb312294.a7f498",
+ "28645f7e.68e9b",
+ "3a8efd21.5d57c2",
+ "4c751d1f.e9a014"
+ ],
+ "x": 434,
+ "y": 179,
+ "w": 232,
+ "h": 342
+ },
+ {
+ "id": "1b32678b.2eedf",
+ "type": "homekit-service",
+ "z": "21f36bce.02d864",
+ "g": "f83a84cb.08b19",
+ "isParent": false,
+ "bridge": "5257174b.4307a8",
+ "parentService": "56282414.102184",
+ "name": "Television Speaker",
+ "serviceName": "TelevisionSpeaker",
+ "topic": "Television Example",
+ "filter": false,
+ "manufacturer": "Default Manufacturer",
+ "model": "Default Model",
+ "serialNo": "Default Serial Number",
+ "firmwareRev": "",
+ "hardwareRev": "",
+ "cameraConfigVideoProcessor": "ffmpeg",
+ "cameraConfigSource": "",
+ "cameraConfigStillImageSource": "",
+ "cameraConfigMaxStreams": 2,
+ "cameraConfigMaxWidth": 1280,
+ "cameraConfigMaxHeight": 720,
+ "cameraConfigMaxFPS": 10,
+ "cameraConfigMaxBitrate": 300,
+ "cameraConfigVideoCodec": "libx264",
+ "cameraConfigAudioCodec": "libfdk_aac",
+ "cameraConfigAudio": false,
+ "cameraConfigPacketSize": 1316,
+ "cameraConfigVerticalFlip": false,
+ "cameraConfigHorizontalFlip": false,
+ "cameraConfigMapVideo": "0:0",
+ "cameraConfigMapAudio": "0:1",
+ "cameraConfigVideoFilter": "scale=1280:720",
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
+ "cameraConfigDebug": false,
+ "cameraConfigSnapshotOutput": "disabled",
+ "cameraConfigInterfaceName": "",
+ "characteristicProperties": "{\n \"VolumeControlType\":1,\n \"VolumeSelector\":true\n}",
+ "outputs": 2,
+ "x": 550,
+ "y": 220,
+ "wires": [[], ["5de4624c.b2aeac"]]
+ },
+ {
+ "id": "cb312294.a7f498",
+ "type": "homekit-service",
+ "z": "21f36bce.02d864",
+ "g": "f83a84cb.08b19",
+ "isParent": false,
+ "bridge": "",
+ "parentService": "56282414.102184",
+ "name": "Input 0",
+ "serviceName": "InputSource",
+ "topic": "Television Example",
+ "filter": false,
+ "manufacturer": "Default Manufacturer",
+ "model": "Default Model",
+ "serialNo": "Default Serial Number",
+ "firmwareRev": "",
+ "hardwareRev": "",
+ "cameraConfigVideoProcessor": "ffmpeg",
+ "cameraConfigSource": "",
+ "cameraConfigStillImageSource": "",
+ "cameraConfigMaxStreams": 2,
+ "cameraConfigMaxWidth": 1280,
+ "cameraConfigMaxHeight": 720,
+ "cameraConfigMaxFPS": 10,
+ "cameraConfigMaxBitrate": 300,
+ "cameraConfigVideoCodec": "libx264",
+ "cameraConfigAudioCodec": "libfdk_aac",
+ "cameraConfigAudio": false,
+ "cameraConfigPacketSize": 1316,
+ "cameraConfigVerticalFlip": false,
+ "cameraConfigHorizontalFlip": false,
+ "cameraConfigMapVideo": "0:0",
+ "cameraConfigMapAudio": "0:1",
+ "cameraConfigVideoFilter": "scale=1280:720",
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
+ "cameraConfigDebug": false,
+ "cameraConfigSnapshotOutput": "disabled",
+ "cameraConfigInterfaceName": "",
+ "characteristicProperties": "{}",
+ "outputs": 2,
+ "x": 580,
+ "y": 300,
+ "wires": [[], []]
+ },
+ {
+ "id": "28645f7e.68e9b",
+ "type": "homekit-service",
+ "z": "21f36bce.02d864",
+ "g": "f83a84cb.08b19",
+ "isParent": false,
+ "bridge": "",
+ "parentService": "56282414.102184",
+ "name": "Input 1",
+ "serviceName": "InputSource",
+ "topic": "Television Example",
+ "filter": false,
+ "manufacturer": "Default Manufacturer",
+ "model": "Default Model",
+ "serialNo": "Default Serial Number",
+ "firmwareRev": "",
+ "hardwareRev": "",
+ "cameraConfigVideoProcessor": "ffmpeg",
+ "cameraConfigSource": "",
+ "cameraConfigStillImageSource": "",
+ "cameraConfigMaxStreams": 2,
+ "cameraConfigMaxWidth": 1280,
+ "cameraConfigMaxHeight": 720,
+ "cameraConfigMaxFPS": 10,
+ "cameraConfigMaxBitrate": 300,
+ "cameraConfigVideoCodec": "libx264",
+ "cameraConfigAudioCodec": "libfdk_aac",
+ "cameraConfigAudio": false,
+ "cameraConfigPacketSize": 1316,
+ "cameraConfigVerticalFlip": false,
+ "cameraConfigHorizontalFlip": false,
+ "cameraConfigMapVideo": "0:0",
+ "cameraConfigMapAudio": "0:1",
+ "cameraConfigVideoFilter": "scale=1280:720",
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
+ "cameraConfigDebug": false,
+ "cameraConfigSnapshotOutput": "disabled",
+ "cameraConfigInterfaceName": "",
+ "characteristicProperties": "{}",
+ "outputs": 2,
+ "x": 580,
+ "y": 360,
+ "wires": [[], []]
+ },
+ {
+ "id": "3a8efd21.5d57c2",
+ "type": "homekit-service",
+ "z": "21f36bce.02d864",
+ "g": "f83a84cb.08b19",
+ "isParent": false,
+ "bridge": "",
+ "parentService": "56282414.102184",
+ "name": "Input 2",
+ "serviceName": "InputSource",
+ "topic": "Television Example",
+ "filter": false,
+ "manufacturer": "Default Manufacturer",
+ "model": "Default Model",
+ "serialNo": "Default Serial Number",
+ "firmwareRev": "",
+ "hardwareRev": "",
+ "cameraConfigVideoProcessor": "ffmpeg",
+ "cameraConfigSource": "",
+ "cameraConfigStillImageSource": "",
+ "cameraConfigMaxStreams": 2,
+ "cameraConfigMaxWidth": 1280,
+ "cameraConfigMaxHeight": 720,
+ "cameraConfigMaxFPS": 10,
+ "cameraConfigMaxBitrate": 300,
+ "cameraConfigVideoCodec": "libx264",
+ "cameraConfigAudioCodec": "libfdk_aac",
+ "cameraConfigAudio": false,
+ "cameraConfigPacketSize": 1316,
+ "cameraConfigVerticalFlip": false,
+ "cameraConfigHorizontalFlip": false,
+ "cameraConfigMapVideo": "0:0",
+ "cameraConfigMapAudio": "0:1",
+ "cameraConfigVideoFilter": "scale=1280:720",
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
+ "cameraConfigDebug": false,
+ "cameraConfigSnapshotOutput": "disabled",
+ "cameraConfigInterfaceName": "",
+ "characteristicProperties": "{}",
+ "outputs": 2,
+ "x": 580,
+ "y": 420,
+ "wires": [[], []]
+ },
+ {
+ "id": "4c751d1f.e9a014",
+ "type": "homekit-service",
+ "z": "21f36bce.02d864",
+ "g": "f83a84cb.08b19",
+ "isParent": false,
+ "bridge": "",
+ "parentService": "56282414.102184",
+ "name": "Input 3",
+ "serviceName": "InputSource",
+ "topic": "Television Example",
+ "filter": false,
+ "manufacturer": "Default Manufacturer",
+ "model": "Default Model",
+ "serialNo": "Default Serial Number",
+ "firmwareRev": "",
+ "hardwareRev": "",
+ "cameraConfigVideoProcessor": "ffmpeg",
+ "cameraConfigSource": "",
+ "cameraConfigStillImageSource": "",
+ "cameraConfigMaxStreams": 2,
+ "cameraConfigMaxWidth": 1280,
+ "cameraConfigMaxHeight": 720,
+ "cameraConfigMaxFPS": 10,
+ "cameraConfigMaxBitrate": 300,
+ "cameraConfigVideoCodec": "libx264",
+ "cameraConfigAudioCodec": "libfdk_aac",
+ "cameraConfigAudio": false,
+ "cameraConfigPacketSize": 1316,
+ "cameraConfigVerticalFlip": false,
+ "cameraConfigHorizontalFlip": false,
+ "cameraConfigMapVideo": "0:0",
+ "cameraConfigMapAudio": "0:1",
+ "cameraConfigVideoFilter": "scale=1280:720",
+ "cameraConfigAdditionalCommandLine": "-tune zerolatency",
+ "cameraConfigDebug": false,
+ "cameraConfigSnapshotOutput": "disabled",
+ "cameraConfigInterfaceName": "",
+ "characteristicProperties": "{}",
+ "outputs": 2,
+ "x": 580,
+ "y": 480,
+ "wires": [[], []]
+ },
+ {
+ "id": "5257174b.4307a8",
+ "type": "homekit-bridge",
+ "z": "",
+ "bridgeName": "Demo TV",
+ "pinCode": "111-11-111",
+ "port": "",
+ "allowInsecureRequest": false,
+ "manufacturer": "NRCHKB",
+ "model": "Demo",
+ "serialNo": "1.1.2",
+ "customMdnsConfig": false,
+ "mdnsMulticast": true,
+ "mdnsInterface": "",
+ "mdnsPort": "",
+ "mdnsIp": "",
+ "mdnsTtl": "",
+ "mdnsLoopback": true,
+ "mdnsReuseAddr": true,
+ "allowMessagePassthrough": false
+ }
]
diff --git a/examples/switch/01 - Plain Switch.json b/examples/switch/01 - Plain Switch.json
index 4f44841c..5d966284 100644
--- a/examples/switch/01 - Plain Switch.json
+++ b/examples/switch/01 - Plain Switch.json
@@ -14,9 +14,7 @@
"style": {
"label": true
},
- "nodes": [
- "d6f9e9ce.b3af8"
- ],
+ "nodes": ["d6f9e9ce.b3af8"],
"x": 434,
"y": 79,
"w": 212,
@@ -31,9 +29,7 @@
"stroke": "#ffC000",
"label": true
},
- "nodes": [
- "4ea13695.19871"
- ],
+ "nodes": ["4ea13695.19871"],
"x": 234,
"y": 79,
"w": 192,
@@ -47,10 +43,7 @@
"style": {
"label": true
},
- "nodes": [
- "e02112b7.b761d",
- "e9073d2c.84e64"
- ],
+ "nodes": ["e02112b7.b761d", "e9073d2c.84e64"],
"x": 54,
"y": 59,
"w": 172,
@@ -99,12 +92,7 @@
"outputs": 2,
"x": 330,
"y": 120,
- "wires": [
- [
- "d6f9e9ce.b3af8"
- ],
- []
- ]
+ "wires": [["d6f9e9ce.b3af8"], []]
},
{
"id": "d6f9e9ce.b3af8",
@@ -144,11 +132,7 @@
"payloadType": "json",
"x": 150,
"y": 100,
- "wires": [
- [
- "4ea13695.19871"
- ]
- ]
+ "wires": [["4ea13695.19871"]]
},
{
"id": "e9073d2c.84e64",
@@ -170,11 +154,7 @@
"payloadType": "json",
"x": 150,
"y": 140,
- "wires": [
- [
- "4ea13695.19871"
- ]
- ]
+ "wires": [["4ea13695.19871"]]
},
{
"id": "3dcda60a.e5ff12",
@@ -200,4 +180,4 @@
"mdnsReuseAddr": true,
"allowMessagePassthrough": true
}
-]
\ No newline at end of file
+]
diff --git a/package-lock.json b/package-lock.json
index 4a1cfdca..97c2cca8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,8602 +1,7637 @@
{
- "name": "node-red-contrib-homekit-bridged",
- "version": "1.7.3",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "node-red-contrib-homekit-bridged",
- "version": "1.7.3",
- "license": "Apache-2.0",
- "dependencies": {
- "@nrchkb/logger": "~3.1.1",
- "hap-nodejs": "0.12.3",
- "node-persist": "^3.1.3",
- "semver": "~7.6.3",
- "uuid": "~11.0.5"
- },
- "devDependencies": {
- "@homebridge/ciao": "~1.3.1",
- "@node-red/registry": "^4.0.8",
- "@types/mocha": "^10.0.10",
- "@types/node": "^18",
- "@types/node-persist": "^3.1.8",
- "@types/node-red": "^1.3.5",
- "@types/node-red-node-test-helper": "^0.3.4",
- "@types/semver": "^7.5.8",
- "@types/uuid": "^10.0.0",
- "@typescript-eslint/eslint-plugin": "^7.16.0",
- "@typescript-eslint/parser": "^7.16.0",
- "babel-eslint": "^10.1.0",
- "del-cli": "^5.1.0",
- "eslint": "^8",
- "eslint-config-prettier": "^9.1.0",
- "eslint-plugin-prettier": "^5.1.3",
- "eslint-plugin-simple-import-sort": "^12.1.1",
- "husky": "^9.0.11",
- "mocha": "^10.6.0",
- "node-red": "^4.0.8",
- "node-red-node-test-helper": "^0.3.4",
- "prettier": "^3.4.2",
- "ts-node": "^10.9.2",
- "typescript": "^5.7.3"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@aashutoshrathi/word-wrap": {
- "version": "1.2.6",
- "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
- "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/@babel/code-frame": {
- "version": "7.23.5",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
- "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
- "dev": true,
- "dependencies": {
- "@babel/highlight": "^7.23.4",
- "chalk": "^2.4.2"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/generator": {
- "version": "7.23.6",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz",
- "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.23.6",
- "@jridgewell/gen-mapping": "^0.3.2",
- "@jridgewell/trace-mapping": "^0.3.17",
- "jsesc": "^2.5.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-environment-visitor": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
- "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-function-name": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
- "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
- "dev": true,
- "dependencies": {
- "@babel/template": "^7.22.15",
- "@babel/types": "^7.23.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-hoist-variables": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
- "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-split-export-declaration": {
- "version": "7.22.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
- "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-string-parser": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz",
- "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
- "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/highlight": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
- "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
- "dev": true,
- "dependencies": {
- "@babel/helper-validator-identifier": "^7.22.20",
- "chalk": "^2.4.2",
- "js-tokens": "^4.0.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/parser": {
- "version": "7.23.6",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz",
- "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==",
- "dev": true,
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/runtime": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz",
- "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "regenerator-runtime": "^0.14.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/template": {
- "version": "7.22.15",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
- "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
- "dev": true,
- "dependencies": {
- "@babel/code-frame": "^7.22.13",
- "@babel/parser": "^7.22.15",
- "@babel/types": "^7.22.15"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/traverse": {
- "version": "7.23.7",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz",
- "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==",
- "dev": true,
- "dependencies": {
- "@babel/code-frame": "^7.23.5",
- "@babel/generator": "^7.23.6",
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-function-name": "^7.23.0",
- "@babel/helper-hoist-variables": "^7.22.5",
- "@babel/helper-split-export-declaration": "^7.22.6",
- "@babel/parser": "^7.23.6",
- "@babel/types": "^7.23.6",
- "debug": "^4.3.1",
- "globals": "^11.1.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/types": {
- "version": "7.23.6",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz",
- "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==",
- "dev": true,
- "dependencies": {
- "@babel/helper-string-parser": "^7.23.4",
- "@babel/helper-validator-identifier": "^7.22.20",
- "to-fast-properties": "^2.0.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@cspotcode/source-map-support": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
- "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
- "dev": true,
- "dependencies": {
- "@jridgewell/trace-mapping": "0.3.9"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.9",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
- "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
- "dev": true,
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.0.3",
- "@jridgewell/sourcemap-codec": "^1.4.10"
- }
- },
- "node_modules/@emnapi/core": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.2.0.tgz",
- "integrity": "sha512-E7Vgw78I93we4ZWdYCb4DGAwRROGkMIXk7/y87UmANR+J6qsWusmC3gLt0H+O0KOt5e6O38U8oJamgbudrES/w==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/wasi-threads": "1.0.1",
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@emnapi/runtime": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.2.0.tgz",
- "integrity": "sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@emnapi/wasi-threads": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.1.tgz",
- "integrity": "sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@eslint-community/eslint-utils": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
- "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
- "dev": true,
- "dependencies": {
- "eslint-visitor-keys": "^3.3.0"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "peerDependencies": {
- "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
- }
- },
- "node_modules/@eslint-community/regexpp": {
- "version": "4.10.1",
- "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz",
- "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==",
- "dev": true,
- "engines": {
- "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
- }
- },
- "node_modules/@eslint/eslintrc": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
- "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
- "dev": true,
- "dependencies": {
- "ajv": "^6.12.4",
- "debug": "^4.3.2",
- "espree": "^9.6.0",
- "globals": "^13.19.0",
- "ignore": "^5.2.0",
- "import-fresh": "^3.2.1",
- "js-yaml": "^4.1.0",
- "minimatch": "^3.1.2",
- "strip-json-comments": "^3.1.1"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/@eslint/eslintrc/node_modules/globals": {
- "version": "13.24.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
- "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
- "dev": true,
- "dependencies": {
- "type-fest": "^0.20.2"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@eslint/eslintrc/node_modules/type-fest": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
- "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@eslint/js": {
- "version": "8.56.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz",
- "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==",
- "dev": true,
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
- "node_modules/@homebridge/ciao": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/@homebridge/ciao/-/ciao-1.3.1.tgz",
- "integrity": "sha512-87tQCBNNnTymlbg8pKlQjRsk7a5uuqhWBpCbUriVYUebz3voJkLbbTmp0TQg7Sa6Jnpk/Uo6LA8zAOy2sbK9bw==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.3.6",
- "fast-deep-equal": "^3.1.3",
- "source-map-support": "^0.5.21",
- "tslib": "^2.6.3"
- },
- "bin": {
- "ciao-bcs": "lib/bonjour-conformance-testing.js"
- },
- "engines": {
- "node": "^18 || ^20 || ^22"
- }
- },
- "node_modules/@homebridge/dbus-native": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/@homebridge/dbus-native/-/dbus-native-0.6.0.tgz",
- "integrity": "sha512-xObqQeYHTXmt6wsfj10+krTo4xbzR9BgUfX2aQ+edDC9nc4ojfzLScfXCh3zluAm6UCowKw+AFfXn6WLWUOPkg==",
- "dependencies": {
- "@homebridge/long": "^5.2.1",
- "@homebridge/put": "^0.0.8",
- "event-stream": "^4.0.1",
- "hexy": "^0.3.5",
- "minimist": "^1.2.6",
- "safe-buffer": "^5.1.2",
- "xml2js": "^0.6.2"
- },
- "bin": {
- "dbus2js": "bin/dbus2js.js"
- }
- },
- "node_modules/@homebridge/long": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/@homebridge/long/-/long-5.2.1.tgz",
- "integrity": "sha512-i5Df8R63XNPCn+Nj1OgAoRdw9e+jHUQb3CNUbvJneI2iu3j4+OtzQj+5PA1Ce+747NR1SPqZSvyvD483dOT3AA=="
- },
- "node_modules/@homebridge/put": {
- "version": "0.0.8",
- "resolved": "https://registry.npmjs.org/@homebridge/put/-/put-0.0.8.tgz",
- "integrity": "sha512-mwxLHHqKebOmOSU0tsPEWQSBHGApPhuaqtNpCe7U+AMdsduweANiu64E9SXXUtdpyTjsOpgSMLhD1+kbLHD2gA==",
- "engines": {
- "node": ">=0.3.0"
- }
- },
- "node_modules/@humanwhocodes/config-array": {
- "version": "0.11.13",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
- "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==",
- "dev": true,
- "dependencies": {
- "@humanwhocodes/object-schema": "^2.0.1",
- "debug": "^4.1.1",
- "minimatch": "^3.0.5"
- },
- "engines": {
- "node": ">=10.10.0"
- }
- },
- "node_modules/@humanwhocodes/module-importer": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
- "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
- "dev": true,
- "engines": {
- "node": ">=12.22"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/nzakas"
- }
- },
- "node_modules/@humanwhocodes/object-schema": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz",
- "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==",
- "dev": true
- },
- "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"
- }
- },
- "node_modules/@isaacs/cliui/node_modules/ansi-regex": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
- "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-regex?sponsor=1"
- }
- },
- "node_modules/@isaacs/cliui/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/@isaacs/cliui/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/@isaacs/cliui/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/@isaacs/cliui/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/@isaacs/cliui/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/@isaacs/fs-minipass": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
- "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "minipass": "^7.0.4"
- },
- "engines": {
- "node": ">=18.0.0"
- }
- },
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
- "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
- "dev": true,
- "dependencies": {
- "@jridgewell/set-array": "^1.0.1",
- "@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.9"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
- "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
- "dev": true,
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/set-array": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
- "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
- "dev": true,
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.4.15",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
- "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
- "dev": true
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.20",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz",
- "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==",
- "dev": true,
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "node_modules/@leichtgewicht/ip-codec": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz",
- "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==",
- "license": "MIT"
- },
- "node_modules/@napi-rs/wasm-runtime": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.4.tgz",
- "integrity": "sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/core": "^1.1.0",
- "@emnapi/runtime": "^1.1.0",
- "@tybys/wasm-util": "^0.9.0"
- }
- },
- "node_modules/@node-red/editor-api": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/@node-red/editor-api/-/editor-api-4.0.8.tgz",
- "integrity": "sha512-ngsyd/Ro5oyefE+jCJa43fU9WLIGWFkTvifTheU9fj+epSgCGHQLLMOoEvs4FKOaPJ8L4dAqHgD/kik9c73rdg==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@node-red/editor-client": "4.0.8",
- "@node-red/util": "4.0.8",
- "bcryptjs": "2.4.3",
- "body-parser": "1.20.3",
- "clone": "2.1.2",
- "cors": "2.8.5",
- "express": "4.21.2",
- "express-session": "1.18.1",
- "memorystore": "1.6.7",
- "mime": "3.0.0",
- "multer": "1.4.5-lts.1",
- "mustache": "4.2.0",
- "oauth2orize": "1.12.0",
- "passport": "0.7.0",
- "passport-http-bearer": "1.0.1",
- "passport-oauth2-client-password": "0.1.2",
- "ws": "7.5.10"
- },
- "optionalDependencies": {
- "@node-rs/bcrypt": "1.10.4"
- }
- },
- "node_modules/@node-red/editor-client": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/@node-red/editor-client/-/editor-client-4.0.8.tgz",
- "integrity": "sha512-LQI24xhXio4iftiiAvZ191Zjo9N1MsD0563aHGwsqGaLKxCTfOa+G1t5LslQoYGf0qMcYusf6Nftc2+5Q4nf/g==",
- "dev": true,
- "license": "Apache-2.0"
- },
- "node_modules/@node-red/nodes": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/@node-red/nodes/-/nodes-4.0.8.tgz",
- "integrity": "sha512-DAj0DyImWZ6lJo7D0LS/tFntkCEiUMAMMKBkyZjOudGLhxppaa99uzcDgQnSkM9vLSU1Uczxc9zHDY3RhxIpdA==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "acorn": "8.12.1",
- "acorn-walk": "8.3.4",
- "ajv": "8.17.1",
- "body-parser": "1.20.3",
- "cheerio": "1.0.0-rc.10",
- "content-type": "1.0.5",
- "cookie": "0.7.2",
- "cookie-parser": "1.4.7",
- "cors": "2.8.5",
- "cronosjs": "1.7.1",
- "denque": "2.1.0",
- "form-data": "4.0.0",
- "fs-extra": "11.2.0",
- "got": "12.6.1",
- "hash-sum": "2.0.0",
- "hpagent": "1.2.0",
- "https-proxy-agent": "5.0.1",
- "iconv-lite": "0.6.3",
- "is-utf8": "0.2.1",
- "js-yaml": "4.1.0",
- "media-typer": "1.1.0",
- "mqtt": "5.7.0",
- "multer": "1.4.5-lts.1",
- "mustache": "4.2.0",
- "node-watch": "0.7.4",
- "on-headers": "1.0.2",
- "raw-body": "3.0.0",
- "tough-cookie": "^5.0.0",
- "uuid": "9.0.1",
- "ws": "7.5.10",
- "xml2js": "0.6.2"
- }
- },
- "node_modules/@node-red/nodes/node_modules/ajv": {
- "version": "8.17.1",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
- "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fast-deep-equal": "^3.1.3",
- "fast-uri": "^3.0.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/@node-red/nodes/node_modules/json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@node-red/nodes/node_modules/raw-body": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
- "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "bytes": "3.1.2",
- "http-errors": "2.0.0",
- "iconv-lite": "0.6.3",
- "unpipe": "1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/@node-red/nodes/node_modules/uuid": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
- "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
- "dev": true,
- "funding": [
- "https://github.com/sponsors/broofa",
- "https://github.com/sponsors/ctavan"
- ],
- "license": "MIT",
- "bin": {
- "uuid": "dist/bin/uuid"
- }
- },
- "node_modules/@node-red/registry": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/@node-red/registry/-/registry-4.0.8.tgz",
- "integrity": "sha512-yZLeMi4crXehsU5VZ9l/TpU9gzVijFlxykDiUB//errA415sdtMMk02yKq+yZVlRyBPAhQRkL97t4/Y3wcWJog==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@node-red/util": "4.0.8",
- "clone": "2.1.2",
- "fs-extra": "11.2.0",
- "semver": "7.6.3",
- "tar": "7.4.3",
- "uglify-js": "3.17.4"
- }
- },
- "node_modules/@node-red/runtime": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/@node-red/runtime/-/runtime-4.0.8.tgz",
- "integrity": "sha512-TYYyDytZr4nYJgkAKwDduCUjOMrIorUnn28aSorHgWCVJEdlllJAbBQgrdDJm6GGqsDNx2iFwmVbgKC3PJbTKg==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@node-red/registry": "4.0.8",
- "@node-red/util": "4.0.8",
- "async-mutex": "0.5.0",
- "clone": "2.1.2",
- "express": "4.21.2",
- "fs-extra": "11.2.0",
- "json-stringify-safe": "5.0.1",
- "rfdc": "^1.3.1"
- }
- },
- "node_modules/@node-red/util": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/@node-red/util/-/util-4.0.8.tgz",
- "integrity": "sha512-Kl2e4i+Oryq5waTMYvY3ntrQtMfy4+hRTMmeXwpkdCa27DTnWfz0grJHIfy0k9F97K7S47gKFOpR6EjRCm0mWw==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "fs-extra": "11.2.0",
- "i18next": "21.10.0",
- "json-stringify-safe": "5.0.1",
- "jsonata": "2.0.5",
- "lodash.clonedeep": "^4.5.0",
- "moment": "2.30.1",
- "moment-timezone": "0.5.46"
- }
- },
- "node_modules/@node-rs/bcrypt": {
- "version": "1.10.4",
- "resolved": "https://registry.npmjs.org/@node-rs/bcrypt/-/bcrypt-1.10.4.tgz",
- "integrity": "sha512-Kzs8HKt2eBeT5VnkeKgiz/QKTjOO3URcvSNEQZahNwZnL6dBeeJQTxxYisc/6969+5n6c3+gNwKvqJsZzmGe7g==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">= 10"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/Brooooooklyn"
- },
- "optionalDependencies": {
- "@node-rs/bcrypt-android-arm-eabi": "1.10.4",
- "@node-rs/bcrypt-android-arm64": "1.10.4",
- "@node-rs/bcrypt-darwin-arm64": "1.10.4",
- "@node-rs/bcrypt-darwin-x64": "1.10.4",
- "@node-rs/bcrypt-freebsd-x64": "1.10.4",
- "@node-rs/bcrypt-linux-arm-gnueabihf": "1.10.4",
- "@node-rs/bcrypt-linux-arm64-gnu": "1.10.4",
- "@node-rs/bcrypt-linux-arm64-musl": "1.10.4",
- "@node-rs/bcrypt-linux-x64-gnu": "1.10.4",
- "@node-rs/bcrypt-linux-x64-musl": "1.10.4",
- "@node-rs/bcrypt-wasm32-wasi": "1.10.4",
- "@node-rs/bcrypt-win32-arm64-msvc": "1.10.4",
- "@node-rs/bcrypt-win32-ia32-msvc": "1.10.4",
- "@node-rs/bcrypt-win32-x64-msvc": "1.10.4"
- }
- },
- "node_modules/@node-rs/bcrypt-android-arm-eabi": {
- "version": "1.10.4",
- "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-android-arm-eabi/-/bcrypt-android-arm-eabi-1.10.4.tgz",
- "integrity": "sha512-55ajutuTdfK1hKseyliflnxzNtxszQQ/EoLtgJlgCe7rI24vGP9EEEZDznB/u9OaJ14/AYzZtIhkEOYdbIdw0A==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@node-rs/bcrypt-android-arm64": {
- "version": "1.10.4",
- "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-android-arm64/-/bcrypt-android-arm64-1.10.4.tgz",
- "integrity": "sha512-dCgQT7nH65tORmJw2hQ6zQgFmmC+/JBYZUWtf7pPZI76AVAn5tc7cIUrxYoV4OT1+uD63b9Av+mS1fT2EPzWEg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@node-rs/bcrypt-darwin-arm64": {
- "version": "1.10.4",
- "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-darwin-arm64/-/bcrypt-darwin-arm64-1.10.4.tgz",
- "integrity": "sha512-gmHdWikHL3YVZgqXAHT+X/PG+kqIyNlPeFAWKdby83RkDI8FUiPV4qqGilgNnBmVWKkobRae9/I1HDbc4Sbhyg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@node-rs/bcrypt-darwin-x64": {
- "version": "1.10.4",
- "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-darwin-x64/-/bcrypt-darwin-x64-1.10.4.tgz",
- "integrity": "sha512-WDzL1WKRtoyTkH6IMPx95Mkd6XaeN0VWJbSDMqQY6AFBOk03yJEj7YYXshCcF+Ur6KBBVSwRf6sdFJ15NI1Z3g==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@node-rs/bcrypt-freebsd-x64": {
- "version": "1.10.4",
- "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-freebsd-x64/-/bcrypt-freebsd-x64-1.10.4.tgz",
- "integrity": "sha512-seSPJi+4MIUd1faL/n/wmDdDwaynd/FTkvTnb7qzCk8LBT+/dxi7MTz+uaD8KYDREcB9Wmhv+lwr0S9/jBTcjg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@node-rs/bcrypt-linux-arm-gnueabihf": {
- "version": "1.10.4",
- "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm-gnueabihf/-/bcrypt-linux-arm-gnueabihf-1.10.4.tgz",
- "integrity": "sha512-YcMLUtN9cGNTWKnaXslxGO1M0S5b4QN9KYhuyG6Kju27RfqvU5UbmpKElCsEUO2EIjxGwzvPu59T+Fyh6sVbwg==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@node-rs/bcrypt-linux-arm64-gnu": {
- "version": "1.10.4",
- "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm64-gnu/-/bcrypt-linux-arm64-gnu-1.10.4.tgz",
- "integrity": "sha512-uYGUK/mO8SiftqmVSAePWxgK82vg+X/gtrVRJi95yq2iwp1+fYJX3ndxCyYPmeplBbd3NJ/F5lPT3FC/IHTTGw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@node-rs/bcrypt-linux-arm64-musl": {
- "version": "1.10.4",
- "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm64-musl/-/bcrypt-linux-arm64-musl-1.10.4.tgz",
- "integrity": "sha512-rLvSMW/gVUBd2k2gAqQfuOReHWd9+jvz58E3i1TbkRE3a5ChvjOFc9qKPEmXuXuD9Mdj7gUwcYwpq8MdB5MtNw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@node-rs/bcrypt-linux-x64-gnu": {
- "version": "1.10.4",
- "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-x64-gnu/-/bcrypt-linux-x64-gnu-1.10.4.tgz",
- "integrity": "sha512-I++6bh+BIp70X/D/crlSgCq8K0s9nGvzmvAGFkqSG4h3LBtjJx4RKbygnoWvcBV9ErK1rvcjfMyjwZt1ukueFA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@node-rs/bcrypt-linux-x64-musl": {
- "version": "1.10.4",
- "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-x64-musl/-/bcrypt-linux-x64-musl-1.10.4.tgz",
- "integrity": "sha512-f9RPl/5n2NS0mMJXB4IYbodKnq5HzOK5x1b9eKbcjsY0rw3mJC3K0XRFc8iaw1a5chA+xV1TPXz5mkykmr2CQQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@node-rs/bcrypt-wasm32-wasi": {
- "version": "1.10.4",
- "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-wasm32-wasi/-/bcrypt-wasm32-wasi-1.10.4.tgz",
- "integrity": "sha512-VaDOf+wic0yoHFimMkC5VMa/33BNqg6ieD+C/ibb7Av3NnVW4/W9YpDpqAWMR2w3fA40uTLWZ7FZSrcFck27oA==",
- "cpu": [
- "wasm32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@napi-rs/wasm-runtime": "^0.2.3"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/@node-rs/bcrypt-win32-arm64-msvc": {
- "version": "1.10.4",
- "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-arm64-msvc/-/bcrypt-win32-arm64-msvc-1.10.4.tgz",
- "integrity": "sha512-M7sGnbKPvhYJ5b76ywXiEwR4mIs/JSDHjRrhm9fshKAvltQrwc3Mou22TJggvDN3gKOF1W85uPiM2OgGX/jxMg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@node-rs/bcrypt-win32-ia32-msvc": {
- "version": "1.10.4",
- "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-ia32-msvc/-/bcrypt-win32-ia32-msvc-1.10.4.tgz",
- "integrity": "sha512-zn/n4DYnuOfC2JgmVDa0JHP+5DUqAOTl2jmV3yrMrmN+StDT4Om5wtvWxvEmgv3CkeZAuAU3Y/fwjSXIpZ0Fhg==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@node-rs/bcrypt-win32-x64-msvc": {
- "version": "1.10.4",
- "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-x64-msvc/-/bcrypt-win32-x64-msvc-1.10.4.tgz",
- "integrity": "sha512-ynQokTTGbuLu/cckaD8dNcE+Zsfam1zElE+teNol8AxcL7Jv+ghJItSnRthPRV/vLxuycDF2DIICgpXG/p9jrQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@nodelib/fs.scandir": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
- "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
- "dev": true,
- "dependencies": {
- "@nodelib/fs.stat": "2.0.5",
- "run-parallel": "^1.1.9"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.stat": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
- "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
- "dev": true,
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.walk": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
- "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
- "dev": true,
- "dependencies": {
- "@nodelib/fs.scandir": "2.1.5",
- "fastq": "^1.6.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nrchkb/logger": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/@nrchkb/logger/-/logger-3.1.1.tgz",
- "integrity": "sha512-37m4lq7Jemg7qzkBflD+VZ1HnFdZv10k9hgglonFXTBMrLmXxkXllWelCKDGABVkfx1hjijAz6IpQoIF+Oo9yw==",
- "license": "Apache-2.0",
- "dependencies": {
- "debug": "^4.3.5"
- }
- },
- "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.1.0",
- "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.0.tgz",
- "integrity": "sha512-Zwq5OCzuwJC2jwqmpEQt7Ds1DTi6BWSwoGkbb1n9pO3hzb35BoJELx7c0T23iDkBGkh2e7tvOtjF3tr3OaQHDQ==",
- "dev": true,
- "engines": {
- "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/unts"
- }
- },
- "node_modules/@sindresorhus/is": {
- "version": "5.6.0",
- "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz",
- "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/is?sponsor=1"
- }
- },
- "node_modules/@sinonjs/commons": {
- "version": "1.8.6",
- "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz",
- "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==",
- "dev": true,
- "dependencies": {
- "type-detect": "4.0.8"
- }
- },
- "node_modules/@sinonjs/fake-timers": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz",
- "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==",
- "dev": true,
- "dependencies": {
- "@sinonjs/commons": "^1.7.0"
- }
- },
- "node_modules/@sinonjs/samsam": {
- "version": "6.1.3",
- "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.1.3.tgz",
- "integrity": "sha512-nhOb2dWPeb1sd3IQXL/dVPnKHDOAFfvichtBf4xV00/rU1QbPCQqKMbvIheIjqwVjh7qIgf2AHTHi391yMOMpQ==",
- "dev": true,
- "dependencies": {
- "@sinonjs/commons": "^1.6.0",
- "lodash.get": "^4.4.2",
- "type-detect": "^4.0.8"
- }
- },
- "node_modules/@sinonjs/text-encoding": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz",
- "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==",
- "dev": true
- },
- "node_modules/@szmarczak/http-timer": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz",
- "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "defer-to-connect": "^2.0.1"
- },
- "engines": {
- "node": ">=14.16"
- }
- },
- "node_modules/@tsconfig/node10": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
- "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
- "dev": true
- },
- "node_modules/@tsconfig/node12": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
- "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
- "dev": true
- },
- "node_modules/@tsconfig/node14": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
- "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
- "dev": true
- },
- "node_modules/@tsconfig/node16": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
- "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
- "dev": true
- },
- "node_modules/@tybys/wasm-util": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz",
- "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@types/ace": {
- "version": "0.0.52",
- "resolved": "https://registry.npmjs.org/@types/ace/-/ace-0.0.52.tgz",
- "integrity": "sha512-YPF9S7fzpuyrxru+sG/rrTpZkC6gpHBPF14W3x70kqVOD+ks6jkYLapk4yceh36xej7K4HYxcyz9ZDQ2lTvwgQ==",
- "dev": true
- },
- "node_modules/@types/body-parser": {
- "version": "1.19.2",
- "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
- "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==",
- "dev": true,
- "dependencies": {
- "@types/connect": "*",
- "@types/node": "*"
- }
- },
- "node_modules/@types/connect": {
- "version": "3.4.35",
- "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
- "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==",
- "dev": true,
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@types/cookiejar": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.2.tgz",
- "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==",
- "dev": true
- },
- "node_modules/@types/cors": {
- "version": "2.8.13",
- "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz",
- "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==",
- "dev": true,
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@types/express": {
- "version": "4.17.17",
- "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz",
- "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==",
- "dev": true,
- "dependencies": {
- "@types/body-parser": "*",
- "@types/express-serve-static-core": "^4.17.33",
- "@types/qs": "*",
- "@types/serve-static": "*"
- }
- },
- "node_modules/@types/express-serve-static-core": {
- "version": "4.17.35",
- "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz",
- "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==",
- "dev": true,
- "dependencies": {
- "@types/node": "*",
- "@types/qs": "*",
- "@types/range-parser": "*",
- "@types/send": "*"
- }
- },
- "node_modules/@types/http-cache-semantics": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz",
- "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/http-errors": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz",
- "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==",
- "dev": true
- },
- "node_modules/@types/jquery": {
- "version": "3.5.30",
- "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.30.tgz",
- "integrity": "sha512-nbWKkkyb919DOUxjmRVk8vwtDb0/k8FKncmUKFi+NY+QXqWltooxTrswvz4LspQwxvLdvzBN1TImr6cw3aQx2A==",
- "dev": true,
- "dependencies": {
- "@types/sizzle": "*"
- }
- },
- "node_modules/@types/mime": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
- "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==",
- "dev": true
- },
- "node_modules/@types/minimist": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz",
- "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==",
- "dev": true
- },
- "node_modules/@types/mocha": {
- "version": "10.0.10",
- "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz",
- "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/node": {
- "version": "18.19.34",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.34.tgz",
- "integrity": "sha512-eXF4pfBNV5DAMKGbI02NnDtWrQ40hAN558/2vvS4gMpMIxaf6JmD7YjnZbq0Q9TDSSkKBamime8ewRoomHdt4g==",
- "dev": true,
- "dependencies": {
- "undici-types": "~5.26.4"
- }
- },
- "node_modules/@types/node-persist": {
- "version": "3.1.8",
- "resolved": "https://registry.npmjs.org/@types/node-persist/-/node-persist-3.1.8.tgz",
- "integrity": "sha512-QLidg6/SadZYPrTKxtxL1A85XBoQlG40bhoMdhu6DH6+eNCMr2j+RGfFZ9I9+IY8W/PDwQonJ+iBWD62jZjMfg==",
- "dev": true,
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@types/node-red": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/@types/node-red/-/node-red-1.3.5.tgz",
- "integrity": "sha512-LBP8TmXJszHOoRgieyxgUrspvatmTZlkPRftlSNGE9TVJCQzSSyX3tF/Qe4evQlIUBmMGOijxcUOcKZSvq4piQ==",
- "dev": true,
- "dependencies": {
- "@types/express": "*",
- "@types/node-red__editor-api": "*",
- "@types/node-red__editor-client": "*",
- "@types/node-red__registry": "*",
- "@types/node-red__runtime": "*",
- "@types/node-red__util": "*"
- }
- },
- "node_modules/@types/node-red__editor-api": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/@types/node-red__editor-api/-/node-red__editor-api-1.3.5.tgz",
- "integrity": "sha512-VE0o/gJzHVBTD2OBhpWth3sjU06TYLlLvlPh62Whs9FXUY0FdFKqWXbaG+ymYQqZreL1ZvTKfFmj0H7LnVEUeg==",
- "dev": true,
- "dependencies": {
- "@types/express": "*",
- "@types/node-red__runtime": "*"
- }
- },
- "node_modules/@types/node-red__editor-client": {
- "version": "1.3.11",
- "resolved": "https://registry.npmjs.org/@types/node-red__editor-client/-/node-red__editor-client-1.3.11.tgz",
- "integrity": "sha512-Y8FGsMfec4TAVfULabH/Jui+4Cj4F3xx9v4GDpoTN5X9uHwOxdRi9UDtdvG+se/S76CFg6VjsctpJW0WjJUXgw==",
- "dev": true,
- "dependencies": {
- "@types/ace": "*",
- "@types/jquery": "*",
- "@types/node-red__registry": "*",
- "@types/node-red__runtime": "*",
- "@types/node-red__util": "*"
- }
- },
- "node_modules/@types/node-red__registry": {
- "version": "1.3.10",
- "resolved": "https://registry.npmjs.org/@types/node-red__registry/-/node-red__registry-1.3.10.tgz",
- "integrity": "sha512-sWjQMHn/k3OTFlrG7ljcfOMjsl1OdFEvDkRHoBga2srUjbtecELEcPaQ4WY5xsJdoXuhgxvhGh/5+ZPhpNTXEA==",
- "dev": true,
- "dependencies": {
- "@types/express": "*",
- "@types/node-red__runtime": "*",
- "@types/node-red__util": "*"
- }
- },
- "node_modules/@types/node-red__runtime": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/@types/node-red__runtime/-/node-red__runtime-1.3.8.tgz",
- "integrity": "sha512-v5wsFjL6/kQ/YSz7WjC1J9yvE+NP8r5uivQTMBxnNnBabmDJo+dBmdp0rqJczbPNQS0ze7JGDQWz3Iuve+pYlw==",
- "dev": true,
- "dependencies": {
- "@types/cors": "*",
- "@types/express": "*",
- "@types/node-red__editor-api": "*",
- "@types/node-red__util": "*",
- "@types/passport": "*"
- }
- },
- "node_modules/@types/node-red__util": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/@types/node-red__util/-/node-red__util-1.3.8.tgz",
- "integrity": "sha512-FQRxaZyUJlyh2phJevzMSF4H8jrsOUmFg05eyhRX5lvDcc/VqdZWcYdAq9dZPRgIwHJwLBttEh9mG3DAcMJiUg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node-red__registry": "*",
- "@types/node-red__runtime": "*",
- "jsonata": "2.0.5"
- }
- },
- "node_modules/@types/node-red-node-test-helper": {
- "version": "0.3.4",
- "resolved": "https://registry.npmjs.org/@types/node-red-node-test-helper/-/node-red-node-test-helper-0.3.4.tgz",
- "integrity": "sha512-g6XWeB9twf+Y3ADRZpmks95rFexElomsM8a8WyWsTaNZKFaPSTGpENsOCBnR8tOG2okiNtoZCaW6tJM4ZL3X3Q==",
- "dev": true,
- "dependencies": {
- "@types/node-red": "*",
- "@types/node-red__runtime": "*",
- "@types/sinon": "*",
- "@types/supertest": "*"
- }
- },
- "node_modules/@types/normalize-package-data": {
- "version": "2.4.4",
- "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz",
- "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
- "dev": true
- },
- "node_modules/@types/passport": {
- "version": "1.0.12",
- "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.12.tgz",
- "integrity": "sha512-QFdJ2TiAEoXfEQSNDISJR1Tm51I78CymqcBa8imbjo6dNNu+l2huDxxbDEIoFIwOSKMkOfHEikyDuZ38WwWsmw==",
- "dev": true,
- "dependencies": {
- "@types/express": "*"
- }
- },
- "node_modules/@types/qs": {
- "version": "6.9.7",
- "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
- "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==",
- "dev": true
- },
- "node_modules/@types/range-parser": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
- "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==",
- "dev": true
- },
- "node_modules/@types/readable-stream": {
- "version": "4.0.18",
- "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.18.tgz",
- "integrity": "sha512-21jK/1j+Wg+7jVw1xnSwy/2Q1VgVjWuFssbYGTREPUBeZ+rqVFl2udq0IkxzPC0ZhOzVceUbyIACFZKLqKEBlA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*",
- "safe-buffer": "~5.1.1"
- }
- },
- "node_modules/@types/readable-stream/node_modules/safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/semver": {
- "version": "7.5.8",
- "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
- "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
- "dev": true
- },
- "node_modules/@types/send": {
- "version": "0.17.1",
- "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz",
- "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==",
- "dev": true,
- "dependencies": {
- "@types/mime": "^1",
- "@types/node": "*"
- }
- },
- "node_modules/@types/serve-static": {
- "version": "1.15.2",
- "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz",
- "integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==",
- "dev": true,
- "dependencies": {
- "@types/http-errors": "*",
- "@types/mime": "*",
- "@types/node": "*"
- }
- },
- "node_modules/@types/sinon": {
- "version": "10.0.16",
- "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.16.tgz",
- "integrity": "sha512-j2Du5SYpXZjJVJtXBokASpPRj+e2z+VUhCPHmM6WMfe3dpHu6iVKJMU6AiBcMp/XTAYnEj6Wc1trJUWwZ0QaAQ==",
- "dev": true,
- "dependencies": {
- "@types/sinonjs__fake-timers": "*"
- }
- },
- "node_modules/@types/sinonjs__fake-timers": {
- "version": "8.1.2",
- "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz",
- "integrity": "sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==",
- "dev": true
- },
- "node_modules/@types/sizzle": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.8.tgz",
- "integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==",
- "dev": true
- },
- "node_modules/@types/superagent": {
- "version": "4.1.18",
- "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.18.tgz",
- "integrity": "sha512-LOWgpacIV8GHhrsQU+QMZuomfqXiqzz3ILLkCtKx3Us6AmomFViuzKT9D693QTKgyut2oCytMG8/efOop+DB+w==",
- "dev": true,
- "dependencies": {
- "@types/cookiejar": "*",
- "@types/node": "*"
- }
- },
- "node_modules/@types/supertest": {
- "version": "2.0.12",
- "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-2.0.12.tgz",
- "integrity": "sha512-X3HPWTwXRerBZS7Mo1k6vMVR1Z6zmJcDVn5O/31whe0tnjE4te6ZJSJGq1RiqHPjzPdMTfjCFogDJmwng9xHaQ==",
- "dev": true,
- "dependencies": {
- "@types/superagent": "*"
- }
- },
- "node_modules/@types/uuid": {
- "version": "10.0.0",
- "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz",
- "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==",
- "dev": true
- },
- "node_modules/@types/ws": {
- "version": "8.5.13",
- "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz",
- "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@typescript-eslint/eslint-plugin": {
- "version": "7.16.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.0.tgz",
- "integrity": "sha512-py1miT6iQpJcs1BiJjm54AMzeuMPBSPuKPlnT8HlfudbcS5rYeX5jajpLf3mrdRh9dA/Ec2FVUY0ifeVNDIhZw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@eslint-community/regexpp": "^4.10.0",
- "@typescript-eslint/scope-manager": "7.16.0",
- "@typescript-eslint/type-utils": "7.16.0",
- "@typescript-eslint/utils": "7.16.0",
- "@typescript-eslint/visitor-keys": "7.16.0",
- "graphemer": "^1.4.0",
- "ignore": "^5.3.1",
- "natural-compare": "^1.4.0",
- "ts-api-utils": "^1.3.0"
- },
- "engines": {
- "node": "^18.18.0 || >=20.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "@typescript-eslint/parser": "^7.0.0",
- "eslint": "^8.56.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/parser": {
- "version": "7.16.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.0.tgz",
- "integrity": "sha512-ar9E+k7CU8rWi2e5ErzQiC93KKEFAXA2Kky0scAlPcxYblLt8+XZuHUZwlyfXILyQa95P6lQg+eZgh/dDs3+Vw==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "@typescript-eslint/scope-manager": "7.16.0",
- "@typescript-eslint/types": "7.16.0",
- "@typescript-eslint/typescript-estree": "7.16.0",
- "@typescript-eslint/visitor-keys": "7.16.0",
- "debug": "^4.3.4"
- },
- "engines": {
- "node": "^18.18.0 || >=20.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.56.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/scope-manager": {
- "version": "7.16.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.0.tgz",
- "integrity": "sha512-8gVv3kW6n01Q6TrI1cmTZ9YMFi3ucDT7i7aI5lEikk2ebk1AEjrwX8MDTdaX5D7fPXMBLvnsaa0IFTAu+jcfOw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/types": "7.16.0",
- "@typescript-eslint/visitor-keys": "7.16.0"
- },
- "engines": {
- "node": "^18.18.0 || >=20.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/type-utils": {
- "version": "7.16.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.0.tgz",
- "integrity": "sha512-j0fuUswUjDHfqV/UdW6mLtOQQseORqfdmoBNDFOqs9rvNVR2e+cmu6zJu/Ku4SDuqiJko6YnhwcL8x45r8Oqxg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/typescript-estree": "7.16.0",
- "@typescript-eslint/utils": "7.16.0",
- "debug": "^4.3.4",
- "ts-api-utils": "^1.3.0"
- },
- "engines": {
- "node": "^18.18.0 || >=20.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.56.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/types": {
- "version": "7.16.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.0.tgz",
- "integrity": "sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^18.18.0 || >=20.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree": {
- "version": "7.16.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.0.tgz",
- "integrity": "sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "@typescript-eslint/types": "7.16.0",
- "@typescript-eslint/visitor-keys": "7.16.0",
- "debug": "^4.3.4",
- "globby": "^11.1.0",
- "is-glob": "^4.0.3",
- "minimatch": "^9.0.4",
- "semver": "^7.6.0",
- "ts-api-utils": "^1.3.0"
- },
- "engines": {
- "node": "^18.18.0 || >=20.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/@typescript-eslint/utils": {
- "version": "7.16.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.0.tgz",
- "integrity": "sha512-PqP4kP3hb4r7Jav+NiRCntlVzhxBNWq6ZQ+zQwII1y/G/1gdIPeYDCKr2+dH6049yJQsWZiHU6RlwvIFBXXGNA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@eslint-community/eslint-utils": "^4.4.0",
- "@typescript-eslint/scope-manager": "7.16.0",
- "@typescript-eslint/types": "7.16.0",
- "@typescript-eslint/typescript-estree": "7.16.0"
- },
- "engines": {
- "node": "^18.18.0 || >=20.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.56.0"
- }
- },
- "node_modules/@typescript-eslint/visitor-keys": {
- "version": "7.16.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.0.tgz",
- "integrity": "sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/types": "7.16.0",
- "eslint-visitor-keys": "^3.4.3"
- },
- "engines": {
- "node": "^18.18.0 || >=20.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@ungap/structured-clone": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
- "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
- "dev": true
- },
- "node_modules/abbrev": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
- "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
- "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==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "event-target-shim": "^5.0.0"
- },
- "engines": {
- "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==",
- "dev": true,
- "dependencies": {
- "mime-types": "~2.1.34",
- "negotiator": "0.6.3"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/acorn": {
- "version": "8.12.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
- "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "acorn": "bin/acorn"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/acorn-jsx": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
- "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
- "dev": true,
- "peerDependencies": {
- "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
- }
- },
- "node_modules/acorn-walk": {
- "version": "8.3.4",
- "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
- "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "acorn": "^8.11.0"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/agent-base": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
- "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "debug": "4"
- },
- "engines": {
- "node": ">= 6.0.0"
- }
- },
- "node_modules/aggregate-error": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz",
- "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==",
- "dev": true,
- "dependencies": {
- "clean-stack": "^4.0.0",
- "indent-string": "^5.0.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
- "dev": true,
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/ansi-colors": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
- "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "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,
- "engines": {
- "node": ">=8"
- }
- },
- "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/anymatch": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
- "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
- "dev": true,
- "dependencies": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/append-field": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz",
- "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/arg": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
- "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
- "dev": true
- },
- "node_modules/argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true
- },
- "node_modules/array-buffer-byte-length": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz",
- "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==",
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.5",
- "is-array-buffer": "^3.0.4"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/array-flatten": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-3.0.0.tgz",
- "integrity": "sha512-zPMVc3ZYlGLNk4mpK1NzP2wg0ml9t7fUgDsayR5Y5rSzxQilzR9FGu/EH2jQOcKSAeAfWeylyW8juy3OkWRvNA==",
- "license": "MIT"
- },
- "node_modules/array-union": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
- "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/arrify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
- "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/asap": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
- "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
- "dev": true
- },
- "node_modules/async-mutex": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.5.0.tgz",
- "integrity": "sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
- "dev": true
- },
- "node_modules/available-typed-arrays": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
- "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
- "license": "MIT",
- "dependencies": {
- "possible-typed-array-names": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/axios": {
- "version": "1.7.7",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
- "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "follow-redirects": "^1.15.6",
- "form-data": "^4.0.0",
- "proxy-from-env": "^1.1.0"
- }
- },
- "node_modules/babel-eslint": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz",
- "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==",
- "deprecated": "babel-eslint is now @babel/eslint-parser. This package will no longer receive updates.",
- "dev": true,
- "dependencies": {
- "@babel/code-frame": "^7.0.0",
- "@babel/parser": "^7.7.0",
- "@babel/traverse": "^7.7.0",
- "@babel/types": "^7.7.0",
- "eslint-visitor-keys": "^1.0.0",
- "resolve": "^1.12.0"
- },
- "engines": {
- "node": ">=6"
- },
- "peerDependencies": {
- "eslint": ">= 4.12.1"
- }
- },
- "node_modules/babel-eslint/node_modules/eslint-visitor-keys": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
- "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "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
- },
- "node_modules/base64-js": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
- "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
- "dev": true,
- "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"
- },
- "node_modules/basic-auth": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
- "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
- "dev": true,
- "dependencies": {
- "safe-buffer": "5.1.2"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/basic-auth/node_modules/safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- },
- "node_modules/bcryptjs": {
- "version": "2.4.3",
- "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz",
- "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/binary-extensions": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
- "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/bl": {
- "version": "6.0.18",
- "resolved": "https://registry.npmjs.org/bl/-/bl-6.0.18.tgz",
- "integrity": "sha512-2k76XmWCuvu9HTvu3tFOl5HDdCH0wLZ/jHYva/LBVJmc9oX8yUtNQjxrFmbTdXsCSmIxwVTANZPNDfMQrvHFUw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/readable-stream": "^4.0.0",
- "buffer": "^6.0.3",
- "inherits": "^2.0.4",
- "readable-stream": "^4.2.0"
- }
- },
- "node_modules/body-parser": {
- "version": "1.20.3",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
- "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "bytes": "3.1.2",
- "content-type": "~1.0.5",
- "debug": "2.6.9",
- "depd": "2.0.0",
- "destroy": "1.2.0",
- "http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
- "on-finished": "2.4.1",
- "qs": "6.13.0",
- "raw-body": "2.5.2",
- "type-is": "~1.6.18",
- "unpipe": "1.0.0"
- },
- "engines": {
- "node": ">= 0.8",
- "npm": "1.2.8000 || >= 1.4.16"
- }
- },
- "node_modules/body-parser/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "dev": true,
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/body-parser/node_modules/iconv-lite": {
- "version": "0.4.24",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
- "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
- "dev": true,
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/body-parser/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "dev": true
- },
- "node_modules/bonjour-hap": {
- "version": "3.8.0",
- "resolved": "https://registry.npmjs.org/bonjour-hap/-/bonjour-hap-3.8.0.tgz",
- "integrity": "sha512-l/Ptvrt/pjN2pCgiVyyA0EkE0uVoXXYZ4DW4xhL4kDVBaw0w54/3Jhdhzn5EyT1Z8YhNXiNhSX0uW6xz2zSxqQ==",
- "license": "MIT",
- "dependencies": {
- "array-flatten": "^3.0.0",
- "deep-equal": "^2.2.3",
- "multicast-dns": "^7.2.5",
- "multicast-dns-service-types": "^1.1.0"
- }
- },
- "node_modules/boolbase": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
- "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "dev": true,
- "dependencies": {
- "fill-range": "^7.1.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/browser-stdout": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
- "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
- "dev": true
- },
- "node_modules/buffer": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
- "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
- "dev": true,
- "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",
- "dependencies": {
- "base64-js": "^1.3.1",
- "ieee754": "^1.2.1"
- }
- },
- "node_modules/buffer-from": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
- "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
- },
- "node_modules/busboy": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
- "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
- "dev": true,
- "dependencies": {
- "streamsearch": "^1.1.0"
- },
- "engines": {
- "node": ">=10.16.0"
- }
- },
- "node_modules/bytes": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
- "dev": true,
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/cacheable-lookup": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz",
- "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14.16"
- }
- },
- "node_modules/cacheable-request": {
- "version": "10.2.14",
- "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz",
- "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/http-cache-semantics": "^4.0.2",
- "get-stream": "^6.0.1",
- "http-cache-semantics": "^4.1.1",
- "keyv": "^4.5.3",
- "mimic-response": "^4.0.0",
- "normalize-url": "^8.0.0",
- "responselike": "^3.0.0"
- },
- "engines": {
- "node": ">=14.16"
- }
- },
- "node_modules/call-bind": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
- "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
- "dependencies": {
- "es-define-property": "^1.0.0",
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2",
- "get-intrinsic": "^1.2.4",
- "set-function-length": "^1.2.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/callsites": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
- "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/camelcase": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
- "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/camelcase-keys": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-7.0.2.tgz",
- "integrity": "sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==",
- "dev": true,
- "dependencies": {
- "camelcase": "^6.3.0",
- "map-obj": "^4.1.0",
- "quick-lru": "^5.1.1",
- "type-fest": "^1.2.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "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/cheerio": {
- "version": "1.0.0-rc.10",
- "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz",
- "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cheerio-select": "^1.5.0",
- "dom-serializer": "^1.3.2",
- "domhandler": "^4.2.0",
- "htmlparser2": "^6.1.0",
- "parse5": "^6.0.1",
- "parse5-htmlparser2-tree-adapter": "^6.0.1",
- "tslib": "^2.2.0"
- },
- "engines": {
- "node": ">= 6"
- },
- "funding": {
- "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
- }
- },
- "node_modules/cheerio-select": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.6.0.tgz",
- "integrity": "sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "css-select": "^4.3.0",
- "css-what": "^6.0.1",
- "domelementtype": "^2.2.0",
- "domhandler": "^4.3.1",
- "domutils": "^2.8.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/fb55"
- }
- },
- "node_modules/chokidar": {
- "version": "3.5.3",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
- "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
- "dev": true,
- "funding": [
- {
- "type": "individual",
- "url": "https://paulmillr.com/funding/"
- }
- ],
- "dependencies": {
- "anymatch": "~3.1.2",
- "braces": "~3.0.2",
- "glob-parent": "~5.1.2",
- "is-binary-path": "~2.1.0",
- "is-glob": "~4.0.1",
- "normalize-path": "~3.0.0",
- "readdirp": "~3.6.0"
- },
- "engines": {
- "node": ">= 8.10.0"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/chokidar/node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/chownr": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
- "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
- "dev": true,
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/clean-stack": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz",
- "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==",
- "dev": true,
- "dependencies": {
- "escape-string-regexp": "5.0.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/clean-stack/node_modules/escape-string-regexp": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
- "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/cli-table": {
- "version": "0.3.11",
- "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.11.tgz",
- "integrity": "sha512-IqLQi4lO0nIB4tcdTpN4LCB9FI3uqrJZK7RC515EnhZ6qBaglkIgICb1wjeAqpdoOabm1+SuQtkXIPdYC93jhQ==",
- "dev": true,
- "dependencies": {
- "colors": "1.0.3"
- },
- "engines": {
- "node": ">= 0.2.0"
- }
- },
- "node_modules/cliui": {
- "version": "7.0.4",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
- "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
- "dev": true,
- "dependencies": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
- "wrap-ansi": "^7.0.0"
- }
- },
- "node_modules/clone": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
- "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
- "dev": true,
- "engines": {
- "node": ">=0.8"
- }
- },
- "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/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/colors": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
- "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.1.90"
- }
- },
- "node_modules/combined-stream": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
- "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "dev": true,
- "dependencies": {
- "delayed-stream": "~1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/commist": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/commist/-/commist-3.2.0.tgz",
- "integrity": "sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/component-emitter": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz",
- "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==",
- "dev": true,
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true
- },
- "node_modules/concat-stream": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
- "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==",
- "dev": true,
- "engines": [
- "node >= 6.0"
- ],
- "license": "MIT",
- "dependencies": {
- "buffer-from": "^1.0.0",
- "inherits": "^2.0.3",
- "readable-stream": "^3.0.2",
- "typedarray": "^0.0.6"
- }
- },
- "node_modules/concat-stream/node_modules/readable-stream": {
- "version": "3.6.2",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
- "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/content-disposition": {
- "version": "0.5.4",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
- "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
- "dev": true,
- "dependencies": {
- "safe-buffer": "5.2.1"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "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==",
- "dev": true,
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/cookie": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
- "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/cookie-parser": {
- "version": "1.4.7",
- "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.7.tgz",
- "integrity": "sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cookie": "0.7.2",
- "cookie-signature": "1.0.6"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/cookie-signature": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
- "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
- "dev": true
- },
- "node_modules/cookiejar": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
- "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==",
- "dev": true
- },
- "node_modules/core-util-is": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
- "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
- "dev": true,
- "license": "MIT"
- },
- "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==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "object-assign": "^4",
- "vary": "^1"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/create-require": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
- "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
- "dev": true
- },
- "node_modules/cronosjs": {
- "version": "1.7.1",
- "resolved": "https://registry.npmjs.org/cronosjs/-/cronosjs-1.7.1.tgz",
- "integrity": "sha512-d6S6+ep7dJxsAG8OQQCdKuByI/S/AV64d9OF5mtmcykOyPu92cAkAnF3Tbc9s5oOaLQBYYQmTNvjqYRkPJ/u5Q==",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": ">=8.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==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/css-select": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz",
- "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "boolbase": "^1.0.0",
- "css-what": "^6.0.1",
- "domhandler": "^4.3.1",
- "domutils": "^2.8.0",
- "nth-check": "^2.0.1"
- },
- "funding": {
- "url": "https://github.com/sponsors/fb55"
- }
- },
- "node_modules/css-what": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
- "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
- "dev": true,
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">= 6"
- },
- "funding": {
- "url": "https://github.com/sponsors/fb55"
- }
- },
- "node_modules/debug": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
- "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/decamelize": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
- "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/decamelize-keys": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz",
- "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==",
- "dev": true,
- "dependencies": {
- "decamelize": "^1.1.0",
- "map-obj": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/decamelize-keys/node_modules/decamelize": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
- "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/decamelize-keys/node_modules/map-obj": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
- "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/decompress-response": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
- "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "mimic-response": "^3.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/decompress-response/node_modules/mimic-response": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
- "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/deep-equal": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz",
- "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==",
- "license": "MIT",
- "dependencies": {
- "array-buffer-byte-length": "^1.0.0",
- "call-bind": "^1.0.5",
- "es-get-iterator": "^1.1.3",
- "get-intrinsic": "^1.2.2",
- "is-arguments": "^1.1.1",
- "is-array-buffer": "^3.0.2",
- "is-date-object": "^1.0.5",
- "is-regex": "^1.1.4",
- "is-shared-array-buffer": "^1.0.2",
- "isarray": "^2.0.5",
- "object-is": "^1.1.5",
- "object-keys": "^1.1.1",
- "object.assign": "^4.1.4",
- "regexp.prototype.flags": "^1.5.1",
- "side-channel": "^1.0.4",
- "which-boxed-primitive": "^1.0.2",
- "which-collection": "^1.0.1",
- "which-typed-array": "^1.1.13"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/deep-is": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
- "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
- "dev": true
- },
- "node_modules/defer-to-connect": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
- "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/define-data-property": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
- "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
- "dependencies": {
- "es-define-property": "^1.0.0",
- "es-errors": "^1.3.0",
- "gopd": "^1.0.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/define-properties": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
- "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
- "license": "MIT",
- "dependencies": {
- "define-data-property": "^1.0.1",
- "has-property-descriptors": "^1.0.0",
- "object-keys": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/del": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/del/-/del-7.1.0.tgz",
- "integrity": "sha512-v2KyNk7efxhlyHpjEvfyxaAihKKK0nWCuf6ZtqZcFFpQRG0bJ12Qsr0RpvsICMjAAZ8DOVCxrlqpxISlMHC4Kg==",
- "dev": true,
- "dependencies": {
- "globby": "^13.1.2",
- "graceful-fs": "^4.2.10",
- "is-glob": "^4.0.3",
- "is-path-cwd": "^3.0.0",
- "is-path-inside": "^4.0.0",
- "p-map": "^5.5.0",
- "rimraf": "^3.0.2",
- "slash": "^4.0.0"
- },
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/del-cli": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/del-cli/-/del-cli-5.1.0.tgz",
- "integrity": "sha512-xwMeh2acluWeccsfzE7VLsG3yTr7nWikbfw+xhMnpRrF15pGSkw+3/vJZWlGoE4I86UiLRNHicmKt4tkIX9Jtg==",
- "dev": true,
- "dependencies": {
- "del": "^7.1.0",
- "meow": "^10.1.3"
- },
- "bin": {
- "del": "cli.js",
- "del-cli": "cli.js"
- },
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/del/node_modules/globby": {
- "version": "13.2.2",
- "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz",
- "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==",
- "dev": true,
- "dependencies": {
- "dir-glob": "^3.0.1",
- "fast-glob": "^3.3.0",
- "ignore": "^5.2.4",
- "merge2": "^1.4.1",
- "slash": "^4.0.0"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/del/node_modules/is-path-inside": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz",
- "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/del/node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "deprecated": "Rimraf versions prior to v4 are no longer supported",
- "dev": true,
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/del/node_modules/slash": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz",
- "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
- "dev": true,
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/denque": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
- "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/depd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
- "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
- "dev": true,
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/destroy": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
- "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
- "dev": true,
- "engines": {
- "node": ">= 0.8",
- "npm": "1.2.8000 || >= 1.4.16"
- }
- },
- "node_modules/dezalgo": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
- "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
- "dev": true,
- "dependencies": {
- "asap": "^2.0.0",
- "wrappy": "1"
- }
- },
- "node_modules/diff": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
- "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
- "dev": true,
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.3.1"
- }
- },
- "node_modules/dir-glob": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
- "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
- "dev": true,
- "dependencies": {
- "path-type": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/dns-packet": {
- "version": "5.6.1",
- "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz",
- "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==",
- "license": "MIT",
- "dependencies": {
- "@leichtgewicht/ip-codec": "^2.0.1"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/doctrine": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
- "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
- "dev": true,
- "dependencies": {
- "esutils": "^2.0.2"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/dom-serializer": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
- "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "domelementtype": "^2.0.1",
- "domhandler": "^4.2.0",
- "entities": "^2.0.0"
- },
- "funding": {
- "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
- }
- },
- "node_modules/domelementtype": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
- "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/fb55"
- }
- ],
- "license": "BSD-2-Clause"
- },
- "node_modules/domhandler": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
- "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "domelementtype": "^2.2.0"
- },
- "engines": {
- "node": ">= 4"
- },
- "funding": {
- "url": "https://github.com/fb55/domhandler?sponsor=1"
- }
- },
- "node_modules/domutils": {
- "version": "2.8.0",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
- "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "dom-serializer": "^1.0.1",
- "domelementtype": "^2.2.0",
- "domhandler": "^4.2.0"
- },
- "funding": {
- "url": "https://github.com/fb55/domutils?sponsor=1"
- }
- },
- "node_modules/duplexer": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
- "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg=="
- },
- "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==",
- "dev": true
- },
- "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
- },
- "node_modules/encodeurl": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
- "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/enquirer": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz",
- "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-colors": "^4.1.1",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/entities": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
- "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
- "dev": true,
- "license": "BSD-2-Clause",
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
- "node_modules/error-ex": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
- "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
- "dev": true,
- "dependencies": {
- "is-arrayish": "^0.2.1"
- }
- },
- "node_modules/es-define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
- "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
- "dependencies": {
- "get-intrinsic": "^1.2.4"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-errors": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
- "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-get-iterator": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz",
- "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==",
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.3",
- "has-symbols": "^1.0.3",
- "is-arguments": "^1.1.1",
- "is-map": "^2.0.2",
- "is-set": "^2.0.2",
- "is-string": "^1.0.7",
- "isarray": "^2.0.5",
- "stop-iteration-iterator": "^1.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/escalade": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
- "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/escape-html": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
- "dev": true,
- "license": "MIT"
- },
- "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/eslint": {
- "version": "8.56.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz",
- "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==",
- "dev": true,
- "dependencies": {
- "@eslint-community/eslint-utils": "^4.2.0",
- "@eslint-community/regexpp": "^4.6.1",
- "@eslint/eslintrc": "^2.1.4",
- "@eslint/js": "8.56.0",
- "@humanwhocodes/config-array": "^0.11.13",
- "@humanwhocodes/module-importer": "^1.0.1",
- "@nodelib/fs.walk": "^1.2.8",
- "@ungap/structured-clone": "^1.2.0",
- "ajv": "^6.12.4",
- "chalk": "^4.0.0",
- "cross-spawn": "^7.0.2",
- "debug": "^4.3.2",
- "doctrine": "^3.0.0",
- "escape-string-regexp": "^4.0.0",
- "eslint-scope": "^7.2.2",
- "eslint-visitor-keys": "^3.4.3",
- "espree": "^9.6.1",
- "esquery": "^1.4.2",
- "esutils": "^2.0.2",
- "fast-deep-equal": "^3.1.3",
- "file-entry-cache": "^6.0.1",
- "find-up": "^5.0.0",
- "glob-parent": "^6.0.2",
- "globals": "^13.19.0",
- "graphemer": "^1.4.0",
- "ignore": "^5.2.0",
- "imurmurhash": "^0.1.4",
- "is-glob": "^4.0.0",
- "is-path-inside": "^3.0.3",
- "js-yaml": "^4.1.0",
- "json-stable-stringify-without-jsonify": "^1.0.1",
- "levn": "^0.4.1",
- "lodash.merge": "^4.6.2",
- "minimatch": "^3.1.2",
- "natural-compare": "^1.4.0",
- "optionator": "^0.9.3",
- "strip-ansi": "^6.0.1",
- "text-table": "^0.2.0"
- },
- "bin": {
- "eslint": "bin/eslint.js"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/eslint-config-prettier": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
- "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
- "dev": true,
- "bin": {
- "eslint-config-prettier": "bin/cli.js"
- },
- "peerDependencies": {
- "eslint": ">=7.0.0"
- }
- },
- "node_modules/eslint-plugin-prettier": {
- "version": "5.1.3",
- "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz",
- "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==",
- "dev": true,
- "dependencies": {
- "prettier-linter-helpers": "^1.0.0",
- "synckit": "^0.8.6"
- },
- "engines": {
- "node": "^14.18.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint-plugin-prettier"
- },
- "peerDependencies": {
- "@types/eslint": ">=8.0.0",
- "eslint": ">=8.0.0",
- "eslint-config-prettier": "*",
- "prettier": ">=3.0.0"
- },
- "peerDependenciesMeta": {
- "@types/eslint": {
- "optional": true
- },
- "eslint-config-prettier": {
- "optional": true
- }
- }
- },
- "node_modules/eslint-plugin-simple-import-sort": {
- "version": "12.1.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.1.tgz",
- "integrity": "sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==",
- "dev": true,
- "license": "MIT",
- "peerDependencies": {
- "eslint": ">=5.0.0"
- }
- },
- "node_modules/eslint-scope": {
- "version": "7.2.2",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
- "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
- "dev": true,
- "dependencies": {
- "esrecurse": "^4.3.0",
- "estraverse": "^5.2.0"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/eslint-visitor-keys": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
- "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
- "dev": true,
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/eslint/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/eslint/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/eslint/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/eslint/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/eslint/node_modules/escape-string-regexp": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
- "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/eslint/node_modules/globals": {
- "version": "13.21.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz",
- "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==",
- "dev": true,
- "dependencies": {
- "type-fest": "^0.20.2"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/eslint/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/eslint/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/eslint/node_modules/type-fest": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
- "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/espree": {
- "version": "9.6.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
- "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
- "dev": true,
- "dependencies": {
- "acorn": "^8.9.0",
- "acorn-jsx": "^5.3.2",
- "eslint-visitor-keys": "^3.4.1"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/esquery": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
- "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
- "dev": true,
- "dependencies": {
- "estraverse": "^5.1.0"
- },
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/esrecurse": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
- "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
- "dev": true,
- "dependencies": {
- "estraverse": "^5.2.0"
- },
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/estraverse": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
- "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
- "dev": true,
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/esutils": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
- "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/etag": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
- "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/event-stream": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-4.0.1.tgz",
- "integrity": "sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==",
- "dependencies": {
- "duplexer": "^0.1.1",
- "from": "^0.1.7",
- "map-stream": "0.0.7",
- "pause-stream": "^0.0.11",
- "split": "^1.0.1",
- "stream-combiner": "^0.2.2",
- "through": "^2.3.8"
- }
- },
- "node_modules/event-target-shim": {
- "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==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/events": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
- "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.8.x"
- }
- },
- "node_modules/express": {
- "version": "4.21.2",
- "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
- "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "accepts": "~1.3.8",
- "array-flatten": "1.1.1",
- "body-parser": "1.20.3",
- "content-disposition": "0.5.4",
- "content-type": "~1.0.4",
- "cookie": "0.7.1",
- "cookie-signature": "1.0.6",
- "debug": "2.6.9",
- "depd": "2.0.0",
- "encodeurl": "~2.0.0",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "finalhandler": "1.3.1",
- "fresh": "0.5.2",
- "http-errors": "2.0.0",
- "merge-descriptors": "1.0.3",
- "methods": "~1.1.2",
- "on-finished": "2.4.1",
- "parseurl": "~1.3.3",
- "path-to-regexp": "0.1.12",
- "proxy-addr": "~2.0.7",
- "qs": "6.13.0",
- "range-parser": "~1.2.1",
- "safe-buffer": "5.2.1",
- "send": "0.19.0",
- "serve-static": "1.16.2",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "type-is": "~1.6.18",
- "utils-merge": "1.0.1",
- "vary": "~1.1.2"
- },
- "engines": {
- "node": ">= 0.10.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/express-session": {
- "version": "1.18.1",
- "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.1.tgz",
- "integrity": "sha512-a5mtTqEaZvBCL9A9aqkrtfz+3SMDhOVUnjafjo+s7A9Txkq+SVX2DLvSp1Zrv4uCXa3lMSK3viWnh9Gg07PBUA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cookie": "0.7.2",
- "cookie-signature": "1.0.7",
- "debug": "2.6.9",
- "depd": "~2.0.0",
- "on-headers": "~1.0.2",
- "parseurl": "~1.3.3",
- "safe-buffer": "5.2.1",
- "uid-safe": "~2.1.5"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/express-session/node_modules/cookie-signature": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz",
- "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/express-session/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/express-session/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/express/node_modules/array-flatten": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
- "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
- "dev": true
- },
- "node_modules/express/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==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/express/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "dev": true,
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/express/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "dev": true
- },
- "node_modules/fast-deep-equal": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
- },
- "node_modules/fast-diff": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
- "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
- "dev": true
- },
- "node_modules/fast-glob": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
- "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
- "dev": true,
- "dependencies": {
- "@nodelib/fs.stat": "^2.0.2",
- "@nodelib/fs.walk": "^1.2.3",
- "glob-parent": "^5.1.2",
- "merge2": "^1.3.0",
- "micromatch": "^4.0.4"
- },
- "engines": {
- "node": ">=8.6.0"
- }
- },
- "node_modules/fast-glob/node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "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
- },
- "node_modules/fast-levenshtein": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
- "dev": true
- },
- "node_modules/fast-safe-stringify": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
- "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
- "dev": true
- },
- "node_modules/fast-srp-hap": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/fast-srp-hap/-/fast-srp-hap-2.0.4.tgz",
- "integrity": "sha512-lHRYYaaIbMrhZtsdGTwPN82UbqD9Bv8QfOlKs+Dz6YRnByZifOh93EYmf2iEWFtkOEIqR2IK8cFD0UN5wLIWBQ==",
- "engines": {
- "node": ">=10.17.0"
- }
- },
- "node_modules/fast-unique-numbers": {
- "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==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.23.8",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.1.0"
- }
- },
- "node_modules/fast-uri": {
- "version": "3.0.5",
- "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.5.tgz",
- "integrity": "sha512-5JnBCWpFlMo0a3ciDy/JckMzzv1U9coZrIhedq+HXxxUfDTAiS0LA8OKVao4G9BxmCVck/jtA5r3KAtRWEyD8Q==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/fastify"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/fastify"
- }
- ],
- "license": "BSD-3-Clause"
- },
- "node_modules/fastq": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
- "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
- "dev": true,
- "dependencies": {
- "reusify": "^1.0.4"
- }
- },
- "node_modules/file-entry-cache": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
- "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
- "dev": true,
- "dependencies": {
- "flat-cache": "^3.0.4"
- },
- "engines": {
- "node": "^10.12.0 || >=12.0.0"
- }
- },
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "dev": true,
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/finalhandler": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
- "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "debug": "2.6.9",
- "encodeurl": "~2.0.0",
- "escape-html": "~1.0.3",
- "on-finished": "2.4.1",
- "parseurl": "~1.3.3",
- "statuses": "2.0.1",
- "unpipe": "~1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/finalhandler/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/finalhandler/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/find-up": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
- "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
- "dev": true,
- "dependencies": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/flat": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
- "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
- "dev": true,
- "bin": {
- "flat": "cli.js"
- }
- },
- "node_modules/flat-cache": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
- "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
- "dev": true,
- "dependencies": {
- "flatted": "^3.1.0",
- "rimraf": "^3.0.2"
- },
- "engines": {
- "node": "^10.12.0 || >=12.0.0"
- }
- },
- "node_modules/flat-cache/node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "dev": true,
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/flatted": {
- "version": "3.2.7",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
- "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
- "dev": true
- },
- "node_modules/follow-redirects": {
- "version": "1.15.9",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
- "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
- "dev": true,
- "funding": [
- {
- "type": "individual",
- "url": "https://github.com/sponsors/RubenVerborgh"
- }
- ],
- "license": "MIT",
- "engines": {
- "node": ">=4.0"
- },
- "peerDependenciesMeta": {
- "debug": {
- "optional": true
- }
- }
- },
- "node_modules/for-each": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
- "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
- "license": "MIT",
- "dependencies": {
- "is-callable": "^1.1.3"
- }
- },
- "node_modules/foreground-child": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
- "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "cross-spawn": "^7.0.0",
- "signal-exit": "^4.0.1"
- },
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/form-data": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
- "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
- "dev": true,
- "dependencies": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "mime-types": "^2.1.12"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/form-data-encoder": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz",
- "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 14.17"
- }
- },
- "node_modules/formidable": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.1.tgz",
- "integrity": "sha512-WJWKelbRHN41m5dumb0/k8TeAx7Id/y3a+Z7QfhxP/htI9Js5zYaEDtG8uMgG0vM0lOlqnmjE99/kfpOYi/0Og==",
- "dev": true,
- "dependencies": {
- "dezalgo": "^1.0.4",
- "hexoid": "^1.0.0",
- "once": "^1.4.0"
- },
- "funding": {
- "url": "https://ko-fi.com/tunnckoCore/commissions"
- }
- },
- "node_modules/forwarded": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
- "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
- "dev": true,
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/fresh": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
- "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/from": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
- "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g=="
- },
- "node_modules/fs-extra": {
- "version": "11.2.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
- "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
- "dev": true,
- "dependencies": {
- "graceful-fs": "^4.2.0",
- "jsonfile": "^6.0.1",
- "universalify": "^2.0.0"
- },
- "engines": {
- "node": ">=14.14"
- }
- },
- "node_modules/fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
- "dev": true
- },
- "node_modules/function-bind": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/functions-have-names": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
- "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/futoin-hkdf": {
- "version": "1.5.3",
- "resolved": "https://registry.npmjs.org/futoin-hkdf/-/futoin-hkdf-1.5.3.tgz",
- "integrity": "sha512-SewY5KdMpaoCeh7jachEWFsh1nNlaDjNHZXWqL5IGwtpEYHTgkr2+AMCgNwKWkcc0wpSYrZfR7he4WdmHFtDxQ==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/get-caller-file": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
- "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
- "dev": true,
- "engines": {
- "node": "6.* || 8.* || >= 10.*"
- }
- },
- "node_modules/get-intrinsic": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
- "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
- "dependencies": {
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2",
- "has-proto": "^1.0.1",
- "has-symbols": "^1.0.3",
- "hasown": "^2.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/get-stream": {
- "version": "6.0.1",
- "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"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/glob": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
- "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
- "dev": true,
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.0.4",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/glob-parent": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
- "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
- "dev": true,
- "dependencies": {
- "is-glob": "^4.0.3"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "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/globby": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
- "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "array-union": "^2.1.0",
- "dir-glob": "^3.0.1",
- "fast-glob": "^3.2.9",
- "ignore": "^5.2.0",
- "merge2": "^1.4.1",
- "slash": "^3.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/gopd": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
- "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
- "dependencies": {
- "get-intrinsic": "^1.1.3"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/got": {
- "version": "12.6.1",
- "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz",
- "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@sindresorhus/is": "^5.2.0",
- "@szmarczak/http-timer": "^5.0.1",
- "cacheable-lookup": "^7.0.0",
- "cacheable-request": "^10.2.8",
- "decompress-response": "^6.0.0",
- "form-data-encoder": "^2.1.2",
- "get-stream": "^6.0.1",
- "http2-wrapper": "^2.1.10",
- "lowercase-keys": "^3.0.0",
- "p-cancelable": "^3.0.0",
- "responselike": "^3.0.0"
- },
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/got?sponsor=1"
- }
- },
- "node_modules/graceful-fs": {
- "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
- },
- "node_modules/graphemer": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
- "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
- "dev": true
- },
- "node_modules/hap-nodejs": {
- "version": "0.12.3",
- "resolved": "https://registry.npmjs.org/hap-nodejs/-/hap-nodejs-0.12.3.tgz",
- "integrity": "sha512-E6uEwSmDejvzaSAHosjjbWp7/YNo0o+LZtcbH2KoediVOHGG1tYRDGEMyOiG7ZtZn6CwXwr6xqSZTnXTzQCImQ==",
- "license": "Apache-2.0",
- "dependencies": {
- "@homebridge/ciao": "^1.3.1",
- "@homebridge/dbus-native": "^0.6.0",
- "bonjour-hap": "^3.8.0",
- "debug": "^4.3.7",
- "fast-srp-hap": "^2.0.4",
- "futoin-hkdf": "^1.5.3",
- "node-persist": "^0.0.12",
- "source-map-support": "^0.5.21",
- "tslib": "^2.8.0",
- "tweetnacl": "^1.0.3"
- },
- "engines": {
- "node": "^18 || ^20 || ^22"
- }
- },
- "node_modules/hap-nodejs/node_modules/node-persist": {
- "version": "0.0.12",
- "resolved": "https://registry.npmjs.org/node-persist/-/node-persist-0.0.12.tgz",
- "integrity": "sha512-Fbia3FYnURzaql53wLu0t19dmAwQg/tXT6O7YPmdwNwysNKEyFmgoT2BQlPD3XXQnYeiQVNvR5lfvufGwKuxhg==",
- "dependencies": {
- "mkdirp": "~0.5.1",
- "q": "~1.1.1"
- }
- },
- "node_modules/hard-rejection": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
- "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/has": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
- "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
- "dev": true,
- "dependencies": {
- "function-bind": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4.0"
- }
- },
- "node_modules/has-bigints": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
- "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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/has-property-descriptors": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
- "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
- "dependencies": {
- "es-define-property": "^1.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
- "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-symbols": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
- "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-tostringtag": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
- "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
- "license": "MIT",
- "dependencies": {
- "has-symbols": "^1.0.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/hash-sum": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz",
- "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/hasown": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz",
- "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==",
- "dependencies": {
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/he": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
- "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
- "dev": true,
- "bin": {
- "he": "bin/he"
- }
- },
- "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==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/hexoid": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",
- "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/hexy": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/hexy/-/hexy-0.3.5.tgz",
- "integrity": "sha512-UCP7TIZPXz5kxYJnNOym+9xaenxCLor/JyhKieo8y8/bJWunGh9xbhy3YrgYJUQ87WwfXGm05X330DszOfINZw==",
- "bin": {
- "hexy": "bin/hexy_cmd.js"
- },
- "engines": {
- "node": ">=10.4"
- }
- },
- "node_modules/hosted-git-info": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
- "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
- "dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/hosted-git-info/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/hosted-git-info/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- },
- "node_modules/hpagent": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-1.2.0.tgz",
- "integrity": "sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/htmlparser2": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
- "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==",
- "dev": true,
- "funding": [
- "https://github.com/fb55/htmlparser2?sponsor=1",
- {
- "type": "github",
- "url": "https://github.com/sponsors/fb55"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "domelementtype": "^2.0.1",
- "domhandler": "^4.0.0",
- "domutils": "^2.5.2",
- "entities": "^2.0.0"
- }
- },
- "node_modules/http-cache-semantics": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
- "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
- "dev": true,
- "license": "BSD-2-Clause"
- },
- "node_modules/http-errors": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
- "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
- "dev": true,
- "dependencies": {
- "depd": "2.0.0",
- "inherits": "2.0.4",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "toidentifier": "1.0.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/http2-wrapper": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz",
- "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "quick-lru": "^5.1.1",
- "resolve-alpn": "^1.2.0"
- },
- "engines": {
- "node": ">=10.19.0"
- }
- },
- "node_modules/https-proxy-agent": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
- "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "agent-base": "6",
- "debug": "4"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/husky": {
- "version": "9.0.11",
- "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz",
- "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==",
- "dev": true,
- "bin": {
- "husky": "bin.mjs"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/typicode"
- }
- },
- "node_modules/i18next": {
- "version": "21.10.0",
- "resolved": "https://registry.npmjs.org/i18next/-/i18next-21.10.0.tgz",
- "integrity": "sha512-YeuIBmFsGjUfO3qBmMOc0rQaun4mIpGKET5WDwvu8lU7gvwpcariZLNtL0Fzj+zazcHUrlXHiptcFhBMFaxzfg==",
- "dev": true,
- "funding": [
- {
- "type": "individual",
- "url": "https://locize.com"
- },
- {
- "type": "individual",
- "url": "https://locize.com/i18next.html"
- },
- {
- "type": "individual",
- "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.17.2"
- }
- },
- "node_modules/iconv-lite": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/ieee754": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
- "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
- "dev": true,
- "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": "BSD-3-Clause"
- },
- "node_modules/ignore": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
- "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
- "dev": true,
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/import-fresh": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
- "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
- "dev": true,
- "dependencies": {
- "parent-module": "^1.0.0",
- "resolve-from": "^4.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/imurmurhash": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
- "dev": true,
- "engines": {
- "node": ">=0.8.19"
- }
- },
- "node_modules/indent-string": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz",
- "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
- "dev": true,
- "dependencies": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "node_modules/inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "dev": true
- },
- "node_modules/internal-slot": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
- "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "hasown": "^2.0.0",
- "side-channel": "^1.0.4"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/ipaddr.js": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
- "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
- "dev": true,
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/is-arguments": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
- "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.2",
- "has-tostringtag": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-array-buffer": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
- "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==",
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.2.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-arrayish": {
- "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-bigint": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
- "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
- "license": "MIT",
- "dependencies": {
- "has-bigints": "^1.0.1"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-binary-path": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
- "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "dev": true,
- "dependencies": {
- "binary-extensions": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-boolean-object": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
- "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.2",
- "has-tostringtag": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-callable": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
- "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-core-module": {
- "version": "2.13.0",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz",
- "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==",
- "dev": true,
- "dependencies": {
- "has": "^1.0.3"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-date-object": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
- "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
- "license": "MIT",
- "dependencies": {
- "has-tostringtag": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "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,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-map": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
- "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true,
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/is-number-object": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
- "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
- "license": "MIT",
- "dependencies": {
- "has-tostringtag": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-path-cwd": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-3.0.0.tgz",
- "integrity": "sha512-kyiNFFLU0Ampr6SDZitD/DwUo4Zs1nSdnygUBqsu3LooL00Qvb5j+UnvApUn/TTj1J3OuE6BTdQ5rudKmU2ZaA==",
- "dev": true,
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/is-path-inside": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
- "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-plain-obj": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
- "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-regex": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
- "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.2",
- "has-tostringtag": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-set": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
- "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-shared-array-buffer": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz",
- "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==",
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.7"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-string": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
- "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
- "license": "MIT",
- "dependencies": {
- "has-tostringtag": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-symbol": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
- "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
- "license": "MIT",
- "dependencies": {
- "has-symbols": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-unicode-supported": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
- "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/is-utf8": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
- "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/is-weakmap": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
- "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-weakset": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz",
- "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==",
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.7",
- "get-intrinsic": "^1.2.4"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/isarray": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
- "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
- "license": "MIT"
- },
- "node_modules/isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "dev": true
- },
- "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/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==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/js-sdsl"
- }
- },
- "node_modules/js-tokens": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "dev": true
- },
- "node_modules/js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "dev": true,
- "dependencies": {
- "argparse": "^2.0.1"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/jsesc": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
- "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
- "dev": true,
- "bin": {
- "jsesc": "bin/jsesc"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/json-buffer": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
- "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
- "dev": true,
- "license": "MIT"
- },
- "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
- },
- "node_modules/json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "dev": true
- },
- "node_modules/json-stable-stringify-without-jsonify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
- "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
- "dev": true
- },
- "node_modules/json-stringify-safe": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
- "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/jsonata": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/jsonata/-/jsonata-2.0.5.tgz",
- "integrity": "sha512-wEse9+QLIIU5IaCgtJCPsFi/H4F3qcikWzF4bAELZiRz08ohfx3Q6CjDRf4ZPF5P/92RI3KIHtb7u3jqPaHXdQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/jsonfile": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
- "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
- "dev": true,
- "dependencies": {
- "universalify": "^2.0.0"
- },
- "optionalDependencies": {
- "graceful-fs": "^4.1.6"
- }
- },
- "node_modules/just-extend": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz",
- "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==",
- "dev": true
- },
- "node_modules/keyv": {
- "version": "4.5.4",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
- "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "json-buffer": "3.0.1"
- }
- },
- "node_modules/kind-of": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
- "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/levn": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
- "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
- "dev": true,
- "dependencies": {
- "prelude-ls": "^1.2.1",
- "type-check": "~0.4.0"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/lines-and-columns": {
- "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
- },
- "node_modules/locate-path": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
- "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
- "dev": true,
- "dependencies": {
- "p-locate": "^5.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/lodash.clonedeep": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
- "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/lodash.get": {
- "version": "4.4.2",
- "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
- "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
- "dev": true
- },
- "node_modules/lodash.merge": {
- "version": "4.6.2",
- "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
- "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
- "dev": true
- },
- "node_modules/log-symbols": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
- "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
- "dev": true,
- "dependencies": {
- "chalk": "^4.1.0",
- "is-unicode-supported": "^0.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/log-symbols/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/log-symbols/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/log-symbols/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/log-symbols/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/log-symbols/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/log-symbols/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/lowercase-keys": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz",
- "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/lru-cache": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
- "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "pseudomap": "^1.0.2",
- "yallist": "^2.1.2"
- }
- },
- "node_modules/make-error": {
- "version": "1.3.6",
- "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
- "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
- "dev": true
- },
- "node_modules/map-obj": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
- "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/map-stream": {
- "version": "0.0.7",
- "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz",
- "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ=="
- },
- "node_modules/media-typer": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
- "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/memorystore": {
- "version": "1.6.7",
- "resolved": "https://registry.npmjs.org/memorystore/-/memorystore-1.6.7.tgz",
- "integrity": "sha512-OZnmNY/NDrKohPQ+hxp0muBcBKrzKNtHr55DbqSx9hLsYVNnomSAMRAtI7R64t3gf3ID7tHQA7mG4oL3Hu9hdw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "debug": "^4.3.0",
- "lru-cache": "^4.0.3"
- },
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/meow": {
- "version": "10.1.5",
- "resolved": "https://registry.npmjs.org/meow/-/meow-10.1.5.tgz",
- "integrity": "sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==",
- "dev": true,
- "dependencies": {
- "@types/minimist": "^1.2.2",
- "camelcase-keys": "^7.0.0",
- "decamelize": "^5.0.0",
- "decamelize-keys": "^1.1.0",
- "hard-rejection": "^2.1.0",
- "minimist-options": "4.1.0",
- "normalize-package-data": "^3.0.2",
- "read-pkg-up": "^8.0.0",
- "redent": "^4.0.0",
- "trim-newlines": "^4.0.2",
- "type-fest": "^1.2.2",
- "yargs-parser": "^20.2.9"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/meow/node_modules/decamelize": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz",
- "integrity": "sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/merge-descriptors": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
- "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
- "dev": true,
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/methods": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
- "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
- "dev": true,
- "engines": {
- "node": ">= 0.6"
- }
- },
- "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"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/mime": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
- "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "mime": "cli.js"
- },
- "engines": {
- "node": ">=10.0.0"
- }
- },
- "node_modules/mime-db": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "dev": true,
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mime-types": {
- "version": "2.1.35",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "dev": true,
- "dependencies": {
- "mime-db": "1.52.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mimic-response": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz",
- "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/min-indent": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
- "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "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,
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/minimist": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
- "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/minimist-options": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
- "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==",
- "dev": true,
- "dependencies": {
- "arrify": "^1.0.1",
- "is-plain-obj": "^1.1.0",
- "kind-of": "^6.0.3"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/minimist-options/node_modules/is-plain-obj": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
- "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "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/minizlib": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz",
- "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "minipass": "^7.0.4",
- "rimraf": "^5.0.5"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/mkdirp": {
- "version": "0.5.6",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
- "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
- "dependencies": {
- "minimist": "^1.2.6"
- },
- "bin": {
- "mkdirp": "bin/cmd.js"
- }
- },
- "node_modules/mocha": {
- "version": "10.6.0",
- "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.6.0.tgz",
- "integrity": "sha512-hxjt4+EEB0SA0ZDygSS015t65lJw/I2yRCS3Ae+SJ5FrbzrXgfYwJr96f0OvIXdj7h4lv/vLCrH3rkiuizFSvw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-colors": "^4.1.3",
- "browser-stdout": "^1.3.1",
- "chokidar": "^3.5.3",
- "debug": "^4.3.5",
- "diff": "^5.2.0",
- "escape-string-regexp": "^4.0.0",
- "find-up": "^5.0.0",
- "glob": "^8.1.0",
- "he": "^1.2.0",
- "js-yaml": "^4.1.0",
- "log-symbols": "^4.1.0",
- "minimatch": "^5.1.6",
- "ms": "^2.1.3",
- "serialize-javascript": "^6.0.2",
- "strip-json-comments": "^3.1.1",
- "supports-color": "^8.1.1",
- "workerpool": "^6.5.1",
- "yargs": "^16.2.0",
- "yargs-parser": "^20.2.9",
- "yargs-unparser": "^2.0.0"
- },
- "bin": {
- "_mocha": "bin/_mocha",
- "mocha": "bin/mocha.js"
- },
- "engines": {
- "node": ">= 14.0.0"
- }
- },
- "node_modules/mocha/node_modules/brace-expansion": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
- "dev": true,
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
- "node_modules/mocha/node_modules/escape-string-regexp": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
- "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/mocha/node_modules/glob": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
- "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
- "dev": true,
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^5.0.1",
- "once": "^1.3.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/mocha/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/mocha/node_modules/minimatch": {
- "version": "5.1.6",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
- "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/mocha/node_modules/supports-color": {
- "version": "8.1.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
- "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/supports-color?sponsor=1"
- }
- },
- "node_modules/moment": {
- "version": "2.30.1",
- "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
- "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "*"
- }
- },
- "node_modules/moment-timezone": {
- "version": "0.5.46",
- "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.46.tgz",
- "integrity": "sha512-ZXm9b36esbe7OmdABqIWJuBBiLLwAjrN7CE+7sYdCCx82Nabt1wHDj8TVseS59QIlfFPbOoiBPm6ca9BioG4hw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "moment": "^2.29.4"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/mqtt": {
- "version": "5.7.0",
- "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.7.0.tgz",
- "integrity": "sha512-/o0CBYSjZzddmQDV2iglCafsA0xWKpqnS62tGbOLOliubBxszpXO1DAQPyfI7ZcPDG0b9ni7QITn+5FW1E2UTg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/readable-stream": "^4.0.5",
- "@types/ws": "^8.5.9",
- "commist": "^3.2.0",
- "concat-stream": "^2.0.0",
- "debug": "^4.3.4",
- "help-me": "^5.0.0",
- "lru-cache": "^10.0.1",
- "minimist": "^1.2.8",
- "mqtt": "^5.2.0",
- "mqtt-packet": "^9.0.0",
- "number-allocator": "^1.0.14",
- "readable-stream": "^4.4.2",
- "reinterval": "^1.1.0",
- "rfdc": "^1.3.0",
- "split2": "^4.2.0",
- "worker-timers": "^7.1.4",
- "ws": "^8.14.2"
- },
- "bin": {
- "mqtt": "build/bin/mqtt.js",
- "mqtt_pub": "build/bin/pub.js",
- "mqtt_sub": "build/bin/sub.js"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/mqtt-packet": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-9.0.1.tgz",
- "integrity": "sha512-koZF1V/X2RZUI6uD9wN5OK1JxxcG1ofAR4H3LjCw1FkeKzruZQ26aAA6v2m1lZyWONZIR5wMMJFrZJDRNzbiQw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "bl": "^6.0.8",
- "debug": "^4.3.4",
- "process-nextick-args": "^2.0.1"
- }
- },
- "node_modules/mqtt/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==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/mqtt/node_modules/ws": {
- "version": "8.18.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
- "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10.0.0"
- },
- "peerDependencies": {
- "bufferutil": "^4.0.1",
- "utf-8-validate": ">=5.0.2"
- },
- "peerDependenciesMeta": {
- "bufferutil": {
- "optional": true
- },
- "utf-8-validate": {
- "optional": true
- }
- }
- },
- "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/multer": {
- "version": "1.4.5-lts.1",
- "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz",
- "integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "append-field": "^1.0.0",
- "busboy": "^1.0.0",
- "concat-stream": "^1.5.2",
- "mkdirp": "^0.5.4",
- "object-assign": "^4.1.1",
- "type-is": "^1.6.4",
- "xtend": "^4.0.0"
- },
- "engines": {
- "node": ">= 6.0.0"
- }
- },
- "node_modules/multer/node_modules/concat-stream": {
- "version": "1.6.2",
- "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
- "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
- "dev": true,
- "engines": [
- "node >= 0.8"
- ],
- "license": "MIT",
- "dependencies": {
- "buffer-from": "^1.0.0",
- "inherits": "^2.0.3",
- "readable-stream": "^2.2.2",
- "typedarray": "^0.0.6"
- }
- },
- "node_modules/multer/node_modules/isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/multer/node_modules/readable-stream": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
- "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "node_modules/multer/node_modules/safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/multer/node_modules/string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "safe-buffer": "~5.1.0"
- }
- },
- "node_modules/multicast-dns": {
- "version": "7.2.5",
- "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz",
- "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==",
- "license": "MIT",
- "dependencies": {
- "dns-packet": "^5.2.2",
- "thunky": "^1.0.2"
- },
- "bin": {
- "multicast-dns": "cli.js"
- }
- },
- "node_modules/multicast-dns-service-types": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
- "integrity": "sha512-cnAsSVxIDsYt0v7HmC0hWZFwwXSh+E6PgCrREDuN/EsjgLwA5XRmlMHhSiDPrt6HxY1gTivEa/Zh7GtODoLevQ==",
- "license": "MIT"
- },
- "node_modules/mustache": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz",
- "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "mustache": "bin/mustache"
- }
- },
- "node_modules/mute-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz",
- "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "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
- },
- "node_modules/negotiator": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
- "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
- "dev": true,
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/nise": {
- "version": "5.1.4",
- "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz",
- "integrity": "sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==",
- "dev": true,
- "dependencies": {
- "@sinonjs/commons": "^2.0.0",
- "@sinonjs/fake-timers": "^10.0.2",
- "@sinonjs/text-encoding": "^0.7.1",
- "just-extend": "^4.0.2",
- "path-to-regexp": "^1.7.0"
- }
- },
- "node_modules/nise/node_modules/@sinonjs/commons": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz",
- "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==",
- "dev": true,
- "dependencies": {
- "type-detect": "4.0.8"
- }
- },
- "node_modules/nise/node_modules/@sinonjs/fake-timers": {
- "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,
- "dependencies": {
- "@sinonjs/commons": "^3.0.0"
- }
- },
- "node_modules/nise/node_modules/@sinonjs/fake-timers/node_modules/@sinonjs/commons": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz",
- "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==",
- "dev": true,
- "dependencies": {
- "type-detect": "4.0.8"
- }
- },
- "node_modules/nise/node_modules/isarray": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
- "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
- "dev": true
- },
- "node_modules/nise/node_modules/path-to-regexp": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz",
- "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "isarray": "0.0.1"
- }
- },
- "node_modules/node-persist": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/node-persist/-/node-persist-3.1.3.tgz",
- "integrity": "sha512-CaFv+kSZtsc+VeDRldK1yR47k1vPLBpzYB9re2z7LIwITxwBtljMq3s8VQnnr+x3E8pQfHbc5r2IyJsBLJhtXg==",
- "license": "MIT",
- "engines": {
- "node": ">=10.12.0"
- }
- },
- "node_modules/node-red": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/node-red/-/node-red-4.0.8.tgz",
- "integrity": "sha512-0A3qtJh27C9zWwzWe79QUIX0luDF9JxBPmqcIxaLNBgfQBtpQgEhSjz0zIR2NXWtLvBab8L2Ju7rQgnHn4iOXg==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@node-red/editor-api": "4.0.8",
- "@node-red/nodes": "4.0.8",
- "@node-red/runtime": "4.0.8",
- "@node-red/util": "4.0.8",
- "basic-auth": "2.0.1",
- "bcryptjs": "2.4.3",
- "cors": "2.8.5",
- "express": "4.21.2",
- "fs-extra": "11.2.0",
- "node-red-admin": "^4.0.1",
- "nopt": "5.0.0",
- "semver": "7.6.3"
- },
- "bin": {
- "node-red": "red.js",
- "node-red-pi": "bin/node-red-pi"
- },
- "engines": {
- "node": ">=18.5"
- },
- "optionalDependencies": {
- "@node-rs/bcrypt": "1.10.4"
- }
- },
- "node_modules/node-red-admin": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/node-red-admin/-/node-red-admin-4.0.1.tgz",
- "integrity": "sha512-NLZgAM8JgFa/2/7Z4+nSSQrtkuBbfS9m+kxegadhHfuta5rErOx6zrrNhF+yAglMTPlVmdoqgso7VSt3nTRBGQ==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "ansi-colors": "^4.1.3",
- "axios": "^1.7.7",
- "bcryptjs": "^2.4.3",
- "cli-table": "^0.3.11",
- "enquirer": "^2.3.6",
- "minimist": "^1.2.8",
- "mustache": "^4.2.0",
- "read": "^3.0.1"
- },
- "bin": {
- "node-red-admin": "node-red-admin.js"
- },
- "engines": {
- "node": ">=18"
- },
- "optionalDependencies": {
- "@node-rs/bcrypt": "1.10.4"
- }
- },
- "node_modules/node-red-node-test-helper": {
- "version": "0.3.4",
- "resolved": "https://registry.npmjs.org/node-red-node-test-helper/-/node-red-node-test-helper-0.3.4.tgz",
- "integrity": "sha512-OFXGEkKZpLkgoijAgpUIjzn5RF8QnbwPX9RjfI2LWXq1ACfeXkXcW0i1ioiphrokdE3MiWQJtH5omLNnSNdyaQ==",
- "dev": true,
- "dependencies": {
- "body-parser": "^1.20.2",
- "express": "^4.19.2",
- "semver": "^7.5.4",
- "should": "^13.2.3",
- "should-sinon": "^0.0.6",
- "sinon": "^11.1.2",
- "stoppable": "^1.1.0",
- "supertest": "^7.0.0"
- },
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/node-watch": {
- "version": "0.7.4",
- "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.7.4.tgz",
- "integrity": "sha512-RinNxoz4W1cep1b928fuFhvAQ5ag/+1UlMDV7rbyGthBIgsiEouS4kvRayvvboxii4m8eolKOIBo3OjDqbc+uQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/nopt": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
- "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
- "dev": true,
- "dependencies": {
- "abbrev": "1"
- },
- "bin": {
- "nopt": "bin/nopt.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/normalize-package-data": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
- "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==",
- "dev": true,
- "dependencies": {
- "hosted-git-info": "^4.0.1",
- "is-core-module": "^2.5.0",
- "semver": "^7.3.4",
- "validate-npm-package-license": "^3.0.1"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "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,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/normalize-url": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz",
- "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/nth-check": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
- "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "boolbase": "^1.0.0"
- },
- "funding": {
- "url": "https://github.com/fb55/nth-check?sponsor=1"
- }
- },
- "node_modules/number-allocator": {
- "version": "1.0.14",
- "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz",
- "integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "debug": "^4.3.1",
- "js-sdsl": "4.3.0"
- }
- },
- "node_modules/oauth2orize": {
- "version": "1.12.0",
- "resolved": "https://registry.npmjs.org/oauth2orize/-/oauth2orize-1.12.0.tgz",
- "integrity": "sha512-j4XtFDQUBsvUHPjUmvmNDUDMYed2MphMIJBhyxVVe8hGCjkuYnjIsW+D9qk8c5ciXRdnk6x6tEbiO6PLeOZdCQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "debug": "2.x.x",
- "uid2": "0.0.x",
- "utils-merge": "1.x.x"
- },
- "engines": {
- "node": ">= 0.4.0"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/jaredhanson"
- }
- },
- "node_modules/oauth2orize/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/oauth2orize/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "dev": true,
- "license": "MIT"
- },
- "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==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object-inspect": {
- "version": "1.13.2",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
- "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/object-is": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz",
- "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==",
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.7",
- "define-properties": "^1.2.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/object-keys": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
- "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/object.assign": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
- "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==",
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.5",
- "define-properties": "^1.2.1",
- "has-symbols": "^1.0.3",
- "object-keys": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/on-finished": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
- "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
- "dev": true,
- "dependencies": {
- "ee-first": "1.1.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/on-headers": {
- "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==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "dev": true,
- "dependencies": {
- "wrappy": "1"
- }
- },
- "node_modules/optionator": {
- "version": "0.9.3",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
- "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
- "dev": true,
- "dependencies": {
- "@aashutoshrathi/word-wrap": "^1.2.3",
- "deep-is": "^0.1.3",
- "fast-levenshtein": "^2.0.6",
- "levn": "^0.4.1",
- "prelude-ls": "^1.2.1",
- "type-check": "^0.4.0"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/p-cancelable": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz",
- "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12.20"
- }
- },
- "node_modules/p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "dev": true,
- "dependencies": {
- "yocto-queue": "^0.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/p-locate": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
- "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
- "dev": true,
- "dependencies": {
- "p-limit": "^3.0.2"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/p-map": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/p-map/-/p-map-5.5.0.tgz",
- "integrity": "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==",
- "dev": true,
- "dependencies": {
- "aggregate-error": "^4.0.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "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/parent-module": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
- "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
- "dev": true,
- "dependencies": {
- "callsites": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "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,
- "dependencies": {
- "@babel/code-frame": "^7.0.0",
- "error-ex": "^1.3.1",
- "json-parse-even-better-errors": "^2.3.0",
- "lines-and-columns": "^1.1.6"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/parse5": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
- "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/parse5-htmlparser2-tree-adapter": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
- "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "parse5": "^6.0.1"
- }
- },
- "node_modules/parseurl": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
- "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/passport": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/passport/-/passport-0.7.0.tgz",
- "integrity": "sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "passport-strategy": "1.x.x",
- "pause": "0.0.1",
- "utils-merge": "^1.0.1"
- },
- "engines": {
- "node": ">= 0.4.0"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/jaredhanson"
- }
- },
- "node_modules/passport-http-bearer": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/passport-http-bearer/-/passport-http-bearer-1.0.1.tgz",
- "integrity": "sha512-SELQM+dOTuMigr9yu8Wo4Fm3ciFfkMq5h/ZQ8ffi4ELgZrX1xh9PlglqZdcUZ1upzJD/whVyt+YWF62s3U6Ipw==",
- "dev": true,
- "dependencies": {
- "passport-strategy": "1.x.x"
- },
- "engines": {
- "node": ">= 0.4.0"
- }
- },
- "node_modules/passport-oauth2-client-password": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/passport-oauth2-client-password/-/passport-oauth2-client-password-0.1.2.tgz",
- "integrity": "sha512-GHQH4UtaEZvCLulAxGKHYoSsPRoPRmGsdmaZtMh5nmz80yMLQbdMA9Bg2sp4/UW3PIxJH/143hVjPTiXaNngTQ==",
- "dev": true,
- "dependencies": {
- "passport-strategy": "1.x.x"
- },
- "engines": {
- "node": ">= 0.4.0"
- }
- },
- "node_modules/passport-strategy": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
- "integrity": "sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==",
- "dev": true,
- "engines": {
- "node": ">= 0.4.0"
- }
- },
- "node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/path-key": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "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-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-scurry/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==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/path-to-regexp": {
- "version": "0.1.12",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
- "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/path-type": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
- "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/pause": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
- "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==",
- "dev": true
- },
- "node_modules/pause-stream": {
- "version": "0.0.11",
- "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
- "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==",
- "dependencies": {
- "through": "~2.3"
- }
- },
- "node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "dev": true,
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/possible-typed-array-names": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
- "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/prelude-ls": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
- "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
- "dev": true,
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/prettier": {
- "version": "3.4.2",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz",
- "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "prettier": "bin/prettier.cjs"
- },
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/prettier/prettier?sponsor=1"
- }
- },
- "node_modules/prettier-linter-helpers": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
- "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
- "dev": true,
- "dependencies": {
- "fast-diff": "^1.1.2"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "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==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.6.0"
- }
- },
- "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==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/proxy-addr": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
- "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
- "dev": true,
- "dependencies": {
- "forwarded": "0.2.0",
- "ipaddr.js": "1.9.1"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/proxy-from-env": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
- "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/pseudomap": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
- "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/punycode": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
- "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/q": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/q/-/q-1.1.2.tgz",
- "integrity": "sha512-ROtylwux7Vkc4C07oKE/ReigUmb33kVoLtcR4SJ1QVqwaZkBEDL3vX4/kwFzIERQ5PfCl0XafbU8u2YUhyGgVA==",
- "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)",
- "engines": {
- "node": ">=0.6.0",
- "teleport": ">=0.2.0"
- }
- },
- "node_modules/qs": {
- "version": "6.13.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
- "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "side-channel": "^1.0.6"
- },
- "engines": {
- "node": ">=0.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/queue-microtask": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
- "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
- "dev": true,
- "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/quick-lru": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
- "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/random-bytes": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
- "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/randombytes": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
- "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "safe-buffer": "^5.1.0"
- }
- },
- "node_modules/range-parser": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
- "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/raw-body": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
- "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
- "dev": true,
- "dependencies": {
- "bytes": "3.1.2",
- "http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
- "unpipe": "1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/raw-body/node_modules/iconv-lite": {
- "version": "0.4.24",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
- "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
- "dev": true,
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/read": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/read/-/read-3.0.1.tgz",
- "integrity": "sha512-SLBrDU/Srs/9EoWhU5GdbAoxG1GzpQHo/6qiGItaoLJ1thmYpcNIM1qISEUvyHBzfGlWIyd6p2DNi1oV1VmAuw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "mute-stream": "^1.0.0"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/read-pkg": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-6.0.0.tgz",
- "integrity": "sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==",
- "dev": true,
- "dependencies": {
- "@types/normalize-package-data": "^2.4.0",
- "normalize-package-data": "^3.0.2",
- "parse-json": "^5.2.0",
- "type-fest": "^1.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/read-pkg-up": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-8.0.0.tgz",
- "integrity": "sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==",
- "dev": true,
- "dependencies": {
- "find-up": "^5.0.0",
- "read-pkg": "^6.0.0",
- "type-fest": "^1.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "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==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "abort-controller": "^3.0.0",
- "buffer": "^6.0.3",
- "events": "^3.3.0",
- "process": "^0.11.10",
- "string_decoder": "^1.3.0"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
- "node_modules/readdirp": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "dev": true,
- "dependencies": {
- "picomatch": "^2.2.1"
- },
- "engines": {
- "node": ">=8.10.0"
- }
- },
- "node_modules/redent": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/redent/-/redent-4.0.0.tgz",
- "integrity": "sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==",
- "dev": true,
- "dependencies": {
- "indent-string": "^5.0.0",
- "strip-indent": "^4.0.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "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==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/regexp.prototype.flags": {
- "version": "1.5.2",
- "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
- "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==",
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.6",
- "define-properties": "^1.2.1",
- "es-errors": "^1.3.0",
- "set-function-name": "^2.0.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/reinterval": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz",
- "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==",
- "dev": true,
- "license": "MIT"
- },
- "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,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/require-from-string": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
- "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/resolve": {
- "version": "1.22.4",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz",
- "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==",
- "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-alpn": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
- "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/resolve-from": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
- "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/responselike": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz",
- "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "lowercase-keys": "^3.0.0"
- },
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/reusify": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
- "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
- "dev": true,
- "engines": {
- "iojs": ">=1.0.0",
- "node": ">=0.10.0"
- }
- },
- "node_modules/rfdc": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
- "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/rimraf": {
- "version": "5.0.10",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz",
- "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "glob": "^10.3.7"
- },
- "bin": {
- "rimraf": "dist/esm/bin.mjs"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/rimraf/node_modules/brace-expansion": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
- "node_modules/rimraf/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==",
- "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"
- },
- "bin": {
- "glob": "dist/esm/bin.mjs"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/rimraf/node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/run-parallel": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
- "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "dependencies": {
- "queue-microtask": "^1.2.2"
- }
- },
- "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/safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "dev": true
- },
- "node_modules/sax": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
- "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="
- },
- "node_modules/semver": {
- "version": "7.6.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
- "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/send": {
- "version": "0.19.0",
- "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
- "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "debug": "2.6.9",
- "depd": "2.0.0",
- "destroy": "1.2.0",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "fresh": "0.5.2",
- "http-errors": "2.0.0",
- "mime": "1.6.0",
- "ms": "2.1.3",
- "on-finished": "2.4.1",
- "range-parser": "~1.2.1",
- "statuses": "2.0.1"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/send/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/send/node_modules/debug/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/send/node_modules/encodeurl": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
- "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/send/node_modules/mime": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
- "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "mime": "cli.js"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/serialize-javascript": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
- "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "randombytes": "^2.1.0"
- }
- },
- "node_modules/serve-static": {
- "version": "1.16.2",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
- "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "encodeurl": "~2.0.0",
- "escape-html": "~1.0.3",
- "parseurl": "~1.3.3",
- "send": "0.19.0"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/set-function-length": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz",
- "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==",
- "dependencies": {
- "define-data-property": "^1.1.2",
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2",
- "get-intrinsic": "^1.2.3",
- "gopd": "^1.0.1",
- "has-property-descriptors": "^1.0.1"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/set-function-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
- "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
- "license": "MIT",
- "dependencies": {
- "define-data-property": "^1.1.4",
- "es-errors": "^1.3.0",
- "functions-have-names": "^1.2.3",
- "has-property-descriptors": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/setprototypeof": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
- "dev": true
- },
- "node_modules/shebang-command": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
- "dev": true,
- "dependencies": {
- "shebang-regex": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/shebang-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/should": {
- "version": "13.2.3",
- "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz",
- "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==",
- "dev": true,
- "dependencies": {
- "should-equal": "^2.0.0",
- "should-format": "^3.0.3",
- "should-type": "^1.4.0",
- "should-type-adaptors": "^1.0.1",
- "should-util": "^1.0.0"
- }
- },
- "node_modules/should-equal": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz",
- "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==",
- "dev": true,
- "dependencies": {
- "should-type": "^1.4.0"
- }
- },
- "node_modules/should-format": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz",
- "integrity": "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==",
- "dev": true,
- "dependencies": {
- "should-type": "^1.3.0",
- "should-type-adaptors": "^1.0.1"
- }
- },
- "node_modules/should-sinon": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/should-sinon/-/should-sinon-0.0.6.tgz",
- "integrity": "sha512-ScBOH5uW5QVFaONmUnIXANSR6z5B8IKzEmBP3HE5sPOCDuZ88oTMdUdnKoCVQdLcCIrRrhRLPS5YT+7H40a04g==",
- "dev": true,
- "peerDependencies": {
- "should": ">= 8.x"
- }
- },
- "node_modules/should-type": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz",
- "integrity": "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==",
- "dev": true
- },
- "node_modules/should-type-adaptors": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz",
- "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==",
- "dev": true,
- "dependencies": {
- "should-type": "^1.3.0",
- "should-util": "^1.0.0"
- }
- },
- "node_modules/should-util": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz",
- "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==",
- "dev": true
- },
- "node_modules/side-channel": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
- "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.7",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.4",
- "object-inspect": "^1.13.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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"
- }
- },
- "node_modules/sinon": {
- "version": "11.1.2",
- "resolved": "https://registry.npmjs.org/sinon/-/sinon-11.1.2.tgz",
- "integrity": "sha512-59237HChms4kg7/sXhiRcUzdSkKuydDeTiamT/jesUVHshBgL8XAmhgFo0GfK6RruMDM/iRSij1EybmMog9cJw==",
- "dev": true,
- "dependencies": {
- "@sinonjs/commons": "^1.8.3",
- "@sinonjs/fake-timers": "^7.1.2",
- "@sinonjs/samsam": "^6.0.2",
- "diff": "^5.0.0",
- "nise": "^5.1.0",
- "supports-color": "^7.2.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/sinon"
- }
- },
- "node_modules/sinon/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/sinon/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "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/source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/source-map-support": {
- "version": "0.5.21",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
- "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
- "dependencies": {
- "buffer-from": "^1.0.0",
- "source-map": "^0.6.0"
- }
- },
- "node_modules/spdx-correct": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
- "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
- "dev": true,
- "dependencies": {
- "spdx-expression-parse": "^3.0.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "node_modules/spdx-exceptions": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
- "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
- "dev": true
- },
- "node_modules/spdx-expression-parse": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
- "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
- "dev": true,
- "dependencies": {
- "spdx-exceptions": "^2.1.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "node_modules/spdx-license-ids": {
- "version": "3.0.18",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz",
- "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==",
- "dev": true
- },
- "node_modules/split": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
- "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
- "dependencies": {
- "through": "2"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/split2": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
- "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": ">= 10.x"
- }
- },
- "node_modules/statuses": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
- "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
- "dev": true,
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/stop-iteration-iterator": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz",
- "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==",
- "license": "MIT",
- "dependencies": {
- "internal-slot": "^1.0.4"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/stoppable": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz",
- "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==",
- "dev": true,
- "engines": {
- "node": ">=4",
- "npm": ">=6"
- }
- },
- "node_modules/stream-combiner": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz",
- "integrity": "sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==",
- "dependencies": {
- "duplexer": "~0.1.1",
- "through": "~2.3.4"
- }
- },
- "node_modules/streamsearch": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
- "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
- "dev": true,
- "engines": {
- "node": ">=10.0.0"
- }
- },
- "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==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "safe-buffer": "~5.2.0"
- }
- },
- "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,
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "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",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "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,
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "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"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-indent": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz",
- "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==",
- "dev": true,
- "dependencies": {
- "min-indent": "^1.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/strip-json-comments": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
- "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
- "dev": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/superagent": {
- "version": "9.0.2",
- "resolved": "https://registry.npmjs.org/superagent/-/superagent-9.0.2.tgz",
- "integrity": "sha512-xuW7dzkUpcJq7QnhOsnNUgtYp3xRwpt2F7abdRYIpCsAt0hhUqia0EdxyXZQQpNmGtsCzYHryaKSV3q3GJnq7w==",
- "dev": true,
- "dependencies": {
- "component-emitter": "^1.3.0",
- "cookiejar": "^2.1.4",
- "debug": "^4.3.4",
- "fast-safe-stringify": "^2.1.1",
- "form-data": "^4.0.0",
- "formidable": "^3.5.1",
- "methods": "^1.1.2",
- "mime": "2.6.0",
- "qs": "^6.11.0"
- },
- "engines": {
- "node": ">=14.18.0"
- }
- },
- "node_modules/superagent/node_modules/mime": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
- "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
- "dev": true,
- "bin": {
- "mime": "cli.js"
- },
- "engines": {
- "node": ">=4.0.0"
- }
- },
- "node_modules/supertest": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.0.0.tgz",
- "integrity": "sha512-qlsr7fIC0lSddmA3tzojvzubYxvlGtzumcdHgPwbFWMISQwL22MhM2Y3LNt+6w9Yyx7559VW5ab70dgphm8qQA==",
- "dev": true,
- "dependencies": {
- "methods": "^1.1.2",
- "superagent": "^9.0.1"
- },
- "engines": {
- "node": ">=14.18.0"
- }
- },
- "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/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,
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/synckit": {
- "version": "0.8.8",
- "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz",
- "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==",
- "dev": true,
- "dependencies": {
- "@pkgr/core": "^0.1.0",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": "^14.18.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/unts"
- }
- },
- "node_modules/tar": {
- "version": "7.4.3",
- "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz",
- "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "@isaacs/fs-minipass": "^4.0.0",
- "chownr": "^3.0.0",
- "minipass": "^7.1.2",
- "minizlib": "^3.0.1",
- "mkdirp": "^3.0.1",
- "yallist": "^5.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/tar/node_modules/mkdirp": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
- "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "mkdirp": "dist/cjs/src/bin.js"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/tar/node_modules/yallist": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
- "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
- "dev": true,
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/text-table": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
- "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
- "dev": true
- },
- "node_modules/through": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
- "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
- },
- "node_modules/thunky": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
- "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
- "license": "MIT"
- },
- "node_modules/tldts": {
- "version": "6.1.72",
- "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.72.tgz",
- "integrity": "sha512-QNtgIqSUb9o2CoUjX9T5TwaIvUUJFU1+12PJkgt42DFV2yf9J6549yTF2uGloQsJ/JOC8X+gIB81ind97hRiIQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "tldts-core": "^6.1.72"
- },
- "bin": {
- "tldts": "bin/cli.js"
- }
- },
- "node_modules/tldts-core": {
- "version": "6.1.72",
- "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.72.tgz",
- "integrity": "sha512-FW3H9aCaGTJ8l8RVCR3EX8GxsxDbQXuwetwwgXA2chYdsX+NY1ytCBl61narjjehWmCw92tc1AxlcY3668CU8g==",
- "dev": true,
- "license": "MIT"
- },
- "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,
- "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,
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/toidentifier": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
- "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
- "dev": true,
- "engines": {
- "node": ">=0.6"
- }
- },
- "node_modules/tough-cookie": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.0.tgz",
- "integrity": "sha512-rvZUv+7MoBYTiDmFPBrhL7Ujx9Sk+q9wwm22x8c8T5IJaR+Wsyc7TNxbVxo84kZoRJZZMazowFLqpankBEQrGg==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "tldts": "^6.1.32"
- },
- "engines": {
- "node": ">=16"
- }
- },
- "node_modules/trim-newlines": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-4.1.1.tgz",
- "integrity": "sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/ts-api-utils": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
- "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
- "dev": true,
- "engines": {
- "node": ">=16"
- },
- "peerDependencies": {
- "typescript": ">=4.2.0"
- }
- },
- "node_modules/ts-node": {
- "version": "10.9.2",
- "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
- "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
- "dev": true,
- "dependencies": {
- "@cspotcode/source-map-support": "^0.8.0",
- "@tsconfig/node10": "^1.0.7",
- "@tsconfig/node12": "^1.0.7",
- "@tsconfig/node14": "^1.0.0",
- "@tsconfig/node16": "^1.0.2",
- "acorn": "^8.4.1",
- "acorn-walk": "^8.1.1",
- "arg": "^4.1.0",
- "create-require": "^1.1.0",
- "diff": "^4.0.1",
- "make-error": "^1.1.1",
- "v8-compile-cache-lib": "^3.0.1",
- "yn": "3.1.1"
- },
- "bin": {
- "ts-node": "dist/bin.js",
- "ts-node-cwd": "dist/bin-cwd.js",
- "ts-node-esm": "dist/bin-esm.js",
- "ts-node-script": "dist/bin-script.js",
- "ts-node-transpile-only": "dist/bin-transpile.js",
- "ts-script": "dist/bin-script-deprecated.js"
- },
- "peerDependencies": {
- "@swc/core": ">=1.2.50",
- "@swc/wasm": ">=1.2.50",
- "@types/node": "*",
- "typescript": ">=2.7"
- },
- "peerDependenciesMeta": {
- "@swc/core": {
- "optional": true
- },
- "@swc/wasm": {
- "optional": true
- }
- }
- },
- "node_modules/ts-node/node_modules/diff": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
- "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
- "dev": true,
- "engines": {
- "node": ">=0.3.1"
- }
- },
- "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"
- },
- "node_modules/tweetnacl": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
- "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw=="
- },
- "node_modules/type-check": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
- "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
- "dev": true,
- "dependencies": {
- "prelude-ls": "^1.2.1"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "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,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/type-fest": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz",
- "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/type-is": {
- "version": "1.6.18",
- "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
- "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
- "dev": true,
- "dependencies": {
- "media-typer": "0.3.0",
- "mime-types": "~2.1.24"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/type-is/node_modules/media-typer": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
- "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
- "dev": true,
- "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==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/typescript": {
- "version": "5.7.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
- "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=14.17"
- }
- },
- "node_modules/uglify-js": {
- "version": "3.17.4",
- "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz",
- "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==",
- "dev": true,
- "bin": {
- "uglifyjs": "bin/uglifyjs"
- },
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/uid-safe": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
- "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "random-bytes": "~1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/uid2": {
- "version": "0.0.4",
- "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.4.tgz",
- "integrity": "sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/undici-types": {
- "version": "5.26.5",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
- "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
- "dev": true
- },
- "node_modules/universalify": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
- "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
- "dev": true,
- "engines": {
- "node": ">= 10.0.0"
- }
- },
- "node_modules/unpipe": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
- "dev": true,
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/uri-js": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
- "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
- "dev": true,
- "dependencies": {
- "punycode": "^2.1.0"
- }
- },
- "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==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/utils-merge": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
- "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
- "dev": true,
- "engines": {
- "node": ">= 0.4.0"
- }
- },
- "node_modules/uuid": {
- "version": "11.0.5",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.5.tgz",
- "integrity": "sha512-508e6IcKLrhxKdBbcA2b4KQZlLVp2+J5UwQ6F7Drckkc5N9ZJwFa4TgWtsww9UG8fGHbm6gbV19TdM5pQ4GaIA==",
- "funding": [
- "https://github.com/sponsors/broofa",
- "https://github.com/sponsors/ctavan"
- ],
- "license": "MIT",
- "bin": {
- "uuid": "dist/esm/bin/uuid"
- }
- },
- "node_modules/v8-compile-cache-lib": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
- "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
- "dev": true
- },
- "node_modules/validate-npm-package-license": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
- "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
- "dev": true,
- "dependencies": {
- "spdx-correct": "^3.0.0",
- "spdx-expression-parse": "^3.0.0"
- }
- },
- "node_modules/vary": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
- "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
- "dev": true,
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "dev": true,
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "node-which": "bin/node-which"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/which-boxed-primitive": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
- "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
- "license": "MIT",
- "dependencies": {
- "is-bigint": "^1.0.1",
- "is-boolean-object": "^1.1.0",
- "is-number-object": "^1.0.4",
- "is-string": "^1.0.5",
- "is-symbol": "^1.0.3"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/which-collection": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
- "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
- "license": "MIT",
- "dependencies": {
- "is-map": "^2.0.3",
- "is-set": "^2.0.3",
- "is-weakmap": "^2.0.2",
- "is-weakset": "^2.0.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/which-typed-array": {
- "version": "1.1.15",
- "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz",
- "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==",
- "license": "MIT",
- "dependencies": {
- "available-typed-arrays": "^1.0.7",
- "call-bind": "^1.0.7",
- "for-each": "^0.3.3",
- "gopd": "^1.0.1",
- "has-tostringtag": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/worker-timers": {
- "version": "7.1.8",
- "resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-7.1.8.tgz",
- "integrity": "sha512-R54psRKYVLuzff7c1OTFcq/4Hue5Vlz4bFtNEIarpSiCYhpifHU3aIQI29S84o1j87ePCYqbmEJPqwBTf+3sfw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@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": "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==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@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": "7.0.71",
- "resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-7.0.71.tgz",
- "integrity": "sha512-ks/5YKwZsto1c2vmljroppOKCivB/ma97g9y77MAAz2TBBjPPgpoOiS1qYQKIgvGTr2QYPT3XhJWIB6Rj2MVPQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.24.5",
- "tslib": "^2.6.2"
- }
- },
- "node_modules/workerpool": {
- "version": "6.5.1",
- "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz",
- "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==",
- "dev": true,
- "license": "Apache-2.0"
- },
- "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,
- "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/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",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
- }
- },
- "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/wrap-ansi-cjs/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/wrap-ansi-cjs/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/wrap-ansi/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/wrap-ansi/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/wrap-ansi/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "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==",
- "dev": true
- },
- "node_modules/ws": {
- "version": "7.5.10",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
- "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8.3.0"
- },
- "peerDependencies": {
- "bufferutil": "^4.0.1",
- "utf-8-validate": "^5.0.2"
- },
- "peerDependenciesMeta": {
- "bufferutil": {
- "optional": true
- },
- "utf-8-validate": {
- "optional": true
- }
- }
- },
- "node_modules/xml2js": {
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz",
- "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==",
- "dependencies": {
- "sax": ">=0.6.0",
- "xmlbuilder": "~11.0.0"
- },
- "engines": {
- "node": ">=4.0.0"
- }
- },
- "node_modules/xmlbuilder": {
- "version": "11.0.1",
- "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
- "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/xtend": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
- "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.4"
- }
- },
- "node_modules/y18n": {
- "version": "5.0.8",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
- "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/yallist": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
- "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/yargs": {
- "version": "16.2.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
- "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
- "dev": true,
- "dependencies": {
- "cliui": "^7.0.2",
- "escalade": "^3.1.1",
- "get-caller-file": "^2.0.5",
- "require-directory": "^2.1.1",
- "string-width": "^4.2.0",
- "y18n": "^5.0.5",
- "yargs-parser": "^20.2.2"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/yargs-parser": {
- "version": "20.2.9",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
- "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/yargs-unparser": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
- "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
- "dev": true,
- "dependencies": {
- "camelcase": "^6.0.0",
- "decamelize": "^4.0.0",
- "flat": "^5.0.2",
- "is-plain-obj": "^2.1.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/yn": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
- "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "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,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
+ "name": "node-red-contrib-homekit-bridged",
+ "version": "2.0.0-dev.5",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "node-red-contrib-homekit-bridged",
+ "version": "2.0.0-dev.5",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@homebridge/hap-nodejs": "2.0.2",
+ "@nrchkb/logger": "~3.1.1",
+ "node-persist": "^3.1.3",
+ "semver": "~7.7.3",
+ "uuid": "~13.0.0"
+ },
+ "devDependencies": {
+ "@biomejs/biome": "2.3.7",
+ "@homebridge/ciao": "~1.3.4",
+ "@node-red/registry": "^4.1.1",
+ "@types/node": "^20",
+ "@types/node-persist": "^3.1.8",
+ "@types/node-red": "^1.3.5",
+ "@types/node-red-node-test-helper": "^0.3.5",
+ "@types/semver": "^7.7.1",
+ "@types/uuid": "^10.0.0",
+ "del-cli": "^7.0.0",
+ "husky": "^9.1.7",
+ "node-red": "^4.1.1",
+ "node-red-node-test-helper": "^0.3.5",
+ "ts-node": "^10.9.2",
+ "typescript": "^5.9.3",
+ "vitest": "^4.0.13"
+ },
+ "engines": {
+ "node": "^20 || ^22 || ^24"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz",
+ "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@biomejs/biome": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.3.7.tgz",
+ "integrity": "sha512-CTbAS/jNAiUc6rcq94BrTB8z83O9+BsgWj2sBCQg9rD6Wkh2gjfR87usjx0Ncx0zGXP1NKgT7JNglay5Zfs9jw==",
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "bin": {
+ "biome": "bin/biome"
+ },
+ "engines": {
+ "node": ">=14.21.3"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/biome"
+ },
+ "optionalDependencies": {
+ "@biomejs/cli-darwin-arm64": "2.3.7",
+ "@biomejs/cli-darwin-x64": "2.3.7",
+ "@biomejs/cli-linux-arm64": "2.3.7",
+ "@biomejs/cli-linux-arm64-musl": "2.3.7",
+ "@biomejs/cli-linux-x64": "2.3.7",
+ "@biomejs/cli-linux-x64-musl": "2.3.7",
+ "@biomejs/cli-win32-arm64": "2.3.7",
+ "@biomejs/cli-win32-x64": "2.3.7"
+ }
+ },
+ "node_modules/@biomejs/cli-darwin-arm64": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.3.7.tgz",
+ "integrity": "sha512-LirkamEwzIUULhXcf2D5b+NatXKeqhOwilM+5eRkbrnr6daKz9rsBL0kNZ16Hcy4b8RFq22SG4tcLwM+yx/wFA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
+ "node_modules/@biomejs/cli-darwin-x64": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.3.7.tgz",
+ "integrity": "sha512-Q4TO633kvrMQkKIV7wmf8HXwF0dhdTD9S458LGE24TYgBjSRbuhvio4D5eOQzirEYg6eqxfs53ga/rbdd8nBKg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
+ "node_modules/@biomejs/cli-linux-arm64": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.3.7.tgz",
+ "integrity": "sha512-inHOTdlstUBzgjDcx0ge71U4SVTbwAljmkfi3MC5WzsYCRhancqfeL+sa4Ke6v2ND53WIwCFD5hGsYExoI3EZQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
+ "node_modules/@biomejs/cli-linux-arm64-musl": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.3.7.tgz",
+ "integrity": "sha512-/afy8lto4CB8scWfMdt+NoCZtatBUF62Tk3ilWH2w8ENd5spLhM77zKlFZEvsKJv9AFNHknMl03zO67CiklL2Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
+ "node_modules/@biomejs/cli-linux-x64": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.3.7.tgz",
+ "integrity": "sha512-fJMc3ZEuo/NaMYo5rvoWjdSS5/uVSW+HPRQujucpZqm2ZCq71b8MKJ9U4th9yrv2L5+5NjPF0nqqILCl8HY/fg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
+ "node_modules/@biomejs/cli-linux-x64-musl": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.3.7.tgz",
+ "integrity": "sha512-CQUtgH1tIN6e5wiYSJqzSwJumHYolNtaj1dwZGCnZXm2PZU1jOJof9TsyiP3bXNDb+VOR7oo7ZvY01If0W3iFQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
+ "node_modules/@biomejs/cli-win32-arm64": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.3.7.tgz",
+ "integrity": "sha512-aJAE8eCNyRpcfx2JJAtsPtISnELJ0H4xVVSwnxm13bzI8RwbXMyVtxy2r5DV1xT3WiSP+7LxORcApWw0LM8HiA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
+ "node_modules/@biomejs/cli-win32-x64": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.3.7.tgz",
+ "integrity": "sha512-pulzUshqv9Ed//MiE8MOUeeEkbkSHVDVY5Cz5wVAnH1DUqliCQG3j6s1POaITTFqFfo7AVIx2sWdKpx/GS+Nqw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
+ "node_modules/@cspotcode/source-map-support": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
+ "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "0.3.9"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@emnapi/core": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.7.1.tgz",
+ "integrity": "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/wasi-threads": "1.1.0",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/runtime": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz",
+ "integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==",
+ "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/@esbuild/aix-ppc64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz",
+ "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz",
+ "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz",
+ "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz",
+ "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz",
+ "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz",
+ "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz",
+ "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz",
+ "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz",
+ "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz",
+ "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz",
+ "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz",
+ "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz",
+ "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz",
+ "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz",
+ "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz",
+ "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz",
+ "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz",
+ "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz",
+ "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz",
+ "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz",
+ "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz",
+ "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz",
+ "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@homebridge/ciao": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/@homebridge/ciao/-/ciao-1.3.4.tgz",
+ "integrity": "sha512-qK6ZgGx0wwOubq/MY6eTbhApQHBUQCvCOsTYpQE01uLvfA2/Prm6egySHlZouKaina1RPuDwfLhCmsRCxwHj3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.1",
+ "fast-deep-equal": "^3.1.3",
+ "source-map-support": "^0.5.21",
+ "tslib": "^2.8.1"
+ },
+ "bin": {
+ "ciao-bcs": "lib/bonjour-conformance-testing.js"
+ }
+ },
+ "node_modules/@homebridge/dbus-native": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/@homebridge/dbus-native/-/dbus-native-0.7.2.tgz",
+ "integrity": "sha512-BNVe6YNxiy5x/E5/ZXDIWMD6Njv9cjW59PM/1CMpYe0jLAJ8pJN+Tq/JhVs3gXwmTavz2S86/sspmHquChet8A==",
+ "license": "MIT",
+ "dependencies": {
+ "event-stream": "^4.0.1",
+ "hexy": "^0.3.5",
+ "long": "^5.3.2",
+ "minimist": "^1.2.8",
+ "safe-buffer": "^5.1.2",
+ "xml2js": "^0.6.2"
+ },
+ "bin": {
+ "dbus2js": "bin/dbus2js.js"
+ }
+ },
+ "node_modules/@homebridge/hap-nodejs": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@homebridge/hap-nodejs/-/hap-nodejs-2.0.2.tgz",
+ "integrity": "sha512-HqlMqVQ8bzh7uFqL0vNI6a5PJHAmCyPzHuPbBxf6XcPVKn02ELwCMDQ8ud5oS1fPO5z20lvV7rIfAqTbSlZ7Uw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@homebridge/ciao": "^1.3.4",
+ "@homebridge/dbus-native": "^0.7.2",
+ "bonjour-hap": "^3.9.1",
+ "debug": "^4.4.3",
+ "fast-srp-hap": "^2.0.4",
+ "futoin-hkdf": "^1.5.3",
+ "node-persist": "^0.0.12",
+ "source-map-support": "^0.5.21",
+ "tslib": "^2.8.1",
+ "tweetnacl": "^1.0.3"
+ },
+ "engines": {
+ "node": "^20 || ^22 || ^24"
+ }
+ },
+ "node_modules/@homebridge/hap-nodejs/node_modules/node-persist": {
+ "version": "0.0.12",
+ "resolved": "https://registry.npmjs.org/node-persist/-/node-persist-0.0.12.tgz",
+ "integrity": "sha512-Fbia3FYnURzaql53wLu0t19dmAwQg/tXT6O7YPmdwNwysNKEyFmgoT2BQlPD3XXQnYeiQVNvR5lfvufGwKuxhg==",
+ "license": "MIT",
+ "dependencies": {
+ "mkdirp": "~0.5.1",
+ "q": "~1.1.1"
+ }
+ },
+ "node_modules/@isaacs/fs-minipass": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
+ "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.4"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "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/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"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
+ "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.0.3",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ }
+ },
+ "node_modules/@leichtgewicht/ip-codec": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz",
+ "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==",
+ "license": "MIT"
+ },
+ "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/@noble/hashes": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz",
+ "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.21.3 || >=16"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/@node-red/editor-api": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/@node-red/editor-api/-/editor-api-4.1.1.tgz",
+ "integrity": "sha512-vev2s3NntphqinzP2e3WmPnQY8+cHfSrQyESis9Fy+prp+E8uSgT4yfLjHMFyT116xPMB5WIg6qSDciq5OV1tA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@node-red/editor-client": "4.1.1",
+ "@node-red/util": "4.1.1",
+ "bcryptjs": "3.0.2",
+ "body-parser": "1.20.3",
+ "clone": "2.1.2",
+ "cors": "2.8.5",
+ "express": "4.21.2",
+ "express-session": "1.18.2",
+ "memorystore": "1.6.7",
+ "mime": "3.0.0",
+ "multer": "2.0.2",
+ "mustache": "4.2.0",
+ "oauth2orize": "1.12.0",
+ "passport": "0.7.0",
+ "passport-http-bearer": "1.0.1",
+ "passport-oauth2-client-password": "0.1.2",
+ "ws": "7.5.10"
+ },
+ "optionalDependencies": {
+ "@node-rs/bcrypt": "1.10.7"
+ }
+ },
+ "node_modules/@node-red/editor-client": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/@node-red/editor-client/-/editor-client-4.1.1.tgz",
+ "integrity": "sha512-JIJirftuB0NrvsFvPZXW3R16c8mLRy2UQh0AyxGU8ZQyz/dmF8auINbbGpQ4qxssBOGFWf9j4ZXP7B8EdLIOBQ==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/@node-red/nodes": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/@node-red/nodes/-/nodes-4.1.1.tgz",
+ "integrity": "sha512-zTTwxpnPebHA5PjDBZEcsGv0BoqMJEjhf27aQIhlGed40/PaNiR0tmc5f5P6HKflmS3Iv6kiwGsY12Mjvyx/3Q==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "acorn": "8.15.0",
+ "acorn-walk": "8.3.4",
+ "ajv": "8.17.1",
+ "body-parser": "1.20.3",
+ "cheerio": "1.0.0-rc.10",
+ "content-type": "1.0.5",
+ "cookie": "0.7.2",
+ "cookie-parser": "1.4.7",
+ "cors": "2.8.5",
+ "cronosjs": "1.7.1",
+ "denque": "2.1.0",
+ "form-data": "4.0.4",
+ "fs-extra": "11.3.0",
+ "got": "12.6.1",
+ "hash-sum": "2.0.0",
+ "hpagent": "1.2.0",
+ "https-proxy-agent": "5.0.1",
+ "iconv-lite": "0.6.3",
+ "is-utf8": "0.2.1",
+ "js-yaml": "4.1.0",
+ "media-typer": "1.1.0",
+ "mqtt": "5.11.0",
+ "multer": "2.0.2",
+ "mustache": "4.2.0",
+ "node-watch": "0.7.4",
+ "on-headers": "1.1.0",
+ "raw-body": "3.0.0",
+ "tough-cookie": "5.1.2",
+ "uuid": "9.0.1",
+ "ws": "7.5.10",
+ "xml2js": "0.6.2"
+ }
+ },
+ "node_modules/@node-red/nodes/node_modules/form-data": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
+ "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/@node-red/nodes/node_modules/uuid": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
+ "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
+ "dev": true,
+ "funding": [
+ "https://github.com/sponsors/broofa",
+ "https://github.com/sponsors/ctavan"
+ ],
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/@node-red/registry": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/@node-red/registry/-/registry-4.1.1.tgz",
+ "integrity": "sha512-+5SvdL+6tXzfYW63TpsfgybNP7G4farM+2div5FYYPdMJULE1D9Z8BHD/fprieU5mTTTO100CeyGXHbkzRH+Qg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@node-red/util": "4.1.1",
+ "clone": "2.1.2",
+ "fs-extra": "11.3.0",
+ "semver": "7.7.1",
+ "tar": "7.4.3",
+ "uglify-js": "3.19.3"
+ }
+ },
+ "node_modules/@node-red/registry/node_modules/semver": {
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@node-red/runtime": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/@node-red/runtime/-/runtime-4.1.1.tgz",
+ "integrity": "sha512-NWV+u2GrLnaPjomJilwVhl5u6WLwJN7tvHEVm5r9/8quW0H8BuYfih5AwCzCl8aly1imhe1+kfiCExSfGVaQUA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@node-red/registry": "4.1.1",
+ "@node-red/util": "4.1.1",
+ "async-mutex": "0.5.0",
+ "clone": "2.1.2",
+ "cronosjs": "1.7.1",
+ "express": "4.21.2",
+ "fs-extra": "11.3.0",
+ "got": "12.6.1",
+ "json-stringify-safe": "5.0.1",
+ "rfdc": "^1.3.1",
+ "semver": "7.7.1"
+ }
+ },
+ "node_modules/@node-red/runtime/node_modules/semver": {
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@node-red/util": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/@node-red/util/-/util-4.1.1.tgz",
+ "integrity": "sha512-gnkRXmz49rj2OXjJC/RAPbFUQvDATC3Oy6yGuhN/McPy8mmL7q4YTIflUwWKyrsd6TU3cK17JmmXtPTQBtS8jQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "chalk": "^4.1.2",
+ "fs-extra": "11.3.0",
+ "i18next": "24.2.3",
+ "json-stringify-safe": "5.0.1",
+ "jsonata": "2.0.6",
+ "lodash.clonedeep": "^4.5.0",
+ "moment": "2.30.1",
+ "moment-timezone": "0.5.48"
+ }
+ },
+ "node_modules/@node-rs/bcrypt": {
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@node-rs/bcrypt/-/bcrypt-1.10.7.tgz",
+ "integrity": "sha512-1wk0gHsUQC/ap0j6SJa2K34qNhomxXRcEe3T8cI5s+g6fgHBgLTN7U9LzWTG/HE6G4+2tWWLeCabk1wiYGEQSA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 10"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ },
+ "optionalDependencies": {
+ "@node-rs/bcrypt-android-arm-eabi": "1.10.7",
+ "@node-rs/bcrypt-android-arm64": "1.10.7",
+ "@node-rs/bcrypt-darwin-arm64": "1.10.7",
+ "@node-rs/bcrypt-darwin-x64": "1.10.7",
+ "@node-rs/bcrypt-freebsd-x64": "1.10.7",
+ "@node-rs/bcrypt-linux-arm-gnueabihf": "1.10.7",
+ "@node-rs/bcrypt-linux-arm64-gnu": "1.10.7",
+ "@node-rs/bcrypt-linux-arm64-musl": "1.10.7",
+ "@node-rs/bcrypt-linux-x64-gnu": "1.10.7",
+ "@node-rs/bcrypt-linux-x64-musl": "1.10.7",
+ "@node-rs/bcrypt-wasm32-wasi": "1.10.7",
+ "@node-rs/bcrypt-win32-arm64-msvc": "1.10.7",
+ "@node-rs/bcrypt-win32-ia32-msvc": "1.10.7",
+ "@node-rs/bcrypt-win32-x64-msvc": "1.10.7"
+ }
+ },
+ "node_modules/@node-rs/bcrypt-android-arm-eabi": {
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-android-arm-eabi/-/bcrypt-android-arm-eabi-1.10.7.tgz",
+ "integrity": "sha512-8dO6/PcbeMZXS3VXGEtct9pDYdShp2WBOWlDvSbcRwVqyB580aCBh0BEFmKYtXLzLvUK8Wf+CG3U6sCdILW1lA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@node-rs/bcrypt-android-arm64": {
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-android-arm64/-/bcrypt-android-arm64-1.10.7.tgz",
+ "integrity": "sha512-UASFBS/CucEMHiCtL/2YYsAY01ZqVR1N7vSb94EOvG5iwW7BQO06kXXCTgj+Xbek9azxixrCUmo3WJnkJZ0hTQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@node-rs/bcrypt-darwin-arm64": {
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-darwin-arm64/-/bcrypt-darwin-arm64-1.10.7.tgz",
+ "integrity": "sha512-DgzFdAt455KTuiJ/zYIyJcKFobjNDR/hnf9OS7pK5NRS13Nq4gLcSIIyzsgHwZHxsJWbLpHmFc1H23Y7IQoQBw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@node-rs/bcrypt-darwin-x64": {
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-darwin-x64/-/bcrypt-darwin-x64-1.10.7.tgz",
+ "integrity": "sha512-SPWVfQ6sxSokoUWAKWD0EJauvPHqOGQTd7CxmYatcsUgJ/bruvEHxZ4bIwX1iDceC3FkOtmeHO0cPwR480n/xA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@node-rs/bcrypt-freebsd-x64": {
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-freebsd-x64/-/bcrypt-freebsd-x64-1.10.7.tgz",
+ "integrity": "sha512-gpa+Ixs6GwEx6U6ehBpsQetzUpuAGuAFbOiuLB2oo4N58yU4AZz1VIcWyWAHrSWRs92O0SHtmo2YPrMrwfBbSw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@node-rs/bcrypt-linux-arm-gnueabihf": {
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm-gnueabihf/-/bcrypt-linux-arm-gnueabihf-1.10.7.tgz",
+ "integrity": "sha512-kYgJnTnpxrzl9sxYqzflobvMp90qoAlaX1oDL7nhNTj8OYJVDIk0jQgblj0bIkjmoPbBed53OJY/iu4uTS+wig==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@node-rs/bcrypt-linux-arm64-gnu": {
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm64-gnu/-/bcrypt-linux-arm64-gnu-1.10.7.tgz",
+ "integrity": "sha512-7cEkK2RA+gBCj2tCVEI1rDSJV40oLbSq7bQ+PNMHNI6jCoXGmj9Uzo7mg7ZRbNZ7piIyNH5zlJqutjo8hh/tmA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@node-rs/bcrypt-linux-arm64-musl": {
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm64-musl/-/bcrypt-linux-arm64-musl-1.10.7.tgz",
+ "integrity": "sha512-X7DRVjshhwxUqzdUKDlF55cwzh+wqWJ2E/tILvZPboO3xaNO07Um568Vf+8cmKcz+tiZCGP7CBmKbBqjvKN/Pw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@node-rs/bcrypt-linux-x64-gnu": {
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-x64-gnu/-/bcrypt-linux-x64-gnu-1.10.7.tgz",
+ "integrity": "sha512-LXRZsvG65NggPD12hn6YxVgH0W3VR5fsE/o1/o2D5X0nxKcNQGeLWnRzs5cP8KpoFOuk1ilctXQJn8/wq+Gn/Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@node-rs/bcrypt-linux-x64-musl": {
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-x64-musl/-/bcrypt-linux-x64-musl-1.10.7.tgz",
+ "integrity": "sha512-tCjHmct79OfcO3g5q21ME7CNzLzpw1MAsUXCLHLGWH+V6pp/xTvMbIcLwzkDj6TI3mxK6kehTn40SEjBkZ3Rog==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@node-rs/bcrypt-wasm32-wasi": {
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-wasm32-wasi/-/bcrypt-wasm32-wasi-1.10.7.tgz",
+ "integrity": "sha512-4qXSihIKeVXYglfXZEq/QPtYtBUvR8d3S85k15Lilv3z5B6NSGQ9mYiNleZ7QHVLN2gEc5gmi7jM353DMH9GkA==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@napi-rs/wasm-runtime": "^0.2.5"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@node-rs/bcrypt-win32-arm64-msvc": {
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-arm64-msvc/-/bcrypt-win32-arm64-msvc-1.10.7.tgz",
+ "integrity": "sha512-FdfUQrqmDfvC5jFhntMBkk8EI+fCJTx/I1v7Rj+Ezlr9rez1j1FmuUnywbBj2Cg15/0BDhwYdbyZ5GCMFli2aQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@node-rs/bcrypt-win32-ia32-msvc": {
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-ia32-msvc/-/bcrypt-win32-ia32-msvc-1.10.7.tgz",
+ "integrity": "sha512-lZLf4Cx+bShIhU071p5BZft4OvP4PGhyp542EEsb3zk34U5GLsGIyCjOafcF/2DGewZL6u8/aqoxbSuROkgFXg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@node-rs/bcrypt-win32-x64-msvc": {
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-x64-msvc/-/bcrypt-win32-x64-msvc-1.10.7.tgz",
+ "integrity": "sha512-hdw7tGmN1DxVAMTzICLdaHpXjy+4rxaxnBMgI8seG1JL5e3VcRGsd1/1vVDogVp2cbsmgq+6d6yAY+D9lW/DCg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nrchkb/logger": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@nrchkb/logger/-/logger-3.1.1.tgz",
+ "integrity": "sha512-37m4lq7Jemg7qzkBflD+VZ1HnFdZv10k9hgglonFXTBMrLmXxkXllWelCKDGABVkfx1hjijAz6IpQoIF+Oo9yw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "debug": "^4.3.5"
+ }
+ },
+ "node_modules/@paralleldrive/cuid2": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.3.1.tgz",
+ "integrity": "sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@noble/hashes": "^1.1.5"
+ }
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz",
+ "integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz",
+ "integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz",
+ "integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz",
+ "integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz",
+ "integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz",
+ "integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz",
+ "integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz",
+ "integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz",
+ "integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz",
+ "integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz",
+ "integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz",
+ "integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz",
+ "integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz",
+ "integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz",
+ "integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz",
+ "integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz",
+ "integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz",
+ "integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz",
+ "integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz",
+ "integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz",
+ "integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz",
+ "integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@sindresorhus/is": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz",
+ "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/is?sponsor=1"
+ }
+ },
+ "node_modules/@sindresorhus/merge-streams": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz",
+ "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@sinonjs/commons": {
+ "version": "1.8.6",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz",
+ "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "node_modules/@sinonjs/fake-timers": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz",
+ "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@sinonjs/commons": "^1.7.0"
+ }
+ },
+ "node_modules/@sinonjs/samsam": {
+ "version": "6.1.3",
+ "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.1.3.tgz",
+ "integrity": "sha512-nhOb2dWPeb1sd3IQXL/dVPnKHDOAFfvichtBf4xV00/rU1QbPCQqKMbvIheIjqwVjh7qIgf2AHTHi391yMOMpQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@sinonjs/commons": "^1.6.0",
+ "lodash.get": "^4.4.2",
+ "type-detect": "^4.0.8"
+ }
+ },
+ "node_modules/@sinonjs/text-encoding": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz",
+ "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==",
+ "dev": true,
+ "license": "(Unlicense OR Apache-2.0)"
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@szmarczak/http-timer": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz",
+ "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "defer-to-connect": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=14.16"
+ }
+ },
+ "node_modules/@tsconfig/node10": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz",
+ "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/node12": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
+ "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/node14": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
+ "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/node16": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
+ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@tybys/wasm-util": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
+ "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@types/ace": {
+ "version": "0.0.52",
+ "resolved": "https://registry.npmjs.org/@types/ace/-/ace-0.0.52.tgz",
+ "integrity": "sha512-YPF9S7fzpuyrxru+sG/rrTpZkC6gpHBPF14W3x70kqVOD+ks6jkYLapk4yceh36xej7K4HYxcyz9ZDQ2lTvwgQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/body-parser": {
+ "version": "1.19.6",
+ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz",
+ "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/connect": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/chai": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz",
+ "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/deep-eql": "*",
+ "assertion-error": "^2.0.1"
+ }
+ },
+ "node_modules/@types/connect": {
+ "version": "3.4.38",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
+ "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/cookiejar": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz",
+ "integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/cors": {
+ "version": "2.8.19",
+ "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz",
+ "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/deep-eql": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz",
+ "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/express": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.5.tgz",
+ "integrity": "sha512-LuIQOcb6UmnF7C1PCFmEU1u2hmiHL43fgFQX67sN3H4Z+0Yk0Neo++mFsBjhOAuLzvlQeqAAkeDOZrJs9rzumQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/body-parser": "*",
+ "@types/express-serve-static-core": "^5.0.0",
+ "@types/serve-static": "^1"
+ }
+ },
+ "node_modules/@types/express-serve-static-core": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.0.tgz",
+ "integrity": "sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "@types/qs": "*",
+ "@types/range-parser": "*",
+ "@types/send": "*"
+ }
+ },
+ "node_modules/@types/http-cache-semantics": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz",
+ "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/http-errors": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz",
+ "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/jquery": {
+ "version": "3.5.33",
+ "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.33.tgz",
+ "integrity": "sha512-SeyVJXlCZpEki5F0ghuYe+L+PprQta6nRZqhONt9F13dWBtR/ftoaIbdRQ7cis7womE+X2LKhsDdDtkkDhJS6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/sizzle": "*"
+ }
+ },
+ "node_modules/@types/methods": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz",
+ "integrity": "sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/mime": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
+ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "20.19.25",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.25.tgz",
+ "integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.21.0"
+ }
+ },
+ "node_modules/@types/node-persist": {
+ "version": "3.1.8",
+ "resolved": "https://registry.npmjs.org/@types/node-persist/-/node-persist-3.1.8.tgz",
+ "integrity": "sha512-QLidg6/SadZYPrTKxtxL1A85XBoQlG40bhoMdhu6DH6+eNCMr2j+RGfFZ9I9+IY8W/PDwQonJ+iBWD62jZjMfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/node-red": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/@types/node-red/-/node-red-1.3.5.tgz",
+ "integrity": "sha512-LBP8TmXJszHOoRgieyxgUrspvatmTZlkPRftlSNGE9TVJCQzSSyX3tF/Qe4evQlIUBmMGOijxcUOcKZSvq4piQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/express": "*",
+ "@types/node-red__editor-api": "*",
+ "@types/node-red__editor-client": "*",
+ "@types/node-red__registry": "*",
+ "@types/node-red__runtime": "*",
+ "@types/node-red__util": "*"
+ }
+ },
+ "node_modules/@types/node-red__editor-api": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/@types/node-red__editor-api/-/node-red__editor-api-1.3.5.tgz",
+ "integrity": "sha512-VE0o/gJzHVBTD2OBhpWth3sjU06TYLlLvlPh62Whs9FXUY0FdFKqWXbaG+ymYQqZreL1ZvTKfFmj0H7LnVEUeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/express": "*",
+ "@types/node-red__runtime": "*"
+ }
+ },
+ "node_modules/@types/node-red__editor-client": {
+ "version": "1.3.11",
+ "resolved": "https://registry.npmjs.org/@types/node-red__editor-client/-/node-red__editor-client-1.3.11.tgz",
+ "integrity": "sha512-Y8FGsMfec4TAVfULabH/Jui+4Cj4F3xx9v4GDpoTN5X9uHwOxdRi9UDtdvG+se/S76CFg6VjsctpJW0WjJUXgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/ace": "*",
+ "@types/jquery": "*",
+ "@types/node-red__registry": "*",
+ "@types/node-red__runtime": "*",
+ "@types/node-red__util": "*"
+ }
+ },
+ "node_modules/@types/node-red__registry": {
+ "version": "1.3.11",
+ "resolved": "https://registry.npmjs.org/@types/node-red__registry/-/node-red__registry-1.3.11.tgz",
+ "integrity": "sha512-q0ALCNdNzq6x2HWBq0Ezeio0u0IrHLtwYT6WNdBG+zbWhNJqXikUpw27ElvnMCstwMiaXM44VQPL7VoTx8OuYw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/express": "*",
+ "@types/node-red__runtime": "*",
+ "@types/node-red__util": "*"
+ }
+ },
+ "node_modules/@types/node-red__runtime": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/@types/node-red__runtime/-/node-red__runtime-1.3.8.tgz",
+ "integrity": "sha512-v5wsFjL6/kQ/YSz7WjC1J9yvE+NP8r5uivQTMBxnNnBabmDJo+dBmdp0rqJczbPNQS0ze7JGDQWz3Iuve+pYlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/cors": "*",
+ "@types/express": "*",
+ "@types/node-red__editor-api": "*",
+ "@types/node-red__util": "*",
+ "@types/passport": "*"
+ }
+ },
+ "node_modules/@types/node-red__util": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/@types/node-red__util/-/node-red__util-1.3.8.tgz",
+ "integrity": "sha512-FQRxaZyUJlyh2phJevzMSF4H8jrsOUmFg05eyhRX5lvDcc/VqdZWcYdAq9dZPRgIwHJwLBttEh9mG3DAcMJiUg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node-red__registry": "*",
+ "@types/node-red__runtime": "*",
+ "jsonata": "2.0.5"
+ }
+ },
+ "node_modules/@types/node-red__util/node_modules/jsonata": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/jsonata/-/jsonata-2.0.5.tgz",
+ "integrity": "sha512-wEse9+QLIIU5IaCgtJCPsFi/H4F3qcikWzF4bAELZiRz08ohfx3Q6CjDRf4ZPF5P/92RI3KIHtb7u3jqPaHXdQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@types/node-red-node-test-helper": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@types/node-red-node-test-helper/-/node-red-node-test-helper-0.3.5.tgz",
+ "integrity": "sha512-ppCrp+3ncOCvciPXwQWhXy5voENjDyK1Xvw98Q9a4tJsSdqiitdy7HsUgtbCSn/mrKStRzZ61l+fHDAknR0BgA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node-red": "*",
+ "@types/node-red__runtime": "*",
+ "@types/sinon": "*",
+ "@types/supertest": "*"
+ }
+ },
+ "node_modules/@types/passport": {
+ "version": "1.0.17",
+ "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.17.tgz",
+ "integrity": "sha512-aciLyx+wDwT2t2/kJGJR2AEeBz0nJU4WuRX04Wu9Dqc5lSUtwu0WERPHYsLhF9PtseiAMPBGNUOtFjxZ56prsg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/express": "*"
+ }
+ },
+ "node_modules/@types/qs": {
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz",
+ "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/range-parser": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
+ "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/readable-stream": {
+ "version": "4.0.22",
+ "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.22.tgz",
+ "integrity": "sha512-/FFhJpfCLAPwAcN3mFycNUa77ddnr8jTgF5VmSNetaemWB2cIlfCA9t0YTM3JAT0wOcv8D4tjPo7pkDhK3EJIg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/semver": {
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/send": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz",
+ "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/serve-static": {
+ "version": "1.15.10",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.10.tgz",
+ "integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/http-errors": "*",
+ "@types/node": "*",
+ "@types/send": "<1"
+ }
+ },
+ "node_modules/@types/serve-static/node_modules/@types/send": {
+ "version": "0.17.6",
+ "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz",
+ "integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/mime": "^1",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/sinon": {
+ "version": "21.0.0",
+ "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-21.0.0.tgz",
+ "integrity": "sha512-+oHKZ0lTI+WVLxx1IbJDNmReQaIsQJjN2e7UUrJHEeByG7bFeKJYsv1E75JxTQ9QKJDp21bAa/0W2Xo4srsDnw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/sinonjs__fake-timers": "*"
+ }
+ },
+ "node_modules/@types/sinonjs__fake-timers": {
+ "version": "15.0.1",
+ "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-15.0.1.tgz",
+ "integrity": "sha512-Ko2tjWJq8oozHzHV+reuvS5KYIRAokHnGbDwGh/J64LntgpbuylF74ipEL24HCyRjf9FOlBiBHWBR1RlVKsI1w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/sizzle": {
+ "version": "2.3.10",
+ "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.10.tgz",
+ "integrity": "sha512-TC0dmN0K8YcWEAEfiPi5gJP14eJe30TTGjkvek3iM/1NdHHsdCA/Td6GvNndMOo/iSnIsZ4HuuhrYPDAmbxzww==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/superagent": {
+ "version": "8.1.9",
+ "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.9.tgz",
+ "integrity": "sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/cookiejar": "^2.1.5",
+ "@types/methods": "^1.1.4",
+ "@types/node": "*",
+ "form-data": "^4.0.0"
+ }
+ },
+ "node_modules/@types/supertest": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-6.0.3.tgz",
+ "integrity": "sha512-8WzXq62EXFhJ7QsH3Ocb/iKQ/Ty9ZVWnVzoTKc9tyyFRRF3a74Tk2+TLFgaFFw364Ere+npzHKEJ6ga2LzIL7w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/methods": "^1.1.4",
+ "@types/superagent": "^8.1.0"
+ }
+ },
+ "node_modules/@types/uuid": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz",
+ "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@vitest/expect": {
+ "version": "4.0.13",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.13.tgz",
+ "integrity": "sha512-zYtcnNIBm6yS7Gpr7nFTmq8ncowlMdOJkWLqYvhr/zweY6tFbDkDi8BPPOeHxEtK1rSI69H7Fd4+1sqvEGli6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@standard-schema/spec": "^1.0.0",
+ "@types/chai": "^5.2.2",
+ "@vitest/spy": "4.0.13",
+ "@vitest/utils": "4.0.13",
+ "chai": "^6.2.1",
+ "tinyrainbow": "^3.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/mocker": {
+ "version": "4.0.13",
+ "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.13.tgz",
+ "integrity": "sha512-eNCwzrI5djoauklwP1fuslHBjrbR8rqIVbvNlAnkq1OTa6XT+lX68mrtPirNM9TnR69XUPt4puBCx2Wexseylg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/spy": "4.0.13",
+ "estree-walker": "^3.0.3",
+ "magic-string": "^0.30.21"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "msw": "^2.4.9",
+ "vite": "^6.0.0 || ^7.0.0-0"
+ },
+ "peerDependenciesMeta": {
+ "msw": {
+ "optional": true
+ },
+ "vite": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vitest/pretty-format": {
+ "version": "4.0.13",
+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.13.tgz",
+ "integrity": "sha512-ooqfze8URWbI2ozOeLDMh8YZxWDpGXoeY3VOgcDnsUxN0jPyPWSUvjPQWqDGCBks+opWlN1E4oP1UYl3C/2EQA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyrainbow": "^3.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/runner": {
+ "version": "4.0.13",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.13.tgz",
+ "integrity": "sha512-9IKlAru58wcVaWy7hz6qWPb2QzJTKt+IOVKjAx5vb5rzEFPTL6H4/R9BMvjZ2ppkxKgTrFONEJFtzvnyEpiT+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/utils": "4.0.13",
+ "pathe": "^2.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/snapshot": {
+ "version": "4.0.13",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.13.tgz",
+ "integrity": "sha512-hb7Usvyika1huG6G6l191qu1urNPsq1iFc2hmdzQY3F5/rTgqQnwwplyf8zoYHkpt7H6rw5UfIw6i/3qf9oSxQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "4.0.13",
+ "magic-string": "^0.30.21",
+ "pathe": "^2.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/spy": {
+ "version": "4.0.13",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.13.tgz",
+ "integrity": "sha512-hSu+m4se0lDV5yVIcNWqjuncrmBgwaXa2utFLIrBkQCQkt+pSwyZTPFQAZiiF/63j8jYa8uAeUZ3RSfcdWaYWw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/utils": {
+ "version": "4.0.13",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.13.tgz",
+ "integrity": "sha512-ydozWyQ4LZuu8rLp47xFUWis5VOKMdHjXCWhs1LuJsTNKww+pTHQNK4e0assIB9K80TxFyskENL6vCu3j34EYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "4.0.13",
+ "tinyrainbow": "^3.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "event-target-shim": "^5.0.0"
+ },
+ "engines": {
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-walk": {
+ "version": "8.3.4",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
+ "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.11.0"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-colors": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
+ "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "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/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/append-field": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz",
+ "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/arg": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
+ "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "is-array-buffer": "^3.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array-flatten": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-3.0.0.tgz",
+ "integrity": "sha512-zPMVc3ZYlGLNk4mpK1NzP2wg0ml9t7fUgDsayR5Y5rSzxQilzR9FGu/EH2jQOcKSAeAfWeylyW8juy3OkWRvNA==",
+ "license": "MIT"
+ },
+ "node_modules/asap": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/assertion-error": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
+ "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/async-mutex": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.5.0.tgz",
+ "integrity": "sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+ "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+ "license": "MIT",
+ "dependencies": {
+ "possible-typed-array-names": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/axios": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz",
+ "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.4",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "dev": true,
+ "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"
+ },
+ "node_modules/basic-auth": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
+ "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "5.1.2"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/basic-auth/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/bcryptjs": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-3.0.2.tgz",
+ "integrity": "sha512-k38b3XOZKv60C4E2hVsXTolJWfkGRMbILBIe2IBITXciy5bOsTKot5kDrf3ZfufQtQOUN5mXceUEpU1rTl9Uog==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "bin": {
+ "bcrypt": "bin/bcrypt"
+ }
+ },
+ "node_modules/bl": {
+ "version": "6.1.4",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-6.1.4.tgz",
+ "integrity": "sha512-ZV/9asSuknOExbM/zPPA8z00lc1ihPKWaStHkkQrxHNeYx+yY+TmF+v80dpv2G0mv3HVXBu7ryoAsxbFFhf4eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/readable-stream": "^4.0.0",
+ "buffer": "^6.0.3",
+ "inherits": "^2.0.4",
+ "readable-stream": "^4.2.0"
+ }
+ },
+ "node_modules/body-parser": {
+ "version": "1.20.3",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
+ "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "content-type": "~1.0.5",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "on-finished": "2.4.1",
+ "qs": "6.13.0",
+ "raw-body": "2.5.2",
+ "type-is": "~1.6.18",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/body-parser/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/body-parser/node_modules/iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/body-parser/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/body-parser/node_modules/raw-body": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
+ "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/bonjour-hap": {
+ "version": "3.9.1",
+ "resolved": "https://registry.npmjs.org/bonjour-hap/-/bonjour-hap-3.9.1.tgz",
+ "integrity": "sha512-ubpbZSBwRyAx2+j5RLKFO+QuRvB02s+7rinC0rQzICx9hEc0zryjRz56Rr9lxoW7UkE/mnZ4rP4mnTCF4/iUkg==",
+ "license": "MIT",
+ "dependencies": {
+ "array-flatten": "^3.0.0",
+ "deep-equal": "^2.2.3",
+ "multicast-dns": "^7.2.5",
+ "multicast-dns-service-types": "^1.1.0"
+ }
+ },
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "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"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/buffer": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+ "dev": true,
+ "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",
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "license": "MIT"
+ },
+ "node_modules/busboy": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
+ "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
+ "dev": true,
+ "dependencies": {
+ "streamsearch": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=10.16.0"
+ }
+ },
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/cacheable-lookup": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz",
+ "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.16"
+ }
+ },
+ "node_modules/cacheable-request": {
+ "version": "10.2.14",
+ "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz",
+ "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/http-cache-semantics": "^4.0.2",
+ "get-stream": "^6.0.1",
+ "http-cache-semantics": "^4.1.1",
+ "keyv": "^4.5.3",
+ "mimic-response": "^4.0.0",
+ "normalize-url": "^8.0.0",
+ "responselike": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
+ "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "set-function-length": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "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"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/chai": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.1.tgz",
+ "integrity": "sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/cheerio": {
+ "version": "1.0.0-rc.10",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz",
+ "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cheerio-select": "^1.5.0",
+ "dom-serializer": "^1.3.2",
+ "domhandler": "^4.2.0",
+ "htmlparser2": "^6.1.0",
+ "parse5": "^6.0.1",
+ "parse5-htmlparser2-tree-adapter": "^6.0.1",
+ "tslib": "^2.2.0"
+ },
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.6.0.tgz",
+ "integrity": "sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "css-select": "^4.3.0",
+ "css-what": "^6.0.1",
+ "domelementtype": "^2.2.0",
+ "domhandler": "^4.3.1",
+ "domutils": "^2.8.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/chownr": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
+ "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/cli-table": {
+ "version": "0.3.11",
+ "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.11.tgz",
+ "integrity": "sha512-IqLQi4lO0nIB4tcdTpN4LCB9FI3uqrJZK7RC515EnhZ6qBaglkIgICb1wjeAqpdoOabm1+SuQtkXIPdYC93jhQ==",
+ "dev": true,
+ "dependencies": {
+ "colors": "1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.2.0"
+ }
+ },
+ "node_modules/clone": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+ "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/colors": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
+ "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.1.90"
+ }
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/commist": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/commist/-/commist-3.2.0.tgz",
+ "integrity": "sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/component-emitter": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz",
+ "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/concat-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
+ "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==",
+ "dev": true,
+ "engines": [
+ "node >= 6.0"
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^3.0.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "node_modules/concat-stream/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/content-disposition": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
+ "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie-parser": {
+ "version": "1.4.7",
+ "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.7.tgz",
+ "integrity": "sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cookie": "0.7.2",
+ "cookie-signature": "1.0.6"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cookiejar": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
+ "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/create-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
+ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cronosjs": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/cronosjs/-/cronosjs-1.7.1.tgz",
+ "integrity": "sha512-d6S6+ep7dJxsAG8OQQCdKuByI/S/AV64d9OF5mtmcykOyPu92cAkAnF3Tbc9s5oOaLQBYYQmTNvjqYRkPJ/u5Q==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/css-select": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz",
+ "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.0.1",
+ "domhandler": "^4.3.1",
+ "domutils": "^2.8.0",
+ "nth-check": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz",
+ "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decompress-response": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
+ "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-response": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/decompress-response/node_modules/mimic-response": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
+ "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/deep-equal": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz",
+ "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==",
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.0",
+ "call-bind": "^1.0.5",
+ "es-get-iterator": "^1.1.3",
+ "get-intrinsic": "^1.2.2",
+ "is-arguments": "^1.1.1",
+ "is-array-buffer": "^3.0.2",
+ "is-date-object": "^1.0.5",
+ "is-regex": "^1.1.4",
+ "is-shared-array-buffer": "^1.0.2",
+ "isarray": "^2.0.5",
+ "object-is": "^1.1.5",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.4",
+ "regexp.prototype.flags": "^1.5.1",
+ "side-channel": "^1.0.4",
+ "which-boxed-primitive": "^1.0.2",
+ "which-collection": "^1.0.1",
+ "which-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/defer-to-connect": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
+ "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.0.1",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/del": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/del/-/del-8.0.1.tgz",
+ "integrity": "sha512-gPqh0mKTPvaUZGAuHbrBUYKZWBNAeHG7TU3QH5EhVwPMyKvmfJaNXhcD2jTcXsJRRcffuho4vaYweu80dRrMGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "globby": "^14.0.2",
+ "is-glob": "^4.0.3",
+ "is-path-cwd": "^3.0.0",
+ "is-path-inside": "^4.0.0",
+ "p-map": "^7.0.2",
+ "presentable-error": "^0.0.1",
+ "slash": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/del-cli": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/del-cli/-/del-cli-7.0.0.tgz",
+ "integrity": "sha512-fRl4pWJYu9WFQH8jXdQUYvcD0IMtij9WEc7qmB7xOyJEweNJNuE7iKmqNeoOT1DbBUjtRjxlw8Y63qKBI/NQ1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "del": "^8.0.1",
+ "meow": "^14.0.0",
+ "presentable-error": "^0.0.1"
+ },
+ "bin": {
+ "del": "cli.js",
+ "del-cli": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/denque": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
+ "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/destroy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/dezalgo": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
+ "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "asap": "^2.0.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/diff": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
+ "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/dns-packet": {
+ "version": "5.6.1",
+ "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz",
+ "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==",
+ "license": "MIT",
+ "dependencies": {
+ "@leichtgewicht/ip-codec": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/dom-serializer": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
+ "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^4.2.0",
+ "entities": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/domhandler": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
+ "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.2.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
+ "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "^1.0.1",
+ "domelementtype": "^2.2.0",
+ "domhandler": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "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",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/duplexer": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
+ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
+ "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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/encodeurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/enquirer": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz",
+ "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-colors": "^4.1.1",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/entities": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/es-define-property": {
+ "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"
+ }
+ },
+ "node_modules/es-errors": {
+ "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"
+ }
+ },
+ "node_modules/es-get-iterator": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz",
+ "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.3",
+ "has-symbols": "^1.0.3",
+ "is-arguments": "^1.1.1",
+ "is-map": "^2.0.2",
+ "is-set": "^2.0.2",
+ "is-string": "^1.0.7",
+ "isarray": "^2.0.5",
+ "stop-iteration-iterator": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-module-lexer": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
+ "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/es-object-atoms": {
+ "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"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz",
+ "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.25.12",
+ "@esbuild/android-arm": "0.25.12",
+ "@esbuild/android-arm64": "0.25.12",
+ "@esbuild/android-x64": "0.25.12",
+ "@esbuild/darwin-arm64": "0.25.12",
+ "@esbuild/darwin-x64": "0.25.12",
+ "@esbuild/freebsd-arm64": "0.25.12",
+ "@esbuild/freebsd-x64": "0.25.12",
+ "@esbuild/linux-arm": "0.25.12",
+ "@esbuild/linux-arm64": "0.25.12",
+ "@esbuild/linux-ia32": "0.25.12",
+ "@esbuild/linux-loong64": "0.25.12",
+ "@esbuild/linux-mips64el": "0.25.12",
+ "@esbuild/linux-ppc64": "0.25.12",
+ "@esbuild/linux-riscv64": "0.25.12",
+ "@esbuild/linux-s390x": "0.25.12",
+ "@esbuild/linux-x64": "0.25.12",
+ "@esbuild/netbsd-arm64": "0.25.12",
+ "@esbuild/netbsd-x64": "0.25.12",
+ "@esbuild/openbsd-arm64": "0.25.12",
+ "@esbuild/openbsd-x64": "0.25.12",
+ "@esbuild/openharmony-arm64": "0.25.12",
+ "@esbuild/sunos-x64": "0.25.12",
+ "@esbuild/win32-arm64": "0.25.12",
+ "@esbuild/win32-ia32": "0.25.12",
+ "@esbuild/win32-x64": "0.25.12"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/estree-walker": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
+ "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0"
+ }
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/event-stream": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-4.0.1.tgz",
+ "integrity": "sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==",
+ "license": "MIT",
+ "dependencies": {
+ "duplexer": "^0.1.1",
+ "from": "^0.1.7",
+ "map-stream": "0.0.7",
+ "pause-stream": "^0.0.11",
+ "split": "^1.0.1",
+ "stream-combiner": "^0.2.2",
+ "through": "^2.3.8"
+ }
+ },
+ "node_modules/event-target-shim": {
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.x"
+ }
+ },
+ "node_modules/expect-type": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz",
+ "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/express": {
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
+ "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "~1.3.8",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.20.3",
+ "content-disposition": "0.5.4",
+ "content-type": "~1.0.4",
+ "cookie": "0.7.1",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "1.3.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "merge-descriptors": "1.0.3",
+ "methods": "~1.1.2",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.12",
+ "proxy-addr": "~2.0.7",
+ "qs": "6.13.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.2.1",
+ "send": "0.19.0",
+ "serve-static": "1.16.2",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/express-session": {
+ "version": "1.18.2",
+ "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.2.tgz",
+ "integrity": "sha512-SZjssGQC7TzTs9rpPDuUrR23GNZ9+2+IkA/+IJWmvQilTr5OSliEHGF+D9scbIpdC6yGtTI0/VhaHoVes2AN/A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cookie": "0.7.2",
+ "cookie-signature": "1.0.7",
+ "debug": "2.6.9",
+ "depd": "~2.0.0",
+ "on-headers": "~1.1.0",
+ "parseurl": "~1.3.3",
+ "safe-buffer": "5.2.1",
+ "uid-safe": "~2.1.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/express-session/node_modules/cookie-signature": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz",
+ "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/express-session/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/express-session/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/express/node_modules/array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/express/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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/express/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/express/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "license": "MIT"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-safe-stringify": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
+ "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-srp-hap": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/fast-srp-hap/-/fast-srp-hap-2.0.4.tgz",
+ "integrity": "sha512-lHRYYaaIbMrhZtsdGTwPN82UbqD9Bv8QfOlKs+Dz6YRnByZifOh93EYmf2iEWFtkOEIqR2IK8cFD0UN5wLIWBQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.17.0"
+ }
+ },
+ "node_modules/fast-unique-numbers": {
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.23.8",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.1.0"
+ }
+ },
+ "node_modules/fast-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
+ "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/fastq": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "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"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
+ "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "statuses": "2.0.1",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/finalhandler/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/finalhandler/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
+ "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/for-each": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
+ "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
+ "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/form-data-encoder": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz",
+ "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.17"
+ }
+ },
+ "node_modules/formidable": {
+ "version": "3.5.4",
+ "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.4.tgz",
+ "integrity": "sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@paralleldrive/cuid2": "^2.2.2",
+ "dezalgo": "^1.0.4",
+ "once": "^1.4.0"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "funding": {
+ "url": "https://ko-fi.com/tunnckoCore/commissions"
+ }
+ },
+ "node_modules/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/from": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
+ "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==",
+ "license": "MIT"
+ },
+ "node_modules/fs-extra": {
+ "version": "11.3.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
+ "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=14.14"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "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"
+ }
+ },
+ "node_modules/functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/futoin-hkdf": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/futoin-hkdf/-/futoin-hkdf-1.5.3.tgz",
+ "integrity": "sha512-SewY5KdMpaoCeh7jachEWFsh1nNlaDjNHZXWqL5IGwtpEYHTgkr2+AMCgNwKWkcc0wpSYrZfR7he4WdmHFtDxQ==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "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",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "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"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "6.0.1",
+ "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"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/globby": {
+ "version": "14.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz",
+ "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sindresorhus/merge-streams": "^2.1.0",
+ "fast-glob": "^3.3.3",
+ "ignore": "^7.0.3",
+ "path-type": "^6.0.0",
+ "slash": "^5.1.0",
+ "unicorn-magic": "^0.3.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/got": {
+ "version": "12.6.1",
+ "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz",
+ "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sindresorhus/is": "^5.2.0",
+ "@szmarczak/http-timer": "^5.0.1",
+ "cacheable-lookup": "^7.0.0",
+ "cacheable-request": "^10.2.8",
+ "decompress-response": "^6.0.0",
+ "form-data-encoder": "^2.1.2",
+ "get-stream": "^6.0.1",
+ "http2-wrapper": "^2.1.10",
+ "lowercase-keys": "^3.0.0",
+ "p-cancelable": "^3.0.0",
+ "responselike": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/got?sponsor=1"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "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"
+ },
+ "node_modules/has-bigints": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
+ "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "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"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hash-sum": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz",
+ "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/hasown": {
+ "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"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/hexy": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/hexy/-/hexy-0.3.5.tgz",
+ "integrity": "sha512-UCP7TIZPXz5kxYJnNOym+9xaenxCLor/JyhKieo8y8/bJWunGh9xbhy3YrgYJUQ87WwfXGm05X330DszOfINZw==",
+ "license": "MIT",
+ "bin": {
+ "hexy": "bin/hexy_cmd.js"
+ },
+ "engines": {
+ "node": ">=10.4"
+ }
+ },
+ "node_modules/hpagent": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-1.2.0.tgz",
+ "integrity": "sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/htmlparser2": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
+ "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==",
+ "dev": true,
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^4.0.0",
+ "domutils": "^2.5.2",
+ "entities": "^2.0.0"
+ }
+ },
+ "node_modules/http-cache-semantics": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz",
+ "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/http-errors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/http2-wrapper": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz",
+ "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "quick-lru": "^5.1.1",
+ "resolve-alpn": "^1.2.0"
+ },
+ "engines": {
+ "node": ">=10.19.0"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+ "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/husky": {
+ "version": "9.1.7",
+ "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz",
+ "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "husky": "bin.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/typicode"
+ }
+ },
+ "node_modules/i18next": {
+ "version": "24.2.3",
+ "resolved": "https://registry.npmjs.org/i18next/-/i18next-24.2.3.tgz",
+ "integrity": "sha512-lfbf80OzkocvX7nmZtu7nSTNbrTYR52sLWxPtlXX1zAhVw8WEnFk4puUkCR4B1dNQwbSpEHHHemcZu//7EcB7A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://locize.com"
+ },
+ {
+ "type": "individual",
+ "url": "https://locize.com/i18next.html"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.26.10"
+ },
+ "peerDependencies": {
+ "typescript": "^5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "dev": true,
+ "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": "BSD-3-Clause"
+ },
+ "node_modules/ignore": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+ "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/internal-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
+ "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "hasown": "^2.0.2",
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/ip-address": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz",
+ "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/is-arguments": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz",
+ "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-array-buffer": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
+ "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-bigint": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
+ "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
+ "license": "MIT",
+ "dependencies": {
+ "has-bigints": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz",
+ "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
+ "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
+ "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "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"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz",
+ "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-path-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-3.0.0.tgz",
+ "integrity": "sha512-kyiNFFLU0Ampr6SDZitD/DwUo4Zs1nSdnygUBqsu3LooL00Qvb5j+UnvApUn/TTj1J3OuE6BTdQ5rudKmU2ZaA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz",
+ "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-regex": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
+ "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-set": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
+ "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-shared-array-buffer": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz",
+ "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz",
+ "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
+ "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-utf8": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+ "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-weakmap": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
+ "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakset": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
+ "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "license": "MIT"
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/js-sdsl"
+ }
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/jsonata": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/jsonata/-/jsonata-2.0.6.tgz",
+ "integrity": "sha512-WhQB5tXQ32qjkx2GYHFw2XbL90u+LLzjofAYwi+86g6SyZeXHz9F1Q0amy3dWRYczshOC3Haok9J4pOCgHtwyQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/jsonfile": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
+ "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/just-extend": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz",
+ "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/lodash.clonedeep": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+ "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
+ "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/long": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
+ "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/lowercase-keys": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz",
+ "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.21",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/map-stream": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz",
+ "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==",
+ "license": "MIT"
+ },
+ "node_modules/math-intrinsics": {
+ "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"
+ }
+ },
+ "node_modules/media-typer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
+ "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/memorystore": {
+ "version": "1.6.7",
+ "resolved": "https://registry.npmjs.org/memorystore/-/memorystore-1.6.7.tgz",
+ "integrity": "sha512-OZnmNY/NDrKohPQ+hxp0muBcBKrzKNtHr55DbqSx9hLsYVNnomSAMRAtI7R64t3gf3ID7tHQA7mG4oL3Hu9hdw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.3.0",
+ "lru-cache": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/meow": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-14.0.0.tgz",
+ "integrity": "sha512-JhC3R1f6dbspVtmF3vKjAWz1EVIvwFrGGPLSdU6rK79xBwHWTuHoLnRX/t1/zHS1Ch1Y2UtIrih7DAHuH9JFJA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/merge-descriptors": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
+ "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "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"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mime": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
+ "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mimic-response": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz",
+ "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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/minizlib": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz",
+ "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minipass": "^7.1.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/mkdirp": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+ "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
+ "license": "MIT",
+ "dependencies": {
+ "minimist": "^1.2.6"
+ },
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ }
+ },
+ "node_modules/moment": {
+ "version": "2.30.1",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
+ "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/moment-timezone": {
+ "version": "0.5.48",
+ "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.48.tgz",
+ "integrity": "sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "moment": "^2.29.4"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/mqtt": {
+ "version": "5.11.0",
+ "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.11.0.tgz",
+ "integrity": "sha512-VDqfADTNvohwcY02NgxPb7OojIeDrNQ1q62r/DcM+bnIWY8LBi3nMTvdEaFEp6Bu4ejBIpHjJVthUEgnvGLemA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/readable-stream": "^4.0.18",
+ "@types/ws": "^8.5.14",
+ "commist": "^3.2.0",
+ "concat-stream": "^2.0.0",
+ "debug": "^4.4.0",
+ "help-me": "^5.0.0",
+ "lru-cache": "^10.4.3",
+ "minimist": "^1.2.8",
+ "mqtt-packet": "^9.0.2",
+ "number-allocator": "^1.0.14",
+ "readable-stream": "^4.7.0",
+ "reinterval": "^1.1.0",
+ "rfdc": "^1.4.1",
+ "socks": "^2.8.3",
+ "split2": "^4.2.0",
+ "worker-timers": "^7.1.8",
+ "ws": "^8.18.0"
+ },
+ "bin": {
+ "mqtt": "build/bin/mqtt.js",
+ "mqtt_pub": "build/bin/pub.js",
+ "mqtt_sub": "build/bin/sub.js"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bl": "^6.0.8",
+ "debug": "^4.3.4",
+ "process-nextick-args": "^2.0.1"
+ }
+ },
+ "node_modules/mqtt/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==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/mqtt/node_modules/ws": {
+ "version": "8.18.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
+ "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "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/multer": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/multer/-/multer-2.0.2.tgz",
+ "integrity": "sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "append-field": "^1.0.0",
+ "busboy": "^1.6.0",
+ "concat-stream": "^2.0.0",
+ "mkdirp": "^0.5.6",
+ "object-assign": "^4.1.1",
+ "type-is": "^1.6.18",
+ "xtend": "^4.0.2"
+ },
+ "engines": {
+ "node": ">= 10.16.0"
+ }
+ },
+ "node_modules/multicast-dns": {
+ "version": "7.2.5",
+ "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz",
+ "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==",
+ "license": "MIT",
+ "dependencies": {
+ "dns-packet": "^5.2.2",
+ "thunky": "^1.0.2"
+ },
+ "bin": {
+ "multicast-dns": "cli.js"
+ }
+ },
+ "node_modules/multicast-dns-service-types": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
+ "integrity": "sha512-cnAsSVxIDsYt0v7HmC0hWZFwwXSh+E6PgCrREDuN/EsjgLwA5XRmlMHhSiDPrt6HxY1gTivEa/Zh7GtODoLevQ==",
+ "license": "MIT"
+ },
+ "node_modules/mustache": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz",
+ "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "mustache": "bin/mustache"
+ }
+ },
+ "node_modules/mute-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz",
+ "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/nise": {
+ "version": "5.1.9",
+ "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz",
+ "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@sinonjs/commons": "^3.0.0",
+ "@sinonjs/fake-timers": "^11.2.2",
+ "@sinonjs/text-encoding": "^0.7.2",
+ "just-extend": "^6.2.0",
+ "path-to-regexp": "^6.2.1"
+ }
+ },
+ "node_modules/nise/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/nise/node_modules/@sinonjs/fake-timers": {
+ "version": "11.3.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.3.1.tgz",
+ "integrity": "sha512-EVJO7nW5M/F5Tur0Rf2z/QoMo+1Ia963RiMtapiQrEWvY0iBUvADo8Beegwjpnle5BHkyHuoxSTW3jF43H1XRA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@sinonjs/commons": "^3.0.1"
+ }
+ },
+ "node_modules/nise/node_modules/path-to-regexp": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz",
+ "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/node-persist": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/node-persist/-/node-persist-3.1.3.tgz",
+ "integrity": "sha512-CaFv+kSZtsc+VeDRldK1yR47k1vPLBpzYB9re2z7LIwITxwBtljMq3s8VQnnr+x3E8pQfHbc5r2IyJsBLJhtXg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.12.0"
+ }
+ },
+ "node_modules/node-red": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/node-red/-/node-red-4.1.1.tgz",
+ "integrity": "sha512-yk8cornC+ELzbmQk8yw3KY1jS+djTMDupMOwZ85HeC+zcxJK0LNYUbJPCFI+Bm2NQny9pd863lNj9/tLwCDotg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@node-red/editor-api": "4.1.1",
+ "@node-red/nodes": "4.1.1",
+ "@node-red/runtime": "4.1.1",
+ "@node-red/util": "4.1.1",
+ "basic-auth": "2.0.1",
+ "bcryptjs": "3.0.2",
+ "cors": "2.8.5",
+ "express": "4.21.2",
+ "fs-extra": "11.3.0",
+ "node-red-admin": "^4.1.2",
+ "nopt": "5.0.0",
+ "semver": "7.7.1"
+ },
+ "bin": {
+ "node-red": "red.js",
+ "node-red-pi": "bin/node-red-pi"
+ },
+ "engines": {
+ "node": ">=18.5"
+ },
+ "optionalDependencies": {
+ "@node-rs/bcrypt": "1.10.7"
+ }
+ },
+ "node_modules/node-red-admin": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/node-red-admin/-/node-red-admin-4.1.2.tgz",
+ "integrity": "sha512-Yqe3dREfZZmc/BqT3Ntg0DEXivbP3HBNYCbjDkUaakkIIrapNR8TK1vj3RgkSW6FMtpfcVXBcLGI4cA0I1zbOw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "ansi-colors": "^4.1.3",
+ "axios": "1.12.2",
+ "bcryptjs": "3.0.2",
+ "cli-table": "^0.3.11",
+ "enquirer": "^2.3.6",
+ "minimist": "^1.2.8",
+ "mustache": "^4.2.0",
+ "read": "^3.0.1"
+ },
+ "bin": {
+ "node-red-admin": "node-red-admin.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@node-rs/bcrypt": "1.10.7"
+ }
+ },
+ "node_modules/node-red-node-test-helper": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/node-red-node-test-helper/-/node-red-node-test-helper-0.3.5.tgz",
+ "integrity": "sha512-sUsg++CoO19UguqlK6j9q2VmluS7kpYgs45o+U3SAv4wW6BSoXwtuO7pJ+9KVQVmd27zwojw6uaeyLsDsRpL3Q==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "body-parser": "^1.20.3",
+ "express": "^4.21.0",
+ "semver": "^7.5.4",
+ "should": "^13.2.3",
+ "should-sinon": "^0.0.6",
+ "sinon": "^11.1.2",
+ "stoppable": "^1.1.0",
+ "supertest": "^7.1.4"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/node-red/node_modules/semver": {
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/node-watch": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.7.4.tgz",
+ "integrity": "sha512-RinNxoz4W1cep1b928fuFhvAQ5ag/+1UlMDV7rbyGthBIgsiEouS4kvRayvvboxii4m8eolKOIBo3OjDqbc+uQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/nopt": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
+ "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "abbrev": "1"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/normalize-url": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.1.0.tgz",
+ "integrity": "sha512-X06Mfd/5aKsRHc0O0J5CUedwnPmnDtLF2+nq+KN9KSDlJHkPuh0JUviWjEWMe0SW/9TDdSLVPuk7L5gGTIA1/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
+ "node_modules/number-allocator": {
+ "version": "1.0.14",
+ "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz",
+ "integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.3.1",
+ "js-sdsl": "4.3.0"
+ }
+ },
+ "node_modules/oauth2orize": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/oauth2orize/-/oauth2orize-1.12.0.tgz",
+ "integrity": "sha512-j4XtFDQUBsvUHPjUmvmNDUDMYed2MphMIJBhyxVVe8hGCjkuYnjIsW+D9qk8c5ciXRdnk6x6tEbiO6PLeOZdCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.x.x",
+ "uid2": "0.0.x",
+ "utils-merge": "1.x.x"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/jaredhanson"
+ }
+ },
+ "node_modules/oauth2orize/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/oauth2orize/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-is": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz",
+ "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.7",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
+ "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0",
+ "has-symbols": "^1.1.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/on-headers": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz",
+ "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/p-cancelable": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz",
+ "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.20"
+ }
+ },
+ "node_modules/p-map": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz",
+ "integrity": "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parse5": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
+ "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parse5": "^6.0.1"
+ }
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/passport": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/passport/-/passport-0.7.0.tgz",
+ "integrity": "sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "passport-strategy": "1.x.x",
+ "pause": "0.0.1",
+ "utils-merge": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/jaredhanson"
+ }
+ },
+ "node_modules/passport-http-bearer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/passport-http-bearer/-/passport-http-bearer-1.0.1.tgz",
+ "integrity": "sha512-SELQM+dOTuMigr9yu8Wo4Fm3ciFfkMq5h/ZQ8ffi4ELgZrX1xh9PlglqZdcUZ1upzJD/whVyt+YWF62s3U6Ipw==",
+ "dev": true,
+ "dependencies": {
+ "passport-strategy": "1.x.x"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/passport-oauth2-client-password": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/passport-oauth2-client-password/-/passport-oauth2-client-password-0.1.2.tgz",
+ "integrity": "sha512-GHQH4UtaEZvCLulAxGKHYoSsPRoPRmGsdmaZtMh5nmz80yMLQbdMA9Bg2sp4/UW3PIxJH/143hVjPTiXaNngTQ==",
+ "dev": true,
+ "dependencies": {
+ "passport-strategy": "1.x.x"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/passport-strategy": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
+ "integrity": "sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/path-to-regexp": {
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
+ "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-type": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz",
+ "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/pathe": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pause": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
+ "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==",
+ "dev": true
+ },
+ "node_modules/pause-stream": {
+ "version": "0.0.11",
+ "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
+ "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==",
+ "license": [
+ "MIT",
+ "Apache2"
+ ],
+ "dependencies": {
+ "through": "~2.3"
+ }
+ },
+ "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"
+ },
+ "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"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/possible-typed-array-names": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
+ "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.6",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
+ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/presentable-error": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/presentable-error/-/presentable-error-0.0.1.tgz",
+ "integrity": "sha512-E6rsNU1QNJgB3sjj7OANinGncFKuK+164sLXw1/CqBjj/EkXSoSdHCtWQGBNlREIGLnL7IEUEGa08YFVUbrhVg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6.0"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pseudomap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+ "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/q": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/q/-/q-1.1.2.tgz",
+ "integrity": "sha512-ROtylwux7Vkc4C07oKE/ReigUmb33kVoLtcR4SJ1QVqwaZkBEDL3vX4/kwFzIERQ5PfCl0XafbU8u2YUhyGgVA==",
+ "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6.0",
+ "teleport": ">=0.2.0"
+ }
+ },
+ "node_modules/qs": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
+ "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "side-channel": "^1.0.6"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "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"
+ },
+ "node_modules/quick-lru": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
+ "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/random-bytes": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
+ "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/raw-body": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
+ "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.6.3",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/read": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/read/-/read-3.0.1.tgz",
+ "integrity": "sha512-SLBrDU/Srs/9EoWhU5GdbAoxG1GzpQHo/6qiGItaoLJ1thmYpcNIM1qISEUvyHBzfGlWIyd6p2DNi1oV1VmAuw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "mute-stream": "^1.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "abort-controller": "^3.0.0",
+ "buffer": "^6.0.3",
+ "events": "^3.3.0",
+ "process": "^0.11.10",
+ "string_decoder": "^1.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/regexp.prototype.flags": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
+ "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-errors": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "set-function-name": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/reinterval": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz",
+ "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve-alpn": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
+ "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/responselike": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz",
+ "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lowercase-keys": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rfdc": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
+ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/rollup": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz",
+ "integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.8"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.53.3",
+ "@rollup/rollup-android-arm64": "4.53.3",
+ "@rollup/rollup-darwin-arm64": "4.53.3",
+ "@rollup/rollup-darwin-x64": "4.53.3",
+ "@rollup/rollup-freebsd-arm64": "4.53.3",
+ "@rollup/rollup-freebsd-x64": "4.53.3",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.53.3",
+ "@rollup/rollup-linux-arm-musleabihf": "4.53.3",
+ "@rollup/rollup-linux-arm64-gnu": "4.53.3",
+ "@rollup/rollup-linux-arm64-musl": "4.53.3",
+ "@rollup/rollup-linux-loong64-gnu": "4.53.3",
+ "@rollup/rollup-linux-ppc64-gnu": "4.53.3",
+ "@rollup/rollup-linux-riscv64-gnu": "4.53.3",
+ "@rollup/rollup-linux-riscv64-musl": "4.53.3",
+ "@rollup/rollup-linux-s390x-gnu": "4.53.3",
+ "@rollup/rollup-linux-x64-gnu": "4.53.3",
+ "@rollup/rollup-linux-x64-musl": "4.53.3",
+ "@rollup/rollup-openharmony-arm64": "4.53.3",
+ "@rollup/rollup-win32-arm64-msvc": "4.53.3",
+ "@rollup/rollup-win32-ia32-msvc": "4.53.3",
+ "@rollup/rollup-win32-x64-gnu": "4.53.3",
+ "@rollup/rollup-win32-x64-msvc": "4.53.3",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "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",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "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"
+ },
+ "node_modules/safe-regex-test": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+ "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-regex": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/sax": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.3.tgz",
+ "integrity": "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==",
+ "license": "BlueOak-1.0.0"
+ },
+ "node_modules/semver": {
+ "version": "7.7.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
+ "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/send": {
+ "version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
+ "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "mime": "1.6.0",
+ "ms": "2.1.3",
+ "on-finished": "2.4.1",
+ "range-parser": "~1.2.1",
+ "statuses": "2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/send/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/send/node_modules/debug/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/send/node_modules/encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/send/node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/serve-static": {
+ "version": "1.16.2",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
+ "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.19.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-function-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
+ "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "functions-have-names": "^1.2.3",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/should": {
+ "version": "13.2.3",
+ "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz",
+ "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "should-equal": "^2.0.0",
+ "should-format": "^3.0.3",
+ "should-type": "^1.4.0",
+ "should-type-adaptors": "^1.0.1",
+ "should-util": "^1.0.0"
+ }
+ },
+ "node_modules/should-equal": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz",
+ "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "should-type": "^1.4.0"
+ }
+ },
+ "node_modules/should-format": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz",
+ "integrity": "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "should-type": "^1.3.0",
+ "should-type-adaptors": "^1.0.1"
+ }
+ },
+ "node_modules/should-sinon": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/should-sinon/-/should-sinon-0.0.6.tgz",
+ "integrity": "sha512-ScBOH5uW5QVFaONmUnIXANSR6z5B8IKzEmBP3HE5sPOCDuZ88oTMdUdnKoCVQdLcCIrRrhRLPS5YT+7H40a04g==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "should": ">= 8.x"
+ }
+ },
+ "node_modules/should-type": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz",
+ "integrity": "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/should-type-adaptors": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz",
+ "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "should-type": "^1.3.0",
+ "should-util": "^1.0.0"
+ }
+ },
+ "node_modules/should-util": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz",
+ "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/side-channel": {
+ "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",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "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"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "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",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "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",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/siginfo": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
+ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/sinon": {
+ "version": "11.1.2",
+ "resolved": "https://registry.npmjs.org/sinon/-/sinon-11.1.2.tgz",
+ "integrity": "sha512-59237HChms4kg7/sXhiRcUzdSkKuydDeTiamT/jesUVHshBgL8XAmhgFo0GfK6RruMDM/iRSij1EybmMog9cJw==",
+ "deprecated": "16.1.1",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@sinonjs/commons": "^1.8.3",
+ "@sinonjs/fake-timers": "^7.1.2",
+ "@sinonjs/samsam": "^6.0.2",
+ "diff": "^5.0.0",
+ "nise": "^5.1.0",
+ "supports-color": "^7.2.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/sinon"
+ }
+ },
+ "node_modules/slash": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz",
+ "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/socks": {
+ "version": "2.8.7",
+ "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz",
+ "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ip-address": "^10.0.1",
+ "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==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/split": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
+ "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
+ "license": "MIT",
+ "dependencies": {
+ "through": "2"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/split2": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
+ "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">= 10.x"
+ }
+ },
+ "node_modules/stackback": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
+ "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/std-env": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz",
+ "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/stop-iteration-iterator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz",
+ "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "internal-slot": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/stoppable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz",
+ "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4",
+ "npm": ">=6"
+ }
+ },
+ "node_modules/stream-combiner": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz",
+ "integrity": "sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==",
+ "license": "MIT",
+ "dependencies": {
+ "duplexer": "~0.1.1",
+ "through": "~2.3.4"
+ }
+ },
+ "node_modules/streamsearch": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
+ "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "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/superagent": {
+ "version": "10.2.3",
+ "resolved": "https://registry.npmjs.org/superagent/-/superagent-10.2.3.tgz",
+ "integrity": "sha512-y/hkYGeXAj7wUMjxRbB21g/l6aAEituGXM9Rwl4o20+SX3e8YOSV6BxFXl+dL3Uk0mjSL3kCbNkwURm8/gEDig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "component-emitter": "^1.3.1",
+ "cookiejar": "^2.1.4",
+ "debug": "^4.3.7",
+ "fast-safe-stringify": "^2.1.1",
+ "form-data": "^4.0.4",
+ "formidable": "^3.5.4",
+ "methods": "^1.1.2",
+ "mime": "2.6.0",
+ "qs": "^6.11.2"
+ },
+ "engines": {
+ "node": ">=14.18.0"
+ }
+ },
+ "node_modules/superagent/node_modules/mime": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
+ "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/supertest": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.1.4.tgz",
+ "integrity": "sha512-tjLPs7dVyqgItVFirHYqe2T+MfWc2VOBQ8QFKKbWTA3PU7liZR8zoSpAi/C1k1ilm9RsXIKYf197oap9wXGVYg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "methods": "^1.1.2",
+ "superagent": "^10.2.3"
+ },
+ "engines": {
+ "node": ">=14.18.0"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/tar": {
+ "version": "7.4.3",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz",
+ "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@isaacs/fs-minipass": "^4.0.0",
+ "chownr": "^3.0.0",
+ "minipass": "^7.1.2",
+ "minizlib": "^3.0.1",
+ "mkdirp": "^3.0.1",
+ "yallist": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tar/node_modules/mkdirp": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
+ "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "mkdirp": "dist/cjs/src/bin.js"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/tar/node_modules/yallist": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
+ "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
+ "license": "MIT"
+ },
+ "node_modules/thunky": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
+ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
+ "license": "MIT"
+ },
+ "node_modules/tinybench": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
+ "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinyexec": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
+ "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.15",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
+ "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/tinyglobby/node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tinyglobby/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_modules/tinyrainbow": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.0.3.tgz",
+ "integrity": "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/tldts": {
+ "version": "6.1.86",
+ "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz",
+ "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tldts-core": "^6.1.86"
+ },
+ "bin": {
+ "tldts": "bin/cli.js"
+ }
+ },
+ "node_modules/tldts-core": {
+ "version": "6.1.86",
+ "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz",
+ "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/tough-cookie": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz",
+ "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "tldts": "^6.1.32"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/ts-node": {
+ "version": "10.9.2",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
+ "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cspotcode/source-map-support": "^0.8.0",
+ "@tsconfig/node10": "^1.0.7",
+ "@tsconfig/node12": "^1.0.7",
+ "@tsconfig/node14": "^1.0.0",
+ "@tsconfig/node16": "^1.0.2",
+ "acorn": "^8.4.1",
+ "acorn-walk": "^8.1.1",
+ "arg": "^4.1.0",
+ "create-require": "^1.1.0",
+ "diff": "^4.0.1",
+ "make-error": "^1.1.1",
+ "v8-compile-cache-lib": "^3.0.1",
+ "yn": "3.1.1"
+ },
+ "bin": {
+ "ts-node": "dist/bin.js",
+ "ts-node-cwd": "dist/bin-cwd.js",
+ "ts-node-esm": "dist/bin-esm.js",
+ "ts-node-script": "dist/bin-script.js",
+ "ts-node-transpile-only": "dist/bin-transpile.js",
+ "ts-script": "dist/bin-script-deprecated.js"
+ },
+ "peerDependencies": {
+ "@swc/core": ">=1.2.50",
+ "@swc/wasm": ">=1.2.50",
+ "@types/node": "*",
+ "typescript": ">=2.7"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "@swc/wasm": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ts-node/node_modules/diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "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"
+ },
+ "node_modules/tweetnacl": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
+ "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==",
+ "license": "Unlicense"
+ },
+ "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"
+ }
+ },
+ "node_modules/type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/type-is/node_modules/media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+ "dev": true,
+ "license": "MIT",
+ "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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/typescript": {
+ "version": "5.9.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/uglify-js": {
+ "version": "3.19.3",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz",
+ "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "bin": {
+ "uglifyjs": "bin/uglifyjs"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/uid-safe": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
+ "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "random-bytes": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/uid2": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.4.tgz",
+ "integrity": "sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/undici-types": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/unicorn-magic": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz",
+ "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "13.0.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz",
+ "integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==",
+ "funding": [
+ "https://github.com/sponsors/broofa",
+ "https://github.com/sponsors/ctavan"
+ ],
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist-node/bin/uuid"
+ }
+ },
+ "node_modules/v8-compile-cache-lib": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
+ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/vite": {
+ "version": "7.2.4",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.4.tgz",
+ "integrity": "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.25.0",
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3",
+ "postcss": "^8.5.6",
+ "rollup": "^4.43.0",
+ "tinyglobby": "^0.2.15"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^20.19.0 || >=22.12.0",
+ "jiti": ">=1.21.0",
+ "less": "^4.0.0",
+ "lightningcss": "^1.21.0",
+ "sass": "^1.70.0",
+ "sass-embedded": "^1.70.0",
+ "stylus": ">=0.54.8",
+ "sugarss": "^5.0.0",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite/node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite/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_modules/vitest": {
+ "version": "4.0.13",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.13.tgz",
+ "integrity": "sha512-QSD4I0fN6uZQfftryIXuqvqgBxTvJ3ZNkF6RWECd82YGAYAfhcppBLFXzXJHQAAhVFyYEuFTrq6h0hQqjB7jIQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/expect": "4.0.13",
+ "@vitest/mocker": "4.0.13",
+ "@vitest/pretty-format": "4.0.13",
+ "@vitest/runner": "4.0.13",
+ "@vitest/snapshot": "4.0.13",
+ "@vitest/spy": "4.0.13",
+ "@vitest/utils": "4.0.13",
+ "debug": "^4.4.3",
+ "es-module-lexer": "^1.7.0",
+ "expect-type": "^1.2.2",
+ "magic-string": "^0.30.21",
+ "pathe": "^2.0.3",
+ "picomatch": "^4.0.3",
+ "std-env": "^3.10.0",
+ "tinybench": "^2.9.0",
+ "tinyexec": "^0.3.2",
+ "tinyglobby": "^0.2.15",
+ "tinyrainbow": "^3.0.3",
+ "vite": "^6.0.0 || ^7.0.0",
+ "why-is-node-running": "^2.3.0"
+ },
+ "bin": {
+ "vitest": "vitest.mjs"
+ },
+ "engines": {
+ "node": "^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "@edge-runtime/vm": "*",
+ "@opentelemetry/api": "^1.9.0",
+ "@types/debug": "^4.1.12",
+ "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0",
+ "@vitest/browser-playwright": "4.0.13",
+ "@vitest/browser-preview": "4.0.13",
+ "@vitest/browser-webdriverio": "4.0.13",
+ "@vitest/ui": "4.0.13",
+ "happy-dom": "*",
+ "jsdom": "*"
+ },
+ "peerDependenciesMeta": {
+ "@edge-runtime/vm": {
+ "optional": true
+ },
+ "@opentelemetry/api": {
+ "optional": true
+ },
+ "@types/debug": {
+ "optional": true
+ },
+ "@types/node": {
+ "optional": true
+ },
+ "@vitest/browser-playwright": {
+ "optional": true
+ },
+ "@vitest/browser-preview": {
+ "optional": true
+ },
+ "@vitest/browser-webdriverio": {
+ "optional": true
+ },
+ "@vitest/ui": {
+ "optional": true
+ },
+ "happy-dom": {
+ "optional": true
+ },
+ "jsdom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vitest/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_modules/which-boxed-primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
+ "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
+ "license": "MIT",
+ "dependencies": {
+ "is-bigint": "^1.1.0",
+ "is-boolean-object": "^1.2.1",
+ "is-number-object": "^1.1.1",
+ "is-string": "^1.1.1",
+ "is-symbol": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-collection": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
+ "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
+ "license": "MIT",
+ "dependencies": {
+ "is-map": "^2.0.3",
+ "is-set": "^2.0.3",
+ "is-weakmap": "^2.0.2",
+ "is-weakset": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.19",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz",
+ "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "for-each": "^0.3.5",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/why-is-node-running": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
+ "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "siginfo": "^2.0.0",
+ "stackback": "0.0.2"
+ },
+ "bin": {
+ "why-is-node-running": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/worker-timers": {
+ "version": "7.1.8",
+ "resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-7.1.8.tgz",
+ "integrity": "sha512-R54psRKYVLuzff7c1OTFcq/4Hue5Vlz4bFtNEIarpSiCYhpifHU3aIQI29S84o1j87ePCYqbmEJPqwBTf+3sfw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@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": "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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@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": "7.0.71",
+ "resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-7.0.71.tgz",
+ "integrity": "sha512-ks/5YKwZsto1c2vmljroppOKCivB/ma97g9y77MAAz2TBBjPPgpoOiS1qYQKIgvGTr2QYPT3XhJWIB6Rj2MVPQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.24.5",
+ "tslib": "^2.6.2"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ws": {
+ "version": "7.5.10",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
+ "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.3.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
}
+ }
+ },
+ "node_modules/xml2js": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz",
+ "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==",
+ "license": "MIT",
+ "dependencies": {
+ "sax": ">=0.6.0",
+ "xmlbuilder": "~11.0.0"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/xmlbuilder": {
+ "version": "11.0.1",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/yn": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+ "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
}
+ }
}
diff --git a/package.json b/package.json
index 7b1f55ca..ee656c2d 100644
--- a/package.json
+++ b/package.json
@@ -1,84 +1,87 @@
{
- "name": "node-red-contrib-homekit-bridged",
- "version": "1.7.3",
- "description": "Node-RED nodes to simulate Apple HomeKit devices.",
- "main": "build/nodes/nrchkb.js",
- "scripts": {
- "build": "npm run clean && tsc",
- "clean": "del-cli \"build/lib\" \"build/**/*.js\"",
- "test": "mocha -r ts-node/register './src/**/*.test.[tj]s' --exit --timeout 30000",
- "prettier": "prettier --write \"**/*.{js,ts}\"",
- "eslint": "eslint \"src/**/*.ts\"",
- "prepare": "husky install"
+ "name": "node-red-contrib-homekit-bridged",
+ "version": "2.0.0-dev.5",
+ "description": "Node-RED nodes to simulate Apple HomeKit devices.",
+ "main": "build/nodes/nrchkb.js",
+ "scripts": {
+ "build": "npm run clean && tsc",
+ "clean": "del-cli \"build/lib\" \"build/**/*.js\"",
+ "test": "vitest run",
+ "test:ci": "vitest run --no-file-parallelism",
+ "test:watch": "vitest",
+ "format": "npx @biomejs/biome check --write",
+ "lint": "npx @biomejs/biome check",
+ "prepare": "husky || true"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/NRCHKB/node-red-contrib-homekit-bridged.git"
+ },
+ "keywords": [
+ "homekit",
+ "node-red",
+ "NRCHKB",
+ "iot",
+ "home",
+ "hap-nodejs",
+ "homebridge"
+ ],
+ "node-red": {
+ "nodes": {
+ "nrchkb": "build/nodes/nrchkb.js",
+ "bridge": "build/nodes/bridge.js",
+ "standalone": "build/nodes/standalone.js",
+ "service": "build/nodes/service.js",
+ "service2": "build/nodes/service2.js",
+ "status": "build/nodes/status.js"
},
- "repository": {
- "type": "git",
- "url": "git+https://github.com/NRCHKB/node-red-contrib-homekit-bridged.git"
- },
- "keywords": [
- "homekit",
- "node-red",
- "NRCHKB",
- "iot",
- "home",
- "hap-nodejs",
- "homebridge"
- ],
- "node-red": {
- "nodes": {
- "nrchkb": "build/nodes/nrchkb.js",
- "bridge": "build/nodes/bridge.js",
- "standalone": "build/nodes/standalone.js",
- "service": "build/nodes/service.js",
- "service2": "build/nodes/service2.js",
- "status": "build/nodes/status.js"
- },
- "version": ">=1.3.7"
- },
- "author": "Tadeusz Wyrzykowski (https://github.com/Shaquu)",
- "license": "Apache-2.0",
- "bugs": {
- "url": "https://github.com/NRCHKB/node-red-contrib-homekit-bridged/issues"
- },
- "homepage": "https://github.com/NRCHKB/node-red-contrib-homekit-bridged#readme",
- "dependencies": {
- "@nrchkb/logger": "~3.1.1",
- "hap-nodejs": "0.12.3",
- "node-persist": "^3.1.3",
- "semver": "~7.6.3",
- "uuid": "~11.0.5"
- },
- "devDependencies": {
- "@homebridge/ciao": "~1.3.1",
- "@node-red/registry": "^4.0.8",
- "@types/mocha": "^10.0.10",
- "@types/node": "^18",
- "@types/node-persist": "^3.1.8",
- "@types/node-red": "^1.3.5",
- "@types/node-red-node-test-helper": "^0.3.4",
- "@types/semver": "^7.5.8",
- "@types/uuid": "^10.0.0",
- "@typescript-eslint/eslint-plugin": "^7.16.0",
- "@typescript-eslint/parser": "^7.16.0",
- "babel-eslint": "^10.1.0",
- "del-cli": "^5.1.0",
- "eslint": "^8",
- "eslint-config-prettier": "^9.1.0",
- "eslint-plugin-prettier": "^5.1.3",
- "eslint-plugin-simple-import-sort": "^12.1.1",
- "husky": "^9.0.11",
- "mocha": "^10.6.0",
- "node-red": "^4.0.8",
- "node-red-node-test-helper": "^0.3.4",
- "prettier": "^3.4.2",
- "ts-node": "^10.9.2",
- "typescript": "^5.7.3"
- },
- "engines": {
- "node": ">=18"
- },
- "files": [
- "/build",
- "/examples"
- ]
+ "version": ">=1.3.7"
+ },
+ "author": "Tadeusz Wyrzykowski (https://github.com/Shaquu)",
+ "license": "Apache-2.0",
+ "bugs": {
+ "url": "https://github.com/NRCHKB/node-red-contrib-homekit-bridged/issues"
+ },
+ "homepage": "https://github.com/NRCHKB/node-red-contrib-homekit-bridged#readme",
+ "dependencies": {
+ "@homebridge/hap-nodejs": "2.0.2",
+ "@nrchkb/logger": "~3.1.1",
+ "node-persist": "^3.1.3",
+ "semver": "~7.7.3",
+ "uuid": "~13.0.0"
+ },
+ "devDependencies": {
+ "@biomejs/biome": "2.3.7",
+ "@homebridge/ciao": "~1.3.4",
+ "@node-red/registry": "^4.1.1",
+ "@types/node": "^20",
+ "@types/node-persist": "^3.1.8",
+ "@types/node-red": "^1.3.5",
+ "@types/node-red-node-test-helper": "^0.3.5",
+ "@types/semver": "^7.7.1",
+ "@types/uuid": "^10.0.0",
+ "del-cli": "^7.0.0",
+ "husky": "^9.1.7",
+ "node-red": "^4.1.1",
+ "node-red-node-test-helper": "^0.3.5",
+ "ts-node": "^10.9.2",
+ "typescript": "^5.9.3",
+ "vitest": "^4.0.13"
+ },
+ "vitest": {
+ "test": {
+ "environment": "node",
+ "testTimeout": 30000,
+ "include": [
+ "src/**/*.test.ts"
+ ]
+ }
+ },
+ "engines": {
+ "node": "^20 || ^22 || ^24"
+ },
+ "files": [
+ "/build",
+ "/examples"
+ ]
}
diff --git a/src/lib/HAPHostNode.ts b/src/lib/HAPHostNode.ts
index a00b173e..91729bf6 100644
--- a/src/lib/HAPHostNode.ts
+++ b/src/lib/HAPHostNode.ts
@@ -1,245 +1,199 @@
-import { logger } from '@nrchkb/logger'
import {
- Accessory,
- Bridge,
- Categories,
- Characteristic,
- MDNSAdvertiser,
- Service,
- uuid,
-} from 'hap-nodejs'
-import { NodeAPI } from 'node-red'
+ Accessory,
+ Bridge,
+ type Categories,
+ Characteristic,
+ MDNSAdvertiser,
+ Service,
+ uuid
+} from '@homebridge/hap-nodejs'
+import { logger } from '@nrchkb/logger'
+import type { NodeAPI } from 'node-red'
import { SemVer } from 'semver'
import semver from 'semver/preload'
import NRCHKBError from './NRCHKBError'
-import BonjourMulticastOptions from './types/hap-nodejs/BonjourMulticastOptions'
-import HapCategories from './types/hap-nodejs/HapCategories'
-import HAPHostConfigType from './types/HAPHostConfigType'
-import HAPHostNodeType from './types/HAPHostNodeType'
+import type HAPHostConfigType from './types/HAPHostConfigType'
+import type HAPHostNodeType from './types/HAPHostNodeType'
import HostType from './types/HostType'
+import HapCategories from './types/hap-nodejs/HapCategories'
module.exports = (RED: NodeAPI, hostType: HostType) => {
- const MdnsUtils = require('./utils/MdnsUtils')()
-
- const init = function (this: HAPHostNodeType, config: HAPHostConfigType) {
- const self = this
- const log = logger('NRCHKB', 'HAPHostNode', config.bridgeName, self)
-
- self.hostType = hostType
- RED.nodes.createNode(self, config)
-
- self.config = config
- self.name = config.bridgeName
-
- if (!hostNameValidator(config.bridgeName)) {
- log.error('Host name is incorrect', false)
- return new NRCHKBError('Host name is incorrect')
- }
-
- if (semver.parse(config.firmwareRev) == null) {
- config.firmwareRev = new SemVer('0.0.0')
- }
-
- if (!config.bind?.length && config.customMdnsConfig) {
- log.error('Custom mdns config is deprecated, use bind instead!')
-
- self.mdnsConfig = {} as BonjourMulticastOptions
-
- if (MdnsUtils.checkMulticast(config.mdnsMulticast)) {
- self.mdnsConfig.multicast = config.mdnsMulticast
- }
+ const init = function (this: HAPHostNodeType, config: HAPHostConfigType) {
+ const log = logger('NRCHKB', 'HAPHostNode', config.bridgeName, this)
- if (MdnsUtils.checkInterface(config.mdnsInterface)) {
- self.mdnsConfig.interface = config.mdnsInterface
- }
+ this.hostType = hostType
+ RED.nodes.createNode(this, config)
- if (MdnsUtils.checkPort(config.mdnsPort)) {
- self.mdnsConfig.port = parseInt(config.mdnsPort?.toString())
- }
+ this.config = config
+ this.name = config.bridgeName
- if (MdnsUtils.checkIp(config.mdnsIp)) {
- self.mdnsConfig.ip = config.mdnsIp
- }
-
- if (MdnsUtils.checkTtl(config.mdnsTtl)) {
- self.mdnsConfig.ttl = parseInt(config.mdnsTtl?.toString())
- }
-
- if (MdnsUtils.checkLoopback(config.mdnsLoopback)) {
- self.mdnsConfig.loopback = config.mdnsLoopback
- }
-
- if (MdnsUtils.checkReuseAddr(config.mdnsReuseAddr)) {
- self.mdnsConfig.reuseAddr = config.mdnsReuseAddr
- }
- }
+ if (!hostNameValidator(config.bridgeName)) {
+ log.error('Host name is incorrect', false)
+ return new NRCHKBError('Host name is incorrect')
+ }
- self.accessoryCategory = (self.hostType == HostType.BRIDGE
- ? HapCategories.BRIDGE
- : self.config.accessoryCategory) as unknown as Categories
+ if (semver.parse(config.firmwareRev) == null) {
+ config.firmwareRev = new SemVer('0.0.0')
+ }
- self.published = false
+ // biome-ignore lint/suspicious/noDoubleEquals: hostType can be a string or a number
+ this.accessoryCategory = (this.hostType == HostType.BRIDGE
+ ? HapCategories.BRIDGE
+ : this.config.accessoryCategory) as unknown as Categories
- try {
- self.bridgeUsername = macify(self.id)
- } catch (error: any) {
- log.error(error)
- return error
- }
+ this.published = false
- const hostUUID = uuid.generate(self.id)
-
- const hostTypeName =
- self.hostType == HostType.BRIDGE ? 'Bridge' : 'Standalone Accessory'
+ try {
+ this.bridgeUsername = macify(this.id)
+ } catch (error: any) {
+ log.error(error)
+ return error
+ }
- log.debug(`Creating ${hostTypeName} with UUID ${hostUUID}`)
+ const hostUUID = uuid.generate(this.id)
- if (self.hostType == HostType.BRIDGE) {
- self.host = new Bridge(self.name, hostUUID)
- } else {
- self.host = new Accessory(self.name, hostUUID)
- }
+ const hostTypeName =
+ // biome-ignore lint/suspicious/noDoubleEquals: hostType can be a string or a number
+ this.hostType == HostType.BRIDGE ? 'Bridge' : 'Standalone Accessory'
- self.publish = function () {
- if (self.hostType == HostType.BRIDGE) {
- log.debug(
- `Publishing ${hostTypeName} with pin code ${self.config.pinCode} and ${self.host.bridgedAccessories.length} accessories`
- )
- } else {
- log.debug(
- `Publishing ${hostTypeName} with pin code ${self.config.pinCode}`
- )
- }
-
- if (
- (self.config.port && self.config.port == 1880) ||
- (self.mdnsConfig?.port && self.mdnsConfig?.port == 1880)
- ) {
- log.error(
- `Cannot publish on ${hostTypeName} port 1880 as it is reserved for node-red`
- )
- self.published = false
- return false
- }
-
- // As HAP-Nodejs cannot understand new pin code format yet, we need to adjust new to old one
- let oldPinCode = self.config.pinCode
-
- if ((oldPinCode.match(/-/g) || []).length == 1) {
- oldPinCode = oldPinCode.replace(/-/g, '')
- oldPinCode = `${oldPinCode.slice(0, 3)}-${oldPinCode.slice(3, 5)}-${oldPinCode.slice(5, 8)}`
- }
-
- let bind
- if (self.config.bind?.length && self.config.bindType) {
- if (self.config.bindType == 'str') {
- bind = self.config.bind
- } else if (self.config.bindType == 'json') {
- bind = JSON.parse(self.config.bind)
- }
- }
-
- self.host.publish(
- {
- username: self.bridgeUsername,
- port:
- self.config.port && !isNaN(self.config.port)
- ? self.config.port
- : 0,
- pincode: oldPinCode,
- category: self.accessoryCategory,
- mdns: self.mdnsConfig,
- bind: bind,
- advertiser:
- self.config.advertiser ?? MDNSAdvertiser.BONJOUR,
- },
- self.config.allowInsecureRequest
- )
-
- self.published = true
-
- return true
- }
+ log.debug(`Creating ${hostTypeName} with UUID ${hostUUID}`)
- self.on('close', async function (removed: any, done: () => any) {
- if (removed) {
- log.debug('This node has been deleted')
- await self.host.destroy()
- } else {
- log.debug('This node is being restarted')
- await self.host.unpublish()
- }
-
- self.published = false
-
- done()
- })
-
- self.host.on('identify', function (paired: any, callback: () => any) {
- if (paired) {
- log.debug(`Identify called on paired ${hostTypeName}`)
- } else {
- log.debug(`Identify called on unpaired ${hostTypeName}`)
- }
-
- callback()
- })
-
- // Service.AccessoryInformation created on Host creation
- const accessoryInformationService =
- self.host.getService(Service.AccessoryInformation) ||
- self.host.addService(Service.AccessoryInformation)
-
- accessoryInformationService
- .setCharacteristic(
- Characteristic.Manufacturer,
- self.config.manufacturer
- )
- .setCharacteristic(
- Characteristic.SerialNumber,
- self.config.serialNo
- )
- .setCharacteristic(Characteristic.Model, self.config.model)
- .setCharacteristic(
- Characteristic.FirmwareRevision,
- self.config.firmwareRev?.toString()
- )
- .setCharacteristic(
- Characteristic.HardwareRevision,
- self.config.hardwareRev?.toString()
- )
- .setCharacteristic(
- Characteristic.SoftwareRevision,
- self.config.softwareRev?.toString()
- )
+ // biome-ignore lint/suspicious/noDoubleEquals: hostType can be a string or a number
+ if (this.hostType == HostType.BRIDGE) {
+ this.host = new Bridge(this.name, hostUUID)
+ } else {
+ this.host = new Accessory(this.name, hostUUID)
}
- const macify = (nodeId: string): string => {
- if (nodeId) {
- const noDecimalStr = nodeId.replace('.', '')
- const paddedStr = noDecimalStr.padEnd(12, '0')
-
- const match = paddedStr.match(/.{1,2}/g)
-
- if (match) {
- return match.join(':').substr(0, 17).toUpperCase()
- } else {
- throw new NRCHKBError(
- `match failed in macify process for padded string ${paddedStr}`
- )
- }
- } else {
- throw new NRCHKBError('nodeId cannot be empty in macify process')
+ this.publish = () => {
+ // biome-ignore lint/suspicious/noDoubleEquals: hostType can be a string or a number
+ if (this.hostType == HostType.BRIDGE) {
+ log.debug(
+ `Publishing ${hostTypeName} with pin code ${this.config.pinCode} and ${this.host.bridgedAccessories.length} accessories`
+ )
+ } else {
+ log.debug(
+ `Publishing ${hostTypeName} with pin code ${this.config.pinCode}`
+ )
+ }
+
+ if (this.config.port === 1880) {
+ log.error(
+ `Cannot publish on ${hostTypeName} port 1880 as it is reserved for node-red`
+ )
+ this.published = false
+ return false
+ }
+
+ // As HAP-Nodejs cannot understand new pin code format yet, we need to adjust new to old one
+ let oldPinCode = this.config.pinCode
+
+ if ((oldPinCode.match(/-/g) || []).length === 1) {
+ oldPinCode = oldPinCode.replace(/-/g, '')
+ oldPinCode = `${oldPinCode.slice(0, 3)}-${oldPinCode.slice(3, 5)}-${oldPinCode.slice(5, 8)}`
+ }
+
+ let bind: string | undefined
+ if (this.config.bind?.length && this.config.bindType) {
+ if (this.config.bindType === 'str') {
+ bind = this.config.bind
+ } else if (this.config.bindType === 'json') {
+ bind = JSON.parse(this.config.bind)
}
+ }
+
+ this.host.publish(
+ {
+ username: this.bridgeUsername,
+ port:
+ this.config.port && !Number.isNaN(this.config.port)
+ ? this.config.port
+ : 0,
+ pincode: oldPinCode,
+ category: this.accessoryCategory,
+ bind: bind,
+ advertiser: this.config.advertiser ?? MDNSAdvertiser.BONJOUR
+ },
+ this.config.allowInsecureRequest
+ )
+
+ this.published = true
+
+ return true
}
- const hostNameValidator = function (hostName: string) {
- return hostName ? /^[^.]{1,64}$/.test(hostName) : false
+ this.on('close', async (removed: any, done: () => any) => {
+ if (removed) {
+ log.debug('This node has been deleted')
+ await this.host.destroy()
+ } else {
+ log.debug('This node is being restarted')
+ await this.host.unpublish()
+ }
+
+ this.published = false
+
+ done()
+ })
+
+ this.host.on('identify', (paired: any, callback: () => any) => {
+ if (paired) {
+ log.debug(`Identify called on paired ${hostTypeName}`)
+ } else {
+ log.debug(`Identify called on unpaired ${hostTypeName}`)
+ }
+
+ callback()
+ })
+
+ // Service.AccessoryInformation created on Host creation
+ const accessoryInformationService =
+ this.host.getService(Service.AccessoryInformation) ||
+ this.host.addService(Service.AccessoryInformation)
+
+ accessoryInformationService
+ .setCharacteristic(Characteristic.Manufacturer, this.config.manufacturer)
+ .setCharacteristic(Characteristic.SerialNumber, this.config.serialNo)
+ .setCharacteristic(Characteristic.Model, this.config.model)
+ .setCharacteristic(
+ Characteristic.FirmwareRevision,
+ this.config.firmwareRev?.toString()
+ )
+ .setCharacteristic(
+ Characteristic.HardwareRevision,
+ this.config.hardwareRev?.toString()
+ )
+ .setCharacteristic(
+ Characteristic.SoftwareRevision,
+ this.config.softwareRev?.toString()
+ )
+ }
+
+ const macify = (nodeId: string): string => {
+ if (nodeId) {
+ const noDecimalStr = nodeId.replace('.', '')
+ const paddedStr = noDecimalStr.padEnd(12, '0')
+
+ const match = paddedStr.match(/.{1,2}/g)
+
+ if (match) {
+ return match.join(':').substr(0, 17).toUpperCase()
+ } else {
+ throw new NRCHKBError(
+ `match failed in macify process for padded string ${paddedStr}`
+ )
+ }
+ } else {
+ throw new NRCHKBError('nodeId cannot be empty in macify process')
}
+ }
- return {
- init,
- macify,
- }
+ const hostNameValidator = (hostName: string) =>
+ hostName ? /^[^.]{1,64}$/.test(hostName) : false
+
+ return {
+ init,
+ macify
+ }
}
diff --git a/src/lib/HAPServiceNode.ts b/src/lib/HAPServiceNode.ts
index 759736de..cd0b0709 100644
--- a/src/lib/HAPServiceNode.ts
+++ b/src/lib/HAPServiceNode.ts
@@ -1,291 +1,286 @@
+import { uuid } from '@homebridge/hap-nodejs'
import { logger } from '@nrchkb/logger'
-import { uuid } from 'hap-nodejs'
-import { NodeAPI } from 'node-red'
+import type { NodeAPI } from 'node-red'
import NRCHKBError from './NRCHKBError'
-import HAPHostNodeType from './types/HAPHostNodeType'
-import HAPServiceConfigType from './types/HAPServiceConfigType'
-import HAPServiceNodeType from './types/HAPServiceNodeType'
+import type HAPHostNodeType from './types/HAPHostNodeType'
+import type HAPServiceConfigType from './types/HAPServiceConfigType'
+import type HAPServiceNodeType from './types/HAPServiceNodeType'
import HostType from './types/HostType'
import { NodeStatusUtils } from './utils/NodeStatusUtils'
module.exports = (RED: NodeAPI) => {
- /**
- * Config override when user created services in old NRCHKB version
- */
- const nrchkbConfigCompatibilityOverride = function (
- this: HAPServiceNodeType
- ) {
- const self = this
-
- const log = logger('NRCHKB', 'HAPServiceNode', self.config.name, self)
-
- if (self.config.isParent === undefined) {
- log.trace(
- `nrchkbConfigCompatibilityOverride => self.config.isParent=${self.config.isParent} value changed to true`
- )
- // Services created in pre linked services era where working in 1.2 but due to more typescript in 1.3+ it started to cause some errors
- self.config.isParent = true
- }
-
- if (self.config.hostType === undefined) {
- // When moving from 1.2 to 1.3 hostType is not defined on homekit-service
- log.trace(
- `nrchkbConfigCompatibilityOverride => self.config.hostType=${self.config.hostType} value changed to HostType.BRIDGE`
- )
- self.config.hostType = HostType.BRIDGE
- }
+ /**
+ * Config override when user created services in old NRCHKB version
+ */
+ const nrchkbConfigCompatibilityOverride = function (
+ this: HAPServiceNodeType
+ ) {
+ const log = logger('NRCHKB', 'HAPServiceNode', this.config.name, this)
+
+ if (this.config.isParent === undefined) {
+ log.trace(
+ `nrchkbConfigCompatibilityOverride => self.config.isParent=${this.config.isParent} value changed to true`
+ )
+ // Services created in pre linked services era where working in 1.2 but due to more typescript in 1.3+ it started to cause some errors
+ this.config.isParent = true
}
- const preInit = function (
- this: HAPServiceNodeType,
- config: HAPServiceConfigType
- ) {
- const self = this
- self.nodeStatusUtils = new NodeStatusUtils(self)
+ if (this.config.hostType === undefined) {
+ // When moving from 1.2 to 1.3 hostType is not defined on homekit-service
+ log.trace(
+ `nrchkbConfigCompatibilityOverride => self.config.hostType=${this.config.hostType} value changed to HostType.BRIDGE`
+ )
+ this.config.hostType = HostType.BRIDGE
+ }
+ }
+
+ const preInit = function (
+ this: HAPServiceNodeType,
+ config: HAPServiceConfigType
+ ) {
+ this.nodeStatusUtils = new NodeStatusUtils(this)
- self.config = config
- self.name = self.config.name
+ this.config = config
+ this.name = this.config.name
- const log = logger('NRCHKB', 'HAPServiceNode', self.config.name, self)
+ const log = logger('NRCHKB', 'HAPServiceNode', this.config.name, this)
- self.RED = RED
- self.publishTimers = {}
+ this.RED = RED
+ this.publishTimers = {}
- nrchkbConfigCompatibilityOverride.call(self)
- RED.nodes.createNode(self, self.config)
+ nrchkbConfigCompatibilityOverride.call(this)
+ RED.nodes.createNode(this, this.config)
- const ServiceUtils = require('./utils/ServiceUtils')(self)
+ const ServiceUtils = require('./utils/ServiceUtils')(this)
- new Promise((resolve) => {
- if (self.config.waitForSetupMsg) {
- log.debug(
- 'Waiting for Setup message. It should be of format {"payload":{"nrchkb":{"setup":{}}}}'
- )
+ new Promise((resolve) => {
+ if (this.config.waitForSetupMsg) {
+ log.debug(
+ 'Waiting for Setup message. It should be of format {"payload":{"nrchkb":{"setup":{}}}}'
+ )
- self.setupDone = false
+ this.setupDone = false
- self.nodeStatusUtils.setStatus({
- fill: 'blue',
- shape: 'dot',
- text: 'Waiting for Setup',
- })
+ this.nodeStatusUtils.setStatus({
+ fill: 'blue',
+ shape: 'dot',
+ text: 'Waiting for Setup'
+ })
- self.handleWaitForSetup = (msg: Record) =>
- ServiceUtils.handleWaitForSetup(self.config, msg, resolve)
- self.on('input', self.handleWaitForSetup)
- } else {
- resolve(self.config)
- }
+ this.handleWaitForSetup = (msg: Record) =>
+ ServiceUtils.handleWaitForSetup(this.config, msg, resolve)
+ this.on('input', this.handleWaitForSetup)
+ } else {
+ resolve(this.config)
+ }
+ })
+ .then((newConfig) => {
+ init.call(this, newConfig)
+ })
+ .catch((error: any) => {
+ log.error(`Error while starting Service due to ${error}`)
+ })
+ }
+
+ const init = function (
+ this: HAPServiceNodeType,
+ config: HAPServiceConfigType
+ ) {
+ this.config = config
+
+ const log = logger('NRCHKB', 'HAPServiceNode', this.config.name, this)
+
+ const ServiceUtils = require('./utils/ServiceUtils')(this)
+
+ if (this.config.isParent) {
+ log.debug('Starting Parent Service')
+ configure.call(this)
+ this.configured = true
+ this.reachable = true
+ } else {
+ const serviceType =
+ config.serviceName === 'CameraControl' ? 'Camera' : 'Linked'
+
+ ServiceUtils.waitForParent()
+ .then(() => {
+ log.debug(`Starting ${serviceType} Service`)
+ configure.call(this)
+ this.configured = true
})
- .then((newConfig) => {
- init.call(self, newConfig)
- })
- .catch((error: any) => {
- log.error(`Error while starting Service due to ${error}`)
- })
+ .catch((error: any) => {
+ log.error(
+ `Error while starting ${serviceType} Service due to ${error}`
+ )
+ })
+ }
+ }
+
+ const configure = function (this: HAPServiceNodeType) {
+ const log = logger('NRCHKB', 'HAPServiceNode', this.config.name, this)
+
+ const Utils = require('./utils')(this)
+ const AccessoryUtils = Utils.AccessoryUtils
+ const BridgeUtils = Utils.BridgeUtils
+ const CharacteristicUtils = Utils.CharacteristicUtils
+ const ServiceUtils = Utils.ServiceUtils
+
+ let parentNode: HAPServiceNodeType
+
+ if (this.config.isParent) {
+ const hostId =
+ // biome-ignore lint/suspicious/noDoubleEquals: hostType can be a string or a number
+ this.config.hostType == HostType.BRIDGE
+ ? this.config.bridge
+ : this.config.accessoryId
+
+ this.hostNode = RED.nodes.getNode(hostId) as HAPHostNodeType
+
+ if (!this.hostNode) {
+ // biome-ignore lint/suspicious/noDoubleEquals: hostType can be a string or a number
+ const message = `Host node ${this.config.hostType == HostType.BRIDGE ? 'Bridge' : 'Standalone Accessory'} ${hostId} not found`
+ log.error(message, false)
+ throw new NRCHKBError(message)
+ }
+
+ this.childNodes = []
+ this.childNodes.push(this)
+ } else {
+ // Retrieve parent service node
+ parentNode = RED.nodes.getNode(
+ this.config.parentService
+ ) as HAPServiceNodeType
+
+ if (!parentNode) {
+ log.error('Parent Node not assigned', false)
+ throw new NRCHKBError('Parent Node not assigned')
+ }
+
+ this.parentNode = parentNode
+ this.parentService = this.parentNode.service
+
+ if (!this.parentService) {
+ log.error('Parent Service not assigned', false)
+ throw new NRCHKBError('Parent Service not assigned')
+ }
+
+ this.hostNode = this.parentNode.hostNode
+ this.parentNode.childNodes?.push(this)
+
+ this.accessory = this.parentNode.accessory
}
- const init = function (
- this: HAPServiceNodeType,
- config: HAPServiceConfigType
+ // Service node properties
+ this.name = this.config.name
+
+ // Find a unique identifier for the current service
+ if (
+ Object.hasOwn(this, '_flow') &&
+ Object.hasOwn(this, '_alias') &&
+ (this._flow ? Object(this._flow).hasOwn('TYPE') : false) &&
+ this._flow?.TYPE === 'subflow'
) {
- const self = this
- self.config = config
-
- const log = logger('NRCHKB', 'HAPServiceNode', self.config.name, self)
-
- const ServiceUtils = require('./utils/ServiceUtils')(self)
-
- if (self.config.isParent) {
- log.debug('Starting Parent Service')
- configure.call(self)
- self.configured = true
- self.reachable = true
- } else {
- const serviceType =
- config.serviceName === 'CameraControl' ? 'Camera' : 'Linked'
-
- ServiceUtils.waitForParent()
- .then(() => {
- log.debug(`Starting ${serviceType} Service`)
- configure.call(self)
- self.configured = true
- })
- .catch((error: any) => {
- log.error(
- `Error while starting ${serviceType} Service due to ${error}`
- )
- })
- }
+ // For subflows, use the service node identifier from the subflow template
+ // plus the full path from the subflow node identifier to the subflow.
+ this.uniqueIdentifier = `${this._alias}/${this._flow.path}`
+ } else {
+ // For top level flows, use the node identifier
+ this.uniqueIdentifier = this.id
}
- const configure = function (this: HAPServiceNodeType) {
- const self = this
-
- const log = logger('NRCHKB', 'HAPServiceNode', self.config.name, self)
-
- const Utils = require('./utils')(self)
- const AccessoryUtils = Utils.AccessoryUtils
- const BridgeUtils = Utils.BridgeUtils
- const CharacteristicUtils = Utils.CharacteristicUtils
- const ServiceUtils = Utils.ServiceUtils
-
- let parentNode: HAPServiceNodeType
-
- if (self.config.isParent) {
- const hostId =
- self.config.hostType == HostType.BRIDGE
- ? self.config.bridge
- : self.config.accessoryId
-
- self.hostNode = RED.nodes.getNode(hostId) as HAPHostNodeType
-
- if (!self.hostNode) {
- const message = `Host node ${self.config.hostType == HostType.BRIDGE ? 'Bridge' : 'Standalone Accessory'} ${hostId} not found`
- log.error(message, false)
- throw new NRCHKBError(message)
- }
-
- self.childNodes = []
- self.childNodes.push(self)
- } else {
- // Retrieve parent service node
- parentNode = RED.nodes.getNode(
- self.config.parentService
- ) as HAPServiceNodeType
-
- if (!parentNode) {
- log.error('Parent Node not assigned', false)
- throw new NRCHKBError('Parent Node not assigned')
- }
-
- self.parentNode = parentNode
- self.parentService = self.parentNode.service
-
- if (!self.parentService) {
- log.error('Parent Service not assigned', false)
- throw new NRCHKBError('Parent Service not assigned')
- }
-
- self.hostNode = self.parentNode.hostNode
- self.parentNode.childNodes?.push(self)
-
- self.accessory = self.parentNode.accessory
- }
-
- // Service node properties
- self.name = self.config.name
-
- // Find a unique identifier for the current service
- if (
- self.hasOwnProperty('_flow') &&
- self.hasOwnProperty('_alias') &&
- self._flow?.hasOwnProperty('TYPE') &&
- self._flow.TYPE === 'subflow'
- ) {
- // For subflows, use the service node identifier from the subflow template
- // plus the full path from the subflow node identifier to the subflow.
- self.uniqueIdentifier = self._alias + '/' + self._flow.path
- } else {
- // For top level flows, use the node identifier
- self.uniqueIdentifier = self.id
- }
-
- // Generate UUID from unique identifier
- const subtypeUUID = uuid.generate(self.uniqueIdentifier)
-
- // Look for existing Accessory or create a new one
- if (self.config.hostType == HostType.BRIDGE) {
- if (self.config.isParent) {
- // According to the HomeKit Accessory Protocol Specification the value
- // of the fields Name, Manufacturer, Serial Number and Model must not
- // change throughout the lifetime of an accessory. Because of that the
- // accessory UUID will be generated based on that data to ensure that
- // a new accessory will be created if any of those configuration values
- // changes.
- const accessoryUUID = uuid.generate(
- 'A' +
- self.uniqueIdentifier +
- self.name +
- self.config.manufacturer +
- self.config.serialNo +
- self.config.model
- )
-
- self.accessory = AccessoryUtils.getOrCreate(
- self.hostNode.host,
- {
- name: self.name,
- UUID: accessoryUUID,
- manufacturer: self.config.manufacturer,
- serialNo: self.config.serialNo,
- model: self.config.model,
- firmwareRev: self.config.firmwareRev,
- hardwareRev: self.config.hardwareRev,
- softwareRev: self.config.softwareRev,
- },
- subtypeUUID // subtype of the primary service for identification
- )
-
- //Respond to identify
- self.onIdentify = AccessoryUtils.onIdentify
- self.accessory.on('identify', self.onIdentify)
- }
- } else {
- // We are using Standalone Accessory mode so no need to create new Accessory as we have "host" already
- log.debug('Binding Service accessory as Standalone Accessory')
- self.accessory = self.hostNode.host
- }
-
- // Look for existing Service or create a new one
- self.service = ServiceUtils.getOrCreate(
- self.accessory,
- {
- name: self.name,
- UUID: subtypeUUID,
- serviceName: self.config.serviceName,
- config: self.config,
- },
- self.parentService
+ // Generate UUID from unique identifier
+ const subtypeUUID = uuid.generate(this.uniqueIdentifier)
+
+ // Look for existing Accessory or create a new one
+ // biome-ignore lint/suspicious/noDoubleEquals: hostType can be a string or a number
+ if (this.config.hostType == HostType.BRIDGE) {
+ if (this.config.isParent) {
+ // According to the HomeKit Accessory Protocol Specification the value
+ // of the fields Name, Manufacturer, Serial Number and Model must not
+ // change throughout the lifetime of an accessory. Because of that the
+ // accessory UUID will be generated based on that data to ensure that
+ // a new accessory will be created if any of those configuration values
+ // changes.
+ const accessoryUUID = uuid.generate(
+ 'A' +
+ this.uniqueIdentifier +
+ this.name +
+ this.config.manufacturer +
+ this.config.serialNo +
+ this.config.model
)
- self.characteristicProperties = CharacteristicUtils.load(
- self.service,
- self.config
+ this.accessory = AccessoryUtils.getOrCreate(
+ this.hostNode.host,
+ {
+ name: this.name,
+ UUID: accessoryUUID,
+ manufacturer: this.config.manufacturer,
+ serialNo: this.config.serialNo,
+ model: this.config.model,
+ firmwareRev: this.config.firmwareRev,
+ hardwareRev: this.config.hardwareRev,
+ softwareRev: this.config.softwareRev
+ },
+ subtypeUUID // subtype of the primary service for identification
)
- ServiceUtils.configureAdaptiveLightning()
+ //Respond to identify
+ this.onIdentify = AccessoryUtils.onIdentify
+ this.accessory.on('identify', this.onIdentify)
+ }
+ } else {
+ // We are using Standalone Accessory mode so no need to create new Accessory as we have "host" already
+ log.debug('Binding Service accessory as Standalone Accessory')
+ this.accessory = this.hostNode.host
+ }
- if (self.config.isParent) {
- BridgeUtils.delayedPublish(self)
- }
+ // Look for existing Service or create a new one
+ this.service = ServiceUtils.getOrCreate(
+ this.accessory,
+ {
+ name: this.name,
+ UUID: subtypeUUID,
+ serviceName: this.config.serviceName,
+ config: this.config
+ },
+ this.parentService
+ )
+
+ this.characteristicProperties = CharacteristicUtils.load(
+ this.service,
+ this.config
+ )
+
+ ServiceUtils.configureAdaptiveLightning()
+
+ if (this.config.isParent) {
+ BridgeUtils.delayedPublish(this)
+ }
- // The pinCode should be shown to the user until interaction with iOS
- // client starts
- self.nodeStatusUtils.setStatus({
- fill: 'yellow',
- shape: 'ring',
- text: self.hostNode.config.pinCode,
- })
+ // The pinCode should be shown to the user until interaction with iOS
+ // client starts
+ this.nodeStatusUtils.setStatus({
+ fill: 'yellow',
+ shape: 'ring',
+ text: this.hostNode.config.pinCode
+ })
- // Emit message when value changes
- // service.on("characteristic-change", ServiceUtils.onCharacteristicChange);
+ // Emit message when value changes
+ // service.on("characteristic-change", ServiceUtils.onCharacteristicChange);
- // Subscribe to set and get on characteristics for that service and get
- // list of all supported
- self.supported = CharacteristicUtils.subscribeAndGetSupported(
- self.service
- )
+ // Subscribe to set and get on characteristics for that service and get
+ // list of all supported
+ this.supported = CharacteristicUtils.subscribeAndGetSupported(this.service)
- // Respond to inputs
- self.on('input', ServiceUtils.onInput)
+ // Respond to inputs
+ this.on('input', ServiceUtils.onInput)
- self.on('close', ServiceUtils.onClose)
- }
+ this.on('close', ServiceUtils.onClose)
+ }
- return {
- preInit,
- init,
- }
+ return {
+ preInit,
+ init
+ }
}
diff --git a/src/lib/HAPServiceNode2.ts b/src/lib/HAPServiceNode2.ts
index 230dbcaf..0175fd4c 100644
--- a/src/lib/HAPServiceNode2.ts
+++ b/src/lib/HAPServiceNode2.ts
@@ -1,293 +1,286 @@
+import { uuid } from '@homebridge/hap-nodejs'
import { logger } from '@nrchkb/logger'
-import { uuid } from 'hap-nodejs'
-import { NodeAPI } from 'node-red'
+import type { NodeAPI } from 'node-red'
import NRCHKBError from './NRCHKBError'
-import HAPHostNodeType from './types/HAPHostNodeType'
-import HAPService2ConfigType from './types/HAPService2ConfigType'
-import HAPService2NodeType from './types/HAPService2NodeType'
+import type HAPHostNodeType from './types/HAPHostNodeType'
+import type HAPService2ConfigType from './types/HAPService2ConfigType'
+import type HAPService2NodeType from './types/HAPService2NodeType'
import HostType from './types/HostType'
import { NodeStatusUtils } from './utils/NodeStatusUtils'
module.exports = (RED: NodeAPI) => {
- /**
- * Config override when user created services in old NRCHKB version
- */
- const nrchkbConfigCompatibilityOverride = function (
- this: HAPService2NodeType
- ) {
- const self = this
-
- const log = logger('NRCHKB', 'HAPServiceNode2', self.config.name, self)
-
- if (self.config.isParent === undefined) {
- log.trace(
- `nrchkbConfigCompatibilityOverride => self.config.isParent=${self.config.isParent} value changed to true`
- )
- // Services created in pre linked services era where working in 1.2 but due to more typescript in 1.3+ it started to cause some errors
- self.config.isParent = true
- }
-
- if (self.config.hostType === undefined) {
- // When moving from 1.2 to 1.3 hostType is not defined on homekit-service
- log.trace(
- `nrchkbConfigCompatibilityOverride => self.config.hostType=${self.config.hostType} value changed to HostType.BRIDGE`
- )
- self.config.hostType = HostType.BRIDGE
- }
+ /**
+ * Config override when user created services in old NRCHKB version
+ */
+ const nrchkbConfigCompatibilityOverride = function (
+ this: HAPService2NodeType
+ ) {
+ const log = logger('NRCHKB', 'HAPServiceNode2', this.config.name, this)
+
+ if (this.config.isParent === undefined) {
+ log.trace(
+ `nrchkbConfigCompatibilityOverride => self.config.isParent=${this.config.isParent} value changed to true`
+ )
+ // Services created in pre linked services era where working in 1.2 but due to more typescript in 1.3+ it started to cause some errors
+ this.config.isParent = true
}
- const preInit = function (
- this: HAPService2NodeType,
- config: HAPService2ConfigType
- ) {
- const self = this
- self.nodeStatusUtils = new NodeStatusUtils(self)
+ if (this.config.hostType === undefined) {
+ // When moving from 1.2 to 1.3 hostType is not defined on homekit-service
+ log.trace(
+ `nrchkbConfigCompatibilityOverride => self.config.hostType=${this.config.hostType} value changed to HostType.BRIDGE`
+ )
+ this.config.hostType = HostType.BRIDGE
+ }
+ }
- self.config = config
- self.name = self.config.name
+ const preInit = function (
+ this: HAPService2NodeType,
+ config: HAPService2ConfigType
+ ) {
+ this.nodeStatusUtils = new NodeStatusUtils(this)
- const log = logger('NRCHKB', 'HAPServiceNode2', self.config.name, self)
+ this.config = config
+ this.name = this.config.name
- self.RED = RED
- self.publishTimers = {}
+ const log = logger('NRCHKB', 'HAPServiceNode2', this.config.name, this)
- nrchkbConfigCompatibilityOverride.call(self)
- RED.nodes.createNode(self, self.config)
+ this.RED = RED
+ this.publishTimers = {}
- const ServiceUtils = require('./utils/ServiceUtils2')(self)
+ nrchkbConfigCompatibilityOverride.call(this)
+ RED.nodes.createNode(this, this.config)
- new Promise((resolve) => {
- if (self.config.waitForSetupMsg) {
- log.debug(
- 'Waiting for Setup message. It should be of format {"payload":{"nrchkb":{"setup":{}}}}'
- )
+ const ServiceUtils = require('./utils/ServiceUtils2')(this)
- self.setupDone = false
+ new Promise((resolve) => {
+ if (this.config.waitForSetupMsg) {
+ log.debug(
+ 'Waiting for Setup message. It should be of format {"payload":{"nrchkb":{"setup":{}}}}'
+ )
- self.nodeStatusUtils.setStatus({
- fill: 'blue',
- shape: 'dot',
- text: 'Waiting for Setup',
- })
+ this.setupDone = false
- self.handleWaitForSetup = (msg: Record) =>
- ServiceUtils.handleWaitForSetup(self.config, msg, resolve)
- self.on('input', self.handleWaitForSetup)
- } else {
- resolve(self.config)
- }
+ this.nodeStatusUtils.setStatus({
+ fill: 'blue',
+ shape: 'dot',
+ text: 'Waiting for Setup'
})
- .then((newConfig) => {
- init.call(self, newConfig)
- })
- .catch((error: any) => {
- log.error(`Error while starting Service due to ${error}`)
- })
- }
- const init = function (
- this: HAPService2NodeType,
- config: HAPService2ConfigType
- ) {
- const self = this
- self.config = config
-
- const log = logger('NRCHKB', 'HAPServiceNode2', self.config.name, self)
-
- const ServiceUtils = require('./utils/ServiceUtils2')(self)
-
- if (self.config.isParent) {
- log.debug('Starting Parent Service')
- configure.call(self)
- self.configured = true
- self.reachable = true
- } else {
- const serviceType =
- config.serviceName === 'CameraControl' ? 'Camera' : 'Linked'
-
- ServiceUtils.waitForParent()
- .then(() => {
- log.debug(`Starting ${serviceType} Service`)
- configure.call(self)
- self.configured = true
- })
- .catch((error: any) => {
- log.error(
- `Error while starting ${serviceType} Service due to ${error}`
- )
- })
- }
+ this.handleWaitForSetup = (msg: Record) =>
+ ServiceUtils.handleWaitForSetup(this.config, msg, resolve)
+ this.on('input', this.handleWaitForSetup)
+ } else {
+ resolve(this.config)
+ }
+ })
+ .then((newConfig) => {
+ init.call(this, newConfig)
+ })
+ .catch((error: any) => {
+ log.error(`Error while starting Service due to ${error}`)
+ })
+ }
+
+ const init = function (
+ this: HAPService2NodeType,
+ config: HAPService2ConfigType
+ ) {
+ this.config = config
+
+ const log = logger('NRCHKB', 'HAPServiceNode2', this.config.name, this)
+
+ const ServiceUtils = require('./utils/ServiceUtils2')(this)
+
+ if (this.config.isParent) {
+ log.debug('Starting Parent Service')
+ configure.call(this)
+ this.configured = true
+ this.reachable = true
+ } else {
+ const serviceType =
+ config.serviceName === 'CameraControl' ? 'Camera' : 'Linked'
+
+ ServiceUtils.waitForParent()
+ .then(() => {
+ log.debug(`Starting ${serviceType} Service`)
+ configure.call(this)
+ this.configured = true
+ })
+ .catch((error: any) => {
+ log.error(
+ `Error while starting ${serviceType} Service due to ${error}`
+ )
+ })
+ }
+ }
+
+ const configure = function (this: HAPService2NodeType) {
+ const log = logger('NRCHKB', 'HAPServiceNode2', this.config.name, this)
+
+ const Utils = require('./utils')(this)
+ const AccessoryUtils = Utils.AccessoryUtils
+ const BridgeUtils = Utils.BridgeUtils
+ const CharacteristicUtils = require('./utils/CharacteristicUtils2')(this)
+ const ServiceUtils = require('./utils/ServiceUtils2')(this)
+
+ let parentNode: HAPService2NodeType
+
+ if (this.config.isParent) {
+ const hostId =
+ // biome-ignore lint/suspicious/noDoubleEquals: hostType can be a string or a number
+ this.config.hostType == HostType.BRIDGE
+ ? this.config.bridge
+ : this.config.accessoryId
+
+ this.hostNode = RED.nodes.getNode(hostId) as HAPHostNodeType
+
+ if (!this.hostNode) {
+ // biome-ignore lint/suspicious/noDoubleEquals: hostType can be a string or a number
+ const message = `Host node ${this.config.hostType == HostType.BRIDGE ? 'Bridge' : 'Standalone Accessory'} ${hostId} not found`
+ log.error(message, false)
+ throw new NRCHKBError(message)
+ }
+
+ this.childNodes = []
+ this.childNodes.push(this)
+ } else {
+ // Retrieve parent service node
+ parentNode = RED.nodes.getNode(
+ this.config.parentService
+ ) as HAPService2NodeType
+
+ if (!parentNode) {
+ log.error('Parent Node not assigned', false)
+ throw new NRCHKBError('Parent Node not assigned')
+ }
+
+ this.parentNode = parentNode
+ this.parentService = this.parentNode.service
+
+ if (!this.parentService) {
+ log.error('Parent Service not assigned', false)
+ throw new NRCHKBError('Parent Service not assigned')
+ }
+
+ this.hostNode = this.parentNode.hostNode
+ this.parentNode.childNodes?.push(this)
+
+ this.accessory = this.parentNode.accessory
}
- const configure = function (this: HAPService2NodeType) {
- const self = this
+ // Service node properties
+ this.name = this.config.name
- const log = logger('NRCHKB', 'HAPServiceNode2', self.config.name, self)
+ // Find a unique identifier for the current service
+ if (
+ Object.hasOwn(this, '_flow') &&
+ Object.hasOwn(this, '_alias') &&
+ (this._flow ? Object(this._flow).hasOwn('TYPE') : false) &&
+ this._flow?.TYPE === 'subflow'
+ ) {
+ // For subflows, use the service node identifier from the subflow template
+ // plus the full path from the subflow node identifier to the subflow.
+ this.uniqueIdentifier = `${this._alias}/${this._flow.path}`
+ } else {
+ // For top level flows, use the node identifier
+ this.uniqueIdentifier = this.id
+ }
- const Utils = require('./utils')(self)
- const AccessoryUtils = Utils.AccessoryUtils
- const BridgeUtils = Utils.BridgeUtils
- const CharacteristicUtils = require('./utils/CharacteristicUtils2')(
- self
- )
- const ServiceUtils = require('./utils/ServiceUtils2')(self)
-
- let parentNode: HAPService2NodeType
-
- if (self.config.isParent) {
- const hostId =
- self.config.hostType == HostType.BRIDGE
- ? self.config.bridge
- : self.config.accessoryId
-
- self.hostNode = RED.nodes.getNode(hostId) as HAPHostNodeType
-
- if (!self.hostNode) {
- const message = `Host node ${self.config.hostType == HostType.BRIDGE ? 'Bridge' : 'Standalone Accessory'} ${hostId} not found`
- log.error(message, false)
- throw new NRCHKBError(message)
- }
-
- self.childNodes = []
- self.childNodes.push(self)
- } else {
- // Retrieve parent service node
- parentNode = RED.nodes.getNode(
- self.config.parentService
- ) as HAPService2NodeType
-
- if (!parentNode) {
- log.error('Parent Node not assigned', false)
- throw new NRCHKBError('Parent Node not assigned')
- }
-
- self.parentNode = parentNode
- self.parentService = self.parentNode.service
-
- if (!self.parentService) {
- log.error('Parent Service not assigned', false)
- throw new NRCHKBError('Parent Service not assigned')
- }
-
- self.hostNode = self.parentNode.hostNode
- self.parentNode.childNodes?.push(self)
-
- self.accessory = self.parentNode.accessory
- }
-
- // Service node properties
- self.name = self.config.name
-
- // Find a unique identifier for the current service
- if (
- self.hasOwnProperty('_flow') &&
- self.hasOwnProperty('_alias') &&
- self._flow?.hasOwnProperty('TYPE') &&
- self._flow.TYPE === 'subflow'
- ) {
- // For subflows, use the service node identifier from the subflow template
- // plus the full path from the subflow node identifier to the subflow.
- self.uniqueIdentifier = self._alias + '/' + self._flow.path
- } else {
- // For top level flows, use the node identifier
- self.uniqueIdentifier = self.id
- }
-
- // Generate UUID from unique identifier
- const subtypeUUID = uuid.generate(self.uniqueIdentifier)
-
- // Look for existing Accessory or create a new one
- if (self.config.hostType == HostType.BRIDGE) {
- if (self.config.isParent) {
- // According to the HomeKit Accessory Protocol Specification the value
- // of the fields Name, Manufacturer, Serial Number and Model must not
- // change throughout the lifetime of an accessory. Because of that the
- // accessory UUID will be generated based on that data to ensure that
- // a new accessory will be created if any of those configuration values
- // changes.
- const accessoryUUID = uuid.generate(
- 'A' +
- self.uniqueIdentifier +
- self.name +
- self.config.manufacturer +
- self.config.serialNo +
- self.config.model
- )
-
- self.accessory = AccessoryUtils.getOrCreate(
- self.hostNode.host,
- {
- name: self.name,
- UUID: accessoryUUID,
- manufacturer: self.config.manufacturer,
- serialNo: self.config.serialNo,
- model: self.config.model,
- firmwareRev: self.config.firmwareRev,
- hardwareRev: self.config.hardwareRev,
- softwareRev: self.config.softwareRev,
- },
- subtypeUUID // subtype of the primary service for identification
- )
-
- //Respond to identify
- self.onIdentify = AccessoryUtils.onIdentify
- self.accessory.on('identify', self.onIdentify)
- }
- } else {
- // We are using Standalone Accessory mode so no need to create new Accessory as we have "host" already
- log.debug('Binding Service accessory as Standalone Accessory')
- self.accessory = self.hostNode.host
- }
-
- // Look for existing Service or create a new one
- self.service = ServiceUtils.getOrCreate(
- self.accessory,
- {
- name: self.name,
- UUID: subtypeUUID,
- serviceName: self.config.serviceName,
- config: self.config,
- },
- self.parentService
+ // Generate UUID from unique identifier
+ const subtypeUUID = uuid.generate(this.uniqueIdentifier)
+
+ // Look for existing Accessory or create a new one
+ // biome-ignore lint/suspicious/noDoubleEquals: hostType can be a string or a number
+ if (this.config.hostType == HostType.BRIDGE) {
+ if (this.config.isParent) {
+ // According to the HomeKit Accessory Protocol Specification the value
+ // of the fields Name, Manufacturer, Serial Number and Model must not
+ // change throughout the lifetime of an accessory. Because of that the
+ // accessory UUID will be generated based on that data to ensure that
+ // a new accessory will be created if any of those configuration values
+ // changes.
+ const accessoryUUID = uuid.generate(
+ 'A' +
+ this.uniqueIdentifier +
+ this.name +
+ this.config.manufacturer +
+ this.config.serialNo +
+ this.config.model
)
- self.characteristicProperties = CharacteristicUtils.load(
- self.service,
- self.config
+ this.accessory = AccessoryUtils.getOrCreate(
+ this.hostNode.host,
+ {
+ name: this.name,
+ UUID: accessoryUUID,
+ manufacturer: this.config.manufacturer,
+ serialNo: this.config.serialNo,
+ model: this.config.model,
+ firmwareRev: this.config.firmwareRev,
+ hardwareRev: this.config.hardwareRev,
+ softwareRev: this.config.softwareRev
+ },
+ subtypeUUID // subtype of the primary service for identification
)
- ServiceUtils.configureAdaptiveLightning()
+ //Respond to identify
+ this.onIdentify = AccessoryUtils.onIdentify
+ this.accessory.on('identify', this.onIdentify)
+ }
+ } else {
+ // We are using Standalone Accessory mode so no need to create new Accessory as we have "host" already
+ log.debug('Binding Service accessory as Standalone Accessory')
+ this.accessory = this.hostNode.host
+ }
- if (self.config.isParent) {
- BridgeUtils.delayedPublish(self)
- }
+ // Look for existing Service or create a new one
+ this.service = ServiceUtils.getOrCreate(
+ this.accessory,
+ {
+ name: this.name,
+ UUID: subtypeUUID,
+ serviceName: this.config.serviceName,
+ config: this.config
+ },
+ this.parentService
+ )
+
+ this.characteristicProperties = CharacteristicUtils.load(
+ this.service,
+ this.config
+ )
+
+ ServiceUtils.configureAdaptiveLightning()
+
+ if (this.config.isParent) {
+ BridgeUtils.delayedPublish(this)
+ }
- // The pinCode should be shown to the user until interaction with iOS
- // client starts
- self.nodeStatusUtils.setStatus({
- fill: 'yellow',
- shape: 'ring',
- text: self.hostNode.config.pinCode,
- })
+ // The pinCode should be shown to the user until interaction with iOS
+ // client starts
+ this.nodeStatusUtils.setStatus({
+ fill: 'yellow',
+ shape: 'ring',
+ text: this.hostNode.config.pinCode
+ })
- // Emit message when value changes
- // service.on("characteristic-change", ServiceUtils.onCharacteristicChange);
+ // Emit message when value changes
+ // service.on("characteristic-change", ServiceUtils.onCharacteristicChange);
- // Subscribe to set and get on characteristics for that service and get
- // list of all supported
- self.supported = CharacteristicUtils.subscribeAndGetSupported(
- self.service
- )
+ // Subscribe to set and get on characteristics for that service and get
+ // list of all supported
+ this.supported = CharacteristicUtils.subscribeAndGetSupported(this.service)
- // Respond to inputs
- self.on('input', ServiceUtils.onInput)
+ // Respond to inputs
+ this.on('input', ServiceUtils.onInput)
- self.on('close', ServiceUtils.onClose)
- }
+ this.on('close', ServiceUtils.onClose)
+ }
- return {
- preInit,
- init,
- }
+ return {
+ preInit,
+ init
+ }
}
diff --git a/src/lib/Storage.ts b/src/lib/Storage.ts
index d9186d7b..ebafa5dc 100644
--- a/src/lib/Storage.ts
+++ b/src/lib/Storage.ts
@@ -1,153 +1,150 @@
+import path from 'node:path'
+import type {
+ CharacteristicEventTypes,
+ SerializedAccessory,
+ SerializedService
+} from '@homebridge/hap-nodejs'
import { logger } from '@nrchkb/logger'
+import storage, { type InitOptions } from 'node-persist'
import {
- CharacteristicEventTypes,
- SerializedAccessory,
- SerializedService,
-} from 'hap-nodejs'
-import storage, { InitOptions } from 'node-persist'
-import path from 'path'
-import {
- v4 as uuidv4,
- validate as uuidValidate,
- version as uuidVersion,
+ validate as uuidValidate,
+ version as uuidVersion,
+ v4 as uuidv4
} from 'uuid'
import NRCHKBError from './NRCHKBError'
-import { SerializedHostType } from './types/storage/SerializedHostType'
+import type { SerializedHostType } from './types/storage/SerializedHostType'
import { StorageType } from './types/storage/StorageType'
type EventCallback = {
- event: CharacteristicEventTypes
- callback: (value?: any) => void
+ event: CharacteristicEventTypes
+ callback: (value?: any) => void
}
+// biome-ignore lint/complexity/noStaticOnlyClass: Storage is a static class
export class Storage {
- private static customStoragePath: string
- private static storageInitialized = false
-
- private static memoryStorage: { [key: string]: any } = {}
-
- private static log = logger('NRCHKB', 'Storage')
-
- static storagePath(): string {
- if (!Storage.storageInitialized) {
- throw new NRCHKBError('Storage path was not initialized!')
- }
-
- return Storage.customStoragePath
- }
-
- static init(...storagePathSegments: string[]): Promise {
- Storage.customStoragePath = path.resolve(...storagePathSegments)
- Storage.storageInitialized = true
-
- Storage.log.trace('Initializing')
-
- return storage.init({ dir: Storage.storagePath() })
- }
-
- static save(
- type: StorageType,
- key: string | undefined,
- value: unknown
- ): Promise {
- const itemName = key ? `${type}-${key}` : type
- Storage.log.trace(`Saving ${itemName}:${value}`)
- return storage.set(itemName, value)
- }
-
- static saveCallback(eventCallback: EventCallback, ttl = 10000) {
- const callbackID = uuidv4()
- Storage.memoryStorage[callbackID] = eventCallback
-
- setTimeout(() => {
- // HAP-NodeJS will complain about slow running get handlers after 3 seconds
- // and terminate the request after 10 seconds.
- if (callbackID in Storage.memoryStorage) {
- Storage.log.debug(`Callback ${callbackID} timeout`)
- eventCallback.callback()
- delete Storage.memoryStorage[callbackID]
- }
- }, ttl)
-
- return callbackID
- }
+ private static customStoragePath: string
+ private static storageInitialized = false
- static saveCustomCharacteristics(
- value: unknown
- ): Promise {
- return Storage.save(
- StorageType.CUSTOM_CHARACTERISTICS,
- undefined,
- value
- )
- }
+ private static memoryStorage: { [key: string]: any } = {}
- static saveService(
- key: string,
- value: unknown
- ): Promise {
- return Storage.save(StorageType.SERVICE, key, value)
- }
+ private static log = logger('NRCHKB', 'Storage')
- static saveAccessory(
- key: string,
- value: unknown
- ): Promise {
- return Storage.save(StorageType.ACCESSORY, key, value)
+ static storagePath(): string {
+ if (!Storage.storageInitialized) {
+ throw new NRCHKBError('Storage path was not initialized!')
}
- static saveHost(
- key: string,
- serializedHost: SerializedHostType
- ): Promise {
- return Storage.save(StorageType.HOST, key, serializedHost)
+ return Storage.customStoragePath
+ }
+
+ static init(...storagePathSegments: string[]): Promise {
+ Storage.customStoragePath = path.resolve(...storagePathSegments)
+ Storage.storageInitialized = true
+
+ Storage.log.trace('Initializing')
+
+ return storage.init({ dir: Storage.storagePath() })
+ }
+
+ static save(
+ type: StorageType,
+ key: string | undefined,
+ value: unknown
+ ): Promise {
+ const itemName = key ? `${type}-${key}` : type
+ Storage.log.trace(`Saving ${itemName}:${value}`)
+ return storage.set(itemName, value)
+ }
+
+ static saveCallback(eventCallback: EventCallback, ttl = 10000) {
+ const callbackID = uuidv4()
+ Storage.memoryStorage[callbackID] = eventCallback
+
+ setTimeout(() => {
+ // HAP-NodeJS will complain about slow running get handlers after 3 seconds
+ // and terminate the request after 10 seconds.
+ if (callbackID in Storage.memoryStorage) {
+ Storage.log.debug(`Callback ${callbackID} timeout`)
+ eventCallback.callback()
+ delete Storage.memoryStorage[callbackID]
+ }
+ }, ttl)
+
+ return callbackID
+ }
+
+ static saveCustomCharacteristics(
+ value: unknown
+ ): Promise {
+ return Storage.save(StorageType.CUSTOM_CHARACTERISTICS, undefined, value)
+ }
+
+ static saveService(
+ key: string,
+ value: unknown
+ ): Promise {
+ return Storage.save(StorageType.SERVICE, key, value)
+ }
+
+ static saveAccessory(
+ key: string,
+ value: unknown
+ ): Promise {
+ return Storage.save(StorageType.ACCESSORY, key, value)
+ }
+
+ static saveHost(
+ key: string,
+ serializedHost: SerializedHostType
+ ): Promise {
+ return Storage.save(StorageType.HOST, key, serializedHost)
+ }
+
+ static load(type: StorageType, key?: string): Promise {
+ const itemName = key ? `${type}-${key}` : type
+ Storage.log.trace(`Loading ${itemName}`)
+ return storage.get(itemName)
+ }
+
+ static loadCallback(key: string): EventCallback | undefined {
+ if (key in Storage.memoryStorage) {
+ Storage.log.trace(`Returning callback ${key}`)
+ const value = Storage.memoryStorage[key]
+ delete Storage.memoryStorage[key]
+ return value
}
- static load(type: StorageType, key?: string): Promise {
- const itemName = key ? `${type}-${key}` : type
- Storage.log.trace(`Loading ${itemName}`)
- return storage.get(itemName)
- }
-
- static loadCallback(key: string): EventCallback | undefined {
- if (key in Storage.memoryStorage) {
- Storage.log.trace(`Returning callback ${key}`)
- const value = Storage.memoryStorage[key]
- delete Storage.memoryStorage[key]
- return value
+ return undefined
+ }
+
+ static loadCustomCharacteristics(): Promise {
+ return Storage.load(StorageType.CUSTOM_CHARACTERISTICS)
+ }
+
+ static loadService(key: string): Promise {
+ return new Promise((resolve, reject) => {
+ Storage.load(StorageType.SERVICE, key).then((value) => {
+ if (value === undefined) {
+ reject('Service data not exists')
+ } else if ('primaryService' in value) {
+ resolve(value)
+ } else {
+ reject('Service data corrupted')
}
+ })
+ })
+ }
- return undefined
- }
-
- static loadCustomCharacteristics(): Promise {
- return Storage.load(StorageType.CUSTOM_CHARACTERISTICS)
- }
-
- static loadService(key: string): Promise {
- return new Promise((resolve, reject) => {
- Storage.load(StorageType.SERVICE, key).then((value) => {
- if (value === undefined) {
- reject('Service data not exists')
- } else if ('primaryService' in value) {
- resolve(value)
- } else {
- reject('Service data corrupted')
- }
- })
- })
- }
+ static loadAccessory(key: string): Promise {
+ return Storage.load(StorageType.ACCESSORY, key)
+ }
- static loadAccessory(key: string): Promise {
- return Storage.load(StorageType.ACCESSORY, key)
- }
+ static loadHost(key: string): Promise {
+ return Storage.load(StorageType.HOST, key)
+ }
- static loadHost(key: string): Promise {
- return Storage.load(StorageType.HOST, key)
- }
-
- static uuid4Validate(uuid: string) {
- return uuidValidate(uuid) && uuidVersion(uuid) === 4
- }
+ static uuid4Validate(uuid: string) {
+ return uuidValidate(uuid) && uuidVersion(uuid) === 4
+ }
}
diff --git a/src/lib/api.ts b/src/lib/api.ts
index ce9dfa59..ff8eee0a 100644
--- a/src/lib/api.ts
+++ b/src/lib/api.ts
@@ -1,419 +1,402 @@
+import {
+ Characteristic,
+ Perms,
+ type SerializedService,
+ Service
+} from '@homebridge/hap-nodejs'
import { logger } from '@nrchkb/logger'
-import express from 'express'
-import { Characteristic, Perms, SerializedService, Service } from 'hap-nodejs'
-import { NodeAPI } from 'node-red'
+import type express from 'express'
+import type { NodeAPI } from 'node-red'
import EveCharacteristics from './hap/eve-app/EveCharacteristics'
import { Storage } from './Storage'
-import CustomCharacteristicType from './types/CustomCharacteristicType'
+import type CustomCharacteristicType from './types/CustomCharacteristicType'
+import type HAPServiceConfigType from './types/HAPServiceConfigType'
+import type HAPServiceNodeType from './types/HAPServiceNodeType'
import HapCategories from './types/hap-nodejs/HapCategories'
-import HAPServiceConfigType from './types/HAPServiceConfigType'
-import HAPServiceNodeType from './types/HAPServiceNodeType'
const version = require('../../package.json').version.trim()
-module.exports = function (RED: NodeAPI) {
- const log = logger('NRCHKB', 'API')
+module.exports = (RED: NodeAPI) => {
+ const log = logger('NRCHKB', 'API')
- // Service API
- const _initServiceAPI = () => {
- log.debug('Initialize Service API')
+ // Service API
+ const _initServiceAPI = () => {
+ log.debug('Initialize Service API')
- type ServiceData = {
- [key: string]: Partial & {
- nrchkbDisabledText?: string
- }
- }
-
- // Service API response data
- const serviceData: ServiceData = {
- BatteryService: {
- nrchkbDisabledText:
- 'BatteryService (deprecated, replaced by Battery)',
- },
- BridgeConfiguration: {
- nrchkbDisabledText: 'BridgeConfiguration (deprecated, unused)',
- },
- BridgingState: {
- nrchkbDisabledText: 'BridgingState (deprecated, unused)',
- },
- // CameraControl: {}, // This service is deprecated but used by nrchkb to link rtsp logic
- CameraEventRecordingManagement: {
- nrchkbDisabledText:
- 'CameraEventRecordingManagement (deprecated, replaced by CameraRecordingManagement)',
- },
- Relay: {
- nrchkbDisabledText:
- 'Relay (deprecated, replaced by CloudRelay)',
- },
- Slat: {
- nrchkbDisabledText: 'Slat (deprecated, replaced by Slats)',
- },
- TimeInformation: {
- nrchkbDisabledText: 'TimeInformation (deprecated, unused)',
- },
- TunneledBTLEAccessoryService: {
- nrchkbDisabledText:
- 'TunneledBTLEAccessoryService (deprecated, replaced by Tunnel)',
- },
- }
-
- Object.values(Service)
- .filter((service) => service.prototype instanceof Service)
- .map((service) => {
- const newService = Service.serialize(new service())
- newService.displayName = service.name
- return newService
- })
- .forEach((serialized) => {
- serviceData[serialized.displayName] = {
- ...serviceData?.[serialized.displayName],
- ...serialized,
- }
- })
-
- // Retrieve Service Types
- RED.httpAdmin.get(
- '/nrchkb/service/types',
- RED.auth.needsPermission('nrchkb.read'),
- (_req: express.Request, res: express.Response) => {
- res.setHeader('Content-Type', 'application/json')
- res.json(serviceData)
- }
- )
+ type ServiceData = {
+ [key: string]: Partial & {
+ nrchkbDisabledText?: string
+ }
}
- const stringifyVersion = (version: string) => {
- const releaseVersionRegex = /(\d+)\.(\d+)\.(\d+)/
- const devVersionRegex = /(\d+)\.(\d+)\.(\d+)-dev\.(\d+)/
-
- const releaseVersionFound = releaseVersionRegex.test(version)
- const devVersionFound = devVersionRegex.test(version)
-
- let xyzVersion = '0.0.0'
-
- if (devVersionFound) {
- try {
- const match = devVersionRegex.exec(version)
+ // Service API response data
+ const serviceData: ServiceData = {
+ BatteryService: {
+ nrchkbDisabledText: 'BatteryService (deprecated, replaced by Battery)'
+ },
+ BridgeConfiguration: {
+ nrchkbDisabledText: 'BridgeConfiguration (deprecated, unused)'
+ },
+ BridgingState: {
+ nrchkbDisabledText: 'BridgingState (deprecated, unused)'
+ },
+ CameraControl: {
+ //TODO: hmm, what is the replacement?
+ nrchkbDisabledText: 'CameraControl (deprecated, replaced by)'
+ },
+ CameraEventRecordingManagement: {
+ nrchkbDisabledText:
+ 'CameraEventRecordingManagement (deprecated, replaced by CameraRecordingManagement)'
+ },
+ Relay: {
+ nrchkbDisabledText: 'Relay (deprecated, replaced by CloudRelay)'
+ },
+ Slat: {
+ nrchkbDisabledText: 'Slat (deprecated, replaced by Slats)'
+ },
+ TimeInformation: {
+ nrchkbDisabledText: 'TimeInformation (deprecated, unused)'
+ },
+ TunneledBTLEAccessoryService: {
+ nrchkbDisabledText:
+ 'TunneledBTLEAccessoryService (deprecated, replaced by Tunnel)'
+ }
+ }
- if (match) {
- xyzVersion = `0.${match[1]}${match[2]}${match[3]}.${match[4]}`
- } else {
- log.debug('Could not match dev version')
- }
- } catch (e) {
- console.error(e)
- }
- } else if (releaseVersionFound) {
- try {
- const match = releaseVersionRegex.exec(version)
-
- if (match) {
- xyzVersion = match[0]
- } else {
- log.debug('Could not match release version')
- }
- } catch (e) {
- console.error(e)
- }
+ Object.values(Service)
+ .filter((service) => service.prototype instanceof Service)
+ .map((service) => {
+ const newService = Service.serialize(new service())
+ newService.displayName = service.name
+ return newService
+ })
+ .forEach((serialized) => {
+ serviceData[serialized.displayName] = {
+ ...serviceData?.[serialized.displayName],
+ ...serialized
+ }
+ })
+
+ // Retrieve Service Types
+ RED.httpAdmin.get(
+ '/nrchkb/service/types',
+ RED.auth.needsPermission('nrchkb.read'),
+ (_req: express.Request, res: express.Response) => {
+ res.setHeader('Content-Type', 'application/json')
+ res.json(serviceData)
+ }
+ )
+ }
+
+ const stringifyVersion = (version: string) => {
+ const releaseVersionRegex = /(\d+)\.(\d+)\.(\d+)/
+ const devVersionRegex = /(\d+)\.(\d+)\.(\d+)-dev\.(\d+)/
+
+ const releaseVersionFound = releaseVersionRegex.test(version)
+ const devVersionFound = devVersionRegex.test(version)
+
+ let xyzVersion = '0.0.0'
+
+ if (devVersionFound) {
+ try {
+ const match = devVersionRegex.exec(version)
+
+ if (match) {
+ xyzVersion = `0.${match[1]}${match[2]}${match[3]}.${match[4]}`
} else {
- log.debug('Bad version format')
- xyzVersion = '0.0.0'
+ log.debug('Could not match dev version')
}
-
- return xyzVersion
+ } catch (e) {
+ log.error(e as any)
+ }
+ } else if (releaseVersionFound) {
+ try {
+ const match = releaseVersionRegex.exec(version)
+
+ if (match) {
+ xyzVersion = match[0]
+ } else {
+ log.debug('Could not match release version')
+ }
+ } catch (e) {
+ log.error(e as any)
+ }
+ } else {
+ log.debug('Bad version format')
+ xyzVersion = '0.0.0'
}
- // NRCHKB Info API
- const _initNRCHKBInfoAPI = () => {
- log.debug('Initialize NRCHKB Info API')
+ return xyzVersion
+ }
- log.debug(`Running version: ${version}`)
+ // NRCHKB Info API
+ const _initNRCHKBInfoAPI = () => {
+ log.debug('Initialize NRCHKB Info API')
- const xyzVersion = stringifyVersion(version)
+ log.debug(`Running version: ${version}`)
- log.debug(`Evaluated as: ${xyzVersion}`)
+ const xyzVersion = stringifyVersion(version)
- const experimental = process.env.NRCHKB_EXPERIMENTAL === 'true'
+ log.debug(`Evaluated as: ${xyzVersion}`)
- log.debug(`Running experimental: ${experimental}`)
+ const experimental = process.env.NRCHKB_EXPERIMENTAL === 'true'
- // Retrieve NRCHKB version
- RED.httpAdmin.get(
- '/nrchkb/info',
- RED.auth.needsPermission('nrchkb.read'),
- (_req: express.Request, res: express.Response) => {
- res.setHeader('Content-Type', 'application/json')
- res.json({
- version: xyzVersion,
- experimental,
- })
- }
- )
- }
+ log.debug(`Running experimental: ${experimental}`)
- // NRCHKB Custom Characteristics API
- const _initNRCHKBCustomCharacteristicsAPI = async () => {
- const getCustomCharacteristics = async () => {
- try {
- const value = await Storage.loadCustomCharacteristics()
-
- log.trace('loadCustomCharacteristics()')
- log.trace(value)
-
- if (Array.isArray(value)) {
- return value
- } else {
- log.debug(
- 'customCharacteristics is not Array, returning empty value'
- )
- return EveCharacteristics
- }
- } catch (error) {
- log.error(
- `Failed to get customCharacteristics in nrchkbStorage due to ${error}`
- )
- return EveCharacteristics
- }
- }
-
- const characteristicNameToKey = (name: string) => {
- return name.replace(' ', '')
- }
+ // Retrieve NRCHKB version
+ RED.httpAdmin.get(
+ '/nrchkb/info',
+ RED.auth.needsPermission('nrchkb.read'),
+ (_req: express.Request, res: express.Response) => {
+ res.setHeader('Content-Type', 'application/json')
+ res.json({
+ version: xyzVersion,
+ experimental
+ })
+ }
+ )
+ }
- const toNumber = (value: any, optional = undefined) => {
- const num = Number(value)
- if (isNaN(num)) {
- return optional
- } else return num
- }
-
- const refreshCustomCharacteristics = (
- customCharacteristics: CustomCharacteristicType[]
- ) => {
- log.debug('Refreshing Custom Characteristics')
-
- const customCharacteristicKeys: string[] = []
-
- customCharacteristics.forEach(({ name, UUID, ...props }) => {
- if (!!UUID && !!name) {
- const key = characteristicNameToKey(name)
-
- log.debug(
- `Adding Custom Characteristic ${name} using key ${key}`
- )
-
- if (customCharacteristicKeys.includes(key)) {
- log.error(
- `Cannot add ${name}. Another Custom Characteristic already defined using key ${key}`
- )
- return
- }
-
- const validatedProps = props
- if (validatedProps.validValues?.length === 0) {
- validatedProps.validValues = undefined
- }
- if (
- !validatedProps.validValueRanges?.[0] ||
- !validatedProps.validValueRanges?.[1]
- ) {
- validatedProps.validValueRanges = undefined
- }
- if (validatedProps.adminOnlyAccess?.length === 0) {
- validatedProps.adminOnlyAccess = undefined
- }
- if (validatedProps.minValue) {
- validatedProps.minValue = toNumber(
- validatedProps.minValue
- )
- }
- if (validatedProps.maxValue) {
- validatedProps.maxValue = toNumber(
- validatedProps.maxValue
- )
- }
- if (validatedProps.minStep) {
- validatedProps.minStep = toNumber(
- validatedProps.minStep
- )
- }
-
- class CustomCharacteristic extends Characteristic {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- static readonly UUID: string = UUID!
-
- constructor() {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- super(name!, CustomCharacteristic.UUID, {
- ...validatedProps,
- perms: validatedProps.perms ?? [
- Perms.PAIRED_READ,
- Perms.PAIRED_WRITE,
- Perms.NOTIFY,
- ],
- })
-
- this.value = this.getDefaultValue()
- }
- }
-
- Object.defineProperty(CustomCharacteristic, 'name', {
- value: key,
- configurable: true,
- })
- Object.defineProperty(Characteristic, key, {
- value: CustomCharacteristic,
- configurable: true,
- })
-
- customCharacteristicKeys.push(key)
- }
- })
+ // NRCHKB Custom Characteristics API
+ const _initNRCHKBCustomCharacteristicsAPI = async () => {
+ const getCustomCharacteristics = async () => {
+ try {
+ const value = await Storage.loadCustomCharacteristics()
- new Promise((resolve) => {
- const isRedInitialized = () => {
- try {
- RED.nodes.eachNode(() => {
- return
- })
- resolve(true)
- } catch (_) {
- log.debug('Waiting for RED to be initialized')
- setTimeout(isRedInitialized, 1000)
- }
- }
+ log.trace('loadCustomCharacteristics()')
+ log.trace(value)
- isRedInitialized()
- }).then(() => {
- RED.nodes.eachNode((node) => {
- if (
- node.type === 'homekit-service' ||
- node.type === 'homekit-service2'
- ) {
- const serviceNodeConfig = node as HAPServiceConfigType
-
- const serviceNode = RED.nodes.getNode(
- serviceNodeConfig.id
- ) as HAPServiceNodeType
-
- if (
- serviceNode &&
- serviceNode.characteristicProperties &&
- serviceNode.service
- ) {
- for (const key in serviceNode.characteristicProperties) {
- if (customCharacteristicKeys.includes(key)) {
- const characteristic = serviceNode.service
- // @ts-ignore
- .getCharacteristic(Characteristic[key])
- .setProps(
- serviceNode
- .characteristicProperties[key]
- )
- serviceNode.supported.push(key)
-
- characteristic.on(
- 'get',
- serviceNode.onCharacteristicGet
- )
- characteristic.on(
- 'set',
- serviceNode.onCharacteristicSet
- )
- characteristic.on(
- 'change',
- serviceNode.onCharacteristicChange
- )
- }
- }
- }
- }
- })
- })
+ if (Array.isArray(value)) {
+ return value
+ } else {
+ log.debug('customCharacteristics is not Array, returning empty value')
+ return EveCharacteristics
}
-
- log.debug('Initialize NRCHKBCustomCharacteristicsAPI')
-
- getCustomCharacteristics().then((value) =>
- refreshCustomCharacteristics(value)
+ } catch (error) {
+ log.error(
+ `Failed to get customCharacteristics in nrchkbStorage due to ${error}`
)
+ return EveCharacteristics
+ }
+ }
- // Retrieve NRCHKB version
- RED.httpAdmin.get(
- '/nrchkb/config',
- RED.auth.needsPermission('nrchkb.read'),
- async (_req: express.Request, res: express.Response) => {
- res.setHeader('Content-Type', 'application/json')
- res.json({
- customCharacteristics: await getCustomCharacteristics(),
- })
- }
- )
+ const characteristicNameToKey = (name: string) => {
+ return name.replace(' ', '')
+ }
- // Change NRCHKB version
- RED.httpAdmin.post(
- '/nrchkb/config',
- RED.auth.needsPermission('nrchkb.write'),
- async (req: express.Request, res: express.Response) => {
- const customCharacteristics: CustomCharacteristicType[] =
- req.body.customCharacteristics || EveCharacteristics
-
- Storage.saveCustomCharacteristics(customCharacteristics)
- .then(() => {
- res.sendStatus(200)
- refreshCustomCharacteristics(customCharacteristics)
- })
- .catch((error) => {
- log.error(error)
- res.sendStatus(500)
- })
- }
- )
+ const toNumber = (value: any, optional = undefined) => {
+ const num = Number(value)
+ if (Number.isNaN(num)) {
+ return optional
+ } else return num
}
- // Accessory API
- const _initAccessoryAPI = function () {
- log.debug('Initialize Accessory API')
-
- // Accessory Categories API response data
- const accessoryCategoriesData: {
- [key: number]: string
- } = {}
-
- // Prepare Accessory data once
- Object.keys(HapCategories)
- .sort()
- .filter((x) => parseInt(x) >= 0)
- .forEach((key) => {
- const keyNumber = key as unknown as number
- accessoryCategoriesData[keyNumber] = HapCategories[keyNumber]
+ const refreshCustomCharacteristics = (
+ customCharacteristics: CustomCharacteristicType[]
+ ) => {
+ log.debug('Refreshing Custom Characteristics')
+
+ const customCharacteristicKeys: string[] = []
+
+ customCharacteristics.forEach(({ name, UUID, ...props }) => {
+ if (!!UUID && !!name) {
+ const key = characteristicNameToKey(name)
+
+ log.debug(`Adding Custom Characteristic ${name} using key ${key}`)
+
+ if (customCharacteristicKeys.includes(key)) {
+ log.error(
+ `Cannot add ${name}. Another Custom Characteristic already defined using key ${key}`
+ )
+ return
+ }
+
+ const validatedProps = props
+ if (validatedProps.validValues?.length === 0) {
+ validatedProps.validValues = undefined
+ }
+ if (
+ !validatedProps.validValueRanges?.[0] ||
+ !validatedProps.validValueRanges?.[1]
+ ) {
+ validatedProps.validValueRanges = undefined
+ }
+ if (validatedProps.adminOnlyAccess?.length === 0) {
+ validatedProps.adminOnlyAccess = undefined
+ }
+ if (validatedProps.minValue) {
+ validatedProps.minValue = toNumber(validatedProps.minValue)
+ }
+ if (validatedProps.maxValue) {
+ validatedProps.maxValue = toNumber(validatedProps.maxValue)
+ }
+ if (validatedProps.minStep) {
+ validatedProps.minStep = toNumber(validatedProps.minStep)
+ }
+
+ class CustomCharacteristic extends Characteristic {
+ // biome-ignore lint/style/noNonNullAssertion: UUID is not null
+ static readonly UUID: string = UUID!
+
+ constructor() {
+ // biome-ignore lint/style/noNonNullAssertion: name is not null
+ super(name!, CustomCharacteristic.UUID, {
+ ...validatedProps,
+ perms: validatedProps.perms ?? [
+ Perms.PAIRED_READ,
+ Perms.PAIRED_WRITE,
+ Perms.NOTIFY
+ ]
+ })
+
+ this.value = this.getDefaultValue()
+ }
+ }
+
+ Object.defineProperty(CustomCharacteristic, 'name', {
+ value: key,
+ configurable: true
+ })
+ Object.defineProperty(Characteristic, key, {
+ value: CustomCharacteristic,
+ configurable: true
+ })
+
+ customCharacteristicKeys.push(key)
+ }
+ })
+
+ new Promise((resolve) => {
+ const isRedInitialized = () => {
+ try {
+ RED.nodes.eachNode(() => {
+ return
})
+ resolve(true)
+ } catch (_) {
+ log.debug('Waiting for RED to be initialized')
+ setTimeout(isRedInitialized, 1000)
+ }
+ }
- // Retrieve Accessory Types
- RED.httpAdmin.get(
- '/nrchkb/accessory/categories',
- RED.auth.needsPermission('nrchkb.read'),
- (_req: express.Request, res: express.Response) => {
- res.setHeader('Content-Type', 'application/json')
- res.json(accessoryCategoriesData)
+ isRedInitialized()
+ }).then(() => {
+ RED.nodes.eachNode((node) => {
+ if (
+ node.type === 'homekit-service' ||
+ node.type === 'homekit-service2'
+ ) {
+ const serviceNodeConfig = node as HAPServiceConfigType
+
+ const serviceNode = RED.nodes.getNode(
+ serviceNodeConfig.id
+ ) as HAPServiceNodeType
+
+ if (serviceNode?.characteristicProperties && serviceNode.service) {
+ for (const key in serviceNode.characteristicProperties) {
+ if (customCharacteristicKeys.includes(key)) {
+ const characteristic = serviceNode.service
+ // @ts-expect-error
+ .getCharacteristic(Characteristic[key])
+ .setProps(serviceNode.characteristicProperties[key])
+ serviceNode.supported.push(key)
+
+ characteristic.on('get', serviceNode.onCharacteristicGet)
+ characteristic.on('set', serviceNode.onCharacteristicSet)
+ characteristic.on(
+ 'change',
+ serviceNode.onCharacteristicChange
+ )
+ }
+ }
}
- )
+ }
+ })
+ })
}
- const init = () => {
- _initServiceAPI()
- _initNRCHKBInfoAPI()
- _initAccessoryAPI()
-
- // Experimental feature
- if (process.env.NRCHKB_EXPERIMENTAL === 'true') {
- _initNRCHKBCustomCharacteristicsAPI().then()
- }
+ log.debug('Initialize NRCHKBCustomCharacteristicsAPI')
+
+ getCustomCharacteristics().then((value) =>
+ refreshCustomCharacteristics(value)
+ )
+
+ // Retrieve NRCHKB version
+ RED.httpAdmin.get(
+ '/nrchkb/config',
+ RED.auth.needsPermission('nrchkb.read'),
+ async (_req: express.Request, res: express.Response) => {
+ res.setHeader('Content-Type', 'application/json')
+ res.json({
+ customCharacteristics: await getCustomCharacteristics()
+ })
+ }
+ )
+
+ // Change NRCHKB version
+ RED.httpAdmin.post(
+ '/nrchkb/config',
+ RED.auth.needsPermission('nrchkb.write'),
+ async (req: express.Request, res: express.Response) => {
+ const customCharacteristics: CustomCharacteristicType[] =
+ req.body.customCharacteristics || EveCharacteristics
+
+ Storage.saveCustomCharacteristics(customCharacteristics)
+ .then(() => {
+ res.sendStatus(200)
+ refreshCustomCharacteristics(customCharacteristics)
+ })
+ .catch((error) => {
+ log.error(error)
+ res.sendStatus(500)
+ })
+ }
+ )
+ }
+
+ // Accessory API
+ const _initAccessoryAPI = () => {
+ log.debug('Initialize Accessory API')
+
+ // Accessory Categories API response data
+ const accessoryCategoriesData: {
+ [key: number]: string
+ } = {}
+
+ // Prepare Accessory data once
+ Object.keys(HapCategories)
+ .sort()
+ .filter((x) => parseInt(x, 10) >= 0)
+ .forEach((key) => {
+ const keyNumber = key as unknown as number
+ accessoryCategoriesData[keyNumber] = HapCategories[keyNumber]
+ })
+
+ // Retrieve Accessory Types
+ RED.httpAdmin.get(
+ '/nrchkb/accessory/categories',
+ RED.auth.needsPermission('nrchkb.read'),
+ (_req: express.Request, res: express.Response) => {
+ res.setHeader('Content-Type', 'application/json')
+ res.json(accessoryCategoriesData)
+ }
+ )
+ }
+
+ const init = () => {
+ _initServiceAPI()
+ _initNRCHKBInfoAPI()
+ _initAccessoryAPI()
+
+ // Experimental feature
+ if (process.env.NRCHKB_EXPERIMENTAL === 'true') {
+ _initNRCHKBCustomCharacteristicsAPI().then()
}
+ }
- return {
- init,
- stringifyVersion,
- }
+ return {
+ init,
+ stringifyVersion
+ }
}
diff --git a/src/lib/camera/CameraControl.ts b/src/lib/camera/CameraControl.ts
new file mode 100644
index 00000000..38b5757f
--- /dev/null
+++ b/src/lib/camera/CameraControl.ts
@@ -0,0 +1,112 @@
+import {
+ type Accessory,
+ AudioBitrate,
+ AudioRecordingCodecType,
+ AudioRecordingSamplerate,
+ CameraController,
+ H264Level,
+ H264Profile,
+ MediaContainerType,
+ SRTPCryptoSuites,
+ VideoCodecType
+} from '@homebridge/hap-nodejs'
+import type CameraConfigType from '../types/CameraConfigType'
+import { CameraDelegate } from './CameraDelegate'
+
+export const configureCamera = (
+ accessory: Accessory,
+ config?: CameraConfigType
+) => {
+ const streamDelegate = new CameraDelegate(accessory, config)
+
+ const cameraController = new CameraController({
+ cameraStreamCount: Math.max(1, config?.cameraConfigMaxStreams || 2), // default 2
+ delegate: streamDelegate,
+
+ streamingOptions: {
+ // srtp: true, // legacy option which will just enable AES_CM_128_HMAC_SHA1_80 (can still be used though)
+
+ // iOS does not support NONE just there for testing with Wireshark, for example
+ supportedCryptoSuites: [
+ SRTPCryptoSuites.NONE,
+ SRTPCryptoSuites.AES_CM_128_HMAC_SHA1_80
+ ],
+ video: {
+ codec: {
+ profiles: [H264Profile.BASELINE, H264Profile.MAIN, H264Profile.HIGH],
+ levels: [H264Level.LEVEL3_1, H264Level.LEVEL3_2, H264Level.LEVEL4_0]
+ },
+ resolutions: (() => {
+ // keep defaults but constrain to configured max width/height/fps if provided
+ const maxW = config?.cameraConfigMaxWidth
+ const maxH = config?.cameraConfigMaxHeight
+ const maxFps = config?.cameraConfigMaxFPS
+ const defaults: [number, number, number][] = [
+ [1920, 1080, 30],
+ [1280, 960, 30],
+ [1280, 720, 30],
+ [1024, 768, 30],
+ [640, 480, 30],
+ [640, 360, 30],
+ [480, 360, 30],
+ [480, 270, 30],
+ [320, 240, 30],
+ [320, 240, 15],
+ [320, 180, 30]
+ ]
+ return defaults
+ .filter(([w, h]) => (!maxW || w <= maxW) && (!maxH || h <= maxH))
+ .map(([w, h, f]) => [w, h, Math.min(f, maxFps || f)])
+ })()
+ }
+ // audio options intentionally omitted here; delegate will honor config for RTP audio path
+ },
+ recording: {
+ options: {
+ prebufferLength: 4000,
+ mediaContainerConfiguration: {
+ type: MediaContainerType.FRAGMENTED_MP4,
+ fragmentLength: 4000
+ },
+ video: {
+ type: VideoCodecType.H264,
+ parameters: {
+ profiles: [H264Profile.HIGH],
+ levels: [H264Level.LEVEL4_0]
+ },
+ resolutions: [
+ [320, 180, 30],
+ [320, 240, 15],
+ [320, 240, 30],
+ [480, 270, 30],
+ [480, 360, 30],
+ [640, 360, 30],
+ [640, 480, 30],
+ [1280, 720, 30],
+ [1280, 960, 30],
+ [1920, 1080, 30],
+ [1600, 1200, 30]
+ ]
+ },
+ audio: {
+ codecs: {
+ type: AudioRecordingCodecType.AAC_ELD,
+ audioChannels: 1,
+ samplerate: AudioRecordingSamplerate.KHZ_48,
+ bitrateMode: AudioBitrate.VARIABLE
+ }
+ }
+ },
+
+ delegate: streamDelegate
+ },
+
+ sensors: {
+ motion: true,
+ occupancy: true
+ }
+ })
+ streamDelegate.controller = cameraController
+
+ accessory.configureController(cameraController)
+}
diff --git a/src/lib/camera/CameraDelegate.ts b/src/lib/camera/CameraDelegate.ts
new file mode 100644
index 00000000..5c4ed379
--- /dev/null
+++ b/src/lib/camera/CameraDelegate.ts
@@ -0,0 +1,594 @@
+// Based on https://github.com/homebridge/HAP-NodeJS/blob/latest/src/accessories/Camera_accessory.ts
+
+import assert from 'node:assert'
+import { type ChildProcess, spawn } from 'node:child_process'
+import {
+ type Accessory,
+ AudioRecordingCodecType,
+ AudioRecordingSamplerate,
+ CameraController,
+ type CameraRecordingConfiguration,
+ type CameraRecordingDelegate,
+ type CameraStreamingDelegate,
+ Characteristic,
+ H264Level,
+ H264Profile,
+ type HDSProtocolSpecificErrorReason,
+ type PrepareStreamCallback,
+ type PrepareStreamRequest,
+ type PrepareStreamResponse,
+ type RecordingPacket,
+ Service,
+ type SnapshotRequest,
+ type SnapshotRequestCallback,
+ SRTPCryptoSuites,
+ type StreamingRequest,
+ type StreamRequestCallback,
+ StreamRequestTypes,
+ type StreamSessionIdentifier,
+ VideoCodecType,
+ type VideoInfo
+} from '@homebridge/hap-nodejs'
+import { logger } from '@nrchkb/logger'
+import type CameraConfigType from '../types/CameraConfigType'
+import { MP4StreamingServer } from './MP4StreamingServer'
+
+type SessionInfo = {
+ address: string // address of the HAP controller
+
+ videoPort: number // port of the controller
+ localVideoPort: number
+ videoCryptoSuite: SRTPCryptoSuites // should be saved if multiple suites are supported
+ videoSRTP: Buffer // key and salt concatenated
+ videoSSRC: number // rtp synchronisation source
+
+ /* Won't be saved as audio is not supported by this example
+ audioPort: number,
+ audioCryptoSuite: SRTPCryptoSuites,
+ audioSRTP: Buffer,
+ audioSSRC: number,
+ */
+}
+
+type OngoingSession = {
+ localVideoPort: number
+ process: ChildProcess
+}
+
+const FFMPEGH264ProfileNames = ['baseline', 'main', 'high']
+const FFMPEGH264LevelNames = ['3.1', '3.2', '4.0']
+
+const ports = new Set()
+
+function getPort(): number {
+ for (let i = 5011; ; i++) {
+ if (!ports.has(i)) {
+ ports.add(i)
+ return i
+ }
+ }
+}
+
+export class CameraDelegate
+ implements CameraStreamingDelegate, CameraRecordingDelegate
+{
+ private ffmpegDebugOutput = false
+
+ private log = logger('NRCHKB', 'CameraDelegate')
+
+ controller?: CameraController
+
+ // keep track of sessions
+ pendingSessions: Record = {}
+ ongoingSessions: Record = {}
+
+ // minimal secure video properties.
+ configuration?: CameraRecordingConfiguration
+ handlingStreamingRequest = false
+ server?: MP4StreamingServer
+
+ constructor(
+ private accessory: Accessory,
+ private config?: CameraConfigType
+ ) {
+ // refine logger with accessory name if available
+ try {
+ const name =
+ accessory?.displayName || accessory?.UUID || 'UnknownAccessory'
+ this.log = logger('NRCHKB', 'CameraDelegate', name)
+ } catch (_) {
+ // keep default logger
+ }
+ }
+
+ handleSnapshotRequest(
+ request: SnapshotRequest,
+ callback: SnapshotRequestCallback
+ ): void {
+ // Prefer configured still image source, else use main source; fallback to testsrc
+ const ffmpegPath = this.config?.cameraConfigVideoProcessor || 'ffmpeg'
+ const stillSource = this.config?.cameraConfigStillImageSource?.trim()
+ const mainSource = this.config?.cameraConfigSource?.trim()
+ let imageSource: string
+ if (stillSource) {
+ imageSource = stillSource
+ } else if (mainSource) {
+ imageSource = mainSource
+ } else {
+ imageSource = `-f lavfi -i testsrc=s=${request.width}x${request.height}`
+ }
+
+ const ffmpegCommand = `${imageSource} -t 1 -s ${request.width}x${request.height} -f image2 -`
+ const ffmpeg = spawn(ffmpegPath, ffmpegCommand.split(' '), {
+ env: process.env
+ })
+
+ const snapshotBuffers: Buffer[] = []
+
+ ffmpeg.stdout.on('data', (data) => snapshotBuffers.push(data))
+ ffmpeg.stderr.on('data', (data) => {
+ if (this.ffmpegDebugOutput || this.config?.cameraConfigDebug) {
+ this.log.debug(`SNAPSHOT: ${String(data)}`)
+ }
+ })
+
+ ffmpeg.on('exit', (code, signal) => {
+ if (signal) {
+ this.log.error(`Snapshot process was killed with signal: ${signal}`)
+ callback(new Error(`killed with signal ${signal}`))
+ } else if (code === 0) {
+ this.log.debug(
+ `Successfully captured snapshot at ${request.width}x${request.height}`
+ )
+ callback(undefined, Buffer.concat(snapshotBuffers))
+ } else {
+ this.log.error(`Snapshot process exited with code ${code}`)
+ callback(new Error(`Snapshot process exited with code ${code}`))
+ }
+ })
+ }
+
+ // called when iOS request rtp setup
+ prepareStream(
+ request: PrepareStreamRequest,
+ callback: PrepareStreamCallback
+ ): void {
+ const sessionId: StreamSessionIdentifier = request.sessionID
+ const targetAddress = request.targetAddress
+
+ const video = request.video
+
+ const videoCryptoSuite = video.srtpCryptoSuite // could be used to support multiple crypto suite (or support no suite for debugging)
+ const videoSrtpKey = video.srtp_key
+ const videoSrtpSalt = video.srtp_salt
+
+ const videoSSRC = CameraController.generateSynchronisationSource()
+
+ const localPort = getPort()
+
+ const sessionInfo: SessionInfo = {
+ address: targetAddress,
+
+ videoPort: video.port,
+ localVideoPort: localPort,
+ videoCryptoSuite: videoCryptoSuite,
+ videoSRTP: Buffer.concat([videoSrtpKey, videoSrtpSalt]),
+ videoSSRC: videoSSRC
+ }
+
+ const response: PrepareStreamResponse = {
+ video: {
+ port: localPort,
+ ssrc: videoSSRC,
+
+ srtp_key: videoSrtpKey,
+ srtp_salt: videoSrtpSalt
+ }
+ // audio is omitted as we do not support audio in this example
+ }
+
+ this.pendingSessions[sessionId] = sessionInfo
+ callback(undefined, response)
+ }
+
+ // called when the iOS device asks stream to start/stop/reconfigure
+ handleStreamRequest(
+ request: StreamingRequest,
+ callback: StreamRequestCallback
+ ): void {
+ const sessionId = request.sessionID
+
+ switch (request.type) {
+ case StreamRequestTypes.START: {
+ const sessionInfo = this.pendingSessions[sessionId]
+
+ const video: VideoInfo = request.video
+
+ const profile = FFMPEGH264ProfileNames[video.profile]
+ const level = FFMPEGH264LevelNames[video.level]
+ const width = video.width
+ const height = video.height
+ let fps = video.fps
+
+ const payloadType = video.pt
+ let maxBitrate = video.max_bit_rate
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ // const rtcpInterval = video.rtcp_interval // usually 0.5
+ const mtu = video.mtu // maximum transmission unit
+
+ const address = sessionInfo.address
+ const videoPort = sessionInfo.videoPort
+ const localVideoPort = sessionInfo.localVideoPort
+ const ssrc = sessionInfo.videoSSRC
+ const cryptoSuite = sessionInfo.videoCryptoSuite
+ const videoSRTP = sessionInfo.videoSRTP.toString('base64')
+
+ // Merge UI config for backward compatibility
+ const cfg = this.config
+ const ffmpegPath = cfg?.cameraConfigVideoProcessor || 'ffmpeg'
+ const source =
+ cfg?.cameraConfigSource ||
+ `-f lavfi -i testsrc=s=${width}x${height}:r=${fps}`
+ const vcodec = cfg?.cameraConfigVideoCodec || 'libx264'
+ const additional = cfg?.cameraConfigAdditionalCommandLine?.trim()
+ const mapvideo = cfg?.cameraConfigMapVideo || '0:0'
+ const mapaudio = cfg?.cameraConfigMapAudio || '0:1'
+ // const packetsize = cfg?.cameraConfigPacketSize || 1316
+ const maxConfigBitrate = cfg?.cameraConfigMaxBitrate
+ if (
+ maxConfigBitrate &&
+ maxConfigBitrate > 0 &&
+ maxConfigBitrate < maxBitrate
+ ) {
+ maxBitrate = maxConfigBitrate
+ }
+ const maxConfigFps = cfg?.cameraConfigMaxFPS
+ if (maxConfigFps && maxConfigFps > 0 && maxConfigFps < fps) {
+ fps = maxConfigFps
+ }
+
+ const vf: string[] = []
+ if (
+ cfg?.cameraConfigVideoFilter !== null &&
+ cfg?.cameraConfigVideoFilter !== undefined &&
+ cfg?.cameraConfigVideoFilter !== ''
+ ) {
+ vf.push(cfg.cameraConfigVideoFilter)
+ if (cfg.cameraConfigHorizontalFlip) vf.push('hflip')
+ if (cfg.cameraConfigVerticalFlip) vf.push('vflip')
+ }
+
+ this.log.debug(
+ `Starting video stream (${width}x${height}, ${fps} fps, ${maxBitrate} kbps, ${mtu} mtu)...`
+ )
+
+ let videoffmpegCommand =
+ `${source} -map ${mapvideo} -vcodec ${vcodec} -pix_fmt yuv420p -r ${fps} -f rawvideo ` +
+ `${additional ? `${additional} ` : ''}` +
+ `${vf.length > 0 ? `-vf ${vf.join(',')} ` : ''}` +
+ `-b:v ${maxBitrate}k -bufsize ${maxBitrate}k -maxrate ${maxBitrate}k ` +
+ `-profile:v ${profile} -level:v ${level} ` +
+ `-payload_type ${payloadType} -ssrc ${ssrc} -f rtp `
+
+ if (cryptoSuite !== SRTPCryptoSuites.NONE) {
+ let suite: string
+ switch (cryptoSuite) {
+ case SRTPCryptoSuites.AES_CM_128_HMAC_SHA1_80: // actually ffmpeg just supports AES_CM_128_HMAC_SHA1_80
+ suite = 'AES_CM_128_HMAC_SHA1_80'
+ break
+ case SRTPCryptoSuites.AES_CM_256_HMAC_SHA1_80:
+ suite = 'AES_CM_256_HMAC_SHA1_80'
+ break
+ }
+
+ videoffmpegCommand += `-srtp_out_suite ${suite} -srtp_out_params ${videoSRTP} s`
+ }
+
+ videoffmpegCommand += `rtp://${address}:${videoPort}?rtcpport=${videoPort}&localrtcpport=${localVideoPort}&pkt_size=${cfg?.cameraConfigPacketSize || mtu}`
+
+ // Optional Audio stream (legacy compatibility)
+ const audioEnabled =
+ (this.config?.cameraConfigAudio as any) === true ||
+ this.config?.cameraConfigAudio === 'true'
+ let audioffmpegCommand = ''
+ if (audioEnabled) {
+ const acodec = cfg?.cameraConfigAudioCodec || 'libfdk_aac'
+ const abitrate = 32 // legacy default
+ const asamplerate = 16 // kHz legacy default
+ const apayloadType = 110
+ // const audioSRTP = sessionInfo.videoSRTP.toString('base64') // placeholder, audio not negotiated separately in this simplified impl
+ audioffmpegCommand =
+ ` -map ${mapaudio} -acodec ${acodec} -profile:a aac_eld -flags +global_header -f null -ar ${asamplerate}k -b:a ${abitrate}k -bufsize ${abitrate}k -ac 1 ` +
+ `-payload_type ${apayloadType} `
+ // not appending RTP audio out url here due to missing audio session params in this example
+ }
+
+ if (this.ffmpegDebugOutput || this.config?.cameraConfigDebug) {
+ this.log.debug(
+ `FFMPEG command: ${ffmpegPath} ${videoffmpegCommand}${audioffmpegCommand}`
+ )
+ }
+
+ const ffmpegVideo = spawn(
+ ffmpegPath,
+ (videoffmpegCommand + audioffmpegCommand).split(' '),
+ {
+ env: process.env
+ }
+ )
+
+ let started = false
+ ffmpegVideo.stderr.on('data', (data: Buffer) => {
+ this.log.debug(data.toString('utf8'))
+ if (!started) {
+ started = true
+ this.log.debug('FFMPEG: received first frame')
+
+ callback() // remember to execute a callback once set up
+ }
+
+ if (this.ffmpegDebugOutput || this.config?.cameraConfigDebug) {
+ this.log.debug(`VIDEO: ${String(data)}`)
+ }
+ })
+ ffmpegVideo.on('error', (error) => {
+ this.log.error(
+ `[Video] Failed to start video stream: ${error.message}`
+ )
+ callback(new Error('ffmpeg process creation failed!'))
+ })
+ ffmpegVideo.on('exit', (code, signal) => {
+ const message =
+ '[Video] ffmpeg exited with code: ' +
+ code +
+ ' and signal: ' +
+ signal
+
+ if (code == null || code === 255) {
+ this.log.debug(`${message} (Video stream stopped!)`)
+ } else {
+ this.log.error(`${message} (error)`)
+
+ if (!started) {
+ callback(new Error(message))
+ } else {
+ this.controller?.forceStopStreamingSession(sessionId)
+ }
+ }
+ })
+
+ this.ongoingSessions[sessionId] = {
+ localVideoPort: localVideoPort,
+ process: ffmpegVideo
+ }
+ delete this.pendingSessions[sessionId]
+
+ break
+ }
+ case StreamRequestTypes.RECONFIGURE:
+ // not supported by this example
+ this.log.debug(
+ 'Received (unsupported) request to reconfigure to: ' +
+ JSON.stringify(request.video)
+ )
+ callback()
+ break
+ case StreamRequestTypes.STOP: {
+ const ongoingSession = this.ongoingSessions[sessionId]
+ if (!ongoingSession) {
+ callback()
+ break
+ }
+
+ ports.delete(ongoingSession.localVideoPort)
+
+ try {
+ ongoingSession.process.kill('SIGKILL')
+ } catch (e) {
+ this.log.error('Error occurred terminating the video process!')
+ this.log.error(String(e))
+ }
+
+ delete this.ongoingSessions[sessionId]
+
+ this.log.debug('Stopped streaming session!')
+ callback()
+ break
+ }
+ }
+ }
+
+ updateRecordingActive(active: boolean): void {
+ // we haven't implemented a prebuffer
+ this.log.debug(`Recording active set to ${active}`)
+ }
+
+ updateRecordingConfiguration(
+ configuration: CameraRecordingConfiguration | undefined
+ ): void {
+ this.configuration = configuration
+ this.log.debug(JSON.stringify(configuration))
+ }
+
+ /**
+ * This is a very minimal, very experimental example of how to implement fmp4 streaming with a
+ * CameraController supporting HomeKit Secure Video.
+ *
+ * An ideal implementation would diverge from this in the following ways:
+ * * It would implement a prebuffer and respect the recording `active` characteristic for that.
+ * * It would start to immediately record after a trigger event occurred and not just
+ * when the HomeKit Controller requests it (see the documentation of `CameraRecordingDelegate`).
+ */
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ async *handleRecordingStreamRequest(
+ _streamId: number
+ ): AsyncGenerator {
+ assert(!!this.configuration)
+
+ /**
+ * With this flag you can control how the generator reacts to a reset to the motion trigger.
+ * If set to true, the generator will send a proper endOfStream if the motion stops.
+ * If set to false, the generator will run till the HomeKit Controller closes the stream.
+ *
+ * Note: In a real implementation you would most likely introduce a bit of a delay.
+ */
+ const STOP_AFTER_MOTION_STOP = false
+
+ this.handlingStreamingRequest = true
+
+ assert(this.configuration.videoCodec.type === VideoCodecType.H264)
+
+ const profile =
+ this.configuration.videoCodec.parameters.profile === H264Profile.HIGH
+ ? 'high'
+ : this.configuration.videoCodec.parameters.profile === H264Profile.MAIN
+ ? 'main'
+ : 'baseline'
+
+ const level =
+ this.configuration.videoCodec.parameters.level === H264Level.LEVEL4_0
+ ? '4.0'
+ : this.configuration.videoCodec.parameters.level === H264Level.LEVEL3_2
+ ? '3.2'
+ : '3.1'
+
+ const videoArgs: Array = [
+ '-an',
+ '-sn',
+ '-dn',
+ '-codec:v',
+ 'libx264',
+ '-pix_fmt',
+ 'yuv420p',
+
+ '-profile:v',
+ profile,
+ '-level:v',
+ level,
+ '-b:v',
+ `${this.configuration.videoCodec.parameters.bitRate}k`,
+ '-force_key_frames',
+ `expr:eq(t,n_forced*${this.configuration.videoCodec.parameters.iFrameInterval / 1000})`,
+ '-r',
+ this.configuration.videoCodec.resolution[2].toString()
+ ]
+
+ let samplerate: string
+ switch (this.configuration.audioCodec.samplerate) {
+ case AudioRecordingSamplerate.KHZ_8:
+ samplerate = '8'
+ break
+ case AudioRecordingSamplerate.KHZ_16:
+ samplerate = '16'
+ break
+ case AudioRecordingSamplerate.KHZ_24:
+ samplerate = '24'
+ break
+ case AudioRecordingSamplerate.KHZ_32:
+ samplerate = '32'
+ break
+ case AudioRecordingSamplerate.KHZ_44_1:
+ samplerate = '44.1'
+ break
+ case AudioRecordingSamplerate.KHZ_48:
+ samplerate = '48'
+ break
+ default:
+ throw new Error(
+ 'Unsupported audio samplerate: ' +
+ this.configuration.audioCodec.samplerate
+ )
+ }
+
+ const audioArgs: Array =
+ this.controller?.recordingManagement?.recordingManagementService.getCharacteristic(
+ Characteristic.RecordingAudioActive
+ )
+ ? [
+ '-acodec',
+ 'libfdk_aac',
+ ...(this.configuration.audioCodec.type ===
+ AudioRecordingCodecType.AAC_LC
+ ? ['-profile:a', 'aac_low']
+ : ['-profile:a', 'aac_eld']),
+ '-ar',
+ `${samplerate}k`,
+ '-b:a',
+ `${this.configuration.audioCodec.bitrate}k`,
+ '-ac',
+ `${this.configuration.audioCodec.audioChannels}`
+ ]
+ : []
+
+ this.server = new MP4StreamingServer(
+ 'ffmpeg',
+ `-f lavfi -i \
+ testsrc=s=${this.configuration.videoCodec.resolution[0]}x${this.configuration.videoCodec.resolution[1]}:r=${this.configuration.videoCodec.resolution[2]}`.split(
+ / /g
+ ),
+ audioArgs,
+ videoArgs
+ )
+
+ await this.server.start()
+ if (!this.server || this.server.destroyed) {
+ return // early exit
+ }
+
+ const pending: Array = []
+
+ try {
+ for await (const box of this.server.generator()) {
+ pending.push(box.header, box.data)
+
+ const motionDetected = this.accessory
+ .getService(Service.MotionSensor)
+ ?.getCharacteristic(Characteristic.MotionDetected).value
+
+ this.log.debug(`mp4 box type ${box.type} and length ${box.length}`)
+ if (box.type === 'moov' || box.type === 'mdat') {
+ const fragment = Buffer.concat(pending)
+ pending.splice(0, pending.length)
+
+ const isLast = STOP_AFTER_MOTION_STOP && !motionDetected
+
+ yield {
+ data: fragment,
+ isLast: isLast
+ }
+
+ if (isLast) {
+ this.log.debug('Ending session due to motion stopped!')
+ break
+ }
+ }
+ }
+ } catch (error: any) {
+ if (!error.message.startsWith('FFMPEG')) {
+ // an inexpensive way of identifying our own emitted errors
+ this.log.error(
+ `Encountered unexpected error on generator ${error.stack}`
+ )
+ }
+ }
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ closeRecordingStream(
+ streamId: number,
+ reason?: HDSProtocolSpecificErrorReason
+ ): void {
+ if (reason) {
+ this.log.error(`Closing stream ${streamId} due to error: ${reason}`)
+ }
+ if (this.server) {
+ this.server.destroy()
+ this.server = undefined
+ }
+ this.handlingStreamingRequest = false
+ }
+
+ acknowledgeStream(streamId: number): void {
+ this.closeRecordingStream(streamId)
+ }
+}
diff --git a/src/lib/camera/MP4StreamingServer.ts b/src/lib/camera/MP4StreamingServer.ts
new file mode 100644
index 00000000..0044eff5
--- /dev/null
+++ b/src/lib/camera/MP4StreamingServer.ts
@@ -0,0 +1,182 @@
+// Based on https://github.com/homebridge/HAP-NodeJS/blob/latest/src/accessories/Camera_accessory.ts
+
+import { type ChildProcess, spawn } from 'node:child_process'
+import { once } from 'node:events'
+import {
+ type AddressInfo,
+ createServer,
+ type Server,
+ type Socket
+} from 'node:net'
+import { logger } from '@nrchkb/logger'
+
+const log = logger('NRCHKB', 'MP4StreamingServer')
+
+interface MP4Atom {
+ header: Buffer
+ length: number
+ type: string
+ data: Buffer
+}
+
+export class MP4StreamingServer {
+ readonly server: Server
+
+ /**
+ * This can be configured to output ffmpeg debug output!
+ */
+ readonly debugMode: boolean = false
+
+ readonly ffmpegPath: string
+ readonly args: string[]
+
+ socket?: Socket
+ childProcess?: ChildProcess
+ destroyed = false
+
+ connectPromise: Promise
+ connectResolve?: () => void
+
+ constructor(
+ ffmpegPath: string,
+ ffmpegInput: Array,
+ audioOutputArgs: Array,
+ videoOutputArgs: Array
+ ) {
+ this.connectPromise = new Promise((resolve) => {
+ this.connectResolve = resolve
+ })
+
+ this.server = createServer(this.handleConnection.bind(this))
+ this.ffmpegPath = ffmpegPath
+ this.args = []
+
+ this.args.push(...ffmpegInput)
+
+ this.args.push(...audioOutputArgs)
+
+ this.args.push('-f', 'mp4')
+ this.args.push(...videoOutputArgs)
+ this.args.push('-fflags', '+genpts', '-reset_timestamps', '1')
+ this.args.push('-movflags', 'frag_keyframe+empty_moov+default_base_moof')
+ }
+
+ async start() {
+ const promise = once(this.server, 'listening')
+ this.server.listen() // listen on random port
+ await promise
+
+ if (this.destroyed) {
+ return
+ }
+
+ const port = (this.server.address() as AddressInfo).port
+ this.args.push(`tcp://127.0.0.1:${port}`)
+
+ log.debug(`${this.ffmpegPath} ${this.args.join(' ')}`)
+
+ this.childProcess = spawn(this.ffmpegPath, this.args, {
+ env: process.env,
+ stdio: this.debugMode ? 'pipe' : 'ignore'
+ })
+ if (!this.childProcess) {
+ log.error('ChildProcess is undefined directly after the init!')
+ }
+ if (this.debugMode) {
+ this.childProcess.stdout?.on('data', (data) => log.debug(data.toString()))
+ this.childProcess.stderr?.on('data', (data) => log.debug(data.toString()))
+ }
+ }
+
+ destroy() {
+ this.socket?.destroy()
+ this.childProcess?.kill()
+
+ this.socket = undefined
+ this.childProcess = undefined
+ this.destroyed = true
+ }
+
+ handleConnection(socket: Socket): void {
+ this.server.close() // don't accept any further clients
+ this.socket = socket
+ this.connectResolve?.()
+ }
+
+ /**
+ * Generator for `MP4Atom`s.
+ * Throws error to signal EOF when socket is closed.
+ */
+ async *generator(): AsyncGenerator {
+ await this.connectPromise
+
+ if (!this.socket || !this.childProcess) {
+ log.error(
+ 'Socket undefined ' +
+ !!this.socket +
+ ' childProcess undefined ' +
+ !!this.childProcess
+ )
+ throw new Error('Unexpected state!')
+ }
+
+ while (true) {
+ const header = await this.read(8)
+ const length = header.readInt32BE(0) - 8
+ const type = header.subarray(4).toString()
+ const data = await this.read(length)
+
+ yield {
+ header: header,
+ length: length,
+ type: type,
+ data: data
+ }
+ }
+ }
+
+ async read(length: number): Promise {
+ if (!this.socket) {
+ throw Error('FFMPEG tried reading from closed socket!')
+ }
+
+ if (!length) {
+ return Buffer.alloc(0)
+ }
+
+ const value = this.socket.read(length)
+ if (value) {
+ return value
+ }
+
+ return new Promise((resolve, reject) => {
+ const readHandler = () => {
+ const value = this.socket?.read(length)
+ if (value) {
+ cleanup()
+ resolve(value)
+ }
+ }
+
+ const endHandler = () => {
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
+ cleanup()
+ reject(
+ new Error(`FFMPEG socket closed during read for ${length} bytes!`)
+ )
+ }
+
+ const cleanup = () => {
+ this.socket?.removeListener('readable', readHandler)
+ this.socket?.removeListener('close', endHandler)
+ }
+
+ if (!this.socket) {
+ throw new Error('FFMPEG socket is closed now!')
+ }
+
+ this.socket.on('readable', readHandler)
+ this.socket.on('close', endHandler)
+ })
+ }
+}
diff --git a/src/lib/cameraSource/index.js b/src/lib/cameraSource/index.js
deleted file mode 100644
index 1bc19889..00000000
--- a/src/lib/cameraSource/index.js
+++ /dev/null
@@ -1,575 +0,0 @@
-import { logger } from '@nrchkb/logger'
-import * as util from 'util'
-
-const HapNodeJS = require('hap-nodejs')
-const uuid = HapNodeJS.uuid
-const StreamController = HapNodeJS.StreamController
-
-const crypto = require('crypto')
-const fs = require('fs')
-const os = require('os')
-const spawn = require('child_process').spawn
-
-const log = logger('CameraSource')
-
-module.exports = {
- Camera: Camera,
-}
-
-function Camera(cameraControlService, config, cameraNode) {
- this.configure(config, cameraControlService)
- this.cameraNode = cameraNode
-}
-
-Camera.prototype.configure = function (config, cameraControlService) {
- this.name = config.name
- this.vcodec = config.cameraConfigVideoCodec
- this.videoProcessor = config.cameraConfigVideoProcessor
- this.audio = config.cameraConfigAudio
- this.acodec = config.cameraConfigAudioCodec
- this.packetsize = config.cameraConfigPacketSize
- this.fps = config.cameraConfigMaxFPS
- this.maxBitrate = config.cameraConfigMaxBitrate
- this.debug = config.cameraConfigDebug
- this.additionalCommandline = config.cameraConfigAdditionalCommandLine
- this.vflip = config.cameraConfigVerticalFlip
- this.hflip = config.cameraConfigHorizontalFlip
- this.mapvideo = config.cameraConfigMapVideo
- this.mapaudio = config.cameraConfigMapAudio
- this.videoFilter = config.cameraConfigVideoFilter
- this.uploader = config.cameraConfigSnapshotOutput
- this.interfaceName = config.cameraConfigInterfaceName
-
- if (!config.cameraConfigSource) {
- throw new NRCHKBError('Missing source for camera.')
- }
-
- if (this.interfaceName !== '') {
- if (
- !Object.keys(require('os').networkInterfaces()).includes(
- this.interfaceName
- )
- ) {
- throw new NRCHKBError('Incorrect interface name for camera.')
- }
- }
-
- this.ffmpegSource = config.cameraConfigSource
- this.ffmpegImageSource = config.cameraConfigStillImageSource
-
- this.services = []
- this.streamControllers = []
-
- this.pendingSessions = {}
- this.ongoingSessions = {}
-
- const numberOfStreams = config.cameraConfigMaxStreams
- const videoResolutions = []
-
- this.maxWidth = config.cameraConfigMaxWidth
- this.maxHeight = config.cameraConfigMaxHeight
- const maxFPS = this.fps > 30 ? 30 : this.fps
-
- if (this.maxWidth >= 320) {
- if (this.maxHeight >= 240) {
- videoResolutions.push([320, 240, maxFPS])
- if (maxFPS > 15) {
- videoResolutions.push([320, 240, 15])
- }
- }
-
- if (this.maxHeight >= 180) {
- videoResolutions.push([320, 180, maxFPS])
- if (maxFPS > 15) {
- videoResolutions.push([320, 180, 15])
- }
- }
- }
-
- if (this.maxWidth >= 480) {
- if (this.maxHeight >= 360) {
- videoResolutions.push([480, 360, maxFPS])
- }
-
- if (this.maxHeight >= 270) {
- videoResolutions.push([480, 270, maxFPS])
- }
- }
-
- if (this.maxWidth >= 640) {
- if (this.maxHeight >= 480) {
- videoResolutions.push([640, 480, maxFPS])
- }
-
- if (this.maxHeight >= 360) {
- videoResolutions.push([640, 360, maxFPS])
- }
- }
-
- if (this.maxWidth >= 1280) {
- if (this.maxHeight >= 960) {
- videoResolutions.push([1280, 960, maxFPS])
- }
-
- if (this.maxHeight >= 720) {
- videoResolutions.push([1280, 720, maxFPS])
- }
- }
-
- if (this.maxWidth >= 1920) {
- if (this.maxHeight >= 1080) {
- videoResolutions.push([1920, 1080, maxFPS])
- }
- }
-
- let options = {
- proxy: false, // Requires RTP/RTCP MUX Proxy TODO: Should I make it configurable?
- srtp: true, // Supports SRTP AES_CM_128_HMAC_SHA1_80 encryption TODO: Should I make it configurable?
- video: {
- resolutions: videoResolutions,
- codec: {
- profiles: [0, 1, 2], // Enum, please refer StreamController.VideoCodecParamProfileIDTypes TODO: Should I make it configurable?
- levels: [0, 1, 2], // Enum, please refer StreamController.VideoCodecParamLevelTypes TODO: Should I make it configurable?
- },
- },
- audio: {
- codecs: [
- {
- type: 'OPUS', // Audio Codec TODO: Should I make it configurable?
- samplerate: 24, // 8, 16, 24 KHz TODO: Should I make it configurable?
- },
- {
- type: 'AAC-eld', // TODO: Should I make it configurable?
- samplerate: 16, // TODO: Should I make it configurable?
- },
- ],
- },
- }
-
- if (cameraControlService) {
- this._createStreamControllers(
- cameraControlService,
- numberOfStreams,
- options
- )
- } else {
- log.error(
- 'Camera reconfigure on the fly is not yet supported. ' +
- 'Please restart node-red to apply all changes to the Camera.'
- )
- }
-}
-
-Camera.prototype.handleCloseConnection = function (connectionID) {
- this.streamControllers.forEach(function (controller) {
- controller.handleCloseConnection(connectionID)
- })
-}
-
-Camera.prototype.handleSnapshotRequest = function (request, callback) {
- let resolution = request.width + 'x' + request.height
-
- let imageSource = this.ffmpegImageSource
-
- if (imageSource === undefined || !imageSource.trim()) {
- imageSource = this.ffmpegSource
- }
-
- let ffmpeg = spawn(
- this.videoProcessor,
- (imageSource + ' -t 1 -s ' + resolution + ' -f image2 -').split(' '),
- { env: process.env }
- )
- let imageBuffer = Buffer.alloc(0)
-
- log.debug('Snapshot from ' + this.name + ' at ' + resolution)
- log.debug(
- 'ffmpeg ' + imageSource + ' -t 1 -s ' + resolution + ' -f image2 -'
- )
-
- ffmpeg.stdout.on('data', function (data) {
- imageBuffer = Buffer.concat([imageBuffer, data])
- })
-
- ffmpeg.on('error', function (error) {
- log.error('An error occurs while making snapshot request')
- log.error(util.inspect(error))
- })
-
- ffmpeg.on(
- 'close',
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- function (code) {
- let msg
-
- if (this.cameraNode) {
- const topic = this.cameraNode.topic
- ? this.cameraNode.topic
- : this.cameraNode.topic_in
- msg = { payload: {}, name: this.cameraNode.name, topic: topic }
- }
-
- if (this.uploader !== 'disabled' && !this.cameraNode) {
- log.error('Node required for camera to send snapshot!')
- } else if (this.uploader === 'path') {
- const filePath =
- __dirname + '/../../cameraSnapshots/' + new Date().getTime()
- log.debug('Saving camera snapshot to: ' + filePath)
-
- const self = this
-
- fs.writeFile(filePath, imageBuffer, function (err) {
- if (err) {
- log.error(
- 'Camera snapshot file failed to save due to: ' + err
- )
- return
- }
-
- msg.payload['cameraSnapshot'] = filePath
- log.debug(
- 'Camera snapshot file has been saved! Sending to output... ' +
- JSON.stringify(msg)
- )
- self.cameraNode.send([null, msg])
- })
- } else if (this.uploader === 'content') {
- msg.payload['cameraSnapshot'] = imageBuffer
- log.debug(
- 'Sending camera snapshot buffer to output...' +
- JSON.stringify(msg)
- )
- this.cameraNode.send([null, null, msg])
- }
-
- callback(undefined, imageBuffer)
- }.bind(this)
- )
-}
-
-Camera.prototype.prepareStream = function (request, callback) {
- const sessionInfo = {}
-
- let sessionID = request['sessionID']
- sessionInfo['address'] = request['targetAddress']
-
- const response = {}
-
- let videoInfo = request['video']
- if (videoInfo) {
- let targetPort = videoInfo['port']
- let srtp_key = videoInfo['srtp_key']
- let srtp_salt = videoInfo['srtp_salt']
-
- // SSRC is a 32 bit integer that is unique per stream
- let ssrcSource = crypto.randomBytes(4)
- ssrcSource[0] = 0
- let ssrc = ssrcSource.readInt32BE(0, true)
-
- response['video'] = {
- port: targetPort,
- ssrc: ssrc,
- srtp_key: srtp_key,
- srtp_salt: srtp_salt,
- }
-
- sessionInfo['video_port'] = targetPort
- sessionInfo['video_srtp'] = Buffer.concat([srtp_key, srtp_salt])
- sessionInfo['video_ssrc'] = ssrc
- }
-
- let audioInfo = request['audio']
- if (audioInfo) {
- let targetPort = audioInfo['port']
- let srtp_key = audioInfo['srtp_key']
- let srtp_salt = audioInfo['srtp_salt']
-
- // SSRC is a 32 bit integer that is unique per stream
- let ssrcSource = crypto.randomBytes(4)
- ssrcSource[0] = 0
- let ssrc = ssrcSource.readInt32BE(0, true)
-
- response['audio'] = {
- port: targetPort,
- ssrc: ssrc,
- srtp_key: srtp_key,
- srtp_salt: srtp_salt,
- }
-
- sessionInfo['audio_port'] = targetPort
- sessionInfo['audio_srtp'] = Buffer.concat([srtp_key, srtp_salt])
- sessionInfo['audio_ssrc'] = ssrc
- }
-
- const networkInterfaces = os.networkInterfaces()
-
- if (this.interfaceName && networkInterfaces[this.interfaceName]) {
- const currentAddress = networkInterfaces[this.interfaceName]
-
- if (currentAddress?.[0]) {
- response['address'] = {
- address: currentAddress[0].address,
- type: currentAddress[0].family === 'IPv4' ? 'v4' : 'v6',
- }
- }
- }
-
- this.pendingSessions[uuid.unparse(sessionID)] = sessionInfo
-
- callback(response)
-}
-
-Camera.prototype.handleStreamRequest = function (request) {
- const sessionID = request['sessionID']
- const requestType = request['type']
- if (sessionID) {
- let sessionIdentifier = uuid.unparse(sessionID)
-
- log.debug('Request type: ' + requestType)
-
- if (requestType === 'start') {
- const sessionInfo = this.pendingSessions[sessionIdentifier]
- if (sessionInfo) {
- let width = 1280
- let height = 720
- let fps = this.fps || 30
- let vbitrate = this.maxBitrate
- let abitrate = 32
- let asamplerate = 16
- const vcodec = this.vcodec
- const acodec = this.acodec
- const packetsize = this.packetsize || 1316
- const additionalCommandline = this.additionalCommandline
- const mapvideo = this.mapvideo
- const mapaudio = this.mapaudio
-
- let videoInfo = request['video']
- if (videoInfo) {
- width = videoInfo['width']
- height = videoInfo['height']
-
- let expectedFPS = videoInfo['fps']
- if (expectedFPS < fps) {
- fps = expectedFPS
- }
- if (videoInfo['max_bit_rate'] < vbitrate) {
- vbitrate = videoInfo['max_bit_rate']
- }
- }
-
- let audioInfo = request['audio']
- if (audioInfo) {
- abitrate = audioInfo['max_bit_rate']
- asamplerate = audioInfo['sample_rate']
- }
-
- let targetAddress = sessionInfo['address']
- let targetVideoPort = sessionInfo['video_port']
- let videoKey = sessionInfo['video_srtp']
- let videoSsrc = sessionInfo['video_ssrc']
- let targetAudioPort = sessionInfo['audio_port']
- let audioKey = sessionInfo['audio_srtp']
- let audioSsrc = sessionInfo['audio_ssrc']
- let vf = []
-
- // Skip vf entirely if videoFilter is empty
- if (this.videoFilter !== null && this.videoFilter !== '') {
- vf.push(this.videoFilter)
-
- if (this.hflip) vf.push('hflip')
-
- if (this.vflip) vf.push('vflip')
- }
-
- let fcmd = this.ffmpegSource
-
- let ffmpegVideoArgs =
- ' -map ' +
- mapvideo +
- ' -vcodec ' +
- vcodec +
- ' -pix_fmt yuv420p' +
- ' -r ' +
- fps +
- ' -f rawvideo' +
- (additionalCommandline ? ' ' + additionalCommandline : '') +
- (vf.length > 0 ? ' -vf ' + vf.join(',') : '') +
- ' -b:v ' +
- vbitrate +
- 'k' +
- ' -bufsize ' +
- vbitrate +
- 'k' +
- ' -maxrate ' +
- vbitrate +
- 'k' +
- ' -payload_type 99'
-
- let ffmpegVideoStream =
- ' -ssrc ' +
- videoSsrc +
- ' -f rtp' +
- ' -srtp_out_suite AES_CM_128_HMAC_SHA1_80' +
- ' -srtp_out_params ' +
- videoKey.toString('base64') +
- ' srtp://' +
- targetAddress +
- ':' +
- targetVideoPort +
- '?rtcpport=' +
- targetVideoPort +
- '&localrtcpport=' +
- targetVideoPort +
- '&pkt_size=' +
- packetsize
-
- // build required video arguments
- fcmd += ffmpegVideoArgs
- fcmd += ffmpegVideoStream
-
- // build optional audio arguments
- if (this.audio) {
- let ffmpegAudioArgs =
- ' -map ' +
- mapaudio +
- ' -acodec ' +
- acodec +
- ' -profile:a aac_eld' +
- ' -flags +global_header' +
- ' -f null' +
- ' -ar ' +
- asamplerate +
- 'k' +
- ' -b:a ' +
- abitrate +
- 'k' +
- ' -bufsize ' +
- abitrate +
- 'k' +
- ' -ac 1' +
- ' -payload_type 110'
-
- let ffmpegAudioStream =
- ' -ssrc ' +
- audioSsrc +
- ' -f rtp' +
- ' -srtp_out_suite AES_CM_128_HMAC_SHA1_80' +
- ' -srtp_out_params ' +
- audioKey.toString('base64') +
- ' srtp://' +
- targetAddress +
- ':' +
- targetAudioPort +
- '?rtcpport=' +
- targetAudioPort +
- '&localrtcpport=' +
- targetAudioPort +
- '&pkt_size=' +
- packetsize
-
- fcmd += ffmpegAudioArgs
- fcmd += ffmpegAudioStream
- }
-
- if (this.debug) {
- fcmd += ' -loglevel debug'
- }
-
- let ffmpeg = spawn(this.videoProcessor, fcmd.split(' '), {
- env: process.env,
- })
- log.debug(
- 'Start streaming video from ' +
- this.name +
- ' with ' +
- width +
- 'x' +
- height +
- '@' +
- vbitrate +
- 'kBit'
- )
- log.debug('ffmpeg ' + fcmd)
-
- ffmpeg.stderr.on(
- 'data',
- function (data) {
- log.debug('ffmpeg data: ' + data.toString())
- }.bind(this)
- )
-
- let self = this
-
- ffmpeg.on('error', function (error) {
- log.error('An error occurred while making stream request')
- log.error(util.inspect(error))
- })
-
- ffmpeg.on('close', (code) => {
- if (code == null || code === 0 || code === 255) {
- log.debug('Stopped streaming')
- } else {
- log.error('ERROR: FFmpeg exited with code ' + code)
-
- for (
- let i = 0;
- i < self.streamControllers.length;
- i++
- ) {
- const controller = self.streamControllers[i]
- if (controller.sessionIdentifier === sessionID) {
- controller.forceStop()
- }
- }
- }
- })
- this.ongoingSessions[sessionIdentifier] = ffmpeg
- }
-
- delete this.pendingSessions[sessionIdentifier]
- } else if (requestType === 'stop') {
- const ffmpegProcess = this.ongoingSessions[sessionIdentifier]
-
- if (ffmpegProcess) {
- ffmpegProcess.kill('SIGTERM')
- }
-
- delete this.ongoingSessions[sessionIdentifier]
- } else if (requestType === 'reconfigure') {
- //TODO: What to do here?
- }
- }
-}
-
-Camera.prototype._createStreamControllers = function (
- cameraControlService,
- maxStreams,
- options
-) {
- let self = this
-
- log.debug('Configuring services for Camera...')
-
- self.services.push(cameraControlService)
- log.debug('...added CameraControl Service')
-
- if (self.audio) {
- log.debug('...audio available')
- } else {
- log.debug('...audio not available')
- }
-
- log.debug(
- 'Creating Camera Stream Controllers: ' + maxStreams + ' - Started'
- )
- log.debug('Camera options: ' + JSON.stringify(options))
-
- for (let i = 0; i < maxStreams; i++) {
- const streamController = new StreamController(i, options, self)
-
- self.services.push(streamController.service)
- self.streamControllers.push(streamController)
- }
-
- log.debug('Creating Camera Stream Controllers - Finished')
-}
diff --git a/src/lib/hap/HAPCharacteristic.ts b/src/lib/hap/HAPCharacteristic.ts
index 569f1898..148daf7f 100644
--- a/src/lib/hap/HAPCharacteristic.ts
+++ b/src/lib/hap/HAPCharacteristic.ts
@@ -1,17 +1,17 @@
-import { Characteristic } from 'hap-nodejs'
+import { Characteristic } from '@homebridge/hap-nodejs'
-import {
- EveS2R1,
- EveS2R2,
- EveS2W1,
- EveS2W2,
+import type {
+ EveS2R1,
+ EveS2R2,
+ EveS2W1,
+ EveS2W2
} from './eve-app/EveCharacteristics'
class HAPCharacteristic extends Characteristic {
- static EveS2R1: typeof EveS2R1
- static EveS2R2: typeof EveS2R2
- static EveS2W1: typeof EveS2W1
- static EveS2W2: typeof EveS2W2
+ static EveS2R1: typeof EveS2R1
+ static EveS2R2: typeof EveS2R2
+ static EveS2W1: typeof EveS2W1
+ static EveS2W2: typeof EveS2W2
}
export default HAPCharacteristic
diff --git a/src/lib/hap/HAPService.ts b/src/lib/hap/HAPService.ts
index f6b45d26..6cb8b4db 100644
--- a/src/lib/hap/HAPService.ts
+++ b/src/lib/hap/HAPService.ts
@@ -1,9 +1,9 @@
-import { Service } from 'hap-nodejs'
+import { Service } from '@homebridge/hap-nodejs'
-import { EveHistoryData } from './eve-app/EveServices'
+import type { EveHistoryData } from './eve-app/EveServices'
class HAPService extends Service {
- static EveHistoryData: typeof EveHistoryData
+ static EveHistoryData: typeof EveHistoryData
}
export default HAPService
diff --git a/src/lib/hap/eve-app/EveCharacteristics.ts b/src/lib/hap/eve-app/EveCharacteristics.ts
index cf70784e..54962bf6 100644
--- a/src/lib/hap/eve-app/EveCharacteristics.ts
+++ b/src/lib/hap/eve-app/EveCharacteristics.ts
@@ -1,6 +1,6 @@
-import { Formats, Perms } from 'hap-nodejs/dist/lib/Characteristic'
+import { Formats, Perms } from '@homebridge/hap-nodejs/dist/lib/Characteristic'
-import CustomCharacteristicType from '../../types/CustomCharacteristicType'
+import type CustomCharacteristicType from '../../types/CustomCharacteristicType'
import HAPCharacteristic from '../HAPCharacteristic'
/**
@@ -11,90 +11,89 @@ import HAPCharacteristic from '../HAPCharacteristic'
*/
const EveCharacteristics: CustomCharacteristicType[] = [
- {
- UUID: 'E863F10A-079E-48FF-8F27-9C2605A29F52',
- name: 'Eve-Volt',
- format: Formats.FLOAT,
- perms: [Perms.PAIRED_READ],
- description: 'Volt (V) value. Used by Eve.app.',
- },
- {
- UUID: 'E863F126-079E-48FF-8F27-9C2605A29F52',
- name: 'Eve-Ampere',
- format: Formats.FLOAT,
- perms: [Perms.PAIRED_READ],
- description: 'Ampere (A) value. Used by Eve.app.',
- },
- {
- UUID: 'E863F10D-079E-48FF-8F27-9C2605A29F52',
- name: 'Eve-Watt',
- format: Formats.FLOAT,
- perms: [Perms.PAIRED_READ],
- description:
- 'Watt (W) value. Used by Eve.app, reported as "Consumption".',
- },
- {
- UUID: 'E863F10C-079E-48FF-8F27-9C2605A29F52',
- name: 'Eve-Kilowatt-hour',
- format: Formats.FLOAT,
- perms: [Perms.PAIRED_READ],
- description:
- 'Kilowatt-hour (kWh) value. Used by Eve.app, reported as Total Consumption.',
- },
- {
- UUID: 'E863F110-079E-48FF-8F27-9C2605A29F52',
- name: 'Eve-Volt-Ampere',
- format: Formats.UINT16,
- perms: [Perms.PAIRED_READ],
- description: 'Volt-Ampere (VA) value. Used by Eve.app.',
- },
+ {
+ UUID: 'E863F10A-079E-48FF-8F27-9C2605A29F52',
+ name: 'Eve-Volt',
+ format: Formats.FLOAT,
+ perms: [Perms.PAIRED_READ],
+ description: 'Volt (V) value. Used by Eve.app.'
+ },
+ {
+ UUID: 'E863F126-079E-48FF-8F27-9C2605A29F52',
+ name: 'Eve-Ampere',
+ format: Formats.FLOAT,
+ perms: [Perms.PAIRED_READ],
+ description: 'Ampere (A) value. Used by Eve.app.'
+ },
+ {
+ UUID: 'E863F10D-079E-48FF-8F27-9C2605A29F52',
+ name: 'Eve-Watt',
+ format: Formats.FLOAT,
+ perms: [Perms.PAIRED_READ],
+ description: 'Watt (W) value. Used by Eve.app, reported as "Consumption".'
+ },
+ {
+ UUID: 'E863F10C-079E-48FF-8F27-9C2605A29F52',
+ name: 'Eve-Kilowatt-hour',
+ format: Formats.FLOAT,
+ perms: [Perms.PAIRED_READ],
+ description:
+ 'Kilowatt-hour (kWh) value. Used by Eve.app, reported as Total Consumption.'
+ },
+ {
+ UUID: 'E863F110-079E-48FF-8F27-9C2605A29F52',
+ name: 'Eve-Volt-Ampere',
+ format: Formats.UINT16,
+ perms: [Perms.PAIRED_READ],
+ description: 'Volt-Ampere (VA) value. Used by Eve.app.'
+ }
]
export class EveS2R1 extends HAPCharacteristic {
- public static readonly UUID: string = 'E863F116-079E-48FF-8F27-9C2605A29F52'
+ public static readonly UUID: string = 'E863F116-079E-48FF-8F27-9C2605A29F52'
- constructor() {
- super('Eve-S2R1', EveS2R1.UUID, {
- format: Formats.DATA,
- perms: [Perms.PAIRED_READ, Perms.NOTIFY, Perms.HIDDEN],
- })
- }
+ constructor() {
+ super('Eve-S2R1', EveS2R1.UUID, {
+ format: Formats.DATA,
+ perms: [Perms.PAIRED_READ, Perms.NOTIFY, Perms.HIDDEN]
+ })
+ }
}
HAPCharacteristic.EveS2R1 = EveS2R1
export class EveS2R2 extends HAPCharacteristic {
- public static readonly UUID: string = 'E863F117-079E-48FF-8F27-9C2605A29F52'
+ public static readonly UUID: string = 'E863F117-079E-48FF-8F27-9C2605A29F52'
- constructor() {
- super('Eve-S2R2', EveS2R2.UUID, {
- format: Formats.DATA,
- perms: [Perms.PAIRED_READ, Perms.NOTIFY, Perms.HIDDEN],
- })
- }
+ constructor() {
+ super('Eve-S2R2', EveS2R2.UUID, {
+ format: Formats.DATA,
+ perms: [Perms.PAIRED_READ, Perms.NOTIFY, Perms.HIDDEN]
+ })
+ }
}
HAPCharacteristic.EveS2R2 = EveS2R2
export class EveS2W1 extends HAPCharacteristic {
- public static readonly UUID: string = 'E863F11C-079E-48FF-8F27-9C2605A29F52'
+ public static readonly UUID: string = 'E863F11C-079E-48FF-8F27-9C2605A29F52'
- constructor() {
- super('Eve-S2W1', EveS2W1.UUID, {
- format: Formats.DATA,
- perms: [Perms.PAIRED_WRITE, Perms.HIDDEN],
- })
- }
+ constructor() {
+ super('Eve-S2W1', EveS2W1.UUID, {
+ format: Formats.DATA,
+ perms: [Perms.PAIRED_WRITE, Perms.HIDDEN]
+ })
+ }
}
HAPCharacteristic.EveS2W1 = EveS2W1
export class EveS2W2 extends HAPCharacteristic {
- public static readonly UUID: string = 'E863F121-079E-48FF-8F27-9C2605A29F52'
+ public static readonly UUID: string = 'E863F121-079E-48FF-8F27-9C2605A29F52'
- constructor() {
- super('Eve-S2W2', EveS2W2.UUID, {
- format: Formats.DATA,
- perms: [Perms.PAIRED_WRITE, Perms.HIDDEN],
- })
- }
+ constructor() {
+ super('Eve-S2W2', EveS2W2.UUID, {
+ format: Formats.DATA,
+ perms: [Perms.PAIRED_WRITE, Perms.HIDDEN]
+ })
+ }
}
HAPCharacteristic.EveS2W2 = EveS2W2
diff --git a/src/lib/hap/eve-app/EveServices.ts b/src/lib/hap/eve-app/EveServices.ts
index 3e638ec1..602aea2d 100644
--- a/src/lib/hap/eve-app/EveServices.ts
+++ b/src/lib/hap/eve-app/EveServices.ts
@@ -6,18 +6,18 @@ import HAPService from '../HAPService'
*/
export class EveHistoryData extends HAPService {
- // Custom service for meta and/or historical information. Characteristics for logging: E863F11C, E863F121, E863F116, E863F117. Used by Eve.app.
- public static readonly UUID: string = 'E863F007-079E-48FF-8F27-9C2605A29F52'
+ // Custom service for meta and/or historical information. Characteristics for logging: E863F11C, E863F121, E863F116, E863F117. Used by Eve.app.
+ public static readonly UUID: string = 'E863F007-079E-48FF-8F27-9C2605A29F52'
- constructor() {
- super('EveHistoryData', EveHistoryData.UUID)
+ constructor() {
+ super('EveHistoryData', EveHistoryData.UUID)
- // Required Characteristics
- this.addCharacteristic(HAPCharacteristic.EveS2R1)
- this.addCharacteristic(HAPCharacteristic.EveS2R2)
- this.addCharacteristic(HAPCharacteristic.EveS2W1)
- this.addCharacteristic(HAPCharacteristic.EveS2W2)
- }
+ // Required Characteristics
+ this.addCharacteristic(HAPCharacteristic.EveS2R1)
+ this.addCharacteristic(HAPCharacteristic.EveS2R2)
+ this.addCharacteristic(HAPCharacteristic.EveS2W1)
+ this.addCharacteristic(HAPCharacteristic.EveS2W2)
+ }
}
HAPService.EveHistoryData = EveHistoryData
diff --git a/src/lib/types/AccessoryInformationType.ts b/src/lib/types/AccessoryInformationType.ts
index c739b654..12f7c6d0 100644
--- a/src/lib/types/AccessoryInformationType.ts
+++ b/src/lib/types/AccessoryInformationType.ts
@@ -1,12 +1,12 @@
type AccessoryInformationType = {
- UUID: string
- name: string
- manufacturer: string
- serialNo: string
- model: string
- firmwareRev: string
- hardwareRev?: string
- softwareRev?: string
+ UUID: string
+ name: string
+ manufacturer: string
+ serialNo: string
+ model: string
+ firmwareRev: string
+ hardwareRev?: string
+ softwareRev?: string
}
export default AccessoryInformationType
diff --git a/src/lib/types/CameraConfigType.ts b/src/lib/types/CameraConfigType.ts
index ce639a7b..eb12260b 100644
--- a/src/lib/types/CameraConfigType.ts
+++ b/src/lib/types/CameraConfigType.ts
@@ -1,25 +1,25 @@
type CameraConfigType = {
- cameraConfigVideoProcessor: string
- cameraConfigSource: string
- cameraConfigStillImageSource?: string
- cameraConfigMaxStreams: number
- cameraConfigMaxWidth: number
- cameraConfigMaxHeight: number
- cameraConfigMaxFPS: number
- cameraConfigMaxBitrate: number
- cameraConfigVideoCodec: string
- cameraConfigAudioCodec: string
- cameraConfigAudio: string
- cameraConfigPacketSize: number
- cameraConfigVerticalFlip: boolean
- cameraConfigHorizontalFlip: boolean
- cameraConfigMapVideo: string
- cameraConfigMapAudio: string
- cameraConfigVideoFilter: string
- cameraConfigAdditionalCommandLine: string
- cameraConfigDebug: boolean
- cameraConfigSnapshotOutput: string
- cameraConfigInterfaceName: string
+ cameraConfigVideoProcessor: string
+ cameraConfigSource: string
+ cameraConfigStillImageSource?: string
+ cameraConfigMaxStreams: number
+ cameraConfigMaxWidth: number
+ cameraConfigMaxHeight: number
+ cameraConfigMaxFPS: number
+ cameraConfigMaxBitrate: number
+ cameraConfigVideoCodec: string
+ cameraConfigAudioCodec: string
+ cameraConfigAudio: string
+ cameraConfigPacketSize: number
+ cameraConfigVerticalFlip: boolean
+ cameraConfigHorizontalFlip: boolean
+ cameraConfigMapVideo: string
+ cameraConfigMapAudio: string
+ cameraConfigVideoFilter: string
+ cameraConfigAdditionalCommandLine: string
+ cameraConfigDebug: boolean
+ cameraConfigSnapshotOutput: string
+ cameraConfigInterfaceName: string
}
export default CameraConfigType
diff --git a/src/lib/types/CustomCharacteristicType.ts b/src/lib/types/CustomCharacteristicType.ts
index f5bd1093..12bc9a75 100644
--- a/src/lib/types/CustomCharacteristicType.ts
+++ b/src/lib/types/CustomCharacteristicType.ts
@@ -1,8 +1,8 @@
-import { CharacteristicProps } from 'hap-nodejs'
+import type { CharacteristicProps } from '@homebridge/hap-nodejs'
type CustomCharacteristicType = CharacteristicProps & {
- UUID?: string
- name?: string
+ UUID?: string
+ name?: string
}
export default CustomCharacteristicType
diff --git a/src/lib/types/HAPHostConfigType.ts b/src/lib/types/HAPHostConfigType.ts
index 8a9b2d72..6a4b8143 100644
--- a/src/lib/types/HAPHostConfigType.ts
+++ b/src/lib/types/HAPHostConfigType.ts
@@ -1,57 +1,25 @@
-import { MDNSAdvertiser } from 'hap-nodejs'
-import { NodeDef } from 'node-red'
-import { SemVer } from 'semver'
+import type { MDNSAdvertiser } from '@homebridge/hap-nodejs'
+import type { NodeDef } from 'node-red'
+import type { SemVer } from 'semver'
-import HapCategories from './hap-nodejs/HapCategories'
+import type HapCategories from './hap-nodejs/HapCategories'
type HAPHostConfigType = NodeDef & {
- bridgeName: string
- pinCode: string
- port?: number
- allowInsecureRequest: boolean
- manufacturer: string
- model: string
- serialNo: string
- firmwareRev: SemVer
- hardwareRev: SemVer
- softwareRev: SemVer
- bind?: string
- bindType?: 'json' | 'str'
- /**
- * @deprecated use bind instead
- */
- customMdnsConfig: boolean
- /**
- * @deprecated use bind instead
- */
- mdnsMulticast: boolean
- /**
- * @deprecated use bind instead
- */
- mdnsInterface: string
- /**
- * @deprecated use bind instead
- */
- mdnsPort: number
- /**
- * @deprecated use bind instead
- */
- mdnsIp: string
- /**
- * @deprecated use bind instead
- */
- mdnsTtl: number
- /**
- * @deprecated use bind instead
- */
- mdnsLoopback: boolean
- /**
- * @deprecated use bind instead
- */
- mdnsReuseAddr: boolean
- allowMessagePassthrough: boolean
- accessoryCategory: HapCategories
- advertiser: MDNSAdvertiser
+ bridgeName: string
+ pinCode: string
+ port?: number
+ allowInsecureRequest: boolean
+ manufacturer: string
+ model: string
+ serialNo: string
+ firmwareRev: SemVer
+ hardwareRev: SemVer
+ softwareRev: SemVer
+ bind?: string
+ bindType?: 'json' | 'str'
+ allowMessagePassthrough: boolean
+ accessoryCategory: HapCategories
+ advertiser: MDNSAdvertiser
}
export default HAPHostConfigType
diff --git a/src/lib/types/HAPHostNodeType.ts b/src/lib/types/HAPHostNodeType.ts
index 83360a4d..a348453e 100644
--- a/src/lib/types/HAPHostNodeType.ts
+++ b/src/lib/types/HAPHostNodeType.ts
@@ -1,19 +1,17 @@
-import { Accessory, Categories } from 'hap-nodejs'
+import type { Accessory, Categories } from '@homebridge/hap-nodejs'
-import BonjourMulticastOptions from './hap-nodejs/BonjourMulticastOptions'
-import HAPHostConfigType from './HAPHostConfigType'
-import HostType from './HostType'
-import NodeType from './NodeType'
+import type HAPHostConfigType from './HAPHostConfigType'
+import type HostType from './HostType'
+import type NodeType from './NodeType'
type HAPHostNodeType = NodeType & {
- config: HAPHostConfigType
- mdnsConfig: BonjourMulticastOptions
- accessoryCategory: Categories
- published: boolean
- bridgeUsername: string
- publish: () => boolean
- hostType: HostType
- host: Accessory
+ config: HAPHostConfigType
+ accessoryCategory: Categories
+ published: boolean
+ bridgeUsername: string
+ publish: () => boolean
+ hostType: HostType
+ host: Accessory
}
export default HAPHostNodeType
diff --git a/src/lib/types/HAPService2ConfigType.ts b/src/lib/types/HAPService2ConfigType.ts
index 6b20a500..63984e43 100644
--- a/src/lib/types/HAPService2ConfigType.ts
+++ b/src/lib/types/HAPService2ConfigType.ts
@@ -1,10 +1,10 @@
-import { NodeDef } from 'node-red'
+import type { NodeDef } from 'node-red'
-import HAPServiceConfigType from './HAPServiceConfigType'
+import type HAPServiceConfigType from './HAPServiceConfigType'
type HAPService2ConfigType = NodeDef &
- HAPServiceConfigType & {
- useEventCallback: boolean
- }
+ HAPServiceConfigType & {
+ useEventCallback: boolean
+ }
export default HAPService2ConfigType
diff --git a/src/lib/types/HAPService2NodeType.ts b/src/lib/types/HAPService2NodeType.ts
index 07ce84c7..39a2da16 100644
--- a/src/lib/types/HAPService2NodeType.ts
+++ b/src/lib/types/HAPService2NodeType.ts
@@ -1,10 +1,10 @@
-import HAPService2ConfigType from './HAPService2ConfigType'
-import HAPServiceNodeType from './HAPServiceNodeType'
-import NodeType from './NodeType'
+import type HAPService2ConfigType from './HAPService2ConfigType'
+import type HAPServiceNodeType from './HAPServiceNodeType'
+import type NodeType from './NodeType'
type HAPService2NodeType = NodeType &
- HAPServiceNodeType & {
- config: HAPService2ConfigType
- }
+ HAPServiceNodeType & {
+ config: HAPService2ConfigType
+ }
export default HAPService2NodeType
diff --git a/src/lib/types/HAPServiceConfigType.ts b/src/lib/types/HAPServiceConfigType.ts
index 8a12de8e..d88ea4f8 100644
--- a/src/lib/types/HAPServiceConfigType.ts
+++ b/src/lib/types/HAPServiceConfigType.ts
@@ -1,32 +1,32 @@
-import { AdaptiveLightingControllerMode } from 'hap-nodejs/dist/lib/controller/AdaptiveLightingController'
-import { NodeDef } from 'node-red'
+import type { AdaptiveLightingControllerMode } from '@homebridge/hap-nodejs/dist/lib/controller/AdaptiveLightingController'
+import type { NodeDef } from 'node-red'
-import CameraConfigType from './CameraConfigType'
+import type CameraConfigType from './CameraConfigType'
type HAPServiceConfigType = NodeDef & {
- isParent: boolean
- // hostType is number but browser js is passing it as string which may cause same comparison issues
- // values are BRIDGE = 0, STANDALONE = 1
- hostType: number
- bridge: string
- accessoryId: string
- parentService: string
- name: string
- serviceName: string
- topic: string
- filter: boolean
- manufacturer: string
- model: string
- serialNo: string
- firmwareRev?: string
- hardwareRev?: string
- softwareRev?: string
- characteristicProperties: string
- waitForSetupMsg: boolean
- // If Service is a LightBulb, you can set AdaptiveLightingControllerMode.ts Lightning Mode
- adaptiveLightingOptionsEnable?: boolean
- adaptiveLightingOptionsMode?: AdaptiveLightingControllerMode
- adaptiveLightingOptionsCustomTemperatureAdjustment?: number
+ isParent: boolean
+ // hostType is number but browser js is passing it as string which may cause same comparison issues
+ // values are BRIDGE = 0, STANDALONE = 1
+ hostType: number
+ bridge: string
+ accessoryId: string
+ parentService: string
+ name: string
+ serviceName: string
+ topic: string
+ filter: boolean
+ manufacturer: string
+ model: string
+ serialNo: string
+ firmwareRev?: string
+ hardwareRev?: string
+ softwareRev?: string
+ characteristicProperties: string
+ waitForSetupMsg: boolean
+ // If Service is a LightBulb, you can set AdaptiveLightingControllerMode.ts Lightning Mode
+ adaptiveLightingOptionsEnable?: boolean
+ adaptiveLightingOptionsMode?: AdaptiveLightingControllerMode
+ adaptiveLightingOptionsCustomTemperatureAdjustment?: number
} & CameraConfigType
export default HAPServiceConfigType
diff --git a/src/lib/types/HAPServiceNodeType.ts b/src/lib/types/HAPServiceNodeType.ts
index 6f7e9e23..2c827a27 100644
--- a/src/lib/types/HAPServiceNodeType.ts
+++ b/src/lib/types/HAPServiceNodeType.ts
@@ -1,63 +1,64 @@
-import {
- Accessory,
- AdaptiveLightingController,
- Characteristic,
- CharacteristicChange,
- CharacteristicGetCallback,
- CharacteristicProps,
- CharacteristicSetCallback,
- CharacteristicValue,
- Service,
-} from 'hap-nodejs'
-import { HAPConnection } from 'hap-nodejs/dist/lib/util/eventedhttp'
-import { NodeAPI } from 'node-red'
+import type {
+ Accessory,
+ AdaptiveLightingController,
+ Characteristic,
+ CharacteristicChange,
+ CharacteristicGetCallback,
+ CharacteristicProps,
+ CharacteristicSetCallback,
+ CharacteristicValue,
+ Service
+} from '@homebridge/hap-nodejs'
+import type { CharacteristicContext } from '@homebridge/hap-nodejs/dist/lib/Characteristic'
+import type { HAPConnection } from '@homebridge/hap-nodejs/dist/lib/util/eventedhttp'
+import type { NodeAPI } from 'node-red'
-import { NodeStatusUtils } from '../utils/NodeStatusUtils'
-import HAPHostNodeType from './HAPHostNodeType'
-import HAPService2NodeType from './HAPService2NodeType'
-import HAPServiceConfigType from './HAPServiceConfigType'
-import NodeType from './NodeType'
-import PublishTimersType from './PublishTimersType'
+import type { NodeStatusUtils } from '../utils/NodeStatusUtils'
+import type HAPHostNodeType from './HAPHostNodeType'
+import type HAPService2NodeType from './HAPService2NodeType'
+import type HAPServiceConfigType from './HAPServiceConfigType'
+import type NodeType from './NodeType'
+import type PublishTimersType from './PublishTimersType'
type HAPServiceNodeType = NodeType & {
- config: HAPServiceConfigType
- RED: NodeAPI
- setupDone: boolean
- configured: boolean
- handleWaitForSetup: (msg: any) => any
- onIdentify: (paired: boolean, callback: () => any) => void
- hostNode: HAPHostNodeType
- childNodes?: (HAPService2NodeType | HAPServiceNodeType)[]
- service: Service
- parentService: Service
- parentNode?: HAPService2NodeType | HAPServiceNodeType
- accessory: Accessory
- characteristicProperties: { [key: string]: CharacteristicProps }
- supported: string[]
- publishTimers: PublishTimersType
- topic_in: string
- onCharacteristicGet: (
- this: Characteristic,
- callback: CharacteristicGetCallback,
- context: any,
- connection?: HAPConnection
- ) => void
- onCharacteristicSet: (
- this: Characteristic,
- newValue: CharacteristicValue,
- callback: CharacteristicSetCallback,
- context: any,
- connection?: HAPConnection
- ) => void
- onCharacteristicChange: (
- this: Characteristic,
- change: CharacteristicChange
- ) => void
- uniqueIdentifier: string
- // Is Accessory reachable? On Linked Service it will be undefined. If is not true then NO_RESPONSE
- reachable?: boolean
- nodeStatusUtils: NodeStatusUtils
- adaptiveLightingController?: AdaptiveLightingController
+ config: HAPServiceConfigType
+ RED: NodeAPI
+ setupDone: boolean
+ configured: boolean
+ handleWaitForSetup: (msg: any) => any
+ onIdentify: (paired: boolean, callback: () => any) => void
+ hostNode: HAPHostNodeType
+ childNodes?: (HAPService2NodeType | HAPServiceNodeType)[]
+ service: Service
+ parentService: Service
+ parentNode?: HAPService2NodeType | HAPServiceNodeType
+ accessory: Accessory
+ characteristicProperties: { [key: string]: CharacteristicProps }
+ supported: string[]
+ publishTimers: PublishTimersType
+ topic_in: string
+ onCharacteristicGet: (
+ this: Characteristic,
+ callback: CharacteristicGetCallback,
+ context: CharacteristicContext,
+ connection?: HAPConnection
+ ) => void
+ onCharacteristicSet: (
+ this: Characteristic,
+ value: CharacteristicValue,
+ callback: CharacteristicSetCallback,
+ context: CharacteristicContext,
+ connection?: HAPConnection
+ ) => void
+ onCharacteristicChange: (
+ this: Characteristic,
+ change: CharacteristicChange
+ ) => void
+ uniqueIdentifier: string
+ // Is Accessory reachable? On Linked Service it will be undefined. If is not true then NO_RESPONSE
+ reachable?: boolean
+ nodeStatusUtils: NodeStatusUtils
+ adaptiveLightingController?: AdaptiveLightingController
}
export default HAPServiceNodeType
diff --git a/src/lib/types/HAPStatusConfigType.ts b/src/lib/types/HAPStatusConfigType.ts
index e24e2795..5267e2c0 100644
--- a/src/lib/types/HAPStatusConfigType.ts
+++ b/src/lib/types/HAPStatusConfigType.ts
@@ -1,7 +1,7 @@
-import { NodeDef } from 'node-red'
+import type { NodeDef } from 'node-red'
type HAPStatusConfigType = NodeDef & {
- serviceNodeId: string
+ serviceNodeId: string
}
export default HAPStatusConfigType
diff --git a/src/lib/types/HAPStatusNodeType.ts b/src/lib/types/HAPStatusNodeType.ts
index 187af0cd..0e1632a7 100644
--- a/src/lib/types/HAPStatusNodeType.ts
+++ b/src/lib/types/HAPStatusNodeType.ts
@@ -1,15 +1,15 @@
-import { NodeAPI } from 'node-red'
+import type { NodeAPI } from 'node-red'
-import { NodeStatusUtils } from '../utils/NodeStatusUtils'
-import HAPServiceNodeType from './HAPServiceNodeType'
-import HAPStatusConfigType from './HAPStatusConfigType'
-import NodeType from './NodeType'
+import type { NodeStatusUtils } from '../utils/NodeStatusUtils'
+import type HAPServiceNodeType from './HAPServiceNodeType'
+import type HAPStatusConfigType from './HAPStatusConfigType'
+import type NodeType from './NodeType'
type HAPStatusNodeType = NodeType & {
- config: HAPStatusConfigType
- RED: NodeAPI
- serviceNode?: HAPServiceNodeType
- nodeStatusUtils: NodeStatusUtils
+ config: HAPStatusConfigType
+ RED: NodeAPI
+ serviceNode?: HAPServiceNodeType
+ nodeStatusUtils: NodeStatusUtils
}
export default HAPStatusNodeType
diff --git a/src/lib/types/HostType.ts b/src/lib/types/HostType.ts
index 12ace0ca..b27bcdbb 100644
--- a/src/lib/types/HostType.ts
+++ b/src/lib/types/HostType.ts
@@ -1,6 +1,6 @@
enum HostType {
- BRIDGE = 0,
- STANDALONE = 1,
+ BRIDGE = 0,
+ STANDALONE = 1
}
export default HostType
diff --git a/src/lib/types/NodeType.ts b/src/lib/types/NodeType.ts
index cb593854..d3d64e73 100644
--- a/src/lib/types/NodeType.ts
+++ b/src/lib/types/NodeType.ts
@@ -1,4 +1,4 @@
-import { Node } from 'node-red'
+import type { Node } from 'node-red'
type NodeType = Node
diff --git a/src/lib/types/PublishTimersType.ts b/src/lib/types/PublishTimersType.ts
index de5fe20e..8d6612a3 100644
--- a/src/lib/types/PublishTimersType.ts
+++ b/src/lib/types/PublishTimersType.ts
@@ -1,5 +1,5 @@
type PublishTimersType = {
- [key: string]: NodeJS.Timeout
+ [key: string]: NodeJS.Timeout
}
export default PublishTimersType
diff --git a/src/lib/types/hap-nodejs/BonjourMulticastOptions.ts b/src/lib/types/hap-nodejs/BonjourMulticastOptions.ts
deleted file mode 100644
index aa6dc31b..00000000
--- a/src/lib/types/hap-nodejs/BonjourMulticastOptions.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-type BonjourMulticastOptions = {
- multicast?: boolean
- interface?: string
- port?: number
- ip?: string
- ttl?: number
- loopback?: boolean
- reuseAddr?: boolean
-}
-
-export default BonjourMulticastOptions
diff --git a/src/lib/types/hap-nodejs/HapAdaptiveLightingControllerMode.ts b/src/lib/types/hap-nodejs/HapAdaptiveLightingControllerMode.ts
index f04a6202..94cb07f8 100644
--- a/src/lib/types/hap-nodejs/HapAdaptiveLightingControllerMode.ts
+++ b/src/lib/types/hap-nodejs/HapAdaptiveLightingControllerMode.ts
@@ -1,13 +1,13 @@
enum HapAdaptiveLightingControllerMode {
- /**
- * In automatic mode pretty much everything from setup to transition scheduling is done by the controller.
- */
- AUTOMATIC = 1,
- /**
- * In manual mode setup is done by the controller but the actual transition must be done by the user.
- * This is useful for lights which natively support transitions.
- */
- MANUAL = 2,
+ /**
+ * In automatic mode pretty much everything from setup to transition scheduling is done by the controller.
+ */
+ AUTOMATIC = 1,
+ /**
+ * In manual mode setup is done by the controller but the actual transition must be done by the user.
+ * This is useful for lights which natively support transitions.
+ */
+ MANUAL = 2
}
export default HapAdaptiveLightingControllerMode
diff --git a/src/lib/types/hap-nodejs/HapCategories.ts b/src/lib/types/hap-nodejs/HapCategories.ts
index 1e7e2e99..8077f826 100644
--- a/src/lib/types/hap-nodejs/HapCategories.ts
+++ b/src/lib/types/hap-nodejs/HapCategories.ts
@@ -1,45 +1,44 @@
-/* eslint-disable @typescript-eslint/no-duplicate-enum-values */
// hap-nodejs declared this as const enum which makes it difficult to iterate key-value
// Known category values. Category is a hint to iOS clients about what "type" of Accessory this represents, for UI only.
enum HapCategories {
- OTHER = 1,
- BRIDGE = 2,
- FAN = 3,
- GARAGE_DOOR_OPENER = 4,
- LIGHTBULB = 5,
- DOOR_LOCK = 6,
- OUTLET = 7,
- SWITCH = 8,
- THERMOSTAT = 9,
- SENSOR = 10,
- ALARM_SYSTEM = 11,
- SECURITY_SYSTEM = 11, //Added to conform to HAP naming
- DOOR = 12,
- WINDOW = 13,
- WINDOW_COVERING = 14,
- PROGRAMMABLE_SWITCH = 15,
- RANGE_EXTENDER = 16,
- CAMERA = 17,
- IP_CAMERA = 17, //Added to conform to HAP naming
- VIDEO_DOORBELL = 18,
- AIR_PURIFIER = 19,
- AIR_HEATER = 20,
- AIR_CONDITIONER = 21,
- AIR_HUMIDIFIER = 22,
- AIR_DEHUMIDIFIER = 23,
- APPLE_TV = 24,
- HOMEPOD = 25,
- SPEAKER = 26,
- AIRPORT = 27,
- SPRINKLER = 28,
- FAUCET = 29,
- SHOWER_HEAD = 30,
- TELEVISION = 31,
- TARGET_CONTROLLER = 32, // Remote Control
- ROUTER = 33,
- AUDIO_RECEIVER = 34,
- TV_SET_TOP_BOX = 35,
- TV_STREAMING_STICK = 36,
+ OTHER = 1,
+ BRIDGE = 2,
+ FAN = 3,
+ GARAGE_DOOR_OPENER = 4,
+ LIGHTBULB = 5,
+ DOOR_LOCK = 6,
+ OUTLET = 7,
+ SWITCH = 8,
+ THERMOSTAT = 9,
+ SENSOR = 10,
+ ALARM_SYSTEM = 11,
+ SECURITY_SYSTEM = 11, //Added to conform to HAP naming
+ DOOR = 12,
+ WINDOW = 13,
+ WINDOW_COVERING = 14,
+ PROGRAMMABLE_SWITCH = 15,
+ RANGE_EXTENDER = 16,
+ CAMERA = 17,
+ IP_CAMERA = 17, //Added to conform to HAP naming
+ VIDEO_DOORBELL = 18,
+ AIR_PURIFIER = 19,
+ AIR_HEATER = 20,
+ AIR_CONDITIONER = 21,
+ AIR_HUMIDIFIER = 22,
+ AIR_DEHUMIDIFIER = 23,
+ APPLE_TV = 24,
+ HOMEPOD = 25,
+ SPEAKER = 26,
+ AIRPORT = 27,
+ SPRINKLER = 28,
+ FAUCET = 29,
+ SHOWER_HEAD = 30,
+ TELEVISION = 31,
+ TARGET_CONTROLLER = 32, // Remote Control
+ ROUTER = 33,
+ AUDIO_RECEIVER = 34,
+ TV_SET_TOP_BOX = 35,
+ TV_STREAMING_STICK = 36
}
export default HapCategories
diff --git a/src/lib/types/storage/SerializedHostType.ts b/src/lib/types/storage/SerializedHostType.ts
index 147244f1..9d334bd2 100644
--- a/src/lib/types/storage/SerializedHostType.ts
+++ b/src/lib/types/storage/SerializedHostType.ts
@@ -1,7 +1,7 @@
-import { SerializedAccessory } from 'hap-nodejs'
+import type { SerializedAccessory } from '@homebridge/hap-nodejs'
type SerializedHostType = {
- _isBridge: boolean
+ _isBridge: boolean
} & SerializedAccessory
-export { SerializedHostType }
+export type { SerializedHostType }
diff --git a/src/lib/types/storage/StorageType.ts b/src/lib/types/storage/StorageType.ts
index d06dd4b2..60e06e58 100644
--- a/src/lib/types/storage/StorageType.ts
+++ b/src/lib/types/storage/StorageType.ts
@@ -1,9 +1,9 @@
enum StorageType {
- SERVICE = 'service', // For Future Use
- ACCESSORY = 'accessory', // For Future Use
- HOST = 'host', // For Future Use
- CUSTOM_CHARACTERISTICS = 'customCharacteristics',
- OTHER = 'other', // For Future Use
+ SERVICE = 'service', // For Future Use
+ ACCESSORY = 'accessory', // For Future Use
+ HOST = 'host', // For Future Use
+ CUSTOM_CHARACTERISTICS = 'customCharacteristics',
+ OTHER = 'other' // For Future Use
}
export { StorageType }
diff --git a/src/lib/utils/AccessoryUtils.ts b/src/lib/utils/AccessoryUtils.ts
index ef7884e0..b6638718 100644
--- a/src/lib/utils/AccessoryUtils.ts
+++ b/src/lib/utils/AccessoryUtils.ts
@@ -1,223 +1,201 @@
+import type { Accessory, Service } from '@homebridge/hap-nodejs'
import { logger } from '@nrchkb/logger'
-import { Accessory, Service } from 'hap-nodejs'
-import AccessoryInformationType from '../types/AccessoryInformationType'
-import HAPServiceNodeType from '../types/HAPServiceNodeType'
-
-module.exports = function (node: HAPServiceNodeType) {
- const HapNodeJS = require('hap-nodejs')
- const Accessory = HapNodeJS.Accessory
- const Service = HapNodeJS.Service
- const Characteristic = HapNodeJS.Characteristic
-
- const log = logger('NRCHKB', 'AccessoryUtils', node.config.name, node)
+import type AccessoryInformationType from '../types/AccessoryInformationType'
+import type HAPServiceNodeType from '../types/HAPServiceNodeType'
+
+module.exports = (node: HAPServiceNodeType) => {
+ const HapNodeJS = require('@homebridge/hap-nodejs')
+ const Accessory = HapNodeJS.Accessory
+ const Service = HapNodeJS.Service
+ const Characteristic = HapNodeJS.Characteristic
+
+ const log = logger('NRCHKB', 'AccessoryUtils', node.config.name, node)
+
+ const getOrCreate = (
+ host: Accessory,
+ accessoryInformation: AccessoryInformationType,
+ subtypeUUID: string
+ ) => {
+ let accessory: Accessory | undefined
+ const services: Service[] = []
+
+ // create accessory object
+ log.debug(`Looking for accessory with service subtype ${subtypeUUID} ...`)
+
+ // Try to find an accessory which contains a service with the same
+ // subtype. Since the UUID of the accessory might have changed the
+ // subtype will be used instead.
+ accessory = host.bridgedAccessories.find((a) => {
+ const service = a.services.find((s) => {
+ return s.subtype === subtypeUUID
+ })
+
+ return service !== undefined
+ })
+
+ if (accessory) {
+ // An accessory was found
+ const accessoryInformationService =
+ accessory.getService(Service.AccessoryInformation) ||
+ accessory.addService(Service.AccessoryInformation)
+
+ if (
+ accessoryInformationService.getCharacteristic(
+ Characteristic.Manufacturer
+ ).value !== accessoryInformation.manufacturer ||
+ accessoryInformationService.getCharacteristic(Characteristic.Model)
+ .value !== accessoryInformation.model ||
+ accessoryInformationService.getCharacteristic(Characteristic.Name)
+ .value !== accessoryInformation.name ||
+ accessoryInformationService.getCharacteristic(
+ Characteristic.SerialNumber
+ ).value !== accessoryInformation.serialNo
+ ) {
+ log.debug(
+ '... Manufacturer, Model, Name or Serial Number changed! Replacing it.'
+ )
- const getOrCreate = function (
- host: Accessory,
- accessoryInformation: AccessoryInformationType,
- subtypeUUID: string
- ) {
- let accessory: Accessory | undefined
- const services: Service[] = []
+ // Removing services from accessory and storing them for later
+ accessory.services
+ .filter(
+ (service) => service.UUID !== Service.AccessoryInformation.UUID
+ )
+ .forEach((service) => {
+ accessory?.removeService(service)
+ services.push(service)
+ })
+
+ // Remove old Accessory
+ host.removeBridgedAccessory(accessory, false)
+ accessory.destroy()
+ accessory = undefined
+ } else {
+ log.debug('... found it! Updating it.')
+ }
+ } else {
+ log.debug(
+ `... didn't find it. Adding new accessory with name ${accessoryInformation.name} and UUID ${accessoryInformation.UUID}`
+ )
+ }
- // create accessory object
- log.debug(
- `Looking for accessory with service subtype ${subtypeUUID} ...`
+ let accessoryInformationService: Service | undefined
+
+ if (!accessory) {
+ // A new accessory will be created.
+ accessory = new Accessory(
+ accessoryInformation.name,
+ accessoryInformation.UUID
+ )
+
+ // If the accessory is getting replaced then all of the old
+ // services (except AccessoryInformation) will be transferred to
+ // the new accessory.
+ services.forEach((service) => {
+ accessory?.addService(service)
+ })
+
+ accessoryInformationService =
+ accessory?.getService(Service.AccessoryInformation) ||
+ accessory?.addService(Service.AccessoryInformation)
+
+ // Setting manufacturer data. According to the HomekitADK specs this
+ // data must persist throughout the lifetime of the accessory and
+ // may not be changed.
+ accessoryInformationService
+ ?.setCharacteristic(Characteristic.Name, accessoryInformation.name)
+ .setCharacteristic(
+ Characteristic.Manufacturer,
+ accessoryInformation.manufacturer
)
+ .setCharacteristic(
+ Characteristic.SerialNumber,
+ accessoryInformation.serialNo
+ )
+ .setCharacteristic(Characteristic.Model, accessoryInformation.model)
- // Try to find an accessory which contains a service with the same
- // subtype. Since the UUID of the accessory might have changed the
- // subtype will be used instead.
- accessory = host.bridgedAccessories.find((a) => {
- const service = a.services.find((s) => {
- return s.subtype === subtypeUUID
- })
-
- return service !== undefined
- })
-
- if (accessory) {
- // An accessory was found
- const accessoryInformationService =
- accessory.getService(Service.AccessoryInformation) ||
- accessory.addService(Service.AccessoryInformation)
-
- if (
- accessoryInformationService.getCharacteristic(
- Characteristic.Manufacturer
- ).value !== accessoryInformation.manufacturer ||
- accessoryInformationService.getCharacteristic(
- Characteristic.Model
- ).value !== accessoryInformation.model ||
- accessoryInformationService.getCharacteristic(
- Characteristic.Name
- ).value !== accessoryInformation.name ||
- accessoryInformationService.getCharacteristic(
- Characteristic.SerialNumber
- ).value !== accessoryInformation.serialNo
- ) {
- log.debug(
- '... Manufacturer, Model, Name or Serial Number changed! Replacing it.'
- )
-
- // Removing services from accessory and storing them for later
- accessory.services
- .filter(
- (service) =>
- service.UUID !== Service.AccessoryInformation.UUID
- )
- .forEach((service) => {
- accessory?.removeService(service)
- services.push(service)
- })
-
- // Remove old Accessory
- host.removeBridgedAccessory(accessory, false)
- accessory.destroy()
- accessory = undefined
- } else {
- log.debug('... found it! Updating it.')
- }
- } else {
- log.debug(
- `... didn't find it. Adding new accessory with name ${accessoryInformation.name} and UUID ${accessoryInformation.UUID}`
- )
- }
-
- let accessoryInformationService: Service | undefined
-
- if (!accessory) {
- // A new accessory will be created.
- accessory = new Accessory(
- accessoryInformation.name,
- accessoryInformation.UUID
- )
-
- // If the accessory is getting replaced then all of the old
- // services (except AccessoryInformation) will be transferred to
- // the new accessory.
- services.forEach((service) => {
- accessory?.addService(service)
- })
-
- accessoryInformationService =
- accessory?.getService(Service.AccessoryInformation) ||
- accessory?.addService(Service.AccessoryInformation)
-
- // Setting manufacturer data. According to the HomekitADK specs this
- // data must persist throughout the lifetime of the accessory and
- // may not be changed.
- accessoryInformationService
- ?.setCharacteristic(
- Characteristic.Name,
- accessoryInformation.name
- )
- .setCharacteristic(
- Characteristic.Manufacturer,
- accessoryInformation.manufacturer
- )
- .setCharacteristic(
- Characteristic.SerialNumber,
- accessoryInformation.serialNo
- )
- .setCharacteristic(
- Characteristic.Model,
- accessoryInformation.model
- )
-
- const revisionRegex = /\d+\.\d+\.\d+/
-
- if (
- accessoryInformation.firmwareRev &&
- accessoryInformation.firmwareRev.match(revisionRegex)
- ) {
- accessoryInformationService?.setCharacteristic(
- Characteristic.FirmwareRevision,
- accessoryInformation.firmwareRev
- )
- }
-
- if (
- accessoryInformation.hardwareRev &&
- accessoryInformation.hardwareRev.match(revisionRegex)
- ) {
- accessoryInformationService?.setCharacteristic(
- Characteristic.HardwareRevision,
- accessoryInformation.hardwareRev
- )
- }
-
- if (
- accessoryInformation.softwareRev &&
- accessoryInformation.softwareRev.match(revisionRegex)
- ) {
- accessoryInformationService?.setCharacteristic(
- Characteristic.SoftwareRevision,
- accessoryInformation.softwareRev
- )
- }
-
- // Adding new accessory to the bridge.
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- host.addBridgedAccessories([accessory!])
- } else {
- accessoryInformationService =
- accessory?.getService(Service.AccessoryInformation) ||
- accessory?.addService(Service.AccessoryInformation)
- }
+ const revisionRegex = /\d+\.\d+\.\d+/
+ if (accessoryInformation.firmwareRev?.match(revisionRegex)) {
accessoryInformationService?.setCharacteristic(
- Characteristic.Identify,
- true
+ Characteristic.FirmwareRevision,
+ accessoryInformation.firmwareRev
)
+ }
- log.debug(
- `Bridge now has ${host.bridgedAccessories.length} accessories.`
+ if (accessoryInformation.hardwareRev?.match(revisionRegex)) {
+ accessoryInformationService?.setCharacteristic(
+ Characteristic.HardwareRevision,
+ accessoryInformation.hardwareRev
)
+ }
- return accessory
+ if (accessoryInformation.softwareRev?.match(revisionRegex)) {
+ accessoryInformationService?.setCharacteristic(
+ Characteristic.SoftwareRevision,
+ accessoryInformation.softwareRev
+ )
+ }
+
+ // Adding new accessory to the bridge.
+ // biome-ignore lint/style/noNonNullAssertion: accessory is not null here
+ host.addBridgedAccessories([accessory!])
+ } else {
+ accessoryInformationService =
+ accessory?.getService(Service.AccessoryInformation) ||
+ accessory?.addService(Service.AccessoryInformation)
}
- const onIdentify = function (paired: boolean, callback: () => any) {
- if (paired) {
- log.debug(
- `Identify called on paired Accessory ${node.accessory.displayName}`
- )
- } else {
- log.debug(
- `Identify called on unpaired Accessory ${node.accessory.displayName}`
- )
- }
-
- const nodes = node.childNodes ?? []
-
- for (let i = 0, len = nodes.length; i < len; i++) {
- const topic = nodes[i].config.topic
- ? nodes[i].config.topic
- : nodes[i].topic_in
- const msg = {
- payload: { Identify: 1 },
- name: nodes[i].name,
- topic: topic,
- }
-
- const statusId = nodes[i].nodeStatusUtils.setStatus({
- fill: 'yellow',
- shape: 'dot',
- text: 'Identify : 1',
- })
-
- setTimeout(function () {
- nodes[i].nodeStatusUtils.clearStatus(statusId)
- }, 3000)
-
- nodes[i].send([msg, msg])
- }
- callback()
+ accessoryInformationService?.setCharacteristic(
+ Characteristic.Identify,
+ true
+ )
+
+ log.debug(`Bridge now has ${host.bridgedAccessories.length} accessories.`)
+
+ return accessory
+ }
+
+ const onIdentify = (paired: boolean, callback: () => any) => {
+ if (paired) {
+ log.debug(
+ `Identify called on paired Accessory ${node.accessory.displayName}`
+ )
+ } else {
+ log.debug(
+ `Identify called on unpaired Accessory ${node.accessory.displayName}`
+ )
}
- return {
- getOrCreate,
- onIdentify,
+ const nodes = node.childNodes ?? []
+
+ for (let i = 0, len = nodes.length; i < len; i++) {
+ const topic = nodes[i].config.topic
+ ? nodes[i].config.topic
+ : nodes[i].topic_in
+ const msg = {
+ payload: { Identify: 1 },
+ name: nodes[i].name,
+ topic: topic
+ }
+
+ const statusId = nodes[i].nodeStatusUtils.setStatus({
+ fill: 'yellow',
+ shape: 'dot',
+ text: 'Identify : 1'
+ })
+
+ setTimeout(() => {
+ nodes[i].nodeStatusUtils.clearStatus(statusId)
+ }, 3000)
+
+ nodes[i].send([msg, msg])
}
+ callback()
+ }
+
+ return {
+ getOrCreate,
+ onIdentify
+ }
}
diff --git a/src/lib/utils/BridgeUtils.ts b/src/lib/utils/BridgeUtils.ts
index c40e5ed2..6bb81534 100644
--- a/src/lib/utils/BridgeUtils.ts
+++ b/src/lib/utils/BridgeUtils.ts
@@ -1,52 +1,53 @@
import { logger } from '@nrchkb/logger'
-import HAPServiceNodeType from '../types/HAPServiceNodeType'
+import type HAPServiceNodeType from '../types/HAPServiceNodeType'
import HostType from '../types/HostType'
-module.exports = function () {
- // Publish accessory after the service has been added
- // BUT ONLY after 5 seconds with no new service have passed
- // otherwise, our bridge would get published too early during startup and
- // services being added after that point would be seen as "new" in iOS,
- // removing all parameters set (Rooms, Groups, Scenes...)
- const delayedPublish = function (node: HAPServiceNodeType) {
- const log = logger('NRCHKB', 'BridgeUtils', node.config.name, node)
-
- if (!node.hostNode.published) {
- if (node.publishTimers[node.hostNode.id] !== undefined) {
- clearTimeout(node.publishTimers[node.hostNode.id])
+module.exports = () => {
+ // Publish accessory after the service has been added
+ // BUT ONLY after 5 seconds with no new service have passed
+ // otherwise, our bridge would get published too early during startup and
+ // services being added after that point would be seen as "new" in iOS,
+ // removing all parameters set (Rooms, Groups, Scenes...)
+ const delayedPublish = (node: HAPServiceNodeType) => {
+ const log = logger('NRCHKB', 'BridgeUtils', node.config.name, node)
+
+ if (!node.hostNode.published) {
+ if (node.publishTimers[node.hostNode.id] !== undefined) {
+ clearTimeout(node.publishTimers[node.hostNode.id])
+ }
+
+ const hostTypeName =
+ // biome-ignore lint/suspicious/noDoubleEquals: hostType can be a string or a number
+ node.hostNode.hostType == HostType.BRIDGE
+ ? 'Bridge'
+ : 'Standalone Accessory'
+
+ node.publishTimers[node.hostNode.id] = setTimeout(() => {
+ try {
+ if (!node.hostNode.published) {
+ const published = node.hostNode.publish()
+
+ if (published) {
+ log.debug(`${hostTypeName} published`)
+ } else {
+ log.error(`${hostTypeName} not published`)
}
-
- const hostTypeName =
- node.hostNode.hostType == HostType.BRIDGE
- ? 'Bridge'
- : 'Standalone Accessory'
-
- node.publishTimers[node.hostNode.id] = setTimeout(function () {
- try {
- if (!node.hostNode.published) {
- const published = node.hostNode.publish()
-
- if (published) {
- log.debug(`${hostTypeName} published`)
- } else {
- log.error(`${hostTypeName} not published`)
- }
- }
- } catch (error) {
- log.error(`${hostTypeName} publish failed due to ${error}`)
-
- node.nodeStatusUtils.setStatus({
- fill: 'red',
- shape: 'ring',
- text: 'Error while publishing ' + hostTypeName,
- })
- }
- }, 5000)
+ }
+ } catch (error) {
+ log.error(`${hostTypeName} publish failed due to ${error}`)
+
+ node.nodeStatusUtils.setStatus({
+ fill: 'red',
+ shape: 'ring',
+ text: `Error while publishing ${hostTypeName}`
+ })
}
+ }, 5000)
}
+ }
- return {
- delayedPublish: delayedPublish,
- }
+ return {
+ delayedPublish: delayedPublish
+ }
}
diff --git a/src/lib/utils/CharacteristicUtils.ts b/src/lib/utils/CharacteristicUtils.ts
index 778b30bc..bafec9ac 100644
--- a/src/lib/utils/CharacteristicUtils.ts
+++ b/src/lib/utils/CharacteristicUtils.ts
@@ -1,101 +1,98 @@
+import {
+ Characteristic,
+ type CharacteristicProps,
+ type Service
+} from '@homebridge/hap-nodejs'
import { logger } from '@nrchkb/logger'
-import { Characteristic, CharacteristicProps, Service } from 'hap-nodejs'
-
-import HAPServiceConfigType from '../types/HAPServiceConfigType'
-import HAPServiceNodeType from '../types/HAPServiceNodeType'
-
-module.exports = function (node: HAPServiceNodeType) {
- const log = logger('NRCHKB', 'CharacteristicUtils', node.config.name, node)
- const ServiceUtils = require('./ServiceUtils')(node)
-
- const load = function (
- service: Service,
- config: HAPServiceConfigType
- ): { [key: string]: CharacteristicProps } {
- let characteristicProperties: {
- [key: string]: CharacteristicProps
- } = {}
-
- if (
- config.characteristicProperties &&
- config.characteristicProperties.length > 0
- ) {
- characteristicProperties = JSON.parse(
- config.characteristicProperties.replace(
- /\${(.*?)}/g,
- (_, envName) =>
- node.RED.util.evaluateNodeProperty(
- envName,
- 'env',
- node,
- {}
- )
- )
- )
-
- log.trace('Evaluating value:')
- log.trace(config.characteristicProperties)
- log.trace('Evaluated as:')
- log.trace(JSON.stringify(characteristicProperties))
-
- // Configure custom characteristic properties
- for (const key in characteristicProperties) {
- if (!characteristicProperties.hasOwnProperty(key)) continue
-
- const characteristic = service.getCharacteristic(
- // @ts-ignore
- Characteristic[key]
- )
-
- if (characteristic && characteristicProperties[key]) {
- log.debug(`Found Characteristic Properties for ${key}`)
- characteristic.setProps(characteristicProperties[key])
- }
- }
- }
-
- return characteristicProperties
- }
- const subscribeAndGetSupported = function (service: Service) {
- const supported: string[] = []
-
- const allCharacteristics = service.characteristics.concat(
- service.optionalCharacteristics
+import type HAPServiceConfigType from '../types/HAPServiceConfigType'
+import type HAPServiceNodeType from '../types/HAPServiceNodeType'
+
+module.exports = (node: HAPServiceNodeType) => {
+ const log = logger('NRCHKB', 'CharacteristicUtils', node.config.name, node)
+ const ServiceUtils = require('./ServiceUtils')(node)
+
+ const load = (
+ service: Service,
+ config: HAPServiceConfigType
+ ): { [key: string]: CharacteristicProps } => {
+ let characteristicProperties: {
+ [key: string]: CharacteristicProps
+ } = {}
+
+ if (
+ config.characteristicProperties &&
+ config.characteristicProperties.length > 0
+ ) {
+ characteristicProperties = JSON.parse(
+ config.characteristicProperties.replace(/\${(.*?)}/g, (_, envName) =>
+ node.RED.util.evaluateNodeProperty(envName, 'env', node, {})
)
+ )
- // Listen to characteristic events and store the listener functions
- // to be able to remove them later
- node.onCharacteristicGet = ServiceUtils.onCharacteristicGet
- node.onCharacteristicSet = ServiceUtils.onCharacteristicSet(
- service.characteristics
- )
- node.onCharacteristicChange = ServiceUtils.onCharacteristicChange(
- service.characteristics
- )
+ log.trace('Evaluating value:')
+ log.trace(config.characteristicProperties)
+ log.trace('Evaluated as:')
+ log.trace(JSON.stringify(characteristicProperties))
- allCharacteristics.map((characteristic) => {
- const cKey = characteristic.constructor.name
+ // Configure custom characteristic properties
+ for (const key in characteristicProperties) {
+ if (!Object.hasOwn(characteristicProperties, key)) continue
- supported.push(cKey)
-
- characteristic.on('get', node.onCharacteristicGet)
- characteristic.on('set', node.onCharacteristicSet)
- characteristic.on('change', node.onCharacteristicChange)
-
- //TODO: Remove when persist table is here
- //Allow for negative temperatures
- if (characteristic.displayName === 'Current Temperature') {
- characteristic.props.minValue = -100
- }
- })
+ const characteristic = service.getCharacteristic(
+ // @ts-expect-error
+ Characteristic[key]
+ )
- // Removing accidental duplicate values
- return [...new Set(supported)]
+ if (characteristic && characteristicProperties[key]) {
+ log.debug(`Found Characteristic Properties for ${key}`)
+ characteristic.setProps(characteristicProperties[key])
+ }
+ }
}
- return {
- load: load,
- subscribeAndGetSupported: subscribeAndGetSupported,
- }
+ return characteristicProperties
+ }
+
+ const subscribeAndGetSupported = (service: Service) => {
+ const supported: string[] = []
+
+ const allCharacteristics = service.characteristics.concat(
+ service.optionalCharacteristics
+ )
+
+ // Listen to characteristic events and store the listener functions
+ // to be able to remove them later
+ node.onCharacteristicGet = ServiceUtils.onCharacteristicGet
+ node.onCharacteristicSet = ServiceUtils.onCharacteristicSet(
+ service.characteristics
+ )
+ node.onCharacteristicChange = ServiceUtils.onCharacteristicChange(
+ service.characteristics
+ )
+
+ allCharacteristics.forEach((characteristic) => {
+ const cKey = characteristic.constructor.name
+
+ supported.push(cKey)
+
+ characteristic.on('get', node.onCharacteristicGet)
+ characteristic.on('set', node.onCharacteristicSet)
+ characteristic.on('change', node.onCharacteristicChange)
+
+ //TODO: Remove when persist table is here
+ //Allow for negative temperatures
+ if (characteristic.displayName === 'Current Temperature') {
+ characteristic.props.minValue = -100
+ }
+ })
+
+ // Removing accidental duplicate values
+ return [...new Set(supported)]
+ }
+
+ return {
+ load: load,
+ subscribeAndGetSupported: subscribeAndGetSupported
+ }
}
diff --git a/src/lib/utils/CharacteristicUtils2.ts b/src/lib/utils/CharacteristicUtils2.ts
index f79737e5..43be4c36 100644
--- a/src/lib/utils/CharacteristicUtils2.ts
+++ b/src/lib/utils/CharacteristicUtils2.ts
@@ -1,103 +1,100 @@
+import {
+ Characteristic,
+ type CharacteristicProps,
+ type Service
+} from '@homebridge/hap-nodejs'
import { logger } from '@nrchkb/logger'
-import { Characteristic, CharacteristicProps, Service } from 'hap-nodejs'
-
-import HAPService2ConfigType from '../types/HAPService2ConfigType'
-import HAPService2NodeType from '../types/HAPService2NodeType'
-
-module.exports = function (node: HAPService2NodeType) {
- const log = logger('NRCHKB', 'CharacteristicUtils', node.config.name, node)
- const ServiceUtils = require('./ServiceUtils2')(node)
-
- const load = function (
- service: Service,
- config: HAPService2ConfigType
- ): { [key: string]: CharacteristicProps } {
- let characteristicProperties: {
- [key: string]: CharacteristicProps
- } = {}
-
- if (
- config.characteristicProperties &&
- config.characteristicProperties.length > 0
- ) {
- characteristicProperties = JSON.parse(
- config.characteristicProperties.replace(
- /\${(.*?)}/g,
- (_, envName) =>
- node.RED.util.evaluateNodeProperty(
- envName,
- 'env',
- node,
- {}
- )
- )
- )
-
- log.trace('Evaluating value:')
- log.trace(config.characteristicProperties)
- log.trace('Evaluated as:')
- log.trace(JSON.stringify(characteristicProperties))
-
- // Configure custom characteristic properties
- for (const key in characteristicProperties) {
- if (!characteristicProperties.hasOwnProperty(key)) continue
-
- const characteristic = service.getCharacteristic(
- // @ts-ignore
- Characteristic[key]
- )
-
- if (characteristic && characteristicProperties[key]) {
- log.debug(`Found Characteristic Properties for ${key}`)
- characteristic.setProps(characteristicProperties[key])
- }
- }
- }
-
- return characteristicProperties
- }
-
- const subscribeAndGetSupported = function (service: Service) {
- const supported: string[] = []
-
- const allCharacteristics = service.characteristics.concat(
- service.optionalCharacteristics
- )
- // Listen to characteristic events and store the listener functions
- // to be able to remove them later
- node.onCharacteristicGet = ServiceUtils.onCharacteristicGet(
- service.characteristics
+import type HAPService2ConfigType from '../types/HAPService2ConfigType'
+import type HAPService2NodeType from '../types/HAPService2NodeType'
+
+module.exports = (node: HAPService2NodeType) => {
+ const log = logger('NRCHKB', 'CharacteristicUtils', node.config.name, node)
+ const ServiceUtils = require('./ServiceUtils2')(node)
+
+ const load = (
+ service: Service,
+ config: HAPService2ConfigType
+ ): { [key: string]: CharacteristicProps } => {
+ let characteristicProperties: {
+ [key: string]: CharacteristicProps
+ } = {}
+
+ if (
+ config.characteristicProperties &&
+ config.characteristicProperties.length > 0
+ ) {
+ characteristicProperties = JSON.parse(
+ config.characteristicProperties.replace(/\${(.*?)}/g, (_, envName) =>
+ node.RED.util.evaluateNodeProperty(envName, 'env', node, {})
)
- node.onCharacteristicSet = ServiceUtils.onCharacteristicSet(
- service.characteristics
- )
- node.onCharacteristicChange = ServiceUtils.onCharacteristicChange(
- service.characteristics
- )
-
- allCharacteristics.map((characteristic) => {
- const cKey = characteristic.constructor.name
+ )
- supported.push(cKey)
+ log.trace('Evaluating value:')
+ log.trace(config.characteristicProperties)
+ log.trace('Evaluated as:')
+ log.trace(JSON.stringify(characteristicProperties))
- characteristic.on('get', node.onCharacteristicGet)
- characteristic.on('set', node.onCharacteristicSet)
- characteristic.on('change', node.onCharacteristicChange)
+ // Configure custom characteristic properties
+ for (const key in characteristicProperties) {
+ if (!Object.hasOwn(characteristicProperties, key)) continue
- //TODO: Remove when persist table is here
- //Allow for negative temperatures
- if (characteristic.displayName === 'Current Temperature') {
- characteristic.props.minValue = -100
- }
- })
+ const characteristic = service.getCharacteristic(
+ // @ts-expect-error
+ Characteristic[key]
+ )
- // Removing accidental duplicate values
- return [...new Set(supported)]
+ if (characteristic && characteristicProperties[key]) {
+ log.debug(`Found Characteristic Properties for ${key}`)
+ characteristic.setProps(characteristicProperties[key])
+ }
+ }
}
- return {
- load: load,
- subscribeAndGetSupported: subscribeAndGetSupported,
- }
+ return characteristicProperties
+ }
+
+ const subscribeAndGetSupported = (service: Service) => {
+ const supported: string[] = []
+
+ const allCharacteristics = service.characteristics.concat(
+ service.optionalCharacteristics
+ )
+
+ // Listen to characteristic events and store the listener functions
+ // to be able to remove them later
+ node.onCharacteristicGet = ServiceUtils.onCharacteristicGet(
+ service.characteristics
+ )
+ node.onCharacteristicSet = ServiceUtils.onCharacteristicSet(
+ service.characteristics
+ )
+ node.onCharacteristicChange = ServiceUtils.onCharacteristicChange(
+ service.characteristics
+ )
+
+ allCharacteristics.forEach((characteristic) => {
+ const cKey = characteristic.constructor.name
+
+ supported.push(cKey)
+
+ characteristic.on('get', node.onCharacteristicGet)
+ characteristic.on('set', node.onCharacteristicSet)
+ characteristic.on('change', node.onCharacteristicChange)
+
+ //TODO: Remove when persist table is here
+ //Allow for negative temperatures
+ if (characteristic.displayName === 'Current Temperature') {
+ characteristic.props.minValue = -100
+ }
+ })
+
+ // Removing accidental duplicate values
+ return [...new Set(supported)]
+ }
+
+ return {
+ load: load,
+ subscribeAndGetSupported: subscribeAndGetSupported
+ }
}
diff --git a/src/lib/utils/MdnsUtils.ts b/src/lib/utils/MdnsUtils.ts
deleted file mode 100644
index e43a1ec4..00000000
--- a/src/lib/utils/MdnsUtils.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-import * as net from 'net'
-import * as os from 'os'
-
-const MdnsUtils = () => {
- let availableInterfaces: string[]
-
- const checkIp = function (value: string) {
- return value.length > 0 && net.isIP(value)
- }
-
- const checkInterface = function (value: string) {
- if (value.length < 1) {
- return false
- }
-
- if (!availableInterfaces) {
- availableInterfaces = []
-
- const networkInterfaces = os.networkInterfaces()
-
- Object.keys(networkInterfaces).forEach((key) =>
- networkInterfaces[key]?.forEach((networkInterface) =>
- availableInterfaces.push(networkInterface.address)
- )
- )
- }
-
- return availableInterfaces.indexOf(value) > -1
- }
-
- const checkMulticast = function (value: any) {
- return checkBoolean(value)
- }
-
- const checkPort = function (value: string) {
- return value.length > 0 && checkNumber(value)
- }
-
- const checkLoopback = function (value: any) {
- return checkBoolean(value)
- }
-
- const checkReuseAddr = function (value: any) {
- return checkBoolean(value)
- }
-
- const checkTtl = function (value: string) {
- if (value.length > 0 && checkNumber(value)) {
- const ttlInt = parseInt(value)
- return ttlInt >= 0 && ttlInt <= 255
- } else return false
- }
-
- const checkBoolean = function (value: any) {
- return typeof value === 'boolean'
- }
-
- const checkNumber = function (value: any) {
- return !isNaN(value)
- }
-
- return {
- checkInterface,
- checkIp,
- checkMulticast,
- checkPort,
- checkLoopback,
- checkReuseAddr,
- checkTtl,
- }
-}
-
-module.exports = MdnsUtils
diff --git a/src/lib/utils/NodeStatusUtils.ts b/src/lib/utils/NodeStatusUtils.ts
index 44d77ce8..bb8c3e0d 100644
--- a/src/lib/utils/NodeStatusUtils.ts
+++ b/src/lib/utils/NodeStatusUtils.ts
@@ -1,6 +1,6 @@
-import { NodeStatus } from '@node-red/registry'
+import type { NodeStatus } from '@node-red/registry'
-import NodeType from '../types/NodeType'
+import type NodeType from '../types/NodeType'
/**
* NO_RESPONSE for NO_RESPONSE
@@ -10,7 +10,7 @@ type StatusType = 'NO_RESPONSE' | 'MSG'
const DEFAULT_STATUS_TYPE: StatusType = 'MSG'
type NodeStatusWithType = NodeStatus & {
- type?: StatusType
+ type?: StatusType
}
type Status = string | NodeStatusWithType
@@ -18,67 +18,67 @@ type Status = string | NodeStatusWithType
* Utils for setting and clearing status of a node in Node-RED flow Editor
*/
export class NodeStatusUtils {
- protected lastStatusId?: number
- protected lastStatusType?: StatusType
+ protected lastStatusId?: number
+ protected lastStatusType?: StatusType
- constructor(private node: Pick) {}
+ constructor(private node: Pick) {}
- /**
- * Set the status
- * @param status - status to be displayed
- * @param timeout - if provided will clear the status after the timeout
- */
- setStatus(status: Status, timeout?: number): number {
- this.node.status(status)
+ /**
+ * Set the status
+ * @param status - status to be displayed
+ * @param timeout - if provided will clear the status after the timeout
+ */
+ setStatus(status: Status, timeout?: number): number {
+ this.node.status(status)
- const newStatusId = new Date().getTime()
- this.lastStatusId = newStatusId
+ const newStatusId = Date.now()
+ this.lastStatusId = newStatusId
- if (typeof status !== 'string') {
- this.lastStatusType = status.type ?? DEFAULT_STATUS_TYPE
- } else {
- this.lastStatusType = DEFAULT_STATUS_TYPE
- }
-
- if (timeout) {
- this.clearStatus(newStatusId, timeout)
- }
+ if (typeof status !== 'string') {
+ this.lastStatusType = status.type ?? DEFAULT_STATUS_TYPE
+ } else {
+ this.lastStatusType = DEFAULT_STATUS_TYPE
+ }
- return newStatusId
+ if (timeout) {
+ this.clearStatus(newStatusId, timeout)
}
- /**
- * Clear the status by type, only if last status type is the same as the type provided
- * @param type - type of status to be cleared
- */
- clearStatusByType(type: StatusType): void {
- if (this.lastStatusType === type) {
- this.clearStatus()
- }
+ return newStatusId
+ }
+
+ /**
+ * Clear the status by type, only if last status type is the same as the type provided
+ * @param type - type of status to be cleared
+ */
+ clearStatusByType(type: StatusType): void {
+ if (this.lastStatusType === type) {
+ this.clearStatus()
}
+ }
- /**
- * Clear the status
- * @param statusId - if provided will clear the status only if the statusId is the same as the last statusId
- * @param timeout - if provided will clear the status after the timeout
- */
- clearStatus(statusId?: number, timeout?: number): void {
- if (statusId !== undefined) {
- if (statusId === this.lastStatusId) {
- if (timeout) {
- setTimeout(
- function (nodeStatusUtil: NodeStatusUtils) {
- nodeStatusUtil.clearStatus(statusId)
- },
- timeout,
- this
- )
- } else {
- this.setStatus('')
- }
- }
+ /**
+ * Clear the status
+ * @param statusId - if provided will clear the status only if the statusId is the same as the last statusId
+ * @param timeout - if provided will clear the status after the timeout
+ */
+ clearStatus(statusId?: number, timeout?: number): void {
+ if (statusId !== undefined) {
+ if (statusId === this.lastStatusId) {
+ if (timeout) {
+ setTimeout(
+ (nodeStatusUtil: NodeStatusUtils) => {
+ nodeStatusUtil.clearStatus(statusId)
+ },
+ timeout,
+ this
+ )
} else {
- this.setStatus('')
+ this.setStatus('')
}
+ }
+ } else {
+ this.setStatus('')
}
+ }
}
diff --git a/src/lib/utils/ServiceUtils.ts b/src/lib/utils/ServiceUtils.ts
index 4b8db647..0898c159 100644
--- a/src/lib/utils/ServiceUtils.ts
+++ b/src/lib/utils/ServiceUtils.ts
@@ -1,573 +1,554 @@
import * as util from 'node:util'
-import { logger } from '@nrchkb/logger'
import {
- Accessory,
- ActiveAdaptiveLightingTransition,
- AdaptiveLightingController,
- AdaptiveLightingControllerMode,
- AdaptiveLightingOptions,
- Characteristic,
- CharacteristicChange,
- CharacteristicGetCallback,
- CharacteristicSetCallback,
- CharacteristicValue,
- HAPStatus,
- HapStatusError,
- Service,
-} from 'hap-nodejs'
-import { HAPConnection } from 'hap-nodejs/dist/lib/util/eventedhttp'
-
+ type Accessory,
+ type ActiveAdaptiveLightingTransition,
+ AdaptiveLightingController,
+ AdaptiveLightingControllerMode,
+ type AdaptiveLightingOptions,
+ type Characteristic,
+ type CharacteristicChange,
+ type CharacteristicGetCallback,
+ type CharacteristicSetCallback,
+ type CharacteristicValue,
+ HAPStatus,
+ HapStatusError,
+ type Service
+} from '@homebridge/hap-nodejs'
+import type { HAPConnection } from '@homebridge/hap-nodejs/dist/lib/util/eventedhttp'
+import { logger } from '@nrchkb/logger'
+import { configureCamera } from '../camera/CameraControl'
import NRCHKBError from '../NRCHKBError'
-import HAPServiceConfigType from '../types/HAPServiceConfigType'
-import HAPServiceNodeType from '../types/HAPServiceNodeType'
+import type HAPServiceConfigType from '../types/HAPServiceConfigType'
+import type HAPServiceNodeType from '../types/HAPServiceNodeType'
-module.exports = function (node: HAPServiceNodeType) {
- const log = logger('NRCHKB', 'ServiceUtils', node.config.name, node)
+module.exports = (node: HAPServiceNodeType) => {
+ const log = logger('NRCHKB', 'ServiceUtils', node.config.name, node)
- const HapNodeJS = require('hap-nodejs')
- const Service = HapNodeJS.Service
- const Characteristic = HapNodeJS.Characteristic
+ const HapNodeJS = require('@homebridge/hap-nodejs')
+ const Service = HapNodeJS.Service
+ const Characteristic = HapNodeJS.Characteristic
- const CameraSource = require('../cameraSource').Camera
+ const NO_RESPONSE_MSG = 'NO_RESPONSE'
- const NO_RESPONSE_MSG = 'NO_RESPONSE'
+ const prepareHapData = (context?: any, connection?: HAPConnection) => {
+ const hap: { [key: string]: any } = {}
- const prepareHapData = (context?: any, connection?: HAPConnection) => {
- const hap: { [key: string]: any } = {}
+ if (connection) {
+ hap.session = {
+ sessionID: connection.sessionID,
+ username: connection.username,
+ remoteAddress: connection.remoteAddress,
+ localAddress: connection.localAddress,
+ httpPort: connection.remotePort
+ }
- if (connection) {
- hap.session = {
- sessionID: connection.sessionID,
- username: connection.username,
- remoteAddress: connection.remoteAddress,
- localAddress: connection.localAddress,
- httpPort: connection.remotePort,
- }
+ hap.context = {}
+ }
- hap.context = {}
- }
+ if (context) {
+ hap.context = context
+ }
- if (context) {
- hap.context = context
- }
+ return hap
+ }
+
+ const onCharacteristicGet = function (
+ this: Characteristic,
+ callback: CharacteristicGetCallback,
+ context: any,
+ connection?: HAPConnection
+ ) {
+ log.debug(
+ `onCharacteristicGet with status: ${this.statusCode}, value: ${
+ this.value
+ }, reachability is ${
+ (node.parentNode ?? node).reachable
+ } with context ${util.inspect(
+ context
+ )} on connection ${connection?.sessionID}`
+ )
+
+ if (callback) {
+ try {
+ callback(
+ (node.parentNode ?? node).reachable
+ ? null
+ : new HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE),
+ this.value
+ )
+ } catch (_) {}
+ }
+ }
+
+ const onValueChange = function (
+ this: Characteristic,
+ allCharacteristics: Characteristic[],
+ outputNumber: number,
+ { oldValue, newValue, context }: any,
+ connection?: HAPConnection
+ ) {
+ const topic = node.config.topic ? node.config.topic : node.topic_in
+ const msg: {
+ payload: { [key: string]: any }
+ hap: any
+ name?: string
+ topic: string
+ } = { payload: {}, hap: {}, name: node.name, topic: topic }
+ const key = this.constructor.name
+
+ msg.payload[key] = newValue
+
+ msg.hap = prepareHapData(context, connection)
+ msg.hap.allChars = allCharacteristics.reduce<{ [key: string]: any }>(
+ (allChars, singleChar) => {
+ const cKey = singleChar.constructor.name
+ allChars[cKey] = singleChar.value
+ return allChars
+ },
+ {}
+ )
+
+ if (oldValue !== undefined) {
+ msg.hap.oldValue = oldValue
+ }
+
+ msg.hap.reachable = node.reachable ?? node.parentNode?.reachable
- return hap
+ if (msg.hap.reachable === false) {
+ ;[node, ...(node.childNodes ?? [])].forEach((n) => {
+ n.nodeStatusUtils.setStatus({
+ fill: 'red',
+ shape: 'ring',
+ text: 'Not reachable',
+ type: 'NO_RESPONSE'
+ })
+ })
+ } else {
+ msg.hap.newValue = newValue
+
+ node.nodeStatusUtils.setStatus(
+ {
+ fill: 'yellow',
+ shape: 'dot',
+ text: `${key}: ${newValue}`
+ },
+ 3000
+ )
+
+ node.childNodes?.forEach((n) => {
+ n.nodeStatusUtils.clearStatusByType('NO_RESPONSE')
+ })
+ node.parentNode?.nodeStatusUtils.clearStatusByType('NO_RESPONSE')
}
- const onCharacteristicGet = function (
- this: Characteristic,
- callback: CharacteristicGetCallback,
- context: any,
- connection?: HAPConnection
+ log.debug(`${node.name} received ${key} : ${newValue}`)
+
+ if (connection || context || node.hostNode.config.allowMessagePassthrough) {
+ if (outputNumber === 0) {
+ node.send(msg)
+ } else if (outputNumber === 1) {
+ node.send([null, msg])
+ }
+ }
+ }
+
+ const onCharacteristicSet = (allCharacteristics: Characteristic[]) =>
+ function (
+ this: Characteristic,
+ newValue: CharacteristicValue,
+ callback: CharacteristicSetCallback,
+ context: any,
+ connection?: HAPConnection
) {
- log.debug(
- `onCharacteristicGet with status: ${this.statusCode}, value: ${
- this.value
- }, reachability is ${
- (node.parentNode ?? node).reachable
- } with context ${util.inspect(
- context
+ log.debug(
+ `onCharacteristicSet with status: ${this.statusCode}, value: ${
+ this.value
+ }, reachability is ${(node.parentNode ?? node).reachable}
+ with context ${util.inspect(
+ context
)} on connection ${connection?.sessionID}`
- )
+ )
+ try {
if (callback) {
- try {
- callback(
- (node.parentNode ?? node).reachable
- ? null
- : new HapStatusError(
- HAPStatus.SERVICE_COMMUNICATION_FAILURE
- ),
- this.value
- )
- } catch (_) {}
+ callback(
+ (node.parentNode ?? node).reachable
+ ? null
+ : new HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE)
+ )
}
+ } catch (_) {}
+
+ onValueChange.call(
+ this,
+ allCharacteristics,
+ 1,
+ {
+ newValue,
+ context
+ },
+ connection
+ )
}
- const onValueChange = function (
- this: Characteristic,
- allCharacteristics: Characteristic[],
- outputNumber: number,
- { oldValue, newValue, context }: any,
- connection?: HAPConnection
- ) {
- const topic = node.config.topic ? node.config.topic : node.topic_in
- const msg: {
- payload: { [key: string]: any }
- hap: any
- name?: string
- topic: string
- } = { payload: {}, hap: {}, name: node.name, topic: topic }
- const key = this.constructor.name
-
- msg.payload[key] = newValue
-
- msg.hap = prepareHapData(context, connection)
- msg.hap.allChars = allCharacteristics.reduce<{ [key: string]: any }>(
- (allChars, singleChar) => {
- const cKey = singleChar.constructor.name
- allChars[cKey] = singleChar.value
- return allChars
- },
- {}
+ const onCharacteristicChange = (allCharacteristics: Characteristic[]) =>
+ function (this: Characteristic, change: CharacteristicChange) {
+ const { oldValue, newValue, context, originator, reason } = change
+
+ log.debug(
+ `onCharacteristicChange with reason: ${reason}, oldValue: ${oldValue}, newValue: ${newValue}, reachability is ${
+ (node.parentNode ?? node).reachable
+ }
+ with context ${util.inspect(
+ context
+ )} on connection ${originator?.sessionID}`
+ )
+
+ if (oldValue !== newValue) {
+ onValueChange.call(
+ this,
+ allCharacteristics,
+ 0,
+ {
+ oldValue,
+ newValue,
+ context
+ },
+ originator
)
+ }
+ }
- if (oldValue !== undefined) {
- msg.hap.oldValue = oldValue
- }
+ const onInput = (msg: Record) => {
+ if (msg.payload) {
+ // payload must be an object
+ const type = typeof msg.payload
+
+ if (type !== 'object') {
+ log.error(`Invalid payload type: ${type}`)
+ return
+ }
+ } else {
+ log.error('Invalid message (payload missing)')
+ return
+ }
- msg.hap.reachable = node.reachable ?? node.parentNode?.reachable
-
- if (msg.hap.reachable === false) {
- ;[node, ...(node.childNodes ?? [])].forEach((n) =>
- n.nodeStatusUtils.setStatus({
- fill: 'red',
- shape: 'ring',
- text: 'Not reachable',
- type: 'NO_RESPONSE',
- })
- )
- } else {
- msg.hap.newValue = newValue
-
- node.nodeStatusUtils.setStatus(
- {
- fill: 'yellow',
- shape: 'dot',
- text: key + ': ' + newValue,
- },
- 3000
- )
-
- node.childNodes?.forEach((n) =>
- n.nodeStatusUtils.clearStatusByType('NO_RESPONSE')
- )
- node.parentNode?.nodeStatusUtils.clearStatusByType('NO_RESPONSE')
- }
+ const topic = node.config.topic ?? node.name
+ if (node.config.filter && msg.topic !== topic) {
+ log.debug(
+ "msg.topic doesn't match configured value and filter is enabled. Dropping message."
+ )
+ return
+ }
+
+ let context: any = null
+ if (msg.payload.Context) {
+ context = msg.payload.Context
+ delete msg.payload.Context
+ }
- log.debug(`${node.name} received ${key} : ${newValue}`)
+ node.topic_in = msg.topic ?? ''
+ Object.keys(msg.payload).forEach((key: string) => {
+ if (node.supported.indexOf(key) < 0) {
if (
- connection ||
- context ||
- node.hostNode.config.allowMessagePassthrough
+ key === 'AdaptiveLightingController' &&
+ node.adaptiveLightingController
) {
- if (outputNumber === 0) {
- node.send(msg)
- } else if (outputNumber === 1) {
- node.send([null, msg])
- }
- }
- }
+ const value = msg.payload?.[key]
+ const event = value?.event
- // eslint-disable-next-line no-unused-vars
- const onCharacteristicSet = (allCharacteristics: Characteristic[]) =>
- function (
- this: Characteristic,
- newValue: CharacteristicValue,
- callback: CharacteristicSetCallback,
- context: any,
- connection?: HAPConnection
- ) {
- log.debug(
- `onCharacteristicSet with status: ${this.statusCode}, value: ${
- this.value
- }, reachability is ${(node.parentNode ?? node).reachable}
- with context ${util.inspect(
- context
- )} on connection ${connection?.sessionID}`
- )
-
- try {
- if (callback) {
- callback(
- (node.parentNode ?? node).reachable
- ? null
- : new HapStatusError(
- HAPStatus.SERVICE_COMMUNICATION_FAILURE
- )
- )
- }
- } catch (_) {}
-
- onValueChange.call(
- this,
- allCharacteristics,
- 1,
- {
- newValue,
- context,
- },
- connection
- )
+ if (event === 'disable') {
+ node.adaptiveLightingController?.disableAdaptiveLighting()
+ }
+ } else {
+ log.error(
+ `Instead of '${key}' try one of these characteristics: '${node.supported.join(
+ "', '"
+ )}'`
+ )
}
+ } else {
+ const value = msg.payload?.[key]
- const onCharacteristicChange = (allCharacteristics: Characteristic[]) =>
- function (this: Characteristic, change: CharacteristicChange) {
- const { oldValue, newValue, context, originator, reason } = change
-
- log.debug(
- `onCharacteristicChange with reason: ${reason}, oldValue: ${oldValue}, newValue: ${newValue}, reachability is ${
- (node.parentNode ?? node).reachable
- }
- with context ${util.inspect(
- context
- )} on connection ${originator?.sessionID}`
- )
-
- if (oldValue != newValue) {
- onValueChange.call(
- this,
- allCharacteristics,
- 0,
- {
- oldValue,
- newValue,
- context,
- },
- originator
- )
- }
- }
+ const parentNode = node.parentNode ?? node
+ parentNode.reachable = value !== NO_RESPONSE_MSG
- const onInput = function (msg: Record) {
- if (msg.payload) {
- // payload must be an object
- const type = typeof msg.payload
+ const characteristic = node.service.getCharacteristic(
+ Characteristic[key]
+ )
- if (type !== 'object') {
- log.error(`Invalid payload type: ${type}`)
- return
- }
+ if (context !== null) {
+ characteristic.setValue(value, context)
} else {
- log.error('Invalid message (payload missing)')
- return
- }
-
- const topic = node.config.topic ?? node.name
- if (node.config.filter && msg.topic !== topic) {
- log.debug(
- "msg.topic doesn't match configured value and filter is enabled. Dropping message."
- )
- return
+ characteristic.setValue(value)
}
+ }
+ })
+ }
+
+ const onClose = (removed: boolean, done: () => void) => {
+ const characteristics = node.service.characteristics.concat(
+ node.service.optionalCharacteristics
+ )
+
+ characteristics.forEach((characteristic) => {
+ // cleanup all node specific listeners
+ characteristic.removeListener('get', node.onCharacteristicGet)
+ characteristic.removeListener('set', node.onCharacteristicSet)
+ characteristic.removeListener('change', node.onCharacteristicChange)
+ })
+
+ if (node.config.isParent) {
+ // remove identify listener to prevent errors with undefined values
+ node.accessory.removeListener('identify', node.onIdentify)
+ }
- let context: any = null
- if (msg.payload.Context) {
- context = msg.payload.Context
- delete msg.payload.Context
- }
+ if (removed) {
+ // This node has been deleted
+ if (node.config.isParent) {
+ // remove accessory from the bridge
+ node.hostNode.host.removeBridgedAccessories([node.accessory])
+ node.accessory.destroy()
+ } else {
+ // only remove the service if it is not a parent
+ node.accessory.removeService(node.service)
+ node.parentService.removeLinkedService(node.service)
+ }
+ }
- node.topic_in = msg.topic ?? ''
-
- Object.keys(msg.payload).map((key: string) => {
- if (node.supported.indexOf(key) < 0) {
- if (
- key === 'AdaptiveLightingController' &&
- node.adaptiveLightingController
- ) {
- const value = msg.payload?.[key]
- const event = value?.event
-
- if (event === 'disable') {
- node.adaptiveLightingController?.disableAdaptiveLighting()
- }
- } else {
- log.error(
- `Instead of '${key}' try one of these characteristics: '${node.supported.join(
- "', '"
- )}'`
- )
- }
- } else {
- const value = msg.payload?.[key]
-
- const parentNode = node.parentNode ?? node
- parentNode.reachable = value !== NO_RESPONSE_MSG
-
- const characteristic = node.service.getCharacteristic(
- Characteristic[key]
- )
-
- if (context !== null) {
- characteristic.setValue(value, undefined, context)
- } else {
- characteristic.setValue(value)
- }
- }
- })
+ done()
+ }
+
+ const getOrCreate = (
+ accessory: Accessory,
+ serviceInformation: {
+ name: string
+ UUID: string
+ serviceName: string
+ config: HAPServiceConfigType
+ },
+ parentService: Service
+ ) => {
+ const newService = new Service[serviceInformation.serviceName](
+ serviceInformation.name,
+ serviceInformation.UUID
+ )
+ log.debug(`Looking for service with UUID ${serviceInformation.UUID} ...`)
+
+ // search for a service with the same subtype
+ let service: Service | undefined = accessory.services.find((service) => {
+ return newService.subtype === service.subtype
+ })
+
+ if (service && newService.UUID !== service.UUID) {
+ // if the UUID and therefore the type changed, the whole service
+ // will be replaced
+ log.debug('... service type changed! Removing the old service.')
+ accessory.removeService(service)
+ service = undefined
}
- const onClose = function (removed: boolean, done: () => void) {
- const characteristics = node.service.characteristics.concat(
- node.service.optionalCharacteristics
- )
+ if (!service) {
+ // if no matching service was found or the type changed, then a new
+ // service will be added
+ log.debug(
+ `... didn't find it. Adding new ${serviceInformation.serviceName} service.`
+ )
+
+ if (serviceInformation.serviceName === 'CameraControl') {
+ configureCameraSource(accessory, newService, serviceInformation.config)
+ service = newService
+ } else {
+ service = accessory.addService(newService)
+ }
+ } else {
+ // if a service with the same UUID and subtype was found, it will
+ // be updated and used
+ log.debug('... found it! Updating it.')
+ service
+ .getCharacteristic(Characteristic.Name)
+ .setValue(serviceInformation.name)
+ }
- characteristics.forEach(function (characteristic) {
- // cleanup all node specific listeners
- characteristic.removeListener('get', node.onCharacteristicGet)
- characteristic.removeListener('set', node.onCharacteristicSet)
- characteristic.removeListener('change', node.onCharacteristicChange)
- })
+ if (parentService) {
+ if (serviceInformation.serviceName === 'CameraControl') {
+ //We don't add or link it since configureCameraSource do this already.
+ log.debug('... and adding service to accessory.')
+ } else if (service) {
+ log.debug('... and linking service to parent.')
+ parentService.addLinkedService(service)
+ }
+ }
- if (node.config.isParent) {
- // remove identify listener to prevent errors with undefined values
- node.accessory.removeListener('identify', node.onIdentify)
- }
+ return service
+ }
- if (removed) {
- // This node has been deleted
- if (node.config.isParent) {
- // remove accessory from bridge
- node.hostNode.host.removeBridgedAccessories([node.accessory])
- node.accessory.destroy()
- } else {
- // only remove the service if it is not a parent
- node.accessory.removeService(node.service)
- node.parentService.removeLinkedService(node.service)
- }
- }
+ const configureCameraSource = (
+ accessory: Accessory,
+ _service: Service,
+ config: HAPServiceConfigType
+ ) => {
+ if (config.cameraConfigSource) {
+ log.debug('Configuring Camera Source')
- done()
+ if (!config.cameraConfigVideoProcessor) {
+ log.error(
+ 'Missing configuration for CameraControl: videoProcessor cannot be empty!'
+ )
+ } else {
+ // Use of deprecated method to be replaced with new Camera API
+ // TODO: https://github.com/homebridge/HAP-NodeJS/blob/latest/src/accessories/Camera_accessory.ts
+ // accessory.configureCameraSource(
+ // new CameraSource(service, config, node)
+ // )
+ configureCamera(accessory, config)
+ }
+ } else {
+ log.error('Missing configuration for CameraControl.')
}
+ }
- const getOrCreate = function (
- accessory: Accessory,
- serviceInformation: {
- name: string
- UUID: string
- serviceName: string
- config: HAPServiceConfigType
- },
- parentService: Service
- ) {
- const newService = new Service[serviceInformation.serviceName](
- serviceInformation.name,
- serviceInformation.UUID
- )
- log.debug(
- `Looking for service with UUID ${serviceInformation.UUID} ...`
- )
+ const waitForParent = () => {
+ log.debug('Waiting for Parent Service')
- // search for a service with the same subtype
- let service: Service | undefined = accessory.services.find(
- (service) => {
- return newService.subtype === service.subtype
- }
- )
+ return new Promise((resolve) => {
+ node.nodeStatusUtils.setStatus({
+ fill: 'blue',
+ shape: 'dot',
+ text: 'Waiting for Parent Service'
+ })
- if (service && newService.UUID !== service.UUID) {
- // if the UUID and therefore the type changed, the whole service
- // will be replaced
- log.debug('... service type changed! Removing the old service.')
- accessory.removeService(service)
- service = undefined
- }
+ const checkAndWait = () => {
+ const parentNode: HAPServiceNodeType = node.RED.nodes.getNode(
+ node.config.parentService
+ ) as HAPServiceNodeType
- if (!service) {
- // if no matching service was found or the type changed, then a new
- // service will be added
- log.debug(
- `... didn't find it. Adding new ${serviceInformation.serviceName} service.`
- )
-
- if (serviceInformation.serviceName === 'CameraControl') {
- configureCameraSource(
- accessory,
- newService,
- serviceInformation.config
- )
- service = newService
- } else {
- service = accessory.addService(newService)
- }
+ if (parentNode?.configured) {
+ resolve(parentNode)
} else {
- // if a service with the same UUID and subtype was found it will
- // be updated and used
- log.debug('... found it! Updating it.')
- service
- .getCharacteristic(Characteristic.Name)
- .setValue(serviceInformation.name)
+ setTimeout(checkAndWait, 1000)
}
-
- if (parentService) {
- if (serviceInformation.serviceName === 'CameraControl') {
- //We don't add or link it since configureCameraSource do this already.
- log.debug('... and adding service to accessory.')
- } else if (service) {
- log.debug('... and linking service to parent.')
- parentService.addLinkedService(service)
- }
- }
-
- return service
+ }
+ checkAndWait()
+ }).catch((error) => {
+ log.error(`Waiting for Parent Service failed due to: ${error}`)
+ throw new NRCHKBError(error)
+ })
+ }
+
+ const handleWaitForSetup = (
+ config: HAPServiceConfigType,
+ msg: Record,
+ resolve: (newConfig: HAPServiceConfigType) => void
+ ) => {
+ if (node.setupDone) {
+ return
}
- const configureCameraSource = function (
- accessory: Accessory,
- service: Service,
- config: HAPServiceConfigType
+ if (
+ Object.hasOwn(msg, 'payload') &&
+ Object.hasOwn(msg.payload, 'nrchkb') &&
+ Object.hasOwn(msg.payload.nrchkb, 'setup')
) {
- if (config.cameraConfigSource) {
- log.debug('Configuring Camera Source')
-
- if (!config.cameraConfigVideoProcessor) {
- log.error(
- 'Missing configuration for CameraControl: videoProcessor cannot be empty!'
- )
- } else {
- // Use of deprecated method to be replaced with new Camera API
- accessory.configureCameraSource(
- new CameraSource(service, config, node)
- )
- }
- } else {
- log.error('Missing configuration for CameraControl.')
- }
- }
+ node.setupDone = true
- const waitForParent = () => {
- log.debug('Waiting for Parent Service')
-
- return new Promise((resolve) => {
- node.nodeStatusUtils.setStatus({
- fill: 'blue',
- shape: 'dot',
- text: 'Waiting for Parent Service',
- })
-
- const checkAndWait = () => {
- const parentNode: HAPServiceNodeType = node.RED.nodes.getNode(
- node.config.parentService
- ) as HAPServiceNodeType
-
- if (parentNode && parentNode.configured) {
- resolve(parentNode)
- } else {
- setTimeout(checkAndWait, 1000)
- }
- }
- checkAndWait()
- }).catch((error) => {
- log.error(`Waiting for Parent Service failed due to: ${error}`)
- throw new NRCHKBError(error)
- })
- }
+ const newConfig = {
+ ...config,
+ ...msg.payload.nrchkb.setup
+ }
- const handleWaitForSetup = (
- config: HAPServiceConfigType,
- msg: Record,
- resolve: (newConfig: HAPServiceConfigType) => void
- ) => {
- if (node.setupDone) {
- return
- }
+ node.removeListener('input', node.handleWaitForSetup)
- if (
- msg.hasOwnProperty('payload') &&
- msg.payload.hasOwnProperty('nrchkb') &&
- msg.payload.nrchkb.hasOwnProperty('setup')
- ) {
- node.setupDone = true
+ resolve(newConfig)
+ } else {
+ log.error(
+ 'Invalid message (required {"payload":{"nrchkb":{"setup":{}}}})'
+ )
+ }
+ }
- const newConfig = {
- ...config,
- ...msg.payload.nrchkb.setup,
- }
+ const configureAdaptiveLightning = () => {
+ if (
+ node.service.UUID === Service.Lightbulb.UUID &&
+ node.config.adaptiveLightingOptionsEnable
+ ) {
+ try {
+ node.service.getCharacteristic(Characteristic.Brightness)
+ node.service.getCharacteristic(Characteristic.ColorTemperature)
+
+ const options: AdaptiveLightingOptions = {
+ controllerMode: node.config.adaptiveLightingOptionsMode
+ ? +node.config.adaptiveLightingOptionsMode
+ : AdaptiveLightingControllerMode.AUTOMATIC,
+ customTemperatureAdjustment: node.config
+ .adaptiveLightingOptionsCustomTemperatureAdjustment
+ ? +node.config.adaptiveLightingOptionsCustomTemperatureAdjustment
+ : undefined
+ }
- node.removeListener('input', node.handleWaitForSetup)
+ log.trace(`Configuring Adaptive Lighting with options:`)
+ log.trace(JSON.stringify(options))
- resolve(newConfig)
- } else {
- log.error(
- 'Invalid message (required {"payload":{"nrchkb":{"setup":{}}}})'
- )
- }
- }
+ const adaptiveLightingController = new AdaptiveLightingController(
+ node.service,
+ options
+ )
- const configureAdaptiveLightning = () => {
- if (
- node.service.UUID === Service.Lightbulb.UUID &&
- node.config.adaptiveLightingOptionsEnable
- ) {
- try {
- node.service.getCharacteristic(Characteristic.Brightness)
- node.service.getCharacteristic(Characteristic.ColorTemperature)
-
- const options: AdaptiveLightingOptions = {
- controllerMode: node.config.adaptiveLightingOptionsMode
- ? +node.config.adaptiveLightingOptionsMode
- : AdaptiveLightingControllerMode.AUTOMATIC,
- customTemperatureAdjustment: node.config
- .adaptiveLightingOptionsCustomTemperatureAdjustment
- ? +node.config
- .adaptiveLightingOptionsCustomTemperatureAdjustment
- : undefined,
- }
-
- log.trace(
- `Configuring Adaptive Lighting with options: ${options}`
- )
-
- const adaptiveLightingController =
- new AdaptiveLightingController(node.service, options)
-
- adaptiveLightingController.on('update', () => {
- const activeAdaptiveLightingTransition: Partial =
- {
- transitionStartMillis:
- adaptiveLightingController.getAdaptiveLightingStartTimeOfTransition(),
- timeMillisOffset:
- adaptiveLightingController.getAdaptiveLightingTimeOffset(),
- transitionCurve:
- adaptiveLightingController.getAdaptiveLightingTransitionCurve(),
- brightnessAdjustmentRange:
- adaptiveLightingController.getAdaptiveLightingBrightnessMultiplierRange(),
- updateInterval:
- adaptiveLightingController.getAdaptiveLightingUpdateInterval(),
- notifyIntervalThreshold:
- adaptiveLightingController.getAdaptiveLightingNotifyIntervalThreshold(),
- }
- node.send({
- payload: {
- AdaptiveLightingController: {
- event: 'update',
- data: activeAdaptiveLightingTransition,
- },
- },
- })
- })
- adaptiveLightingController.on('disable', () => {
- node.send({
- payload: {
- AdaptiveLightingController: {
- event: 'disable',
- },
- },
- })
- })
-
- node.accessory.configureController(adaptiveLightingController)
-
- node.adaptiveLightingController = adaptiveLightingController
- } catch (error) {
- log.error(
- `Failed to configure Adaptive Lightning due to ${error}`
- )
+ adaptiveLightingController.on('update', () => {
+ const activeAdaptiveLightingTransition: Partial =
+ {
+ transitionStartMillis:
+ adaptiveLightingController.getAdaptiveLightingStartTimeOfTransition(),
+ timeMillisOffset:
+ adaptiveLightingController.getAdaptiveLightingTimeOffset(),
+ transitionCurve:
+ adaptiveLightingController.getAdaptiveLightingTransitionCurve(),
+ brightnessAdjustmentRange:
+ adaptiveLightingController.getAdaptiveLightingBrightnessMultiplierRange(),
+ updateInterval:
+ adaptiveLightingController.getAdaptiveLightingUpdateInterval(),
+ notifyIntervalThreshold:
+ adaptiveLightingController.getAdaptiveLightingNotifyIntervalThreshold()
}
- }
- }
+ node.send({
+ payload: {
+ AdaptiveLightingController: {
+ event: 'update',
+ data: activeAdaptiveLightingTransition
+ }
+ }
+ })
+ })
+ adaptiveLightingController.on('disable', () => {
+ node.send({
+ payload: {
+ AdaptiveLightingController: {
+ event: 'disable'
+ }
+ }
+ })
+ })
+
+ node.accessory.configureController(adaptiveLightingController)
- return {
- getOrCreate,
- onCharacteristicGet,
- onCharacteristicSet,
- onCharacteristicChange,
- onInput,
- onClose,
- waitForParent,
- handleWaitForSetup,
- configureAdaptiveLightning,
+ node.adaptiveLightingController = adaptiveLightingController
+ } catch (error) {
+ log.error(`Failed to configure Adaptive Lightning due to ${error}`)
+ }
}
+ }
+
+ return {
+ getOrCreate,
+ onCharacteristicGet,
+ onCharacteristicSet,
+ onCharacteristicChange,
+ onInput,
+ onClose,
+ waitForParent,
+ handleWaitForSetup,
+ configureAdaptiveLightning
+ }
}
diff --git a/src/lib/utils/ServiceUtils2.ts b/src/lib/utils/ServiceUtils2.ts
index f60dd158..d53186ca 100644
--- a/src/lib/utils/ServiceUtils2.ts
+++ b/src/lib/utils/ServiceUtils2.ts
@@ -1,548 +1,526 @@
-import { logger } from '@nrchkb/logger'
-import {
- Accessory,
- Characteristic,
- CharacteristicChange,
- CharacteristicEventTypes,
- CharacteristicGetCallback,
- CharacteristicSetCallback,
- CharacteristicValue,
- HAPStatus,
- HapStatusError,
- Service,
-} from 'hap-nodejs'
import {
- HAPConnection,
- HAPUsername,
-} from 'hap-nodejs/dist/lib/util/eventedhttp'
-import { SessionIdentifier } from 'hap-nodejs/dist/types'
-
+ type Accessory,
+ type Characteristic,
+ type CharacteristicChange,
+ CharacteristicEventTypes,
+ type CharacteristicGetCallback,
+ type CharacteristicSetCallback,
+ type CharacteristicValue,
+ HAPStatus,
+ HapStatusError,
+ type Service
+} from '@homebridge/hap-nodejs'
+import type {
+ HAPConnection,
+ HAPUsername
+} from '@homebridge/hap-nodejs/dist/lib/util/eventedhttp'
+import type { SessionIdentifier } from '@homebridge/hap-nodejs/dist/types'
+import { logger } from '@nrchkb/logger'
+import { configureCamera } from '../camera/CameraControl'
import NRCHKBError from '../NRCHKBError'
import { Storage } from '../Storage'
-import HAPService2ConfigType from '../types/HAPService2ConfigType'
-import HAPService2NodeType from '../types/HAPService2NodeType'
+import type HAPService2ConfigType from '../types/HAPService2ConfigType'
+import type HAPService2NodeType from '../types/HAPService2NodeType'
+
+module.exports = (node: HAPService2NodeType) => {
+ const log = logger('NRCHKB', 'ServiceUtils2', node.config.name, node)
+
+ const ServiceUtilsLegacy = require('./ServiceUtils')(node)
+
+ const HapNodeJS = require('@homebridge/hap-nodejs')
+ const Service = HapNodeJS.Service
+ const Characteristic = HapNodeJS.Characteristic
+
+ const NO_RESPONSE_MSG = 'NO_RESPONSE'
+
+ type HAPServiceNodeEvent = {
+ name: CharacteristicEventTypes // Event type
+ context?: {
+ callbackID?: string // ID used to update Characteristic value with get event
+ key?: string // Characteristic key
+ reason?: string
+ } & Record // Additional event data provided by event caller
+ }
+
+ type HAPServiceMessage = {
+ payload?: { [key: string]: any }
+ hap?: {
+ oldValue?: any
+ newValue?: any
+ reachable?: boolean
+ event?: HAPServiceNodeEvent
+ session?: {
+ sessionID?: SessionIdentifier
+ username?: HAPUsername
+ remoteAddress?: string
+ localAddress?: string
+ httpPort?: number
+ }
+ allChars: { [key: string]: any }
+ }
+ name?: string
+ topic?: string
+ }
+
+ const output = function (
+ this: Characteristic,
+ allCharacteristics: Characteristic[],
+ event: CharacteristicEventTypes | HAPServiceNodeEvent,
+ { oldValue, newValue }: any,
+ connection?: HAPConnection
+ ) {
+ const eventObject = typeof event === 'object' ? event : { name: event }
+
+ log.debug(
+ `${eventObject.name} event, oldValue: ${oldValue}, newValue: ${newValue}, connection ${connection?.sessionID}`
+ )
+
+ const msg: HAPServiceMessage = {
+ name: node.name,
+ topic: node.config.topic ? node.config.topic : node.topic_in
+ }
+ msg.payload = {}
+ msg.hap = {
+ event: eventObject,
+ allChars: allCharacteristics.reduce<{ [key: string]: any }>(
+ (allChars, singleChar) => {
+ const cKey = singleChar.constructor.name
+ allChars[cKey] = singleChar.value
+ return allChars
+ },
+ {}
+ ),
+ oldValue
+ }
-module.exports = function (node: HAPService2NodeType) {
- const log = logger('NRCHKB', 'ServiceUtils2', node.config.name, node)
+ const key = this.constructor.name
- const ServiceUtilsLegacy = require('./ServiceUtils')(node)
+ msg.hap.reachable = node.reachable ?? node.parentNode?.reachable
- const HapNodeJS = require('hap-nodejs')
- const Service = HapNodeJS.Service
- const Characteristic = HapNodeJS.Characteristic
+ if (msg.hap.reachable === false) {
+ ;[node, ...(node.childNodes ?? [])].forEach((n) => {
+ n.nodeStatusUtils.setStatus({
+ fill: 'red',
+ shape: 'ring',
+ text: 'Not reachable',
+ type: 'NO_RESPONSE'
+ })
+ })
+ } else {
+ msg.hap.newValue = newValue
+
+ node.nodeStatusUtils.setStatus(
+ {
+ fill: 'yellow',
+ shape: 'dot',
+ text: `[${eventObject.name}] ${key}${
+ newValue !== undefined ? `: ${newValue}` : ''
+ }`
+ },
+ 3000
+ )
- const CameraSource = require('../cameraSource').Camera
+ node.childNodes?.forEach((n) => {
+ n.nodeStatusUtils.clearStatusByType('NO_RESPONSE')
+ })
+ node.parentNode?.nodeStatusUtils.clearStatusByType('NO_RESPONSE')
+ }
- const NO_RESPONSE_MSG = 'NO_RESPONSE'
+ msg.payload[key] = newValue
- type HAPServiceNodeEvent = {
- name: CharacteristicEventTypes // Event type
- context?: {
- callbackID?: string // ID used to update Characteristic value with get event
- key?: string // Characteristic key
- reason?: string
- } & Record // Additional event data provided by event caller
+ if (connection) {
+ msg.hap.session = {
+ sessionID: connection.sessionID,
+ username: connection.username,
+ remoteAddress: connection.remoteAddress,
+ localAddress: connection.localAddress,
+ httpPort: connection.remotePort
+ }
}
- type HAPServiceMessage = {
- payload?: { [key: string]: any }
- hap?: {
- oldValue?: any
- newValue?: any
- reachable?: boolean
- event?: HAPServiceNodeEvent
- session?: {
- sessionID?: SessionIdentifier
- username?: HAPUsername
- remoteAddress?: string
- localAddress?: string
- httpPort?: number
- }
- allChars: { [key: string]: any }
- }
- name?: string
- topic?: string
- }
+ log.debug(`${node.name} received ${eventObject.name} ${key}: ${newValue}`)
- const output = function (
- this: Characteristic,
- allCharacteristics: Characteristic[],
- event: CharacteristicEventTypes | HAPServiceNodeEvent,
- { oldValue, newValue }: any,
- connection?: HAPConnection
+ if (connection || node.hostNode.config.allowMessagePassthrough) {
+ node.send(msg)
+ }
+ }
+
+ const onCharacteristicGet = (allCharacteristics: Characteristic[]) =>
+ function (
+ this: Characteristic,
+ callback: CharacteristicGetCallback,
+ _context: any,
+ connection?: HAPConnection
) {
- const eventObject = typeof event === 'object' ? event : { name: event }
+ const oldValue = this.value
+
+ const delayedCallback = (value?: any) => {
+ const newValue = value ?? this.value
+ if (callback) {
+ try {
+ callback(
+ (node.parentNode ?? node).reachable
+ ? null
+ : new HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE),
+ newValue
+ )
+ } catch (_) {}
+ }
- log.debug(
- `${eventObject.name} event, oldValue: ${oldValue}, newValue: ${newValue}, connection ${connection?.sessionID}`
+ output.call(
+ this,
+ allCharacteristics,
+ {
+ name: CharacteristicEventTypes.GET,
+ context: { key: this.displayName }
+ },
+ { oldValue, newValue },
+ connection
)
+ }
- const msg: HAPServiceMessage = {
- name: node.name,
- topic: node.config.topic ? node.config.topic : node.topic_in,
- }
- msg.payload = {}
- msg.hap = {
- event: eventObject,
- allChars: allCharacteristics.reduce<{ [key: string]: any }>(
- (allChars, singleChar) => {
- const cKey = singleChar.constructor.name
- allChars[cKey] = singleChar.value
- return allChars
- },
- {}
- ),
- oldValue,
- }
-
- const key = this.constructor.name
+ if (node.config.useEventCallback) {
+ const callbackID = Storage.saveCallback({
+ event: CharacteristicEventTypes.GET,
+ callback: delayedCallback
+ })
- msg.hap.reachable = node.reachable ?? node.parentNode?.reachable
+ log.debug(
+ `Registered callback ${callbackID} for Characteristic ${this.displayName}`
+ )
- if (msg.hap.reachable === false) {
- ;[node, ...(node.childNodes ?? [])].forEach((n) =>
- n.nodeStatusUtils.setStatus({
- fill: 'red',
- shape: 'ring',
- text: 'Not reachable',
- type: 'NO_RESPONSE',
- })
- )
- } else {
- msg.hap.newValue = newValue
-
- node.nodeStatusUtils.setStatus(
- {
- fill: 'yellow',
- shape: 'dot',
- text: `[${eventObject.name}] ${key}${
- newValue != undefined ? `: ${newValue}` : ''
- }`,
- },
- 3000
- )
+ output.call(
+ this,
+ allCharacteristics,
+ {
+ name: CharacteristicEventTypes.GET,
+ context: { callbackID, key: this.displayName }
+ },
+ { oldValue },
+ connection
+ )
+ } else {
+ delayedCallback()
+ }
+ }
- node.childNodes?.forEach((n) =>
- n.nodeStatusUtils.clearStatusByType('NO_RESPONSE')
- )
- node.parentNode?.nodeStatusUtils.clearStatusByType('NO_RESPONSE')
+ const onCharacteristicSet = (allCharacteristics: Characteristic[]) =>
+ function (
+ this: Characteristic,
+ newValue: CharacteristicValue,
+ callback: CharacteristicSetCallback,
+ _context: any,
+ connection?: HAPConnection
+ ) {
+ try {
+ if (callback) {
+ callback(
+ (node.parentNode ?? node).reachable
+ ? null
+ : new HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE)
+ )
}
+ } catch (_) {}
+
+ output.call(
+ this,
+ allCharacteristics,
+ {
+ name: CharacteristicEventTypes.SET,
+ context: { key: this.displayName }
+ },
+ { newValue },
+ connection
+ )
+ }
- msg.payload[key] = newValue
+ const onCharacteristicChange = (allCharacteristics: Characteristic[]) =>
+ function (this: Characteristic, change: CharacteristicChange) {
+ const { oldValue, newValue, context, originator, reason } = change
+
+ if (oldValue !== newValue) {
+ output.call(
+ this,
+ allCharacteristics,
+ {
+ name: CharacteristicEventTypes.CHANGE,
+ context: { reason, key: this.displayName }
+ },
+ { oldValue, newValue, context },
+ originator
+ )
+ }
+ }
- if (connection) {
- msg.hap.session = {
- sessionID: connection.sessionID,
- username: connection.username,
- remoteAddress: connection.remoteAddress,
- localAddress: connection.localAddress,
- httpPort: connection.remotePort,
- }
- }
+ const onInput = (msg: HAPServiceMessage) => {
+ if (msg.payload) {
+ // payload must be an object
+ const type = typeof msg.payload
+
+ if (type !== 'object') {
+ log.error(`Invalid payload type: ${type}`)
+ return
+ }
+ } else {
+ log.error('Invalid message (payload missing)')
+ return
+ }
- log.debug(
- `${node.name} received ${eventObject.name} ${key}: ${newValue}`
- )
+ const topic = node.config.topic ?? node.name
+ if (node.config.filter && msg.topic !== topic) {
+ log.debug(
+ "msg.topic doesn't match configured value and filter is enabled. Dropping message."
+ )
+ return
+ }
- if (connection || node.hostNode.config.allowMessagePassthrough) {
- node.send(msg)
- }
+ let context: any = null
+ if (msg.payload.Context) {
+ context = msg.payload.Context
+ delete msg.payload.Context
}
- const onCharacteristicGet = (allCharacteristics: Characteristic[]) =>
- function (
- this: Characteristic,
- callback: CharacteristicGetCallback,
- _context: any,
- connection?: HAPConnection
+ node.topic_in = msg.topic ?? ''
+
+ Object.keys(msg.payload).forEach((key: string) => {
+ if (node.supported.indexOf(key) < 0) {
+ if (node.config.useEventCallback && Storage.uuid4Validate(key)) {
+ const callbackID = key
+ const callbackValue = msg.payload?.[key]
+ const eventCallback = Storage.loadCallback(callbackID)
+
+ if (eventCallback) {
+ log.debug(`Calling ${eventCallback.event} callback ${callbackID}`)
+ eventCallback.callback(callbackValue)
+ } else {
+ log.error(`Callback ${callbackID} timeout`)
+ }
+ } else if (
+ key === 'AdaptiveLightingController' &&
+ node.adaptiveLightingController
) {
- const characteristic = this
- const oldValue = characteristic.value
-
- const delayedCallback = (value?: any) => {
- const newValue = value ?? characteristic.value
- if (callback) {
- try {
- callback(
- (node.parentNode ?? node).reachable
- ? null
- : new HapStatusError(
- HAPStatus.SERVICE_COMMUNICATION_FAILURE
- ),
- newValue
- )
- } catch (_) {}
- }
-
- output.call(
- characteristic,
- allCharacteristics,
- {
- name: CharacteristicEventTypes.GET,
- context: { key: this.displayName },
- },
- { oldValue, newValue },
- connection
- )
- }
-
- if (node.config.useEventCallback) {
- const callbackID = Storage.saveCallback({
- event: CharacteristicEventTypes.GET,
- callback: delayedCallback,
- })
-
- log.debug(
- `Registered callback ${callbackID} for Characteristic ${characteristic.displayName}`
- )
-
- output.call(
- this,
- allCharacteristics,
- {
- name: CharacteristicEventTypes.GET,
- context: { callbackID, key: this.displayName },
- },
- { oldValue },
- connection
- )
- } else {
- delayedCallback()
- }
- }
+ const value = msg.payload?.[key]
+ const event = value?.event
- // eslint-disable-next-line no-unused-vars
- const onCharacteristicSet = (allCharacteristics: Characteristic[]) =>
- function (
- this: Characteristic,
- newValue: CharacteristicValue,
- callback: CharacteristicSetCallback,
- _context: any,
- connection?: HAPConnection
- ) {
- try {
- if (callback) {
- callback(
- (node.parentNode ?? node).reachable
- ? null
- : new HapStatusError(
- HAPStatus.SERVICE_COMMUNICATION_FAILURE
- )
- )
- }
- } catch (_) {}
-
- output.call(
- this,
- allCharacteristics,
- {
- name: CharacteristicEventTypes.SET,
- context: { key: this.displayName },
- },
- { newValue },
- connection
- )
+ if (event === 'disable') {
+ node.adaptiveLightingController?.disableAdaptiveLighting()
+ }
+ } else {
+ log.error(
+ `Instead of '${key}' try one of these characteristics: '${node.supported.join(
+ "', '"
+ )}'`
+ )
}
+ } else {
+ const value = msg.payload?.[key]
- const onCharacteristicChange = (allCharacteristics: Characteristic[]) =>
- function (this: Characteristic, change: CharacteristicChange) {
- const { oldValue, newValue, context, originator, reason } = change
-
- if (oldValue != newValue) {
- output.call(
- this,
- allCharacteristics,
- {
- name: CharacteristicEventTypes.CHANGE,
- context: { reason, key: this.displayName },
- },
- { oldValue, newValue, context },
- originator
- )
- }
- }
+ const parentNode = node.parentNode ?? node
+ parentNode.reachable = value !== NO_RESPONSE_MSG
- const onInput = function (msg: HAPServiceMessage) {
- if (msg.payload) {
- // payload must be an object
- const type = typeof msg.payload
+ const characteristic = node.service.getCharacteristic(
+ Characteristic[key]
+ )
- if (type !== 'object') {
- log.error(`Invalid payload type: ${type}`)
- return
- }
+ if (context !== null) {
+ characteristic.setValue(value, context)
} else {
- log.error('Invalid message (payload missing)')
- return
- }
-
- const topic = node.config.topic ?? node.name
- if (node.config.filter && msg.topic !== topic) {
- log.debug(
- "msg.topic doesn't match configured value and filter is enabled. Dropping message."
- )
- return
+ characteristic.setValue(value)
}
+ }
+ })
+ }
+
+ const onClose = (removed: boolean, done: () => void) => {
+ const characteristics = node.service.characteristics.concat(
+ node.service.optionalCharacteristics
+ )
+
+ characteristics.forEach((characteristic) => {
+ // cleanup all node specific listeners
+ characteristic.removeListener('get', node.onCharacteristicGet)
+ characteristic.removeListener('set', node.onCharacteristicSet)
+ characteristic.removeListener('change', node.onCharacteristicChange)
+ })
+
+ if (node.config.isParent) {
+ // remove identify listener to prevent errors with undefined values
+ node.accessory.removeListener('identify', node.onIdentify)
+ }
- let context: any = null
- if (msg.payload.Context) {
- context = msg.payload.Context
- delete msg.payload.Context
- }
+ if (removed) {
+ // This node has been deleted
+ if (node.config.isParent) {
+ // remove accessory from the bridge
+ node.hostNode.host.removeBridgedAccessories([node.accessory])
+ node.accessory.destroy()
+ } else {
+ // only remove the service if it is not a parent
+ node.accessory.removeService(node.service)
+ node.parentService.removeLinkedService(node.service)
+ }
+ }
- node.topic_in = msg.topic ?? ''
-
- Object.keys(msg.payload).map((key: string) => {
- if (node.supported.indexOf(key) < 0) {
- if (
- node.config.useEventCallback &&
- Storage.uuid4Validate(key)
- ) {
- const callbackID = key
- const callbackValue = msg.payload?.[key]
- const eventCallback = Storage.loadCallback(callbackID)
-
- if (eventCallback) {
- log.debug(
- `Calling ${eventCallback.event} callback ${callbackID}`
- )
- eventCallback.callback(callbackValue)
- } else {
- log.error(`Callback ${callbackID} timeout`)
- }
- } else if (
- key === 'AdaptiveLightingController' &&
- node.adaptiveLightingController
- ) {
- const value = msg.payload?.[key]
- const event = value?.event
-
- if (event === 'disable') {
- node.adaptiveLightingController?.disableAdaptiveLighting()
- }
- } else {
- log.error(
- `Instead of '${key}' try one of these characteristics: '${node.supported.join(
- "', '"
- )}'`
- )
- }
- } else {
- const value = msg.payload?.[key]
-
- const parentNode = node.parentNode ?? node
- parentNode.reachable = value !== NO_RESPONSE_MSG
-
- const characteristic = node.service.getCharacteristic(
- Characteristic[key]
- )
-
- if (context !== null) {
- characteristic.setValue(value, undefined, context)
- } else {
- characteristic.setValue(value)
- }
- }
- })
+ done()
+ }
+
+ const getOrCreate = (
+ accessory: Accessory,
+ serviceInformation: {
+ name: string
+ UUID: string
+ serviceName: string
+ config: HAPService2ConfigType
+ },
+ parentService: Service
+ ) => {
+ const newService = new Service[serviceInformation.serviceName](
+ serviceInformation.name,
+ serviceInformation.UUID
+ )
+ log.debug(`Looking for service with UUID ${serviceInformation.UUID} ...`)
+
+ // search for a service with the same subtype
+ let service: Service | undefined = accessory.services.find((service) => {
+ return newService.subtype === service.subtype
+ })
+
+ if (service && newService.UUID !== service.UUID) {
+ // if the UUID and therefore the type changed, the whole service
+ // will be replaced
+ log.debug('... service type changed! Removing the old service.')
+ accessory.removeService(service)
+ service = undefined
}
- const onClose = function (removed: boolean, done: () => void) {
- const characteristics = node.service.characteristics.concat(
- node.service.optionalCharacteristics
- )
+ if (!service) {
+ // if no matching service was found or the type changed, then a new
+ // service will be added
+ log.debug(
+ `... didn't find it. Adding new ${serviceInformation.serviceName} service.`
+ )
+
+ if (serviceInformation.serviceName === 'CameraControl') {
+ configureCameraSource(accessory, newService, serviceInformation.config)
+ service = newService
+ } else {
+ service = accessory.addService(newService)
+ }
+ } else {
+ // if a service with the same UUID and subtype was found, it will
+ // be updated and used
+ log.debug('... found it! Updating it.')
+ service
+ .getCharacteristic(Characteristic.Name)
+ .setValue(serviceInformation.name)
+ }
- characteristics.forEach(function (characteristic) {
- // cleanup all node specific listeners
- characteristic.removeListener('get', node.onCharacteristicGet)
- characteristic.removeListener('set', node.onCharacteristicSet)
- characteristic.removeListener('change', node.onCharacteristicChange)
- })
+ if (parentService) {
+ if (serviceInformation.serviceName === 'CameraControl') {
+ //We don't add or link it since configureCameraSource do this already.
+ log.debug('... and adding service to accessory.')
+ } else if (service) {
+ log.debug('... and linking service to parent.')
+ parentService.addLinkedService(service)
+ }
+ }
- if (node.config.isParent) {
- // remove identify listener to prevent errors with undefined values
- node.accessory.removeListener('identify', node.onIdentify)
- }
+ return service
+ }
- if (removed) {
- // This node has been deleted
- if (node.config.isParent) {
- // remove accessory from bridge
- node.hostNode.host.removeBridgedAccessories([node.accessory])
- node.accessory.destroy()
- } else {
- // only remove the service if it is not a parent
- node.accessory.removeService(node.service)
- node.parentService.removeLinkedService(node.service)
- }
- }
+ const configureCameraSource = (
+ accessory: Accessory,
+ _service: Service,
+ config: HAPService2ConfigType
+ ) => {
+ if (config.cameraConfigSource) {
+ log.debug('Configuring Camera Source')
- done()
+ if (!config.cameraConfigVideoProcessor) {
+ log.error(
+ 'Missing configuration for CameraControl: videoProcessor cannot be empty!'
+ )
+ } else {
+ // Use of deprecated method to be replaced with new Camera API
+ // TODO: https://github.com/homebridge/HAP-NodeJS/blob/latest/src/accessories/Camera_accessory.ts
+ // accessory.configureCameraSource(
+ // new CameraSource(service, config, node)
+ // )
+ configureCamera(accessory, config)
+ }
+ } else {
+ log.error('Missing configuration for CameraControl.')
}
+ }
- const getOrCreate = function (
- accessory: Accessory,
- serviceInformation: {
- name: string
- UUID: string
- serviceName: string
- config: HAPService2ConfigType
- },
- parentService: Service
- ) {
- const newService = new Service[serviceInformation.serviceName](
- serviceInformation.name,
- serviceInformation.UUID
- )
- log.debug(
- `Looking for service with UUID ${serviceInformation.UUID} ...`
- )
+ const waitForParent = () => {
+ log.debug('Waiting for Parent Service')
- // search for a service with the same subtype
- let service: Service | undefined = accessory.services.find(
- (service) => {
- return newService.subtype === service.subtype
- }
- )
+ return new Promise((resolve) => {
+ node.nodeStatusUtils.setStatus({
+ fill: 'blue',
+ shape: 'dot',
+ text: 'Waiting for Parent Service'
+ })
- if (service && newService.UUID !== service.UUID) {
- // if the UUID and therefore the type changed, the whole service
- // will be replaced
- log.debug('... service type changed! Removing the old service.')
- accessory.removeService(service)
- service = undefined
- }
-
- if (!service) {
- // if no matching service was found or the type changed, then a new
- // service will be added
- log.debug(
- `... didn't find it. Adding new ${serviceInformation.serviceName} service.`
- )
+ const checkAndWait = () => {
+ const parentNode: HAPService2NodeType = node.RED.nodes.getNode(
+ node.config.parentService
+ ) as HAPService2NodeType
- if (serviceInformation.serviceName === 'CameraControl') {
- configureCameraSource(
- accessory,
- newService,
- serviceInformation.config
- )
- service = newService
- } else {
- service = accessory.addService(newService)
- }
+ if (parentNode?.configured) {
+ resolve(parentNode)
} else {
- // if a service with the same UUID and subtype was found it will
- // be updated and used
- log.debug('... found it! Updating it.')
- service
- .getCharacteristic(Characteristic.Name)
- .setValue(serviceInformation.name)
+ setTimeout(checkAndWait, 1000)
}
-
- if (parentService) {
- if (serviceInformation.serviceName === 'CameraControl') {
- //We don't add or link it since configureCameraSource do this already.
- log.debug('... and adding service to accessory.')
- } else if (service) {
- log.debug('... and linking service to parent.')
- parentService.addLinkedService(service)
- }
- }
-
- return service
+ }
+ checkAndWait()
+ }).catch((error) => {
+ log.error(`Waiting for Parent Service failed due to: ${error}`)
+ throw new NRCHKBError(error)
+ })
+ }
+
+ const handleWaitForSetup = (
+ config: HAPService2ConfigType,
+ msg: Record,
+ resolve: (newConfig: HAPService2ConfigType) => void
+ ) => {
+ if (node.setupDone) {
+ return
}
- const configureCameraSource = function (
- accessory: Accessory,
- service: Service,
- config: HAPService2ConfigType
+ if (
+ Object.hasOwn(msg, 'payload') &&
+ Object.hasOwn(msg.payload, 'nrchkb') &&
+ Object.hasOwn(msg.payload.nrchkb, 'setup')
) {
- if (config.cameraConfigSource) {
- log.debug('Configuring Camera Source')
-
- if (!config.cameraConfigVideoProcessor) {
- log.error(
- 'Missing configuration for CameraControl: videoProcessor cannot be empty!'
- )
- } else {
- // Use of deprecated method to be replaced with new Camera API
- accessory.configureCameraSource(
- new CameraSource(service, config, node)
- )
- }
- } else {
- log.error('Missing configuration for CameraControl.')
- }
- }
+ node.setupDone = true
- const waitForParent = () => {
- log.debug('Waiting for Parent Service')
-
- return new Promise((resolve) => {
- node.nodeStatusUtils.setStatus({
- fill: 'blue',
- shape: 'dot',
- text: 'Waiting for Parent Service',
- })
-
- const checkAndWait = () => {
- const parentNode: HAPService2NodeType = node.RED.nodes.getNode(
- node.config.parentService
- ) as HAPService2NodeType
-
- if (parentNode && parentNode.configured) {
- resolve(parentNode)
- } else {
- setTimeout(checkAndWait, 1000)
- }
- }
- checkAndWait()
- }).catch((error) => {
- log.error(`Waiting for Parent Service failed due to: ${error}`)
- throw new NRCHKBError(error)
- })
- }
+ const newConfig = {
+ ...config,
+ ...msg.payload.nrchkb.setup
+ }
- const handleWaitForSetup = (
- config: HAPService2ConfigType,
- msg: Record,
- resolve: (newConfig: HAPService2ConfigType) => void
- ) => {
- if (node.setupDone) {
- return
- }
-
- if (
- msg.hasOwnProperty('payload') &&
- msg.payload.hasOwnProperty('nrchkb') &&
- msg.payload.nrchkb.hasOwnProperty('setup')
- ) {
- node.setupDone = true
-
- const newConfig = {
- ...config,
- ...msg.payload.nrchkb.setup,
- }
-
- node.removeListener('input', node.handleWaitForSetup)
-
- resolve(newConfig)
- } else {
- log.error(
- 'Invalid message (required {"payload":{"nrchkb":{"setup":{}}}})'
- )
- }
- }
+ node.removeListener('input', node.handleWaitForSetup)
- return {
- getOrCreate,
- onCharacteristicGet,
- onCharacteristicSet,
- onCharacteristicChange,
- onInput,
- onClose,
- waitForParent,
- handleWaitForSetup,
- configureAdaptiveLightning:
- ServiceUtilsLegacy.configureAdaptiveLightning,
+ resolve(newConfig)
+ } else {
+ log.error(
+ 'Invalid message (required {"payload":{"nrchkb":{"setup":{}}}})'
+ )
}
+ }
+
+ return {
+ getOrCreate,
+ onCharacteristicGet,
+ onCharacteristicSet,
+ onCharacteristicChange,
+ onInput,
+ onClose,
+ waitForParent,
+ handleWaitForSetup,
+ configureAdaptiveLightning: ServiceUtilsLegacy.configureAdaptiveLightning
+ }
}
diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts
index 8865469a..c6c8c544 100644
--- a/src/lib/utils/index.ts
+++ b/src/lib/utils/index.ts
@@ -1,17 +1,15 @@
-import HAPServiceNodeType from '../types/HAPServiceNodeType'
+import type HAPServiceNodeType from '../types/HAPServiceNodeType'
-module.exports = function (node: HAPServiceNodeType) {
- const ServiceUtils = require('./ServiceUtils')(node)
- const BridgeUtils = require('./BridgeUtils')()
- const AccessoryUtils = require('./AccessoryUtils')(node)
- const CharacteristicUtils = require('./CharacteristicUtils')(node)
- const MdnsUtils = require('./MdnsUtils')()
+module.exports = (node: HAPServiceNodeType) => {
+ const ServiceUtils = require('./ServiceUtils')(node)
+ const BridgeUtils = require('./BridgeUtils')()
+ const AccessoryUtils = require('./AccessoryUtils')(node)
+ const CharacteristicUtils = require('./CharacteristicUtils')(node)
- return {
- ServiceUtils,
- BridgeUtils,
- AccessoryUtils,
- CharacteristicUtils,
- MdnsUtils,
- }
+ return {
+ ServiceUtils,
+ BridgeUtils,
+ AccessoryUtils,
+ CharacteristicUtils
+ }
}
diff --git a/src/nodes/bridge.ts b/src/nodes/bridge.ts
index 245c3913..bfe391ef 100644
--- a/src/nodes/bridge.ts
+++ b/src/nodes/bridge.ts
@@ -1,13 +1,13 @@
import { logger } from '@nrchkb/logger'
-import { NodeAPI } from 'node-red'
+import type { NodeAPI } from 'node-red'
import HostType from '../lib/types/HostType'
const log = logger('NRCHKB', 'HAPHostNode')
module.exports = (RED: NodeAPI) => {
- const HAPHostNode = require('../lib/HAPHostNode')(RED, HostType.BRIDGE)
+ const HAPHostNode = require('../lib/HAPHostNode')(RED, HostType.BRIDGE)
- log.debug('Registering homekit-bridge type')
- RED.nodes.registerType('homekit-bridge', HAPHostNode.init)
+ log.debug('Registering homekit-bridge type')
+ RED.nodes.registerType('homekit-bridge', HAPHostNode.init)
}
diff --git a/src/nodes/nrchkb.ts b/src/nodes/nrchkb.ts
index 23693369..49c4e06c 100644
--- a/src/nodes/nrchkb.ts
+++ b/src/nodes/nrchkb.ts
@@ -1,7 +1,7 @@
+import * as path from 'node:path'
+import { HAPStorage } from '@homebridge/hap-nodejs'
import { logger, loggerSetup } from '@nrchkb/logger'
-import { HAPStorage } from 'hap-nodejs'
-import { NodeAPI } from 'node-red'
-import * as path from 'path'
+import type { NodeAPI } from 'node-red'
import semver from 'semver'
import { Storage } from '../lib/Storage'
@@ -10,67 +10,67 @@ loggerSetup({ timestampEnabled: 'NRCHKB' })
const log = logger('NRCHKB')
if (process.env.NRCHKB_EXPERIMENTAL === 'true') {
- log.error('Experimental features enabled')
+ log.error('Experimental features enabled')
}
module.exports = (RED: NodeAPI) => {
- const deprecatedMinimalNodeVersion = '10.22.1'
- const minimalNodeVersion = '12.0.0'
- const nodeVersion = process.version
+ const deprecatedMinimalNodeVersion = '10.22.1'
+ const minimalNodeVersion = '12.0.0'
+ const nodeVersion = process.version
- if (semver.gte(nodeVersion, deprecatedMinimalNodeVersion)) {
- log.debug(
- `Node.js version requirement met. Required >=${deprecatedMinimalNodeVersion}. Installed ${nodeVersion}`
- )
- if (semver.lt(nodeVersion, minimalNodeVersion)) {
- log.error(
- 'Node.js version requirement met but will be deprecated in Node-RED 2.0.0'
- )
- log.error(
- `Recommended >=${minimalNodeVersion}. Installed ${nodeVersion}. Consider upgrading.`
- )
- }
- } else {
- throw RangeError(
- `Node.js version requirement not met. Required >=${deprecatedMinimalNodeVersion}. Installed ${nodeVersion}`
- )
+ if (semver.gte(nodeVersion, deprecatedMinimalNodeVersion)) {
+ log.debug(
+ `Node.js version requirement met. Required >=${deprecatedMinimalNodeVersion}. Installed ${nodeVersion}`
+ )
+ if (semver.lt(nodeVersion, minimalNodeVersion)) {
+ log.error(
+ 'Node.js version requirement met but will be deprecated in Node-RED 2.0.0'
+ )
+ log.error(
+ `Recommended >=${minimalNodeVersion}. Installed ${nodeVersion}. Consider upgrading.`
+ )
}
+ } else {
+ throw RangeError(
+ `Node.js version requirement not met. Required >=${deprecatedMinimalNodeVersion}. Installed ${nodeVersion}`
+ )
+ }
- const API = require('../lib/api')(RED)
+ const API = require('../lib/api')(RED)
- let rootFolder: string
+ let rootFolder: string
- // Initialize our storage system
- if (RED.settings.available() && RED.settings.userDir) {
- log.debug('RED settings available')
- rootFolder = RED.settings.userDir
- } else {
- log.error('RED settings not available')
- rootFolder = path.join(require('os').homedir(), '.node-red')
- }
+ // Initialize our storage system
+ if (RED.settings.available() && RED.settings.userDir) {
+ log.debug('RED settings available')
+ rootFolder = RED.settings.userDir
+ } else {
+ log.error('RED settings not available')
+ rootFolder = path.join(require('node:os').homedir(), '.node-red')
+ }
- Storage.init(rootFolder, 'nrchkb').then(() => {
- log.debug(`nrchkb storage path set to ${Storage.storagePath()}`)
- API.init()
+ Storage.init(rootFolder, 'nrchkb').then(() => {
+ log.debug(`nrchkb storage path set to ${Storage.storagePath()}`)
+ API.init()
- const hapStoragePath = path.resolve(rootFolder, 'homekit-persist')
+ const hapStoragePath = path.resolve(rootFolder, 'homekit-persist')
- try {
- HAPStorage.setCustomStoragePath(hapStoragePath)
- log.debug(`HAPStorage path set to ${hapStoragePath}`)
- } catch (error: any) {
- log.debug('HAPStorage already initialized')
- log.error('node-red restart highly recommended')
- log.trace(error)
- }
+ try {
+ HAPStorage.setCustomStoragePath(hapStoragePath)
+ log.debug(`HAPStorage path set to ${hapStoragePath}`)
+ } catch (error: any) {
+ log.debug('HAPStorage already initialized')
+ log.error('node-red restart highly recommended')
+ log.trace(error)
+ }
+ })
- // Experimental feature
- if (process.env.NRCHKB_EXPERIMENTAL === 'true') {
- log.debug('Registering nrchkb type')
+ // Experimental feature
+ if (process.env.NRCHKB_EXPERIMENTAL === 'true') {
+ log.debug('Registering nrchkb type')
- RED.nodes.registerType('nrchkb', function (this: any, config) {
- RED.nodes.createNode(this, config)
- })
- }
+ RED.nodes.registerType('nrchkb', function (this: any, config) {
+ RED.nodes.createNode(this, config)
})
+ }
}
diff --git a/src/nodes/service.ts b/src/nodes/service.ts
index dc4a7afe..3ae2b44a 100644
--- a/src/nodes/service.ts
+++ b/src/nodes/service.ts
@@ -1,11 +1,11 @@
import { logger } from '@nrchkb/logger'
-import { NodeAPI } from 'node-red'
+import type { NodeAPI } from 'node-red'
const log = logger('NRCHKB', 'HAPServiceNode')
module.exports = (RED: NodeAPI) => {
- const HAPServiceNode = require('../lib/HAPServiceNode')(RED)
+ const HAPServiceNode = require('../lib/HAPServiceNode')(RED)
- log.debug('Registering homekit-service type')
- RED.nodes.registerType('homekit-service', HAPServiceNode.preInit)
+ log.debug('Registering homekit-service type')
+ RED.nodes.registerType('homekit-service', HAPServiceNode.preInit)
}
diff --git a/src/nodes/service2.ts b/src/nodes/service2.ts
index d59017e2..20c4d914 100644
--- a/src/nodes/service2.ts
+++ b/src/nodes/service2.ts
@@ -1,13 +1,13 @@
import { logger } from '@nrchkb/logger'
-import { NodeAPI } from 'node-red'
+import type { NodeAPI } from 'node-red'
const log = logger('NRCHKB', 'HAPServiceNode2')
module.exports = (RED: NodeAPI) => {
- const HAPServiceNode2 = require('../lib/HAPServiceNode2')(RED)
+ const HAPServiceNode2 = require('../lib/HAPServiceNode2')(RED)
- if (process.env.NRCHKB_EXPERIMENTAL === 'true') {
- log.debug('Registering homekit-service2 type')
- RED.nodes.registerType('homekit-service2', HAPServiceNode2.preInit)
- }
+ if (process.env.NRCHKB_EXPERIMENTAL === 'true') {
+ log.debug('Registering homekit-service2 type')
+ RED.nodes.registerType('homekit-service2', HAPServiceNode2.preInit)
+ }
}
diff --git a/src/nodes/standalone.ts b/src/nodes/standalone.ts
index 5575665d..7d78ba2c 100644
--- a/src/nodes/standalone.ts
+++ b/src/nodes/standalone.ts
@@ -1,13 +1,13 @@
import { logger } from '@nrchkb/logger'
-import { NodeAPI } from 'node-red'
+import type { NodeAPI } from 'node-red'
import HostType from '../lib/types/HostType'
const log = logger('NRCHKB', 'HAPHostNode')
module.exports = (RED: NodeAPI) => {
- const HAPHostNode = require('../lib/HAPHostNode')(RED, HostType.STANDALONE)
+ const HAPHostNode = require('../lib/HAPHostNode')(RED, HostType.STANDALONE)
- log.debug('Registering homekit-standalone type')
- RED.nodes.registerType('homekit-standalone', HAPHostNode.init)
+ log.debug('Registering homekit-standalone type')
+ RED.nodes.registerType('homekit-standalone', HAPHostNode.init)
}
diff --git a/src/nodes/status.ts b/src/nodes/status.ts
index 341570b3..9bd260d4 100644
--- a/src/nodes/status.ts
+++ b/src/nodes/status.ts
@@ -1,62 +1,59 @@
+import { Service } from '@homebridge/hap-nodejs'
import { logger } from '@nrchkb/logger'
-import { Service } from 'hap-nodejs'
-import { NodeAPI } from 'node-red'
+import type { NodeAPI } from 'node-red'
-import HAPServiceNodeType from '../lib/types/HAPServiceNodeType'
-import HAPStatusConfigType from '../lib/types/HAPStatusConfigType'
-import HAPStatusNodeType from '../lib/types/HAPStatusNodeType'
+import type HAPServiceNodeType from '../lib/types/HAPServiceNodeType'
+import type HAPStatusConfigType from '../lib/types/HAPStatusConfigType'
+import type HAPStatusNodeType from '../lib/types/HAPStatusNodeType'
import { NodeStatusUtils } from '../lib/utils/NodeStatusUtils'
const log = logger('NRCHKB', 'HAPStatusNode')
module.exports = (RED: NodeAPI) => {
- log.debug('Registering homekit-status type')
- RED.nodes.registerType(
- 'homekit-status',
- function (this: HAPStatusNodeType, config: HAPStatusConfigType) {
- const self = this
- self.config = config
- RED.nodes.createNode(self, config)
+ log.debug('Registering homekit-status type')
+ RED.nodes.registerType(
+ 'homekit-status',
+ function (this: HAPStatusNodeType, config: HAPStatusConfigType) {
+ this.config = config
+ RED.nodes.createNode(this, config)
- self.nodeStatusUtils = new NodeStatusUtils(self)
+ this.nodeStatusUtils = new NodeStatusUtils(this)
- try {
- self.serviceNode = RED.nodes.getNode(
- self.config.serviceNodeId
- ) as HAPServiceNodeType
- } catch (error: any) {
- log.error(error)
- }
+ try {
+ this.serviceNode = RED.nodes.getNode(
+ this.config.serviceNodeId
+ ) as HAPServiceNodeType
+ } catch (error: any) {
+ log.error(error)
+ }
- self.on('input', (_: Record) => {
- if (self.serviceNode) {
- self.nodeStatusUtils.setStatus(
- {
- fill: 'green',
- shape: 'dot',
- text: 'Done',
- },
- 3000
- )
- const serializedService = Service.serialize(
- self.serviceNode.service
- )
- self.send({
- payload: serializedService,
- })
- } else {
- self.nodeStatusUtils.setStatus({
- fill: 'red',
- shape: 'dot',
- text: 'Check your config',
- })
- }
- })
-
- self.on('close', (_: boolean, done: () => void) => {
- self.serviceNode = undefined
- done()
- })
+ this.on('input', (_: Record) => {
+ if (this.serviceNode) {
+ this.nodeStatusUtils.setStatus(
+ {
+ fill: 'green',
+ shape: 'dot',
+ text: 'Done'
+ },
+ 3000
+ )
+ const serializedService = Service.serialize(this.serviceNode.service)
+ this.send({
+ payload: serializedService
+ })
+ } else {
+ this.nodeStatusUtils.setStatus({
+ fill: 'red',
+ shape: 'dot',
+ text: 'Check your config'
+ })
}
- )
+ })
+
+ this.on('close', (_: boolean, done: () => void) => {
+ this.serviceNode = undefined
+ done()
+ })
+ }
+ )
}
diff --git a/src/test/lib/HAPBridgeNode.test.ts b/src/test/lib/HAPBridgeNode.test.ts
index 371b8c4c..792a8c8e 100644
--- a/src/test/lib/HAPBridgeNode.test.ts
+++ b/src/test/lib/HAPBridgeNode.test.ts
@@ -1,47 +1,40 @@
-import 'should'
-
import { loggerSetup } from '@nrchkb/logger'
-import { describe, it } from 'mocha'
-import should from 'should'
+import { describe, expect, it } from 'vitest'
-const HAPHostNode = require('../../lib/HAPHostNode')()
+const HAPHostNode = require('../../../build/lib/HAPHostNode')()
loggerSetup({
- debugEnabled: true,
- errorEnabled: true,
- traceEnabled: false,
+ debugEnabled: true,
+ errorEnabled: true,
+ traceEnabled: false
})
-describe('HAPHostNode', function () {
- this.timeout(30000)
-
- it('string macify should pass', function (done) {
- const stringToMacify = 'BRIDGE NAME'
- HAPHostNode.macify(stringToMacify)
- done()
- })
-
- it('null string macify should fail', function (done) {
- const stringToMacify = null as unknown as string
- should.throws(() => {
- HAPHostNode.macify(stringToMacify)
- }, 'nodeId cannot be empty in macify process')
- done()
- })
-
- it('undefined string macify should fail', function (done) {
- const stringToMacify = undefined as unknown as string
- should.throws(() => {
- HAPHostNode.macify(stringToMacify)
- }, 'nodeId cannot be empty in macify process')
- done()
- })
-
- it('empty string macify should fail', function (done) {
- const stringToMacify = ''
- should.throws(() => {
- HAPHostNode.macify(stringToMacify)
- }, 'nodeId cannot be empty in macify process')
- done()
- })
+describe('HAPHostNode', () => {
+ // allow longer for this suite (configured via package.json vitest.test.testTimeout)
+
+ it('string macify should pass', () => {
+ const stringToMacify = 'BRIDGE NAME'
+ HAPHostNode.macify(stringToMacify)
+ })
+
+ it('null string macify should fail', () => {
+ const stringToMacify = null as unknown as string
+ expect(() => {
+ HAPHostNode.macify(stringToMacify)
+ }).toThrow('nodeId cannot be empty in macify process')
+ })
+
+ it('undefined string macify should fail', () => {
+ const stringToMacify = undefined as unknown as string
+ expect(() => {
+ HAPHostNode.macify(stringToMacify)
+ }).toThrow('nodeId cannot be empty in macify process')
+ })
+
+ it('empty string macify should fail', () => {
+ const stringToMacify = ''
+ expect(() => {
+ HAPHostNode.macify(stringToMacify)
+ }).toThrow('nodeId cannot be empty in macify process')
+ })
})
diff --git a/src/test/lib/NodeStatusUtils.test.ts b/src/test/lib/NodeStatusUtils.test.ts
index e34f0e4b..6c98e04c 100644
--- a/src/test/lib/NodeStatusUtils.test.ts
+++ b/src/test/lib/NodeStatusUtils.test.ts
@@ -1,115 +1,87 @@
-import 'should'
-
-import { NodeStatus } from '@node-red/registry'
-import assert from 'assert'
-import { after, before, beforeEach, describe, it } from 'mocha'
-import sinon, { SinonFakeTimers } from 'sinon'
+import type { NodeStatus } from '@node-red/registry'
+import {
+ afterAll,
+ beforeAll,
+ beforeEach,
+ describe,
+ expect,
+ it,
+ vi
+} from 'vitest'
import { NodeStatusUtils } from '../../lib/utils/NodeStatusUtils'
class NodeWithStatusMock {
- constructor(public currentStatus: string | NodeStatus = '') {}
- status(status: string | NodeStatus): void {
- this.currentStatus = status
- }
+ constructor(public currentStatus: string | NodeStatus = '') {}
+ status(status: string | NodeStatus): void {
+ this.currentStatus = status
+ }
}
-describe('NodeStatusUtils', function () {
- let node: NodeWithStatusMock
- let nodeStatusUtils: NodeStatusUtils
- let clock: SinonFakeTimers
+describe('NodeStatusUtils', () => {
+ let node: NodeWithStatusMock
+ let nodeStatusUtils: NodeStatusUtils
- before(function () {
- clock = sinon.useFakeTimers()
- })
+ beforeAll(() => {
+ vi.useFakeTimers()
+ })
- after(function () {
- clock.restore()
- })
+ afterAll(() => {
+ vi.useRealTimers()
+ })
- beforeEach(function (done) {
- node = new NodeWithStatusMock()
- nodeStatusUtils = new NodeStatusUtils(node)
- done()
- })
+ beforeEach(() => {
+ node = new NodeWithStatusMock()
+ nodeStatusUtils = new NodeStatusUtils(node)
+ })
- it('setStatus', function (done) {
- try {
- nodeStatusUtils.setStatus('test')
- assert.strictEqual(node.currentStatus, 'test')
- done()
- } catch (error: any) {
- done(new Error(error))
- }
- })
+ it('setStatus', () => {
+ nodeStatusUtils.setStatus('test')
+ expect(node.currentStatus).toBe('test')
+ })
- it('clearStatus', function (done) {
- try {
- nodeStatusUtils.setStatus('test')
- assert.strictEqual(node.currentStatus, 'test')
- nodeStatusUtils.clearStatus()
- assert.strictEqual(node.currentStatus, '')
- done()
- } catch (error: any) {
- done(new Error(error))
- }
- })
+ it('clearStatus', () => {
+ nodeStatusUtils.setStatus('test')
+ expect(node.currentStatus).toBe('test')
+ nodeStatusUtils.clearStatus()
+ expect(node.currentStatus).toBe('')
+ })
- it('setStatusWithTimeout', function (done) {
- try {
- nodeStatusUtils.setStatus('test', 2000)
- assert.strictEqual(node.currentStatus, 'test')
- clock.tick(1000)
- assert.strictEqual(node.currentStatus, 'test')
- clock.tick(1000)
- assert.strictEqual(node.currentStatus, '')
- done()
- } catch (error: any) {
- done(new Error(error))
- }
- })
+ it('setStatusWithTimeout', () => {
+ nodeStatusUtils.setStatus('test', 2000)
+ expect(node.currentStatus).toBe('test')
+ vi.advanceTimersByTime(1000)
+ expect(node.currentStatus).toBe('test')
+ vi.advanceTimersByTime(1000)
+ expect(node.currentStatus).toBe('')
+ })
- it('setStatusWithTimeout - should not clear status with different id', function (done) {
- try {
- nodeStatusUtils.setStatus('test', 2000)
- assert.strictEqual(node.currentStatus, 'test')
- clock.tick(1000)
- assert.strictEqual(node.currentStatus, 'test')
- nodeStatusUtils.setStatus('test2', 2000)
- clock.tick(1000)
- assert.strictEqual(node.currentStatus, 'test2')
- clock.tick(1000)
- assert.strictEqual(node.currentStatus, '')
- done()
- } catch (error: any) {
- done(new Error(error))
- }
- })
+ it('setStatusWithTimeout - should not clear status with different id', () => {
+ nodeStatusUtils.setStatus('test', 2000)
+ expect(node.currentStatus).toBe('test')
+ vi.advanceTimersByTime(1000)
+ expect(node.currentStatus).toBe('test')
+ nodeStatusUtils.setStatus('test2', 2000)
+ vi.advanceTimersByTime(1000)
+ expect(node.currentStatus).toBe('test2')
+ vi.advanceTimersByTime(1000)
+ expect(node.currentStatus).toBe('')
+ })
- it('clearStatusByType - should not clear other type', function (done) {
- try {
- nodeStatusUtils.setStatus({ text: 'test' })
- assert.deepStrictEqual(node.currentStatus, { text: 'test' })
- nodeStatusUtils.clearStatusByType('NO_RESPONSE')
- assert.deepStrictEqual(node.currentStatus, { text: 'test' })
- done()
- } catch (error: any) {
- done(new Error(error))
- }
- })
+ it('clearStatusByType - should not clear other type', () => {
+ nodeStatusUtils.setStatus({ text: 'test' })
+ expect(node.currentStatus).toStrictEqual({ text: 'test' })
+ nodeStatusUtils.clearStatusByType('NO_RESPONSE')
+ expect(node.currentStatus).toStrictEqual({ text: 'test' })
+ })
- it('clearStatusByType - should clear same type', function (done) {
- try {
- nodeStatusUtils.setStatus({ text: 'test', type: 'NO_RESPONSE' })
- assert.deepStrictEqual(node.currentStatus, {
- text: 'test',
- type: 'NO_RESPONSE',
- })
- nodeStatusUtils.clearStatusByType('NO_RESPONSE')
- assert.deepStrictEqual(node.currentStatus, '')
- done()
- } catch (error: any) {
- done(new Error(error))
- }
+ it('clearStatusByType - should clear same type', () => {
+ nodeStatusUtils.setStatus({ text: 'test', type: 'NO_RESPONSE' })
+ expect(node.currentStatus).toStrictEqual({
+ text: 'test',
+ type: 'NO_RESPONSE'
})
+ nodeStatusUtils.clearStatusByType('NO_RESPONSE')
+ expect(node.currentStatus).toStrictEqual('')
+ })
})
diff --git a/src/test/lib/api.test.ts b/src/test/lib/api.test.ts
index e5fe2f4a..676eb3d2 100644
--- a/src/test/lib/api.test.ts
+++ b/src/test/lib/api.test.ts
@@ -1,125 +1,83 @@
-import 'should'
-
import { loggerSetup } from '@nrchkb/logger'
-import assert from 'assert'
-import { afterEach, before, describe, it } from 'mocha'
import helper from 'node-red-node-test-helper'
+import { afterAll, afterEach, beforeAll, describe, expect, it } from 'vitest'
import { version } from '../../../package.json'
import {
- accessoryCategoriesResponse,
- serviceTypesResponse,
+ accessoryCategoriesResponse,
+ serviceTypesResponse
} from '../test-utils/data'
-const API = require('../../lib/api')()
-const nrchkb = require('../../nodes/nrchkb')
+const API = require('../../../build/lib/api')()
+const nrchkb = require('../../../build/nodes/nrchkb')
process.env.NRCHKB_EXPERIMENTAL = 'true'
loggerSetup({
- debugEnabled: true,
- errorEnabled: true,
- traceEnabled: false,
+ debugEnabled: true,
+ errorEnabled: true,
+ traceEnabled: false
})
-describe('api', function () {
- this.timeout(30000)
+describe('api', () => {
+ beforeAll(() => new Promise((resolve) => helper.startServer(resolve)))
- before(function (done) {
- helper.startServer(done)
- })
+ afterAll(() => new Promise((resolve) => helper.stopServer(resolve)))
- after(function (done) {
- helper.stopServer(done)
- })
+ afterEach(() => {
+ return helper.unload()
+ })
- afterEach(function () {
- helper.unload()
- })
+ it('Service API', async () => {
+ await helper.load([nrchkb], [])
+ const response = await helper
+ .request()
+ .get('/nrchkb/service/types')
+ .expect('Content-Type', /json/)
+ .expect(200)
+ expect(response.body).toStrictEqual(serviceTypesResponse)
+ })
- it('Service API', function (done) {
- helper
- .load([nrchkb], [], function () {
- helper
- .request()
- .get('/nrchkb/service/types')
- .expect('Content-Type', /json/)
- .expect(200)
- .then((response) => {
- assert.deepStrictEqual(
- response.body,
- serviceTypesResponse
- )
- done()
- })
- .catch((err) => done(err))
- })
- .catch((error: any) => {
- done(new Error(error))
- })
+ describe('stringifyVersion', () => {
+ it('release', () => {
+ const input = '1.2.3'
+ const expected = '1.2.3'
+ const result = API.stringifyVersion(input)
+ expect(result).toBe(expected)
})
- describe('stringifyVersion', function () {
- it('release', function (done) {
- const input = '1.2.3'
- const expected = '1.2.3'
- const result = API.stringifyVersion(input)
- assert.strictEqual(result, expected)
- done()
- })
-
- it('dev', function (done) {
- const input = '1.2.3-dev.45'
- const expected = '0.123.45'
- const result = API.stringifyVersion(input)
- assert.strictEqual(result, expected)
- done()
- })
+ it('dev', () => {
+ const input = '1.2.3-dev.45'
+ const expected = '0.123.45'
+ const result = API.stringifyVersion(input)
+ expect(result).toBe(expected)
})
+ })
- it('NRCHKB Info API', function (done) {
- helper
- .load([nrchkb], [], function () {
- const xyzVersion = API.stringifyVersion(version)
+ it('NRCHKB Info API', async () => {
+ await helper.load([nrchkb], [])
+ const xyzVersion = API.stringifyVersion(version)
- helper
- .request()
- .get('/nrchkb/info')
- .expect('Content-Type', /json/)
- .expect(200)
- .then((response) => {
- assert.deepStrictEqual(response.body, {
- experimental: true,
- version: xyzVersion,
- })
- done()
- })
- .catch((err) => done(err))
- })
- .catch((error: any) => {
- done(new Error(error))
- })
- })
+ const response = await helper
+ .request()
+ .get('/nrchkb/info')
+ .expect('Content-Type', /json/)
+ .expect(200)
- it('Accessory API', function (done) {
- helper
- .load([nrchkb], [], function () {
- helper
- .request()
- .get('/nrchkb/accessory/categories')
- .expect('Content-Type', /json/)
- .expect(200)
- .then((response) => {
- assert.deepStrictEqual(
- response.body,
- accessoryCategoriesResponse
- )
- done()
- })
- .catch((err) => done(err))
- })
- .catch((error: any) => {
- done(new Error(error))
- })
+ expect(response.body).toStrictEqual({
+ experimental: true,
+ version: xyzVersion
})
+ })
+
+ it('Accessory API', async () => {
+ await helper.load([nrchkb], [])
+ const response = await helper
+ .request()
+ .get('/nrchkb/accessory/categories')
+ .expect('Content-Type', /json/)
+ .expect(200)
+
+ expect(response.body).toStrictEqual(accessoryCategoriesResponse)
+ })
})
diff --git a/src/test/nodes/service.test.ts b/src/test/nodes/service.test.ts
index 7642bf39..7ed82248 100644
--- a/src/test/nodes/service.test.ts
+++ b/src/test/nodes/service.test.ts
@@ -1,172 +1,125 @@
-import 'should'
-
import { loggerSetup } from '@nrchkb/logger'
-import { afterEach, before, describe, it } from 'mocha'
import helper from 'node-red-node-test-helper'
+import {
+ afterAll,
+ afterEach,
+ beforeAll,
+ describe,
+ expect,
+ it,
+ vi
+} from 'vitest'
import { switchServiceBridgeFlow } from '../test-utils/data'
-const homekitBridgeNode = require('../../nodes/bridge')
-const nrchkb = require('../../nodes/nrchkb')
-const homekitServiceNode = require('../../nodes/service')
+
+const homekitBridgeNode = require('../../../build/nodes/bridge')
+const nrchkb = require('../../../build/nodes/nrchkb')
+const homekitServiceNode = require('../../../build/nodes/service')
loggerSetup({
- debugEnabled: true,
- errorEnabled: true,
- traceEnabled: false,
+ debugEnabled: true,
+ errorEnabled: true,
+ traceEnabled: false
})
-describe('Service Node', function () {
- before(function (done) {
- helper.startServer(done)
- })
+describe('Service Node', () => {
+ beforeAll(() => new Promise((resolve) => helper.startServer(resolve)))
- after(function (done) {
- helper.stopServer(done)
- })
+ afterAll(() => new Promise((resolve) => helper.stopServer(resolve)))
- afterEach(function () {
- helper.unload()
- })
+ afterEach(() => {
+ return helper.unload()
+ })
- it('should be loaded', function (done) {
- const { serviceId, flow } = switchServiceBridgeFlow()
- helper
- .load(
- [nrchkb, homekitBridgeNode, homekitServiceNode],
- flow,
- function () {
- try {
- const s1 = helper.getNode(serviceId)
- s1.should.have.property('type', 'homekit-service')
- done()
- } catch (err) {
- done(err)
- }
- }
- )
- .catch((error: any) => {
- done(new Error(error))
- })
- })
+ it('should be loaded', async () => {
+ const { serviceId, flow } = switchServiceBridgeFlow()
+ await helper.load([nrchkb, homekitBridgeNode, homekitServiceNode], flow)
+ const s1 = helper.getNode(serviceId)
+ expect(s1).toHaveProperty('type', 'homekit-service')
+ })
- it('should output ON:true payload', function (done) {
- const { serviceId, flow } = switchServiceBridgeFlow()
- helper
- .load(
- [nrchkb, homekitBridgeNode, homekitServiceNode],
- flow,
- function () {
- const s1 = helper.getNode(serviceId)
-
- s1.on('input', (msg: any) => {
- try {
- msg.payload.should.have.property('On', true)
- done()
- } catch (err) {
- done(err)
- }
- })
-
- s1.receive({ payload: { On: true } })
- }
- )
- .catch((error: any) => {
- done(new Error(error))
- })
- })
+ it('should output ON:true payload', async () => {
+ const { serviceId, flow } = switchServiceBridgeFlow()
+ await helper.load([nrchkb, homekitBridgeNode, homekitServiceNode], flow)
+ const s1 = helper.getNode(serviceId)
- it('should output ON:false payload', function (done) {
- const { serviceId, flow } = switchServiceBridgeFlow()
- helper
- .load(
- [nrchkb, homekitBridgeNode, homekitServiceNode],
- flow,
- function () {
- const s1 = helper.getNode(serviceId)
-
- s1.on('input', function (msg: any) {
- try {
- msg.payload.should.have.property('On', false)
- done()
- } catch (err) {
- done(err)
- }
- })
-
- s1.receive({ payload: { On: false } })
- }
- )
- .catch((error: any) => {
- done(new Error(error))
- })
- })
+ await new Promise((resolve) => {
+ s1.on('input', (msg: any) => {
+ expect(msg.payload).toHaveProperty('On', true)
+ resolve()
+ })
- it('should output reachable true', function (done) {
- const { serviceId, flow } = switchServiceBridgeFlow()
- helper
- .load(
- [nrchkb, homekitBridgeNode, homekitServiceNode],
- flow,
- function () {
- const s1 = helper.getNode(serviceId)
- const h1 = helper.getNode('h1')
-
- let count = 0
-
- h1.on('input', function (msg: any) {
- if (count === 0) {
- try {
- msg.payload.should.have.property('On', true)
- msg.hap.should.have.property('newValue', true)
- msg.hap.should.have.property('reachable', true)
- done()
- } catch (err) {
- done(err)
- }
- count++
- }
- })
-
- s1.receive({ payload: { On: true } })
- }
- )
- .catch((error: any) => {
- done(new Error(error))
- })
+ s1.receive({ payload: { On: true } })
})
+ })
+
+ it('should output ON:false payload', async () => {
+ const { serviceId, flow } = switchServiceBridgeFlow()
+ await helper.load([nrchkb, homekitBridgeNode, homekitServiceNode], flow)
+ const s1 = helper.getNode(serviceId)
- it('should output reachable false', function (done) {
- const { serviceId, flow } = switchServiceBridgeFlow()
- helper
- .load(
- [nrchkb, homekitBridgeNode, homekitServiceNode],
- flow,
- function () {
- const s1 = helper.getNode(serviceId)
- const h1 = helper.getNode('h1')
-
- h1.on('input', function (msg: any) {
- try {
- msg.payload.should.have.property('On', false)
- msg.hap.should.have.property('reachable', false)
- // @ts-ignore
- s1.status.should.be.calledWithExactly({
- fill: 'red',
- shape: 'ring',
- text: 'Not reachable',
- type: 'NO_RESPONSE',
- })
- done()
- } catch (err) {
- done(err)
- }
- })
-
- s1.receive({ payload: { On: 'NO_RESPONSE' } })
- }
- )
- .catch((error: any) => {
- done(new Error(error))
- })
+ await new Promise((resolve) => {
+ s1.on('input', (msg: any) => {
+ expect(msg.payload).toHaveProperty('On', false)
+ resolve()
+ })
+
+ s1.receive({ payload: { On: false } })
+ })
+ })
+
+ it('should output reachable true', async () => {
+ const { serviceId, flow } = switchServiceBridgeFlow()
+ await helper.load([nrchkb, homekitBridgeNode, homekitServiceNode], flow)
+ const s1 = helper.getNode(serviceId)
+ const h1 = helper.getNode('h1')
+
+ let count = 0
+
+ await new Promise((resolve) => {
+ h1.on('input', (msg: any) => {
+ if (count === 0) {
+ expect(msg.payload).toHaveProperty('On', true)
+ expect(msg.hap).toHaveProperty('newValue', true)
+ expect(msg.hap).toHaveProperty('reachable', true)
+ resolve()
+ count++
+ }
+ })
+
+ s1.receive({ payload: { On: true } })
+ })
+ })
+
+ it('should output reachable false', async () => {
+ const { serviceId, flow } = switchServiceBridgeFlow()
+ await helper.load([nrchkb, homekitBridgeNode, homekitServiceNode], flow)
+ const s1 = helper.getNode(serviceId)
+ const h1 = helper.getNode('h1')
+
+ await new Promise((resolve, reject) => {
+ // spy status so we can assert it was called
+ const statusSpy = vi
+ .spyOn(s1 as any, 'status')
+ .mockImplementation(() => {})
+
+ h1.on('input', (msg: any) => {
+ try {
+ expect(msg.payload).toHaveProperty('On', false)
+ expect(msg.hap).toHaveProperty('reachable', false)
+ expect(statusSpy).toHaveBeenCalledWith({
+ fill: 'red',
+ shape: 'ring',
+ text: 'Not reachable',
+ type: 'NO_RESPONSE'
+ })
+ resolve()
+ } catch (err) {
+ reject(err)
+ }
+ })
+
+ s1.receive({ payload: { On: 'NO_RESPONSE' } })
})
+ })
})
diff --git a/src/test/nodes/service2.test.ts b/src/test/nodes/service2.test.ts
index 29156f1f..08afb482 100644
--- a/src/test/nodes/service2.test.ts
+++ b/src/test/nodes/service2.test.ts
@@ -1,174 +1,126 @@
-import 'should'
-
import { loggerSetup } from '@nrchkb/logger'
-import { afterEach, before, describe, it } from 'mocha'
import helper from 'node-red-node-test-helper'
+import {
+ afterAll,
+ afterEach,
+ beforeAll,
+ describe,
+ expect,
+ it,
+ vi
+} from 'vitest'
import { switchService2BridgeFlow } from '../test-utils/data'
-const homekitBridgeNode = require('../../nodes/bridge')
-const nrchkb = require('../../nodes/nrchkb')
-const homekitService2Node = require('../../nodes/service2')
+
+const homekitBridgeNode = require('../../../build/nodes/bridge')
+const nrchkb = require('../../../build/nodes/nrchkb')
+const homekitService2Node = require('../../../build/nodes/service2')
process.env.NRCHKB_EXPERIMENTAL = 'true'
loggerSetup({
- debugEnabled: true,
- errorEnabled: true,
- traceEnabled: false,
+ debugEnabled: true,
+ errorEnabled: true,
+ traceEnabled: false
})
-describe('Service Node', function () {
- before(function (done) {
- helper.startServer(done)
- })
+describe('Service Node', () => {
+ beforeAll(() => new Promise((resolve) => helper.startServer(resolve)))
- after(function (done) {
- helper.stopServer(done)
- })
+ afterAll(() => new Promise((resolve) => helper.stopServer(resolve)))
- afterEach(function () {
- helper.unload()
- })
+ afterEach(() => {
+ return helper.unload()
+ })
- it('should be loaded', function (done) {
- const { serviceId, flow } = switchService2BridgeFlow()
- helper
- .load(
- [nrchkb, homekitBridgeNode, homekitService2Node],
- flow,
- function () {
- try {
- const s1 = helper.getNode(serviceId)
- s1.should.have.property('type', 'homekit-service2')
- done()
- } catch (err) {
- done(err)
- }
- }
- )
- .catch((error: any) => {
- done(new Error(error))
- })
- })
+ it('should be loaded', async () => {
+ const { serviceId, flow } = switchService2BridgeFlow()
+ await helper.load([nrchkb, homekitBridgeNode, homekitService2Node], flow)
+ const s1 = helper.getNode(serviceId)
+ expect(s1).toHaveProperty('type', 'homekit-service2')
+ })
- it('should output ON:true payload', function (done) {
- const { serviceId, flow } = switchService2BridgeFlow()
- helper
- .load(
- [nrchkb, homekitBridgeNode, homekitService2Node],
- flow,
- function () {
- const s1 = helper.getNode(serviceId)
-
- s1.on('input', (msg: any) => {
- try {
- msg.payload.should.have.property('On', true)
- done()
- } catch (err) {
- done(err)
- }
- })
-
- s1.receive({ payload: { On: true } })
- }
- )
- .catch((error: any) => {
- done(new Error(error))
- })
- })
+ it('should output ON:true payload', async () => {
+ const { serviceId, flow } = switchService2BridgeFlow()
+ await helper.load([nrchkb, homekitBridgeNode, homekitService2Node], flow)
+ const s1 = helper.getNode(serviceId)
- it('should output ON:false payload', function (done) {
- const { serviceId, flow } = switchService2BridgeFlow()
- helper
- .load(
- [nrchkb, homekitBridgeNode, homekitService2Node],
- flow,
- function () {
- const s1 = helper.getNode(serviceId)
-
- s1.on('input', function (msg: any) {
- try {
- msg.payload.should.have.property('On', false)
- done()
- } catch (err) {
- done(err)
- }
- })
-
- s1.receive({ payload: { On: false } })
- }
- )
- .catch((error: any) => {
- done(new Error(error))
- })
- })
+ await new Promise((resolve) => {
+ s1.on('input', (msg: any) => {
+ expect(msg.payload).toHaveProperty('On', true)
+ resolve()
+ })
- it('should output reachable true', function (done) {
- const { serviceId, flow } = switchService2BridgeFlow()
- helper
- .load(
- [nrchkb, homekitBridgeNode, homekitService2Node],
- flow,
- function () {
- const s1 = helper.getNode(serviceId)
- const h1 = helper.getNode('h1')
-
- let count = 0
-
- h1.on('input', function (msg: any) {
- if (count === 0) {
- try {
- msg.payload.should.have.property('On', true)
- msg.hap.should.have.property('newValue', true)
- msg.hap.should.have.property('reachable', true)
- done()
- } catch (err) {
- done(err)
- }
- count++
- }
- })
-
- s1.receive({ payload: { On: true } })
- }
- )
- .catch((error: any) => {
- done(new Error(error))
- })
+ s1.receive({ payload: { On: true } })
})
+ })
+
+ it('should output ON:false payload', async () => {
+ const { serviceId, flow } = switchService2BridgeFlow()
+ await helper.load([nrchkb, homekitBridgeNode, homekitService2Node], flow)
+ const s1 = helper.getNode(serviceId)
- it('should output reachable false', function (done) {
- const { serviceId, flow } = switchService2BridgeFlow()
- helper
- .load(
- [nrchkb, homekitBridgeNode, homekitService2Node],
- flow,
- function () {
- const s1 = helper.getNode(serviceId)
- const h1 = helper.getNode('h1')
-
- h1.on('input', function (msg: any) {
- try {
- msg.payload.should.have.property('On', false)
- msg.hap.should.have.property('reachable', false)
- // @ts-ignore
- s1.status.should.be.calledWithExactly({
- fill: 'red',
- shape: 'ring',
- text: 'Not reachable',
- type: 'NO_RESPONSE',
- })
- done()
- } catch (err) {
- done(err)
- }
- })
-
- s1.receive({ payload: { On: 'NO_RESPONSE' } })
- }
- )
- .catch((error: any) => {
- done(new Error(error))
- })
+ await new Promise((resolve) => {
+ s1.on('input', (msg: any) => {
+ expect(msg.payload).toHaveProperty('On', false)
+ resolve()
+ })
+
+ s1.receive({ payload: { On: false } })
+ })
+ })
+
+ it('should output reachable true', async () => {
+ const { serviceId, flow } = switchService2BridgeFlow()
+ await helper.load([nrchkb, homekitBridgeNode, homekitService2Node], flow)
+ const s1 = helper.getNode(serviceId)
+ const h1 = helper.getNode('h1')
+
+ let count = 0
+
+ await new Promise((resolve) => {
+ h1.on('input', (msg: any) => {
+ if (count === 0) {
+ expect(msg.payload).toHaveProperty('On', true)
+ expect(msg.hap).toHaveProperty('newValue', true)
+ expect(msg.hap).toHaveProperty('reachable', true)
+ resolve()
+ count++
+ }
+ })
+
+ s1.receive({ payload: { On: true } })
+ })
+ })
+
+ it('should output reachable false', async () => {
+ const { serviceId, flow } = switchService2BridgeFlow()
+ await helper.load([nrchkb, homekitBridgeNode, homekitService2Node], flow)
+ const s1 = helper.getNode(serviceId)
+ const h1 = helper.getNode('h1')
+
+ await new Promise((resolve, reject) => {
+ const statusSpy = vi
+ .spyOn(s1 as any, 'status')
+ .mockImplementation(() => {})
+
+ h1.on('input', (msg: any) => {
+ try {
+ expect(msg.payload).toHaveProperty('On', false)
+ expect(msg.hap).toHaveProperty('reachable', false)
+ expect(statusSpy).toHaveBeenCalledWith({
+ fill: 'red',
+ shape: 'ring',
+ text: 'Not reachable',
+ type: 'NO_RESPONSE'
+ })
+ resolve()
+ } catch (err) {
+ reject(err)
+ }
+ })
+
+ s1.receive({ payload: { On: 'NO_RESPONSE' } })
})
+ })
})
diff --git a/src/test/test-utils/data/api.accessory.categories.response.ts b/src/test/test-utils/data/api.accessory.categories.response.ts
index 25b318ba..cef33f77 100644
--- a/src/test/test-utils/data/api.accessory.categories.response.ts
+++ b/src/test/test-utils/data/api.accessory.categories.response.ts
@@ -1,38 +1,38 @@
export const accessoryCategoriesResponse = {
- '1': 'OTHER',
- '2': 'BRIDGE',
- '3': 'FAN',
- '4': 'GARAGE_DOOR_OPENER',
- '5': 'LIGHTBULB',
- '6': 'DOOR_LOCK',
- '7': 'OUTLET',
- '8': 'SWITCH',
- '9': 'THERMOSTAT',
- '10': 'SENSOR',
- '11': 'SECURITY_SYSTEM',
- '12': 'DOOR',
- '13': 'WINDOW',
- '14': 'WINDOW_COVERING',
- '15': 'PROGRAMMABLE_SWITCH',
- '16': 'RANGE_EXTENDER',
- '17': 'IP_CAMERA',
- '18': 'VIDEO_DOORBELL',
- '19': 'AIR_PURIFIER',
- '20': 'AIR_HEATER',
- '21': 'AIR_CONDITIONER',
- '22': 'AIR_HUMIDIFIER',
- '23': 'AIR_DEHUMIDIFIER',
- '24': 'APPLE_TV',
- '25': 'HOMEPOD',
- '26': 'SPEAKER',
- '27': 'AIRPORT',
- '28': 'SPRINKLER',
- '29': 'FAUCET',
- '30': 'SHOWER_HEAD',
- '31': 'TELEVISION',
- '32': 'TARGET_CONTROLLER',
- '33': 'ROUTER',
- '34': 'AUDIO_RECEIVER',
- '35': 'TV_SET_TOP_BOX',
- '36': 'TV_STREAMING_STICK',
+ '1': 'OTHER',
+ '2': 'BRIDGE',
+ '3': 'FAN',
+ '4': 'GARAGE_DOOR_OPENER',
+ '5': 'LIGHTBULB',
+ '6': 'DOOR_LOCK',
+ '7': 'OUTLET',
+ '8': 'SWITCH',
+ '9': 'THERMOSTAT',
+ '10': 'SENSOR',
+ '11': 'SECURITY_SYSTEM',
+ '12': 'DOOR',
+ '13': 'WINDOW',
+ '14': 'WINDOW_COVERING',
+ '15': 'PROGRAMMABLE_SWITCH',
+ '16': 'RANGE_EXTENDER',
+ '17': 'IP_CAMERA',
+ '18': 'VIDEO_DOORBELL',
+ '19': 'AIR_PURIFIER',
+ '20': 'AIR_HEATER',
+ '21': 'AIR_CONDITIONER',
+ '22': 'AIR_HUMIDIFIER',
+ '23': 'AIR_DEHUMIDIFIER',
+ '24': 'APPLE_TV',
+ '25': 'HOMEPOD',
+ '26': 'SPEAKER',
+ '27': 'AIRPORT',
+ '28': 'SPRINKLER',
+ '29': 'FAUCET',
+ '30': 'SHOWER_HEAD',
+ '31': 'TELEVISION',
+ '32': 'TARGET_CONTROLLER',
+ '33': 'ROUTER',
+ '34': 'AUDIO_RECEIVER',
+ '35': 'TV_SET_TOP_BOX',
+ '36': 'TV_STREAMING_STICK'
}
diff --git a/src/test/test-utils/data/api.service.types.response.ts b/src/test/test-utils/data/api.service.types.response.ts
index b5cfc68b..71ada317 100644
--- a/src/test/test-utils/data/api.service.types.response.ts
+++ b/src/test/test-utils/data/api.service.types.response.ts
@@ -1,6457 +1,6146 @@
export const serviceTypesResponse = {
- AccessCode: {
- UUID: '00000260-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000262-0000-1000-8000-0026BB765291',
- constructorName: 'AccessCodeControlPoint',
- displayName: 'Access Code Control Point',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr', 'pw', 'wr'],
- },
- value: '',
- },
- {
- UUID: '00000261-0000-1000-8000-0026BB765291',
- constructorName: 'AccessCodeSupportedConfiguration',
- displayName: 'Access Code Supported Configuration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000263-0000-1000-8000-0026BB765291',
- constructorName: 'ConfigurationState',
- displayName: 'Configuration State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint16',
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- ],
- constructorName: 'AccessCode',
- displayName: 'AccessCode',
- hiddenService: false,
- optionalCharacteristics: [],
- primaryService: false,
- },
- AccessControl: {
- UUID: '000000DA-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '000000E5-0000-1000-8000-0026BB765291',
- constructorName: 'AccessControlLevel',
- displayName: 'Access Control Level',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint16',
- maxValue: 2,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- },
- value: 0,
- },
- ],
- constructorName: 'AccessControl',
- displayName: 'AccessControl',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '000000E4-0000-1000-8000-0026BB765291',
- constructorName: 'PasswordSetting',
- displayName: 'Password Setting',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['ev', 'pr', 'pw'],
- },
- value: '',
- },
- ],
- primaryService: false,
- },
- AccessoryInformation: {
- UUID: '0000003E-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000014-0000-1000-8000-0026BB765291',
- constructorName: 'Identify',
- displayName: 'Identify',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['pw'],
- },
- value: false,
- },
- {
- UUID: '00000020-0000-1000-8000-0026BB765291',
- constructorName: 'Manufacturer',
- displayName: 'Manufacturer',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: 'Default-Manufacturer',
- },
- {
- UUID: '00000021-0000-1000-8000-0026BB765291',
- constructorName: 'Model',
- displayName: 'Model',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: 'Default-Model',
- },
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: 'Unnamed Service',
- },
- {
- UUID: '00000030-0000-1000-8000-0026BB765291',
- constructorName: 'SerialNumber',
- displayName: 'Serial Number',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: 'Default-SerialNumber',
- },
- {
- UUID: '00000052-0000-1000-8000-0026BB765291',
- constructorName: 'FirmwareRevision',
- displayName: 'Firmware Revision',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- perms: ['pr'],
- },
- value: '0.0.0',
- },
- ],
- constructorName: 'AccessoryInformation',
- displayName: 'AccessoryInformation',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '000000A6-0000-1000-8000-0026BB765291',
- constructorName: 'AccessoryFlags',
- displayName: 'Accessory Flags',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint32',
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- {
- UUID: '000000A4-0000-1000-8000-0026BB765291',
- constructorName: 'AppMatchingIdentifier',
- displayName: 'App Matching Identifier',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '000000E3-0000-1000-8000-0026BB765291',
- constructorName: 'ConfiguredName',
- displayName: 'Configured Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- perms: ['ev', 'pr', 'pw'],
- },
- value: '',
- },
- {
- UUID: '0000026C-0000-1000-8000-0026BB765291',
- constructorName: 'HardwareFinish',
- displayName: 'Hardware Finish',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000053-0000-1000-8000-0026BB765291',
- constructorName: 'HardwareRevision',
- displayName: 'Hardware Revision',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000220-0000-1000-8000-0026BB765291',
- constructorName: 'ProductData',
- displayName: 'Product Data',
- eventOnlyCharacteristic: false,
- props: {
- format: 'data',
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000054-0000-1000-8000-0026BB765291',
- constructorName: 'SoftwareRevision',
- displayName: 'Software Revision',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- perms: ['pr'],
- },
- value: '',
- },
- ],
- primaryService: false,
- },
- AccessoryMetrics: {
- UUID: '00000270-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '000000B0-0000-1000-8000-0026BB765291',
- constructorName: 'Active',
- displayName: 'Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000272-0000-1000-8000-0026BB765291',
- constructorName: 'MetricsBufferFullState',
- displayName: 'Metrics Buffer Full State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr'],
- },
- value: false,
- },
- {
- UUID: '00000271-0000-1000-8000-0026BB765291',
- constructorName: 'SupportedMetrics',
- displayName: 'Supported Metrics',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr', 'pw'],
- },
- value: '',
- },
- ],
- constructorName: 'AccessoryMetrics',
- displayName: 'AccessoryMetrics',
- hiddenService: false,
- optionalCharacteristics: [],
- primaryService: false,
- },
- AccessoryRuntimeInformation: {
- UUID: '00000239-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '0000023C-0000-1000-8000-0026BB765291',
- constructorName: 'Ping',
- displayName: 'Ping',
- eventOnlyCharacteristic: false,
- props: {
- format: 'data',
- perms: ['pr'],
- },
- value: '',
- },
- ],
- constructorName: 'AccessoryRuntimeInformation',
- displayName: 'AccessoryRuntimeInformation',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '0000023B-0000-1000-8000-0026BB765291',
- constructorName: 'ActivityInterval',
- displayName: 'Activity Interval',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint32',
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- {
- UUID: '0000024A-0000-1000-8000-0026BB765291',
- constructorName: 'HeartBeat',
- displayName: 'Heart Beat',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint32',
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- {
- UUID: '0000023A-0000-1000-8000-0026BB765291',
- constructorName: 'SleepInterval',
- displayName: 'Sleep Interval',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint32',
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- AirPurifier: {
- UUID: '000000BB-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '000000B0-0000-1000-8000-0026BB765291',
- constructorName: 'Active',
- displayName: 'Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '000000A9-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentAirPurifierState',
- displayName: 'Current Air Purifier State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 2,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2],
- },
- value: 0,
- },
- {
- UUID: '000000A8-0000-1000-8000-0026BB765291',
- constructorName: 'TargetAirPurifierState',
- displayName: 'Target Air Purifier State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- constructorName: 'AirPurifier',
- displayName: 'AirPurifier',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '000000A7-0000-1000-8000-0026BB765291',
- constructorName: 'LockPhysicalControls',
- displayName: 'Lock Physical Controls',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000029-0000-1000-8000-0026BB765291',
- constructorName: 'RotationSpeed',
- displayName: 'Rotation Speed',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'percentage',
- },
- value: 0,
- },
- {
- UUID: '000000B6-0000-1000-8000-0026BB765291',
- constructorName: 'SwingMode',
- displayName: 'Swing Mode',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- AirQualitySensor: {
- UUID: '0000008D-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000095-0000-1000-8000-0026BB765291',
- constructorName: 'AirQuality',
- displayName: 'Air Quality',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 5,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2, 3, 4, 5],
- },
- value: 0,
- },
- ],
- constructorName: 'AirQualitySensor',
- displayName: 'AirQualitySensor',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '000000C4-0000-1000-8000-0026BB765291',
- constructorName: 'NitrogenDioxideDensity',
- displayName: 'Nitrogen Dioxide Density',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 1000,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- {
- UUID: '000000C3-0000-1000-8000-0026BB765291',
- constructorName: 'OzoneDensity',
- displayName: 'Ozone Density',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 1000,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- {
- UUID: '000000C7-0000-1000-8000-0026BB765291',
- constructorName: 'PM10Density',
- displayName: 'PM10 Density',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 1000,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- {
- UUID: '000000C6-0000-1000-8000-0026BB765291',
- constructorName: 'PM2_5Density',
- displayName: 'PM2.5 Density',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 1000,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- {
- UUID: '000000C5-0000-1000-8000-0026BB765291',
- constructorName: 'SulphurDioxideDensity',
- displayName: 'Sulphur Dioxide Density',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 1000,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- {
- UUID: '000000C8-0000-1000-8000-0026BB765291',
- constructorName: 'VOCDensity',
- displayName: 'VOC Density',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 1000,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000075-0000-1000-8000-0026BB765291',
- constructorName: 'StatusActive',
- displayName: 'Status Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr'],
- },
- value: false,
- },
- {
- UUID: '00000077-0000-1000-8000-0026BB765291',
- constructorName: 'StatusFault',
- displayName: 'Status Fault',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000079-0000-1000-8000-0026BB765291',
- constructorName: 'StatusLowBattery',
- displayName: 'Status Low Battery',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '0000007A-0000-1000-8000-0026BB765291',
- constructorName: 'StatusTampered',
- displayName: 'Status Tampered',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- AssetUpdate: {
- UUID: '00000267-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000269-0000-1000-8000-0026BB765291',
- constructorName: 'AssetUpdateReadiness',
- displayName: 'Asset Update Readiness',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint32',
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- {
- UUID: '00000268-0000-1000-8000-0026BB765291',
- constructorName: 'SupportedAssetTypes',
- displayName: 'Supported Asset Types',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint32',
- perms: ['pr'],
- },
- value: 0,
- },
- ],
- constructorName: 'AssetUpdate',
- displayName: 'AssetUpdate',
- hiddenService: false,
- optionalCharacteristics: [],
- primaryService: false,
- },
- Assistant: {
- UUID: '0000026A-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '000000B0-0000-1000-8000-0026BB765291',
- constructorName: 'Active',
- displayName: 'Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '000000E6-0000-1000-8000-0026BB765291',
- constructorName: 'Identifier',
- displayName: 'Identifier',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint32',
- perms: ['pr'],
- },
- value: 0,
- },
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: 'Unnamed Service',
- },
- ],
- constructorName: 'Assistant',
- displayName: 'Assistant',
- hiddenService: false,
- optionalCharacteristics: [],
- primaryService: false,
- },
- AudioStreamManagement: {
- UUID: '00000127-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000115-0000-1000-8000-0026BB765291',
- constructorName: 'SupportedAudioStreamConfiguration',
- displayName: 'Supported Audio Stream Configuration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000128-0000-1000-8000-0026BB765291',
- constructorName: 'SelectedAudioStreamConfiguration',
- displayName: 'Selected Audio Stream Configuration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr', 'pw'],
- },
- value: '',
- },
- ],
- constructorName: 'AudioStreamManagement',
- displayName: 'AudioStreamManagement',
- hiddenService: false,
- optionalCharacteristics: [],
- primaryService: false,
- },
- Battery: {
- UUID: '00000096-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000079-0000-1000-8000-0026BB765291',
- constructorName: 'StatusLowBattery',
- displayName: 'Status Low Battery',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- constructorName: 'Battery',
- displayName: 'Battery',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000068-0000-1000-8000-0026BB765291',
- constructorName: 'BatteryLevel',
- displayName: 'Battery Level',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- unit: 'percentage',
- },
- value: 0,
- },
- {
- UUID: '0000008F-0000-1000-8000-0026BB765291',
- constructorName: 'ChargingState',
- displayName: 'Charging State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 2,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2],
- },
- value: 0,
- },
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- ],
- primaryService: false,
- },
- BatteryService: {
- nrchkbDisabledText: 'BatteryService (deprecated, replaced by Battery)',
- },
- BridgeConfiguration: {
- UUID: '000000A1-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '0000009D-0000-1000-8000-0026BB765291',
- constructorName: 'ConfigureBridgedAccessoryStatus',
- displayName: 'Configure Bridged Accessory Status',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['ev', 'pr'],
- },
- value: '',
- },
- {
- UUID: '0000009E-0000-1000-8000-0026BB765291',
- constructorName: 'DiscoverBridgedAccessories',
- displayName: 'Discover Bridged Accessories',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- perms: ['ev', 'pr', 'pw'],
- },
- value: 0,
- },
- {
- UUID: '0000009F-0000-1000-8000-0026BB765291',
- constructorName: 'DiscoveredBridgedAccessories',
- displayName: 'Discovered Bridged Accessories',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint16',
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- {
- UUID: '000000A0-0000-1000-8000-0026BB765291',
- constructorName: 'ConfigureBridgedAccessory',
- displayName: 'Configure Bridged Accessory',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pw'],
- },
- value: '',
- },
- ],
- constructorName: 'BridgeConfiguration',
- displayName: 'BridgeConfiguration',
- hiddenService: false,
- nrchkbDisabledText: 'BridgeConfiguration (deprecated, unused)',
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- ],
- primaryService: false,
- },
- BridgingState: {
- UUID: '00000062-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000063-0000-1000-8000-0026BB765291',
- constructorName: 'Reachable',
- displayName: 'Reachable',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['pr', 'pw'],
- },
- value: false,
- },
- {
- UUID: '0000009C-0000-1000-8000-0026BB765291',
- constructorName: 'LinkQuality',
- displayName: 'Link Quality',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 4,
- minValue: 1,
- perms: ['ev', 'pr'],
- },
- value: 1,
- },
- {
- UUID: '00000057-0000-1000-8000-0026BB765291',
- constructorName: 'AccessoryIdentifier',
- displayName: 'Accessory Identifier',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '000000A3-0000-1000-8000-0026BB765291',
- constructorName: 'Category',
- displayName: 'Category',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint16',
- maxValue: 16,
- minValue: 1,
- perms: ['ev', 'pr'],
- },
- value: 1,
- },
- ],
- constructorName: 'BridgingState',
- displayName: 'BridgingState',
- hiddenService: false,
- nrchkbDisabledText: 'BridgingState (deprecated, unused)',
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- ],
- primaryService: false,
- },
- CameraControl: {
- UUID: '00000111-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000025-0000-1000-8000-0026BB765291',
- constructorName: 'On',
- displayName: 'On',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr', 'pw'],
- },
- value: false,
- },
- ],
- constructorName: 'CameraControl',
- displayName: 'CameraControl',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '0000006C-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentHorizontalTiltAngle',
- displayName: 'Current Horizontal Tilt Angle',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- maxValue: 90,
- minStep: 1,
- minValue: -90,
- perms: ['ev', 'pr'],
- unit: 'arcdegrees',
- },
- value: -90,
- },
- {
- UUID: '0000006E-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentVerticalTiltAngle',
- displayName: 'Current Vertical Tilt Angle',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- maxValue: 90,
- minStep: 1,
- minValue: -90,
- perms: ['ev', 'pr'],
- unit: 'arcdegrees',
- },
- value: -90,
- },
- {
- UUID: '0000007B-0000-1000-8000-0026BB765291',
- constructorName: 'TargetHorizontalTiltAngle',
- displayName: 'Target Horizontal Tilt Angle',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- maxValue: 90,
- minStep: 1,
- minValue: -90,
- perms: ['ev', 'pr', 'pw'],
- unit: 'arcdegrees',
- },
- value: -90,
- },
- {
- UUID: '0000007D-0000-1000-8000-0026BB765291',
- constructorName: 'TargetVerticalTiltAngle',
- displayName: 'Target Vertical Tilt Angle',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- maxValue: 90,
- minStep: 1,
- minValue: -90,
- perms: ['ev', 'pr', 'pw'],
- unit: 'arcdegrees',
- },
- value: -90,
- },
- {
- UUID: '0000011B-0000-1000-8000-0026BB765291',
- constructorName: 'NightVision',
- displayName: 'Night Vision',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr', 'pw', 'tw'],
- },
- value: false,
- },
- {
- UUID: '0000011C-0000-1000-8000-0026BB765291',
- constructorName: 'OpticalZoom',
- displayName: 'Optical Zoom',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- minStep: 0.1,
- perms: ['ev', 'pr', 'pw'],
- },
- value: 0,
- },
- {
- UUID: '0000011D-0000-1000-8000-0026BB765291',
- constructorName: 'DigitalZoom',
- displayName: 'Digital Zoom',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- minStep: 0.1,
- perms: ['ev', 'pr', 'pw'],
- },
- value: 0,
- },
- {
- UUID: '0000011E-0000-1000-8000-0026BB765291',
- constructorName: 'ImageRotation',
- displayName: 'Image Rotation',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- maxValue: 360,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'arcdegrees',
- },
- value: 0,
- },
- {
- UUID: '0000011F-0000-1000-8000-0026BB765291',
- constructorName: 'ImageMirroring',
- displayName: 'Image Mirroring',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr', 'pw'],
- },
- value: false,
- },
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- ],
- primaryService: false,
- },
- CameraEventRecordingManagement: {
- nrchkbDisabledText:
- 'CameraEventRecordingManagement (deprecated, replaced by CameraRecordingManagement)',
- },
- CameraOperatingMode: {
- UUID: '0000021A-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000223-0000-1000-8000-0026BB765291',
- constructorName: 'EventSnapshotsActive',
- displayName: 'Event Snapshots Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '0000021B-0000-1000-8000-0026BB765291',
- constructorName: 'HomeKitCameraActive',
- displayName: 'HomeKit Camera Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- constructorName: 'CameraOperatingMode',
- displayName: 'CameraOperatingMode',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '0000021D-0000-1000-8000-0026BB765291',
- constructorName: 'CameraOperatingModeIndicator',
- displayName: 'Camera Operating Mode Indicator',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr', 'pw', 'tw'],
- },
- value: false,
- },
- {
- UUID: '00000227-0000-1000-8000-0026BB765291',
- constructorName: 'ManuallyDisabled',
- displayName: 'Manually Disabled',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr'],
- },
- value: false,
- },
- {
- UUID: '0000011B-0000-1000-8000-0026BB765291',
- constructorName: 'NightVision',
- displayName: 'Night Vision',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr', 'pw', 'tw'],
- },
- value: false,
- },
- {
- UUID: '00000225-0000-1000-8000-0026BB765291',
- constructorName: 'PeriodicSnapshotsActive',
- displayName: 'Periodic Snapshots Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '0000021C-0000-1000-8000-0026BB765291',
- constructorName: 'ThirdPartyCameraActive',
- displayName: 'Third Party Camera Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000224-0000-1000-8000-0026BB765291',
- constructorName: 'DiagonalFieldOfView',
- displayName: 'Diagonal Field Of View',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 360,
- minValue: 0,
- perms: ['ev', 'pr'],
- unit: 'arcdegrees',
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- CameraRTPStreamManagement: {
- UUID: '00000110-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000117-0000-1000-8000-0026BB765291',
- constructorName: 'SelectedRTPStreamConfiguration',
- displayName: 'Selected RTP Stream Configuration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr', 'pw'],
- },
- value: '',
- },
- {
- UUID: '00000118-0000-1000-8000-0026BB765291',
- constructorName: 'SetupEndpoints',
- displayName: 'Setup Endpoints',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr', 'pw'],
- },
- value: '',
- },
- {
- UUID: '00000120-0000-1000-8000-0026BB765291',
- constructorName: 'StreamingStatus',
- displayName: 'Streaming Status',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['ev', 'pr'],
- },
- value: '',
- },
- {
- UUID: '00000115-0000-1000-8000-0026BB765291',
- constructorName: 'SupportedAudioStreamConfiguration',
- displayName: 'Supported Audio Stream Configuration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000116-0000-1000-8000-0026BB765291',
- constructorName: 'SupportedRTPConfiguration',
- displayName: 'Supported RTP Configuration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000114-0000-1000-8000-0026BB765291',
- constructorName: 'SupportedVideoStreamConfiguration',
- displayName: 'Supported Video Stream Configuration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr'],
- },
- value: '',
- },
- ],
- constructorName: 'CameraRTPStreamManagement',
- displayName: 'CameraRTPStreamManagement',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '000000B0-0000-1000-8000-0026BB765291',
- constructorName: 'Active',
- displayName: 'Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- CameraRecordingManagement: {
- UUID: '00000204-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '000000B0-0000-1000-8000-0026BB765291',
- constructorName: 'Active',
- displayName: 'Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000209-0000-1000-8000-0026BB765291',
- constructorName: 'SelectedCameraRecordingConfiguration',
- displayName: 'Selected Camera Recording Configuration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['ev', 'pr', 'pw'],
- },
- value: '',
- },
- {
- UUID: '00000207-0000-1000-8000-0026BB765291',
- constructorName: 'SupportedAudioRecordingConfiguration',
- displayName: 'Supported Audio Recording Configuration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['ev', 'pr'],
- },
- value: '',
- },
- {
- UUID: '00000205-0000-1000-8000-0026BB765291',
- constructorName: 'SupportedCameraRecordingConfiguration',
- displayName: 'Supported Camera Recording Configuration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['ev', 'pr'],
- },
- value: '',
- },
- {
- UUID: '00000206-0000-1000-8000-0026BB765291',
- constructorName: 'SupportedVideoRecordingConfiguration',
- displayName: 'Supported Video Recording Configuration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['ev', 'pr'],
- },
- value: '',
- },
- ],
- constructorName: 'CameraRecordingManagement',
- displayName: 'CameraRecordingManagement',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000226-0000-1000-8000-0026BB765291',
- constructorName: 'RecordingAudioActive',
- displayName: 'Recording Audio Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- perms: ['ev', 'pr', 'pw', 'tw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- CarbonDioxideSensor: {
- UUID: '00000097-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000092-0000-1000-8000-0026BB765291',
- constructorName: 'CarbonDioxideDetected',
- displayName: 'Carbon Dioxide Detected',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- constructorName: 'CarbonDioxideSensor',
- displayName: 'CarbonDioxideSensor',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000093-0000-1000-8000-0026BB765291',
- constructorName: 'CarbonDioxideLevel',
- displayName: 'Carbon Dioxide Level',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 100000,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- {
- UUID: '00000094-0000-1000-8000-0026BB765291',
- constructorName: 'CarbonDioxidePeakLevel',
- displayName: 'Carbon Dioxide Peak Level',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 100000,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000075-0000-1000-8000-0026BB765291',
- constructorName: 'StatusActive',
- displayName: 'Status Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr'],
- },
- value: false,
- },
- {
- UUID: '00000077-0000-1000-8000-0026BB765291',
- constructorName: 'StatusFault',
- displayName: 'Status Fault',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000079-0000-1000-8000-0026BB765291',
- constructorName: 'StatusLowBattery',
- displayName: 'Status Low Battery',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '0000007A-0000-1000-8000-0026BB765291',
- constructorName: 'StatusTampered',
- displayName: 'Status Tampered',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- CarbonMonoxideSensor: {
- UUID: '0000007F-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000069-0000-1000-8000-0026BB765291',
- constructorName: 'CarbonMonoxideDetected',
- displayName: 'Carbon Monoxide Detected',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- constructorName: 'CarbonMonoxideSensor',
- displayName: 'CarbonMonoxideSensor',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000090-0000-1000-8000-0026BB765291',
- constructorName: 'CarbonMonoxideLevel',
- displayName: 'Carbon Monoxide Level',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- {
- UUID: '00000091-0000-1000-8000-0026BB765291',
- constructorName: 'CarbonMonoxidePeakLevel',
- displayName: 'Carbon Monoxide Peak Level',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000075-0000-1000-8000-0026BB765291',
- constructorName: 'StatusActive',
- displayName: 'Status Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr'],
- },
- value: false,
- },
- {
- UUID: '00000077-0000-1000-8000-0026BB765291',
- constructorName: 'StatusFault',
- displayName: 'Status Fault',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000079-0000-1000-8000-0026BB765291',
- constructorName: 'StatusLowBattery',
- displayName: 'Status Low Battery',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '0000007A-0000-1000-8000-0026BB765291',
- constructorName: 'StatusTampered',
- displayName: 'Status Tampered',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- CloudRelay: {
- UUID: '0000005A-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '0000005E-0000-1000-8000-0026BB765291',
- constructorName: 'RelayControlPoint',
- displayName: 'Relay Control Point',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['ev', 'pr', 'pw'],
- },
- value: '',
- },
- {
- UUID: '0000005C-0000-1000-8000-0026BB765291',
- constructorName: 'RelayState',
- displayName: 'Relay State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 5,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- {
- UUID: '0000005B-0000-1000-8000-0026BB765291',
- constructorName: 'RelayEnabled',
- displayName: 'Relay Enabled',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr', 'pw'],
- },
- value: false,
- },
- ],
- constructorName: 'CloudRelay',
- displayName: 'CloudRelay',
- hiddenService: false,
- optionalCharacteristics: [],
- primaryService: false,
- },
- ContactSensor: {
- UUID: '00000080-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '0000006A-0000-1000-8000-0026BB765291',
- constructorName: 'ContactSensorState',
- displayName: 'Contact Sensor State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- constructorName: 'ContactSensor',
- displayName: 'ContactSensor',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000075-0000-1000-8000-0026BB765291',
- constructorName: 'StatusActive',
- displayName: 'Status Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr'],
- },
- value: false,
- },
- {
- UUID: '00000077-0000-1000-8000-0026BB765291',
- constructorName: 'StatusFault',
- displayName: 'Status Fault',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000079-0000-1000-8000-0026BB765291',
- constructorName: 'StatusLowBattery',
- displayName: 'Status Low Battery',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '0000007A-0000-1000-8000-0026BB765291',
- constructorName: 'StatusTampered',
- displayName: 'Status Tampered',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- DataStreamTransportManagement: {
- UUID: '00000129-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000131-0000-1000-8000-0026BB765291',
- constructorName: 'SetupDataStreamTransport',
- displayName: 'Setup Data Stream Transport',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr', 'pw', 'wr'],
- },
- value: '',
- },
- {
- UUID: '00000130-0000-1000-8000-0026BB765291',
- constructorName: 'SupportedDataStreamTransportConfiguration',
- displayName: 'Supported Data Stream Transport Configuration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000037-0000-1000-8000-0026BB765291',
- constructorName: 'Version',
- displayName: 'Version',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- ],
- constructorName: 'DataStreamTransportManagement',
- displayName: 'DataStreamTransportManagement',
- hiddenService: false,
- optionalCharacteristics: [],
- primaryService: false,
- },
- Diagnostics: {
- UUID: '00000237-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000238-0000-1000-8000-0026BB765291',
- constructorName: 'SupportedDiagnosticsSnapshot',
- displayName: 'Supported Diagnostics Snapshot',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr'],
- },
- value: '',
- },
- ],
- constructorName: 'Diagnostics',
- displayName: 'Diagnostics',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '0000024D-0000-1000-8000-0026BB765291',
- constructorName: 'SelectedDiagnosticsModes',
- displayName: 'Selected Diagnostics Modes',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint32',
- perms: ['pr', 'pw'],
- },
- value: 0,
- },
- {
- UUID: '0000024C-0000-1000-8000-0026BB765291',
- constructorName: 'SupportedDiagnosticsModes',
- displayName: 'Supported Diagnostics Modes',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint32',
- perms: ['pr'],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- Door: {
- UUID: '00000081-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '0000006D-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentPosition',
- displayName: 'Current Position',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- unit: 'percentage',
- },
- value: 0,
- },
- {
- UUID: '00000072-0000-1000-8000-0026BB765291',
- constructorName: 'PositionState',
- displayName: 'Position State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 2,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2],
- },
- value: 0,
- },
- {
- UUID: '0000007C-0000-1000-8000-0026BB765291',
- constructorName: 'TargetPosition',
- displayName: 'Target Position',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'percentage',
- },
- value: 0,
- },
- ],
- constructorName: 'Door',
- displayName: 'Door',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000024-0000-1000-8000-0026BB765291',
- constructorName: 'ObstructionDetected',
- displayName: 'Obstruction Detected',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr'],
- },
- value: false,
- },
- {
- UUID: '0000006F-0000-1000-8000-0026BB765291',
- constructorName: 'HoldPosition',
- displayName: 'Hold Position',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['pw'],
- },
- value: false,
- },
- ],
- primaryService: false,
- },
- Doorbell: {
- UUID: '00000121-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000073-0000-1000-8000-0026BB765291',
- constructorName: 'ProgrammableSwitchEvent',
- displayName: 'Programmable Switch Event',
- eventOnlyCharacteristic: true,
- props: {
- format: 'uint8',
- maxValue: 2,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2],
- },
- value: 0,
- },
- ],
- constructorName: 'Doorbell',
- displayName: 'Doorbell',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000008-0000-1000-8000-0026BB765291',
- constructorName: 'Brightness',
- displayName: 'Brightness',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'percentage',
- },
- value: 0,
- },
- {
- UUID: '0000011A-0000-1000-8000-0026BB765291',
- constructorName: 'Mute',
- displayName: 'Mute',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr', 'pw'],
- },
- value: false,
- },
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000232-0000-1000-8000-0026BB765291',
- constructorName: 'OperatingStateResponse',
- displayName: 'Operating State Response',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['ev', 'pr'],
- },
- value: '',
- },
- {
- UUID: '00000119-0000-1000-8000-0026BB765291',
- constructorName: 'Volume',
- displayName: 'Volume',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'percentage',
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- Fan: {
- UUID: '00000040-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000025-0000-1000-8000-0026BB765291',
- constructorName: 'On',
- displayName: 'On',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr', 'pw'],
- },
- value: false,
- },
- ],
- constructorName: 'Fan',
- displayName: 'Fan',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000028-0000-1000-8000-0026BB765291',
- constructorName: 'RotationDirection',
- displayName: 'Rotation Direction',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000029-0000-1000-8000-0026BB765291',
- constructorName: 'RotationSpeed',
- displayName: 'Rotation Speed',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'percentage',
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- Fanv2: {
- UUID: '000000B7-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '000000B0-0000-1000-8000-0026BB765291',
- constructorName: 'Active',
- displayName: 'Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- constructorName: 'Fanv2',
- displayName: 'Fanv2',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '000000AF-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentFanState',
- displayName: 'Current Fan State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 2,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2],
- },
- value: 0,
- },
- {
- UUID: '000000BF-0000-1000-8000-0026BB765291',
- constructorName: 'TargetFanState',
- displayName: 'Target Fan State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '000000A7-0000-1000-8000-0026BB765291',
- constructorName: 'LockPhysicalControls',
- displayName: 'Lock Physical Controls',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000028-0000-1000-8000-0026BB765291',
- constructorName: 'RotationDirection',
- displayName: 'Rotation Direction',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000029-0000-1000-8000-0026BB765291',
- constructorName: 'RotationSpeed',
- displayName: 'Rotation Speed',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'percentage',
- },
- value: 0,
- },
- {
- UUID: '000000B6-0000-1000-8000-0026BB765291',
- constructorName: 'SwingMode',
- displayName: 'Swing Mode',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- Faucet: {
- UUID: '000000D7-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '000000B0-0000-1000-8000-0026BB765291',
- constructorName: 'Active',
- displayName: 'Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- constructorName: 'Faucet',
- displayName: 'Faucet',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000077-0000-1000-8000-0026BB765291',
- constructorName: 'StatusFault',
- displayName: 'Status Fault',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- FilterMaintenance: {
- UUID: '000000BA-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '000000AC-0000-1000-8000-0026BB765291',
- constructorName: 'FilterChangeIndication',
- displayName: 'Filter Change Indication',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- constructorName: 'FilterMaintenance',
- displayName: 'FilterMaintenance',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '000000AB-0000-1000-8000-0026BB765291',
- constructorName: 'FilterLifeLevel',
- displayName: 'Filter Life Level',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- {
- UUID: '000000AD-0000-1000-8000-0026BB765291',
- constructorName: 'ResetFilterIndication',
- displayName: 'Reset Filter Indication',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 1,
- perms: ['pw'],
- },
- value: 1,
- },
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- ],
- primaryService: false,
- },
- FirmwareUpdate: {
- UUID: '00000236-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000234-0000-1000-8000-0026BB765291',
- constructorName: 'FirmwareUpdateReadiness',
- displayName: 'Firmware Update Readiness',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['ev', 'pr'],
- },
- value: '',
- },
- {
- UUID: '00000235-0000-1000-8000-0026BB765291',
- constructorName: 'FirmwareUpdateStatus',
- displayName: 'Firmware Update Status',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['ev', 'pr'],
- },
- value: '',
- },
- ],
- constructorName: 'FirmwareUpdate',
- displayName: 'FirmwareUpdate',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000249-0000-1000-8000-0026BB765291',
- constructorName: 'StagedFirmwareVersion',
- displayName: 'Staged Firmware Version',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- perms: ['ev', 'pr'],
- },
- value: '',
- },
- {
- UUID: '00000233-0000-1000-8000-0026BB765291',
- constructorName: 'SupportedFirmwareUpdateConfiguration',
- displayName: 'Supported Firmware Update Configuration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr'],
- },
- value: '',
- },
- ],
- primaryService: false,
- },
- GarageDoorOpener: {
- UUID: '00000041-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '0000000E-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentDoorState',
- displayName: 'Current Door State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 4,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2, 3, 4],
- },
- value: 0,
- },
- {
- UUID: '00000032-0000-1000-8000-0026BB765291',
- constructorName: 'TargetDoorState',
- displayName: 'Target Door State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000024-0000-1000-8000-0026BB765291',
- constructorName: 'ObstructionDetected',
- displayName: 'Obstruction Detected',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr'],
- },
- value: false,
- },
- ],
- constructorName: 'GarageDoorOpener',
- displayName: 'GarageDoorOpener',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '0000001D-0000-1000-8000-0026BB765291',
- constructorName: 'LockCurrentState',
- displayName: 'Lock Current State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 3,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2, 3],
- },
- value: 0,
- },
- {
- UUID: '0000001E-0000-1000-8000-0026BB765291',
- constructorName: 'LockTargetState',
- displayName: 'Lock Target State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- ],
- primaryService: false,
- },
- HeaterCooler: {
- UUID: '000000BC-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '000000B0-0000-1000-8000-0026BB765291',
- constructorName: 'Active',
- displayName: 'Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '000000B1-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentHeaterCoolerState',
- displayName: 'Current Heater-Cooler State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 3,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2, 3],
- },
- value: 0,
- },
- {
- UUID: '000000B2-0000-1000-8000-0026BB765291',
- constructorName: 'TargetHeaterCoolerState',
- displayName: 'Target Heater-Cooler State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 2,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1, 2],
- },
- value: 0,
- },
- {
- UUID: '00000011-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentTemperature',
- displayName: 'Current Temperature',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 100,
- minStep: 0.1,
- minValue: -270,
- perms: ['ev', 'pr'],
- unit: 'celsius',
- },
- value: 0,
- },
- ],
- constructorName: 'HeaterCooler',
- displayName: 'HeaterCooler',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '000000A7-0000-1000-8000-0026BB765291',
- constructorName: 'LockPhysicalControls',
- displayName: 'Lock Physical Controls',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000029-0000-1000-8000-0026BB765291',
- constructorName: 'RotationSpeed',
- displayName: 'Rotation Speed',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'percentage',
- },
- value: 0,
- },
- {
- UUID: '000000B6-0000-1000-8000-0026BB765291',
- constructorName: 'SwingMode',
- displayName: 'Swing Mode',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '0000000D-0000-1000-8000-0026BB765291',
- constructorName: 'CoolingThresholdTemperature',
- displayName: 'Cooling Threshold Temperature',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 35,
- minStep: 0.1,
- minValue: 10,
- perms: ['ev', 'pr', 'pw'],
- unit: 'celsius',
- },
- value: 10,
- },
- {
- UUID: '00000012-0000-1000-8000-0026BB765291',
- constructorName: 'HeatingThresholdTemperature',
- displayName: 'Heating Threshold Temperature',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 25,
- minStep: 0.1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'celsius',
- },
- value: 0,
- },
- {
- UUID: '00000036-0000-1000-8000-0026BB765291',
- constructorName: 'TemperatureDisplayUnits',
- displayName: 'Temperature Display Units',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- HumidifierDehumidifier: {
- UUID: '000000BD-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '000000B0-0000-1000-8000-0026BB765291',
- constructorName: 'Active',
- displayName: 'Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '000000B3-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentHumidifierDehumidifierState',
- displayName: 'Current Humidifier-Dehumidifier State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 3,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2, 3],
- },
- value: 0,
- },
- {
- UUID: '000000B4-0000-1000-8000-0026BB765291',
- constructorName: 'TargetHumidifierDehumidifierState',
- displayName: 'Target Humidifier-Dehumidifier State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 2,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1, 2],
- },
- value: 0,
- },
- {
- UUID: '00000010-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentRelativeHumidity',
- displayName: 'Current Relative Humidity',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- unit: 'percentage',
- },
- value: 0,
- },
- ],
- constructorName: 'HumidifierDehumidifier',
- displayName: 'HumidifierDehumidifier',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '000000A7-0000-1000-8000-0026BB765291',
- constructorName: 'LockPhysicalControls',
- displayName: 'Lock Physical Controls',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '000000C9-0000-1000-8000-0026BB765291',
- constructorName: 'RelativeHumidityDehumidifierThreshold',
- displayName: 'Relative Humidity Dehumidifier Threshold',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'percentage',
- },
- value: 0,
- },
- {
- UUID: '000000CA-0000-1000-8000-0026BB765291',
- constructorName: 'RelativeHumidityHumidifierThreshold',
- displayName: 'Relative Humidity Humidifier Threshold',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'percentage',
- },
- value: 0,
- },
- {
- UUID: '00000029-0000-1000-8000-0026BB765291',
- constructorName: 'RotationSpeed',
- displayName: 'Rotation Speed',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'percentage',
- },
- value: 0,
- },
- {
- UUID: '000000B6-0000-1000-8000-0026BB765291',
- constructorName: 'SwingMode',
- displayName: 'Swing Mode',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '000000B5-0000-1000-8000-0026BB765291',
- constructorName: 'WaterLevel',
- displayName: 'Water Level',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- unit: 'percentage',
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- HumiditySensor: {
- UUID: '00000082-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000010-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentRelativeHumidity',
- displayName: 'Current Relative Humidity',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- unit: 'percentage',
- },
- value: 0,
- },
- ],
- constructorName: 'HumiditySensor',
- displayName: 'HumiditySensor',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000075-0000-1000-8000-0026BB765291',
- constructorName: 'StatusActive',
- displayName: 'Status Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr'],
- },
- value: false,
- },
- {
- UUID: '00000077-0000-1000-8000-0026BB765291',
- constructorName: 'StatusFault',
- displayName: 'Status Fault',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000079-0000-1000-8000-0026BB765291',
- constructorName: 'StatusLowBattery',
- displayName: 'Status Low Battery',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '0000007A-0000-1000-8000-0026BB765291',
- constructorName: 'StatusTampered',
- displayName: 'Status Tampered',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- InputSource: {
- UUID: '000000D9-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '000000E3-0000-1000-8000-0026BB765291',
- constructorName: 'ConfiguredName',
- displayName: 'Configured Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- perms: ['ev', 'pr', 'pw'],
- },
- value: '',
- },
- {
- UUID: '000000DB-0000-1000-8000-0026BB765291',
- constructorName: 'InputSourceType',
- displayName: 'Input Source Type',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 10,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
- },
- value: 0,
- },
- {
- UUID: '000000D6-0000-1000-8000-0026BB765291',
- constructorName: 'IsConfigured',
- displayName: 'Is Configured',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: 'Unnamed Service',
- },
- {
- UUID: '00000135-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentVisibilityState',
- displayName: 'Current Visibility State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- constructorName: 'InputSource',
- displayName: 'InputSource',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '000000E6-0000-1000-8000-0026BB765291',
- constructorName: 'Identifier',
- displayName: 'Identifier',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint32',
- perms: ['pr'],
- },
- value: 0,
- },
- {
- UUID: '000000DC-0000-1000-8000-0026BB765291',
- constructorName: 'InputDeviceType',
- displayName: 'Input Device Type',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 6,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2, 3, 4, 5, 6],
- },
- value: 0,
- },
- {
- UUID: '00000134-0000-1000-8000-0026BB765291',
- constructorName: 'TargetVisibilityState',
- displayName: 'Target Visibility State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- IrrigationSystem: {
- UUID: '000000CF-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '000000B0-0000-1000-8000-0026BB765291',
- constructorName: 'Active',
- displayName: 'Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '000000D1-0000-1000-8000-0026BB765291',
- constructorName: 'ProgramMode',
- displayName: 'Program Mode',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 2,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2],
- },
- value: 0,
- },
- {
- UUID: '000000D2-0000-1000-8000-0026BB765291',
- constructorName: 'InUse',
- displayName: 'In Use',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- constructorName: 'IrrigationSystem',
- displayName: 'IrrigationSystem',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '000000D4-0000-1000-8000-0026BB765291',
- constructorName: 'RemainingDuration',
- displayName: 'Remaining Duration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint32',
- maxValue: 3600,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- unit: 'seconds',
- },
- value: 0,
- },
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000077-0000-1000-8000-0026BB765291',
- constructorName: 'StatusFault',
- displayName: 'Status Fault',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- LeakSensor: {
- UUID: '00000083-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000070-0000-1000-8000-0026BB765291',
- constructorName: 'LeakDetected',
- displayName: 'Leak Detected',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- constructorName: 'LeakSensor',
- displayName: 'LeakSensor',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000075-0000-1000-8000-0026BB765291',
- constructorName: 'StatusActive',
- displayName: 'Status Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr'],
- },
- value: false,
- },
- {
- UUID: '00000077-0000-1000-8000-0026BB765291',
- constructorName: 'StatusFault',
- displayName: 'Status Fault',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000079-0000-1000-8000-0026BB765291',
- constructorName: 'StatusLowBattery',
- displayName: 'Status Low Battery',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '0000007A-0000-1000-8000-0026BB765291',
- constructorName: 'StatusTampered',
- displayName: 'Status Tampered',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- LightSensor: {
- UUID: '00000084-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '0000006B-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentAmbientLightLevel',
- displayName: 'Current Ambient Light Level',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 100000,
- minValue: 0.0001,
- perms: ['ev', 'pr'],
- unit: 'lux',
- },
- value: 0.0001,
- },
- ],
- constructorName: 'LightSensor',
- displayName: 'LightSensor',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000075-0000-1000-8000-0026BB765291',
- constructorName: 'StatusActive',
- displayName: 'Status Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr'],
- },
- value: false,
- },
- {
- UUID: '00000077-0000-1000-8000-0026BB765291',
- constructorName: 'StatusFault',
- displayName: 'Status Fault',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000079-0000-1000-8000-0026BB765291',
- constructorName: 'StatusLowBattery',
- displayName: 'Status Low Battery',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '0000007A-0000-1000-8000-0026BB765291',
- constructorName: 'StatusTampered',
- displayName: 'Status Tampered',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- Lightbulb: {
- UUID: '00000043-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000025-0000-1000-8000-0026BB765291',
- constructorName: 'On',
- displayName: 'On',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr', 'pw'],
- },
- value: false,
- },
- ],
- constructorName: 'Lightbulb',
- displayName: 'Lightbulb',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000008-0000-1000-8000-0026BB765291',
- constructorName: 'Brightness',
- displayName: 'Brightness',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'percentage',
- },
- value: 0,
- },
- {
- UUID: '0000024B-0000-1000-8000-0026BB765291',
- constructorName: 'CharacteristicValueActiveTransitionCount',
- displayName: 'Characteristic Value Active Transition Count',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- {
- UUID: '00000143-0000-1000-8000-0026BB765291',
- constructorName: 'CharacteristicValueTransitionControl',
- displayName: 'Characteristic Value Transition Control',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr', 'pw', 'wr'],
- },
- value: '',
- },
- {
- UUID: '000000CE-0000-1000-8000-0026BB765291',
- constructorName: 'ColorTemperature',
- displayName: 'Color Temperature',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- maxValue: 500,
- minStep: 1,
- minValue: 140,
- perms: ['ev', 'pr', 'pw'],
- },
- value: 140,
- },
- {
- UUID: '00000013-0000-1000-8000-0026BB765291',
- constructorName: 'Hue',
- displayName: 'Hue',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 360,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'arcdegrees',
- },
- value: 0,
- },
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '0000002F-0000-1000-8000-0026BB765291',
- constructorName: 'Saturation',
- displayName: 'Saturation',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'percentage',
- },
- value: 0,
- },
- {
- UUID: '00000144-0000-1000-8000-0026BB765291',
- constructorName:
- 'SupportedCharacteristicValueTransitionConfiguration',
- displayName:
- 'Supported Characteristic Value Transition Configuration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr'],
- },
- value: '',
- },
- ],
- primaryService: false,
- },
- LockManagement: {
- UUID: '00000044-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000019-0000-1000-8000-0026BB765291',
- constructorName: 'LockControlPoint',
- displayName: 'Lock Control Point',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pw'],
- },
- value: '',
- },
- {
- UUID: '00000037-0000-1000-8000-0026BB765291',
- constructorName: 'Version',
- displayName: 'Version',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- ],
- constructorName: 'LockManagement',
- displayName: 'LockManagement',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000001-0000-1000-8000-0026BB765291',
- constructorName: 'AdministratorOnlyAccess',
- displayName: 'Administrator Only Access',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr', 'pw'],
- },
- value: false,
- },
- {
- UUID: '00000005-0000-1000-8000-0026BB765291',
- constructorName: 'AudioFeedback',
- displayName: 'Audio Feedback',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr', 'pw'],
- },
- value: false,
- },
- {
- UUID: '0000000E-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentDoorState',
- displayName: 'Current Door State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 4,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2, 3, 4],
- },
- value: 0,
- },
- {
- UUID: '0000001A-0000-1000-8000-0026BB765291',
- constructorName: 'LockManagementAutoSecurityTimeout',
- displayName: 'Lock Management Auto Security Timeout',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint32',
- perms: ['ev', 'pr', 'pw'],
- unit: 'seconds',
- },
- value: 0,
- },
- {
- UUID: '0000001C-0000-1000-8000-0026BB765291',
- constructorName: 'LockLastKnownAction',
- displayName: 'Lock Last Known Action',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 10,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
- },
- value: 0,
- },
- {
- UUID: '0000001F-0000-1000-8000-0026BB765291',
- constructorName: 'Logs',
- displayName: 'Logs',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['ev', 'pr'],
- },
- value: '',
- },
- {
- UUID: '00000022-0000-1000-8000-0026BB765291',
- constructorName: 'MotionDetected',
- displayName: 'Motion Detected',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr'],
- },
- value: false,
- },
- ],
- primaryService: false,
- },
- LockMechanism: {
- UUID: '00000045-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '0000001D-0000-1000-8000-0026BB765291',
- constructorName: 'LockCurrentState',
- displayName: 'Lock Current State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 3,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2, 3],
- },
- value: 0,
- },
- {
- UUID: '0000001E-0000-1000-8000-0026BB765291',
- constructorName: 'LockTargetState',
- displayName: 'Lock Target State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- constructorName: 'LockMechanism',
- displayName: 'LockMechanism',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- ],
- primaryService: false,
- },
- Microphone: {
- UUID: '00000112-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '0000011A-0000-1000-8000-0026BB765291',
- constructorName: 'Mute',
- displayName: 'Mute',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr', 'pw'],
- },
- value: false,
- },
- ],
- constructorName: 'Microphone',
- displayName: 'Microphone',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000119-0000-1000-8000-0026BB765291',
- constructorName: 'Volume',
- displayName: 'Volume',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'percentage',
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- MotionSensor: {
- UUID: '00000085-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000022-0000-1000-8000-0026BB765291',
- constructorName: 'MotionDetected',
- displayName: 'Motion Detected',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr'],
- },
- value: false,
- },
- ],
- constructorName: 'MotionSensor',
- displayName: 'MotionSensor',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000075-0000-1000-8000-0026BB765291',
- constructorName: 'StatusActive',
- displayName: 'Status Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr'],
- },
- value: false,
- },
- {
- UUID: '00000077-0000-1000-8000-0026BB765291',
- constructorName: 'StatusFault',
- displayName: 'Status Fault',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000079-0000-1000-8000-0026BB765291',
- constructorName: 'StatusLowBattery',
- displayName: 'Status Low Battery',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '0000007A-0000-1000-8000-0026BB765291',
- constructorName: 'StatusTampered',
- displayName: 'Status Tampered',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- NFCAccess: {
- UUID: '00000266-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000263-0000-1000-8000-0026BB765291',
- constructorName: 'ConfigurationState',
- displayName: 'Configuration State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint16',
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- {
- UUID: '00000264-0000-1000-8000-0026BB765291',
- constructorName: 'NFCAccessControlPoint',
- displayName: 'NFC Access Control Point',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr', 'pw', 'wr'],
- },
- value: '',
- },
- {
- UUID: '00000265-0000-1000-8000-0026BB765291',
- constructorName: 'NFCAccessSupportedConfiguration',
- displayName: 'NFC Access Supported Configuration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr'],
- },
- value: '',
- },
- ],
- constructorName: 'NFCAccess',
- displayName: 'NFCAccess',
- hiddenService: false,
- optionalCharacteristics: [],
- primaryService: false,
- },
- OccupancySensor: {
- UUID: '00000086-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000071-0000-1000-8000-0026BB765291',
- constructorName: 'OccupancyDetected',
- displayName: 'Occupancy Detected',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- constructorName: 'OccupancySensor',
- displayName: 'OccupancySensor',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000075-0000-1000-8000-0026BB765291',
- constructorName: 'StatusActive',
- displayName: 'Status Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr'],
- },
- value: false,
- },
- {
- UUID: '00000077-0000-1000-8000-0026BB765291',
- constructorName: 'StatusFault',
- displayName: 'Status Fault',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000079-0000-1000-8000-0026BB765291',
- constructorName: 'StatusLowBattery',
- displayName: 'Status Low Battery',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '0000007A-0000-1000-8000-0026BB765291',
- constructorName: 'StatusTampered',
- displayName: 'Status Tampered',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- Outlet: {
- UUID: '00000047-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000025-0000-1000-8000-0026BB765291',
- constructorName: 'On',
- displayName: 'On',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr', 'pw'],
- },
- value: false,
- },
- ],
- constructorName: 'Outlet',
- displayName: 'Outlet',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000026-0000-1000-8000-0026BB765291',
- constructorName: 'OutletInUse',
- displayName: 'Outlet In Use',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr'],
- },
- value: false,
- },
- ],
- primaryService: false,
- },
- Pairing: {
- UUID: '00000055-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000050-0000-1000-8000-0026BB765291',
- constructorName: 'ListPairings',
- displayName: 'List Pairings',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr', 'pw'],
- },
- value: '',
- },
- {
- UUID: '0000004C-0000-1000-8000-0026BB765291',
- constructorName: 'PairSetup',
- displayName: 'Pair Setup',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr', 'pw'],
- },
- value: '',
- },
- {
- UUID: '0000004E-0000-1000-8000-0026BB765291',
- constructorName: 'PairVerify',
- displayName: 'Pair Verify',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr', 'pw'],
- },
- value: '',
- },
- {
- UUID: '0000004F-0000-1000-8000-0026BB765291',
- constructorName: 'PairingFeatures',
- displayName: 'Pairing Features',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- perms: ['pr'],
- },
- value: 0,
- },
- ],
- constructorName: 'Pairing',
- displayName: 'Pairing',
- hiddenService: false,
- optionalCharacteristics: [],
- primaryService: false,
- },
- PowerManagement: {
- UUID: '00000221-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000222-0000-1000-8000-0026BB765291',
- constructorName: 'WakeConfiguration',
- displayName: 'Wake Configuration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr'],
- },
- value: '',
- },
- ],
- constructorName: 'PowerManagement',
- displayName: 'PowerManagement',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000252-0000-1000-8000-0026BB765291',
- constructorName: 'SelectedSleepConfiguration',
- displayName: 'Selected Sleep Configuration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['ev', 'pr', 'pw', 'wr'],
- },
- value: '',
- },
- {
- UUID: '00000251-0000-1000-8000-0026BB765291',
- constructorName: 'SupportedSleepConfiguration',
- displayName: 'Supported Sleep Configuration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr'],
- },
- value: '',
- },
- ],
- primaryService: false,
- },
- ProtocolInformation: {
- UUID: '000000A2-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000037-0000-1000-8000-0026BB765291',
- constructorName: 'Version',
- displayName: 'Version',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- ],
- constructorName: 'ProtocolInformation',
- displayName: 'ProtocolInformation',
- hiddenService: false,
- optionalCharacteristics: [],
- primaryService: false,
- },
- Relay: {
- nrchkbDisabledText: 'Relay (deprecated, replaced by CloudRelay)',
- },
- SecuritySystem: {
- UUID: '0000007E-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000066-0000-1000-8000-0026BB765291',
- constructorName: 'SecuritySystemCurrentState',
- displayName: 'Security System Current State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 4,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2, 3, 4],
- },
- value: 0,
- },
- {
- UUID: '00000067-0000-1000-8000-0026BB765291',
- constructorName: 'SecuritySystemTargetState',
- displayName: 'Security System Target State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 3,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1, 2, 3],
- },
- value: 0,
- },
- ],
- constructorName: 'SecuritySystem',
- displayName: 'SecuritySystem',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '0000008E-0000-1000-8000-0026BB765291',
- constructorName: 'SecuritySystemAlarmType',
- displayName: 'Security System Alarm Type',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- {
- UUID: '00000077-0000-1000-8000-0026BB765291',
- constructorName: 'StatusFault',
- displayName: 'Status Fault',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '0000007A-0000-1000-8000-0026BB765291',
- constructorName: 'StatusTampered',
- displayName: 'Status Tampered',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- ServiceLabel: {
- UUID: '000000CC-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '000000CD-0000-1000-8000-0026BB765291',
- constructorName: 'ServiceLabelNamespace',
- displayName: 'Service Label Namespace',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- constructorName: 'ServiceLabel',
- displayName: 'ServiceLabel',
- hiddenService: false,
- optionalCharacteristics: [],
- primaryService: false,
- },
- Siri: {
- UUID: '00000133-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000132-0000-1000-8000-0026BB765291',
- constructorName: 'SiriInputType',
- displayName: 'Siri Input Type',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 0,
- minValue: 0,
- perms: ['pr'],
- validValues: [0],
- },
- value: 0,
- },
- ],
- constructorName: 'Siri',
- displayName: 'Siri',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '0000026B-0000-1000-8000-0026BB765291',
- constructorName: 'MultifunctionButton',
- displayName: 'Multifunction Button',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- {
- UUID: '00000255-0000-1000-8000-0026BB765291',
- constructorName: 'SiriEnable',
- displayName: 'Siri Enable',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- },
- value: 0,
- },
- {
- UUID: '0000025A-0000-1000-8000-0026BB765291',
- constructorName: 'SiriEngineVersion',
- displayName: 'Siri Engine Version',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000258-0000-1000-8000-0026BB765291',
- constructorName: 'SiriLightOnUse',
- displayName: 'Siri Light On Use',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- },
- value: 0,
- },
- {
- UUID: '00000256-0000-1000-8000-0026BB765291',
- constructorName: 'SiriListening',
- displayName: 'Siri Listening',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- },
- value: 0,
- },
- {
- UUID: '00000257-0000-1000-8000-0026BB765291',
- constructorName: 'SiriTouchToUse',
- displayName: 'Siri Touch To Use',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- SiriEndpoint: {
- UUID: '00000253-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000254-0000-1000-8000-0026BB765291',
- constructorName: 'SiriEndpointSessionStatus',
- displayName: 'Siri Endpoint Session Status',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['ev', 'pr'],
- },
- value: '',
- },
- {
- UUID: '00000037-0000-1000-8000-0026BB765291',
- constructorName: 'Version',
- displayName: 'Version',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- ],
- constructorName: 'SiriEndpoint',
- displayName: 'SiriEndpoint',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '000000E7-0000-1000-8000-0026BB765291',
- constructorName: 'ActiveIdentifier',
- displayName: 'Active Identifier',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint32',
- perms: ['ev', 'pr', 'pw'],
- },
- value: 0,
- },
- {
- UUID: '00000227-0000-1000-8000-0026BB765291',
- constructorName: 'ManuallyDisabled',
- displayName: 'Manually Disabled',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr'],
- },
- value: false,
- },
- ],
- primaryService: false,
- },
- Slat: {
- nrchkbDisabledText: 'Slat (deprecated, replaced by Slats)',
- },
- Slats: {
- UUID: '000000B9-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '000000AA-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentSlatState',
- displayName: 'Current Slat State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 2,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2],
- },
- value: 0,
- },
- {
- UUID: '000000C0-0000-1000-8000-0026BB765291',
- constructorName: 'SlatType',
- displayName: 'Slat Type',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- constructorName: 'Slats',
- displayName: 'Slats',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '000000B6-0000-1000-8000-0026BB765291',
- constructorName: 'SwingMode',
- displayName: 'Swing Mode',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '000000C1-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentTiltAngle',
- displayName: 'Current Tilt Angle',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- maxValue: 90,
- minStep: 1,
- minValue: -90,
- perms: ['ev', 'pr'],
- unit: 'arcdegrees',
- },
- value: -90,
- },
- {
- UUID: '000000C2-0000-1000-8000-0026BB765291',
- constructorName: 'TargetTiltAngle',
- displayName: 'Target Tilt Angle',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- maxValue: 90,
- minStep: 1,
- minValue: -90,
- perms: ['ev', 'pr', 'pw'],
- unit: 'arcdegrees',
- },
- value: -90,
- },
- ],
- primaryService: false,
- },
- SmartSpeaker: {
- UUID: '00000228-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '000000E0-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentMediaState',
- displayName: 'Current Media State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 5,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2, 4, 5],
- },
- value: 0,
- },
- {
- UUID: '00000137-0000-1000-8000-0026BB765291',
- constructorName: 'TargetMediaState',
- displayName: 'Target Media State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 2,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1, 2],
- },
- value: 0,
- },
- ],
- constructorName: 'SmartSpeaker',
- displayName: 'SmartSpeaker',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '0000025B-0000-1000-8000-0026BB765291',
- constructorName: 'AirPlayEnable',
- displayName: 'AirPlay Enable',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- },
- value: 0,
- },
- {
- UUID: '000000E3-0000-1000-8000-0026BB765291',
- constructorName: 'ConfiguredName',
- displayName: 'Configured Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- perms: ['ev', 'pr', 'pw'],
- },
- value: '',
- },
- {
- UUID: '0000011A-0000-1000-8000-0026BB765291',
- constructorName: 'Mute',
- displayName: 'Mute',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr', 'pw'],
- },
- value: false,
- },
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000119-0000-1000-8000-0026BB765291',
- constructorName: 'Volume',
- displayName: 'Volume',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'percentage',
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- SmokeSensor: {
- UUID: '00000087-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000076-0000-1000-8000-0026BB765291',
- constructorName: 'SmokeDetected',
- displayName: 'Smoke Detected',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- constructorName: 'SmokeSensor',
- displayName: 'SmokeSensor',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000075-0000-1000-8000-0026BB765291',
- constructorName: 'StatusActive',
- displayName: 'Status Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr'],
- },
- value: false,
- },
- {
- UUID: '00000077-0000-1000-8000-0026BB765291',
- constructorName: 'StatusFault',
- displayName: 'Status Fault',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000079-0000-1000-8000-0026BB765291',
- constructorName: 'StatusLowBattery',
- displayName: 'Status Low Battery',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '0000007A-0000-1000-8000-0026BB765291',
- constructorName: 'StatusTampered',
- displayName: 'Status Tampered',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- Speaker: {
- UUID: '00000113-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '0000011A-0000-1000-8000-0026BB765291',
- constructorName: 'Mute',
- displayName: 'Mute',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr', 'pw'],
- },
- value: false,
- },
- ],
- constructorName: 'Speaker',
- displayName: 'Speaker',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '000000B0-0000-1000-8000-0026BB765291',
- constructorName: 'Active',
- displayName: 'Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000119-0000-1000-8000-0026BB765291',
- constructorName: 'Volume',
- displayName: 'Volume',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'percentage',
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- StatefulProgrammableSwitch: {
- UUID: '00000088-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000073-0000-1000-8000-0026BB765291',
- constructorName: 'ProgrammableSwitchEvent',
- displayName: 'Programmable Switch Event',
- eventOnlyCharacteristic: true,
- props: {
- format: 'uint8',
- maxValue: 2,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2],
- },
- value: 0,
- },
- {
- UUID: '00000074-0000-1000-8000-0026BB765291',
- constructorName: 'ProgrammableSwitchOutputState',
- displayName: 'Programmable Switch Output State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- },
- value: 0,
- },
- ],
- constructorName: 'StatefulProgrammableSwitch',
- displayName: 'StatefulProgrammableSwitch',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- ],
- primaryService: false,
- },
- StatelessProgrammableSwitch: {
- UUID: '00000089-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000073-0000-1000-8000-0026BB765291',
- constructorName: 'ProgrammableSwitchEvent',
- displayName: 'Programmable Switch Event',
- eventOnlyCharacteristic: true,
- props: {
- format: 'uint8',
- maxValue: 2,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2],
- },
- value: 0,
- },
- ],
- constructorName: 'StatelessProgrammableSwitch',
- displayName: 'StatelessProgrammableSwitch',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '000000CB-0000-1000-8000-0026BB765291',
- constructorName: 'ServiceLabelIndex',
- displayName: 'Service Label Index',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 255,
- minStep: 1,
- minValue: 1,
- perms: ['pr'],
- },
- value: 1,
- },
- ],
- primaryService: false,
- },
- Switch: {
- UUID: '00000049-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000025-0000-1000-8000-0026BB765291',
- constructorName: 'On',
- displayName: 'On',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr', 'pw'],
- },
- value: false,
- },
- ],
- constructorName: 'Switch',
- displayName: 'Switch',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- ],
- primaryService: false,
- },
- TapManagement: {
- UUID: '0000022E-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '000000B0-0000-1000-8000-0026BB765291',
- constructorName: 'Active',
- displayName: 'Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000250-0000-1000-8000-0026BB765291',
- constructorName: 'CryptoHash',
- displayName: 'Crypto Hash',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pw', 'wr'],
- },
- value: '',
- },
- {
- UUID: '0000022F-0000-1000-8000-0026BB765291',
- constructorName: 'TapType',
- displayName: 'Tap Type',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint16',
- perms: ['pr'],
- },
- value: 0,
- },
- {
- UUID: '00000231-0000-1000-8000-0026BB765291',
- constructorName: 'Token',
- displayName: 'Token',
- eventOnlyCharacteristic: false,
- props: {
- format: 'data',
- perms: ['pw'],
- },
- value: '',
- },
- ],
- constructorName: 'TapManagement',
- displayName: 'TapManagement',
- hiddenService: false,
- optionalCharacteristics: [],
- primaryService: false,
- },
- TargetControl: {
- UUID: '00000125-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '000000B0-0000-1000-8000-0026BB765291',
- constructorName: 'Active',
- displayName: 'Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '000000E7-0000-1000-8000-0026BB765291',
- constructorName: 'ActiveIdentifier',
- displayName: 'Active Identifier',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint32',
- perms: ['ev', 'pr', 'pw'],
- },
- value: 0,
- },
- {
- UUID: '00000126-0000-1000-8000-0026BB765291',
- constructorName: 'ButtonEvent',
- displayName: 'Button Event',
- eventOnlyCharacteristic: false,
- props: {
- adminOnlyAccess: [2],
- format: 'tlv8',
- perms: ['ev', 'pr'],
- },
- value: '',
- },
- ],
- constructorName: 'TargetControl',
- displayName: 'TargetControl',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- ],
- primaryService: false,
- },
- TargetControlManagement: {
- UUID: '00000122-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000123-0000-1000-8000-0026BB765291',
- constructorName: 'TargetControlSupportedConfiguration',
- displayName: 'Target Control Supported Configuration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000124-0000-1000-8000-0026BB765291',
- constructorName: 'TargetControlList',
- displayName: 'Target Control List',
- eventOnlyCharacteristic: false,
- props: {
- adminOnlyAccess: [0, 1],
- format: 'tlv8',
- perms: ['pr', 'pw', 'wr'],
- },
- value: '',
- },
- ],
- constructorName: 'TargetControlManagement',
- displayName: 'TargetControlManagement',
- hiddenService: false,
- optionalCharacteristics: [],
- primaryService: false,
- },
- Television: {
- UUID: '000000D8-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '000000B0-0000-1000-8000-0026BB765291',
- constructorName: 'Active',
- displayName: 'Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '000000E7-0000-1000-8000-0026BB765291',
- constructorName: 'ActiveIdentifier',
- displayName: 'Active Identifier',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint32',
- perms: ['ev', 'pr', 'pw'],
- },
- value: 0,
- },
- {
- UUID: '000000E3-0000-1000-8000-0026BB765291',
- constructorName: 'ConfiguredName',
- displayName: 'Configured Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- perms: ['ev', 'pr', 'pw'],
- },
- value: '',
- },
- {
- UUID: '000000E1-0000-1000-8000-0026BB765291',
- constructorName: 'RemoteKey',
- displayName: 'Remote Key',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 16,
- minStep: 1,
- minValue: 0,
- perms: ['pw'],
- validValues: [
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16,
- ],
- },
- value: 0,
- },
- {
- UUID: '000000E8-0000-1000-8000-0026BB765291',
- constructorName: 'SleepDiscoveryMode',
- displayName: 'Sleep Discovery Mode',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- constructorName: 'Television',
- displayName: 'Television',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000008-0000-1000-8000-0026BB765291',
- constructorName: 'Brightness',
- displayName: 'Brightness',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'percentage',
- },
- value: 0,
- },
- {
- UUID: '000000DD-0000-1000-8000-0026BB765291',
- constructorName: 'ClosedCaptions',
- displayName: 'Closed Captions',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000136-0000-1000-8000-0026BB765291',
- constructorName: 'DisplayOrder',
- displayName: 'Display Order',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['ev', 'pr', 'pw'],
- },
- value: '',
- },
- {
- UUID: '000000E0-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentMediaState',
- displayName: 'Current Media State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 5,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2, 4, 5],
- },
- value: 0,
- },
- {
- UUID: '00000137-0000-1000-8000-0026BB765291',
- constructorName: 'TargetMediaState',
- displayName: 'Target Media State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 2,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1, 2],
- },
- value: 0,
- },
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '000000E2-0000-1000-8000-0026BB765291',
- constructorName: 'PictureMode',
- displayName: 'Picture Mode',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 13,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
- },
- value: 0,
- },
- {
- UUID: '000000DF-0000-1000-8000-0026BB765291',
- constructorName: 'PowerModeSelection',
- displayName: 'Power Mode Selection',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- TelevisionSpeaker: {
- UUID: '00000113-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '0000011A-0000-1000-8000-0026BB765291',
- constructorName: 'Mute',
- displayName: 'Mute',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr', 'pw'],
- },
- value: false,
- },
- ],
- constructorName: 'TelevisionSpeaker',
- displayName: 'TelevisionSpeaker',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '000000B0-0000-1000-8000-0026BB765291',
- constructorName: 'Active',
- displayName: 'Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000119-0000-1000-8000-0026BB765291',
- constructorName: 'Volume',
- displayName: 'Volume',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'percentage',
- },
- value: 0,
- },
- {
- UUID: '000000E9-0000-1000-8000-0026BB765291',
- constructorName: 'VolumeControlType',
- displayName: 'Volume Control Type',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 3,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2, 3],
- },
- value: 0,
- },
- {
- UUID: '000000EA-0000-1000-8000-0026BB765291',
- constructorName: 'VolumeSelector',
- displayName: 'Volume Selector',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- TemperatureSensor: {
- UUID: '0000008A-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000011-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentTemperature',
- displayName: 'Current Temperature',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 100,
- minStep: 0.1,
- minValue: -270,
- perms: ['ev', 'pr'],
- unit: 'celsius',
- },
- value: 0,
- },
- ],
- constructorName: 'TemperatureSensor',
- displayName: 'TemperatureSensor',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000075-0000-1000-8000-0026BB765291',
- constructorName: 'StatusActive',
- displayName: 'Status Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr'],
- },
- value: false,
- },
- {
- UUID: '00000077-0000-1000-8000-0026BB765291',
- constructorName: 'StatusFault',
- displayName: 'Status Fault',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000079-0000-1000-8000-0026BB765291',
- constructorName: 'StatusLowBattery',
- displayName: 'Status Low Battery',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '0000007A-0000-1000-8000-0026BB765291',
- constructorName: 'StatusTampered',
- displayName: 'Status Tampered',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- Thermostat: {
- UUID: '0000004A-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '0000000F-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentHeatingCoolingState',
- displayName: 'Current Heating Cooling State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 2,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2],
- },
- value: 0,
- },
- {
- UUID: '00000033-0000-1000-8000-0026BB765291',
- constructorName: 'TargetHeatingCoolingState',
- displayName: 'Target Heating Cooling State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 3,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1, 2, 3],
- },
- value: 0,
- },
- {
- UUID: '00000011-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentTemperature',
- displayName: 'Current Temperature',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 100,
- minStep: 0.1,
- minValue: -270,
- perms: ['ev', 'pr'],
- unit: 'celsius',
- },
- value: 0,
- },
- {
- UUID: '00000035-0000-1000-8000-0026BB765291',
- constructorName: 'TargetTemperature',
- displayName: 'Target Temperature',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 38,
- minStep: 0.1,
- minValue: 10,
- perms: ['ev', 'pr', 'pw'],
- unit: 'celsius',
- },
- value: 10,
- },
- {
- UUID: '00000036-0000-1000-8000-0026BB765291',
- constructorName: 'TemperatureDisplayUnits',
- displayName: 'Temperature Display Units',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- constructorName: 'Thermostat',
- displayName: 'Thermostat',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000010-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentRelativeHumidity',
- displayName: 'Current Relative Humidity',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- unit: 'percentage',
- },
- value: 0,
- },
- {
- UUID: '00000034-0000-1000-8000-0026BB765291',
- constructorName: 'TargetRelativeHumidity',
- displayName: 'Target Relative Humidity',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'percentage',
- },
- value: 0,
- },
- {
- UUID: '0000000D-0000-1000-8000-0026BB765291',
- constructorName: 'CoolingThresholdTemperature',
- displayName: 'Cooling Threshold Temperature',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 35,
- minStep: 0.1,
- minValue: 10,
- perms: ['ev', 'pr', 'pw'],
- unit: 'celsius',
- },
- value: 10,
- },
- {
- UUID: '00000012-0000-1000-8000-0026BB765291',
- constructorName: 'HeatingThresholdTemperature',
- displayName: 'Heating Threshold Temperature',
- eventOnlyCharacteristic: false,
- props: {
- format: 'float',
- maxValue: 25,
- minStep: 0.1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'celsius',
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- ThreadTransport: {
- UUID: '00000701-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '0000022B-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentTransport',
- displayName: 'Current Transport',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['pr'],
- },
- value: false,
- },
- {
- UUID: '00000704-0000-1000-8000-0026BB765291',
- constructorName: 'ThreadControlPoint',
- displayName: 'Thread Control Point',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pw'],
- },
- value: '',
- },
- {
- UUID: '00000702-0000-1000-8000-0026BB765291',
- constructorName: 'ThreadNodeCapabilities',
- displayName: 'Thread Node Capabilities',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint16',
- maxValue: 31,
- minStep: 1,
- minValue: 0,
- perms: ['pr'],
- },
- value: 0,
- },
- {
- UUID: '00000703-0000-1000-8000-0026BB765291',
- constructorName: 'ThreadStatus',
- displayName: 'Thread Status',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint16',
- maxValue: 6,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- ],
- constructorName: 'ThreadTransport',
- displayName: 'ThreadTransport',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000246-0000-1000-8000-0026BB765291',
- constructorName: 'CCAEnergyDetectThreshold',
- displayName: 'CCA Energy Detect Threshold',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- perms: ['pr'],
- },
- value: 0,
- },
- {
- UUID: '00000245-0000-1000-8000-0026BB765291',
- constructorName: 'CCASignalDetectThreshold',
- displayName: 'CCA Signal Detect Threshold',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- perms: ['pr'],
- },
- value: 0,
- },
- {
- UUID: '0000023D-0000-1000-8000-0026BB765291',
- constructorName: 'EventRetransmissionMaximum',
- displayName: 'Event Retransmission Maximum',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- perms: ['pr'],
- },
- value: 0,
- },
- {
- UUID: '0000023E-0000-1000-8000-0026BB765291',
- constructorName: 'EventTransmissionCounters',
- displayName: 'Event Transmission Counters',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint32',
- perms: ['pr'],
- },
- value: 0,
- },
- {
- UUID: '00000247-0000-1000-8000-0026BB765291',
- constructorName: 'MACRetransmissionMaximum',
- displayName: 'MAC Retransmission Maximum',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- perms: ['pr'],
- },
- value: 0,
- },
- {
- UUID: '00000248-0000-1000-8000-0026BB765291',
- constructorName: 'MACTransmissionCounters',
- displayName: 'MAC Transmission Counters',
- eventOnlyCharacteristic: false,
- props: {
- format: 'data',
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000244-0000-1000-8000-0026BB765291',
- constructorName: 'ReceiverSensitivity',
- displayName: 'Receiver Sensitivity',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- perms: ['pr'],
- },
- value: 0,
- },
- {
- UUID: '0000023F-0000-1000-8000-0026BB765291',
- constructorName: 'ReceivedSignalStrengthIndication',
- displayName: 'Received Signal Strength Indication',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- perms: ['pr'],
- },
- value: 0,
- },
- {
- UUID: '00000241-0000-1000-8000-0026BB765291',
- constructorName: 'SignalToNoiseRatio',
- displayName: 'Signal To Noise Ratio',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- perms: ['pr'],
- },
- value: 0,
- },
- {
- UUID: '00000706-0000-1000-8000-0026BB765291',
- constructorName: 'ThreadOpenThreadVersion',
- displayName: 'Thread OpenThread Version',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000242-0000-1000-8000-0026BB765291',
- constructorName: 'TransmitPower',
- displayName: 'Transmit Power',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- perms: ['pr'],
- },
- value: 0,
- },
- {
- UUID: '00000243-0000-1000-8000-0026BB765291',
- constructorName: 'MaximumTransmitPower',
- displayName: 'Maximum Transmit Power',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- perms: ['pr'],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- TimeInformation: {
- UUID: '00000099-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '0000009B-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentTime',
- displayName: 'Current Time',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- perms: ['pr', 'pw'],
- },
- value: '',
- },
- {
- UUID: '00000098-0000-1000-8000-0026BB765291',
- constructorName: 'DayoftheWeek',
- displayName: 'Day of the Week',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 7,
- minValue: 1,
- perms: ['pr', 'pw'],
- },
- value: 1,
- },
- {
- UUID: '0000009A-0000-1000-8000-0026BB765291',
- constructorName: 'TimeUpdate',
- displayName: 'Time Update',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['pr', 'pw'],
- },
- value: false,
- },
- ],
- constructorName: 'TimeInformation',
- displayName: 'TimeInformation',
- hiddenService: false,
- nrchkbDisabledText: 'TimeInformation (deprecated, unused)',
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- ],
- primaryService: false,
- },
- TransferTransportManagement: {
- UUID: '00000203-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000202-0000-1000-8000-0026BB765291',
- constructorName: 'SupportedTransferTransportConfiguration',
- displayName: 'Supported Transfer Transport Configuration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000201-0000-1000-8000-0026BB765291',
- constructorName: 'SetupTransferTransport',
- displayName: 'Setup Transfer Transport',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pw', 'wr'],
- },
- value: '',
- },
- ],
- constructorName: 'TransferTransportManagement',
- displayName: 'TransferTransportManagement',
- hiddenService: false,
- optionalCharacteristics: [],
- primaryService: false,
- },
- Tunnel: {
- UUID: '00000056-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '00000057-0000-1000-8000-0026BB765291',
- constructorName: 'AccessoryIdentifier',
- displayName: 'Accessory Identifier',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000061-0000-1000-8000-0026BB765291',
- constructorName: 'TunnelConnectionTimeout',
- displayName: 'Tunnel Connection Timeout',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- perms: ['ev', 'pr', 'pw'],
- },
- value: 0,
- },
- {
- UUID: '00000060-0000-1000-8000-0026BB765291',
- constructorName: 'TunneledAccessoryAdvertising',
- displayName: 'Tunneled Accessory Advertising',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr', 'pw'],
- },
- value: false,
- },
- {
- UUID: '00000059-0000-1000-8000-0026BB765291',
- constructorName: 'TunneledAccessoryConnected',
- displayName: 'Tunneled Accessory Connected',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr', 'pw'],
- },
- value: false,
- },
- {
- UUID: '00000058-0000-1000-8000-0026BB765291',
- constructorName: 'TunneledAccessoryStateNumber',
- displayName: 'Tunneled Accessory State Number',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- perms: ['ev', 'pr'],
- },
- value: 0,
- },
- ],
- constructorName: 'Tunnel',
- displayName: 'Tunnel',
- hiddenService: false,
- optionalCharacteristics: [],
- primaryService: false,
- },
- TunneledBTLEAccessoryService: {
- nrchkbDisabledText:
- 'TunneledBTLEAccessoryService (deprecated, replaced by Tunnel)',
- },
- Valve: {
- UUID: '000000D0-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '000000B0-0000-1000-8000-0026BB765291',
- constructorName: 'Active',
- displayName: 'Active',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '000000D2-0000-1000-8000-0026BB765291',
- constructorName: 'InUse',
- displayName: 'In Use',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '000000D5-0000-1000-8000-0026BB765291',
- constructorName: 'ValveType',
- displayName: 'Valve Type',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 3,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2, 3],
- },
- value: 0,
- },
- ],
- constructorName: 'Valve',
- displayName: 'Valve',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '000000D6-0000-1000-8000-0026BB765291',
- constructorName: 'IsConfigured',
- displayName: 'Is Configured',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '000000D4-0000-1000-8000-0026BB765291',
- constructorName: 'RemainingDuration',
- displayName: 'Remaining Duration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint32',
- maxValue: 3600,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- unit: 'seconds',
- },
- value: 0,
- },
- {
- UUID: '000000CB-0000-1000-8000-0026BB765291',
- constructorName: 'ServiceLabelIndex',
- displayName: 'Service Label Index',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 255,
- minStep: 1,
- minValue: 1,
- perms: ['pr'],
- },
- value: 1,
- },
- {
- UUID: '000000D3-0000-1000-8000-0026BB765291',
- constructorName: 'SetDuration',
- displayName: 'Set Duration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint32',
- maxValue: 3600,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'seconds',
- },
- value: 0,
- },
- {
- UUID: '00000077-0000-1000-8000-0026BB765291',
- constructorName: 'StatusFault',
- displayName: 'Status Fault',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- ],
- primaryService: false,
- },
- WiFiRouter: {
- UUID: '0000020A-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '000000E3-0000-1000-8000-0026BB765291',
- constructorName: 'ConfiguredName',
- displayName: 'Configured Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- perms: ['ev', 'pr', 'pw'],
- },
- value: '',
- },
- {
- UUID: '00000215-0000-1000-8000-0026BB765291',
- constructorName: 'ManagedNetworkEnable',
- displayName: 'Managed Network Enable',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw', 'tw'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '0000021F-0000-1000-8000-0026BB765291',
- constructorName: 'NetworkAccessViolationControl',
- displayName: 'Network Access Violation Control',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['ev', 'pr', 'pw', 'tw', 'wr'],
- },
- value: '',
- },
- {
- UUID: '0000020C-0000-1000-8000-0026BB765291',
- constructorName: 'NetworkClientProfileControl',
- displayName: 'Network Client Profile Control',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['ev', 'pr', 'pw', 'tw', 'wr'],
- },
- value: '',
- },
- {
- UUID: '0000020D-0000-1000-8000-0026BB765291',
- constructorName: 'NetworkClientStatusControl',
- displayName: 'Network Client Status Control',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr', 'pw', 'wr'],
- },
- value: '',
- },
- {
- UUID: '0000020E-0000-1000-8000-0026BB765291',
- constructorName: 'RouterStatus',
- displayName: 'Router Status',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1],
- },
- value: 0,
- },
- {
- UUID: '00000210-0000-1000-8000-0026BB765291',
- constructorName: 'SupportedRouterConfiguration',
- displayName: 'Supported Router Configuration',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000211-0000-1000-8000-0026BB765291',
- constructorName: 'WANConfigurationList',
- displayName: 'WAN Configuration List',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['ev', 'pr'],
- },
- value: '',
- },
- {
- UUID: '00000212-0000-1000-8000-0026BB765291',
- constructorName: 'WANStatusList',
- displayName: 'WAN Status List',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['ev', 'pr'],
- },
- value: '',
- },
- ],
- constructorName: 'WiFiRouter',
- displayName: 'WiFiRouter',
- hiddenService: false,
- optionalCharacteristics: [],
- primaryService: false,
- },
- WiFiSatellite: {
- UUID: '0000020F-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '0000021E-0000-1000-8000-0026BB765291',
- constructorName: 'WiFiSatelliteStatus',
- displayName: 'Wi-Fi Satellite Status',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 2,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2],
- },
- value: 0,
- },
- ],
- constructorName: 'WiFiSatellite',
- displayName: 'WiFiSatellite',
- hiddenService: false,
- optionalCharacteristics: [],
- primaryService: false,
- },
- WiFiTransport: {
- UUID: '0000022A-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '0000022B-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentTransport',
- displayName: 'Current Transport',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['pr'],
- },
- value: false,
- },
- {
- UUID: '0000022C-0000-1000-8000-0026BB765291',
- constructorName: 'WiFiCapabilities',
- displayName: 'Wi-Fi Capabilities',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint32',
- perms: ['pr'],
- },
- value: 0,
- },
- ],
- constructorName: 'WiFiTransport',
- displayName: 'WiFiTransport',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '0000022D-0000-1000-8000-0026BB765291',
- constructorName: 'WiFiConfigurationControl',
- displayName: 'Wi-Fi Configuration Control',
- eventOnlyCharacteristic: false,
- props: {
- format: 'tlv8',
- perms: ['ev', 'pr', 'pw', 'tw', 'wr'],
- },
- value: '',
- },
- ],
- primaryService: false,
- },
- Window: {
- UUID: '0000008B-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '0000006D-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentPosition',
- displayName: 'Current Position',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- unit: 'percentage',
- },
- value: 0,
- },
- {
- UUID: '00000072-0000-1000-8000-0026BB765291',
- constructorName: 'PositionState',
- displayName: 'Position State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 2,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2],
- },
- value: 0,
- },
- {
- UUID: '0000007C-0000-1000-8000-0026BB765291',
- constructorName: 'TargetPosition',
- displayName: 'Target Position',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'percentage',
- },
- value: 0,
- },
- ],
- constructorName: 'Window',
- displayName: 'Window',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000024-0000-1000-8000-0026BB765291',
- constructorName: 'ObstructionDetected',
- displayName: 'Obstruction Detected',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr'],
- },
- value: false,
- },
- {
- UUID: '0000006F-0000-1000-8000-0026BB765291',
- constructorName: 'HoldPosition',
- displayName: 'Hold Position',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['pw'],
- },
- value: false,
- },
- ],
- primaryService: false,
- },
- WindowCovering: {
- UUID: '0000008C-0000-1000-8000-0026BB765291',
- characteristics: [
- {
- UUID: '0000006D-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentPosition',
- displayName: 'Current Position',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- unit: 'percentage',
- },
- value: 0,
- },
- {
- UUID: '00000072-0000-1000-8000-0026BB765291',
- constructorName: 'PositionState',
- displayName: 'Position State',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 2,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr'],
- validValues: [0, 1, 2],
- },
- value: 0,
- },
- {
- UUID: '0000007C-0000-1000-8000-0026BB765291',
- constructorName: 'TargetPosition',
- displayName: 'Target Position',
- eventOnlyCharacteristic: false,
- props: {
- format: 'uint8',
- maxValue: 100,
- minStep: 1,
- minValue: 0,
- perms: ['ev', 'pr', 'pw'],
- unit: 'percentage',
- },
- value: 0,
- },
- ],
- constructorName: 'WindowCovering',
- displayName: 'WindowCovering',
- hiddenService: false,
- optionalCharacteristics: [
- {
- UUID: '0000006C-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentHorizontalTiltAngle',
- displayName: 'Current Horizontal Tilt Angle',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- maxValue: 90,
- minStep: 1,
- minValue: -90,
- perms: ['ev', 'pr'],
- unit: 'arcdegrees',
- },
- value: -90,
- },
- {
- UUID: '0000007B-0000-1000-8000-0026BB765291',
- constructorName: 'TargetHorizontalTiltAngle',
- displayName: 'Target Horizontal Tilt Angle',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- maxValue: 90,
- minStep: 1,
- minValue: -90,
- perms: ['ev', 'pr', 'pw'],
- unit: 'arcdegrees',
- },
- value: -90,
- },
- {
- UUID: '00000023-0000-1000-8000-0026BB765291',
- constructorName: 'Name',
- displayName: 'Name',
- eventOnlyCharacteristic: false,
- props: {
- format: 'string',
- maxLen: 64,
- perms: ['pr'],
- },
- value: '',
- },
- {
- UUID: '00000024-0000-1000-8000-0026BB765291',
- constructorName: 'ObstructionDetected',
- displayName: 'Obstruction Detected',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['ev', 'pr'],
- },
- value: false,
- },
- {
- UUID: '0000006F-0000-1000-8000-0026BB765291',
- constructorName: 'HoldPosition',
- displayName: 'Hold Position',
- eventOnlyCharacteristic: false,
- props: {
- format: 'bool',
- perms: ['pw'],
- },
- value: false,
- },
- {
- UUID: '0000006E-0000-1000-8000-0026BB765291',
- constructorName: 'CurrentVerticalTiltAngle',
- displayName: 'Current Vertical Tilt Angle',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- maxValue: 90,
- minStep: 1,
- minValue: -90,
- perms: ['ev', 'pr'],
- unit: 'arcdegrees',
- },
- value: -90,
- },
- {
- UUID: '0000007D-0000-1000-8000-0026BB765291',
- constructorName: 'TargetVerticalTiltAngle',
- displayName: 'Target Vertical Tilt Angle',
- eventOnlyCharacteristic: false,
- props: {
- format: 'int',
- maxValue: 90,
- minStep: 1,
- minValue: -90,
- perms: ['ev', 'pr', 'pw'],
- unit: 'arcdegrees',
- },
- value: -90,
- },
- ],
- primaryService: false,
- },
+ AccessCode: {
+ UUID: '00000260-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000262-0000-1000-8000-0026BB765291',
+ constructorName: 'AccessCodeControlPoint',
+ displayName: 'Access Code Control Point',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr', 'pw', 'wr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000261-0000-1000-8000-0026BB765291',
+ constructorName: 'AccessCodeSupportedConfiguration',
+ displayName: 'Access Code Supported Configuration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000263-0000-1000-8000-0026BB765291',
+ constructorName: 'ConfigurationState',
+ displayName: 'Configuration State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint16',
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'AccessCode',
+ displayName: 'AccessCode',
+ hiddenService: false,
+ optionalCharacteristics: [],
+ primaryService: false
+ },
+ AccessControl: {
+ UUID: '000000DA-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '000000E5-0000-1000-8000-0026BB765291',
+ constructorName: 'AccessControlLevel',
+ displayName: 'Access Control Level',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint16',
+ maxValue: 2,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'AccessControl',
+ displayName: 'AccessControl',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '000000E4-0000-1000-8000-0026BB765291',
+ constructorName: 'PasswordSetting',
+ displayName: 'Password Setting',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: ''
+ }
+ ],
+ primaryService: false
+ },
+ AccessoryInformation: {
+ UUID: '0000003E-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000014-0000-1000-8000-0026BB765291',
+ constructorName: 'Identify',
+ displayName: 'Identify',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['pw']
+ },
+ value: false
+ },
+ {
+ UUID: '00000020-0000-1000-8000-0026BB765291',
+ constructorName: 'Manufacturer',
+ displayName: 'Manufacturer',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: 'Default-Manufacturer'
+ },
+ {
+ UUID: '00000021-0000-1000-8000-0026BB765291',
+ constructorName: 'Model',
+ displayName: 'Model',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: 'Default-Model'
+ },
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: 'Unnamed Service'
+ },
+ {
+ UUID: '00000030-0000-1000-8000-0026BB765291',
+ constructorName: 'SerialNumber',
+ displayName: 'Serial Number',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: 'Default-SerialNumber'
+ },
+ {
+ UUID: '00000052-0000-1000-8000-0026BB765291',
+ constructorName: 'FirmwareRevision',
+ displayName: 'Firmware Revision',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ perms: ['pr']
+ },
+ value: '0.0.0'
+ }
+ ],
+ constructorName: 'AccessoryInformation',
+ displayName: 'AccessoryInformation',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '000000A6-0000-1000-8000-0026BB765291',
+ constructorName: 'AccessoryFlags',
+ displayName: 'Accessory Flags',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint32',
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '000000A4-0000-1000-8000-0026BB765291',
+ constructorName: 'AppMatchingIdentifier',
+ displayName: 'App Matching Identifier',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '000000E3-0000-1000-8000-0026BB765291',
+ constructorName: 'ConfiguredName',
+ displayName: 'Configured Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: ''
+ },
+ {
+ UUID: '0000026D-0000-1000-8000-0026BB765291',
+ constructorName: 'MatterFirmwareRevisionNumber',
+ displayName: 'Matter Firmware Revision Number',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint32',
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '0000026C-0000-1000-8000-0026BB765291',
+ constructorName: 'HardwareFinish',
+ displayName: 'Hardware Finish',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000053-0000-1000-8000-0026BB765291',
+ constructorName: 'HardwareRevision',
+ displayName: 'Hardware Revision',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000220-0000-1000-8000-0026BB765291',
+ constructorName: 'ProductData',
+ displayName: 'Product Data',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'data',
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000054-0000-1000-8000-0026BB765291',
+ constructorName: 'SoftwareRevision',
+ displayName: 'Software Revision',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ perms: ['pr']
+ },
+ value: ''
+ }
+ ],
+ primaryService: false
+ },
+ AccessoryMetrics: {
+ UUID: '00000270-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '000000B0-0000-1000-8000-0026BB765291',
+ constructorName: 'Active',
+ displayName: 'Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000272-0000-1000-8000-0026BB765291',
+ constructorName: 'MetricsBufferFullState',
+ displayName: 'Metrics Buffer Full State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr']
+ },
+ value: false
+ },
+ {
+ UUID: '00000271-0000-1000-8000-0026BB765291',
+ constructorName: 'SupportedMetrics',
+ displayName: 'Supported Metrics',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr', 'pw']
+ },
+ value: ''
+ }
+ ],
+ constructorName: 'AccessoryMetrics',
+ displayName: 'AccessoryMetrics',
+ hiddenService: false,
+ optionalCharacteristics: [],
+ primaryService: false
+ },
+ AccessoryRuntimeInformation: {
+ UUID: '00000239-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '0000023C-0000-1000-8000-0026BB765291',
+ constructorName: 'Ping',
+ displayName: 'Ping',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'data',
+ perms: ['pr']
+ },
+ value: ''
+ }
+ ],
+ constructorName: 'AccessoryRuntimeInformation',
+ displayName: 'AccessoryRuntimeInformation',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '0000023B-0000-1000-8000-0026BB765291',
+ constructorName: 'ActivityInterval',
+ displayName: 'Activity Interval',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint32',
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '0000024A-0000-1000-8000-0026BB765291',
+ constructorName: 'HeartBeat',
+ displayName: 'Heart Beat',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint32',
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '0000023A-0000-1000-8000-0026BB765291',
+ constructorName: 'SleepInterval',
+ displayName: 'Sleep Interval',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint32',
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ AirPurifier: {
+ UUID: '000000BB-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '000000B0-0000-1000-8000-0026BB765291',
+ constructorName: 'Active',
+ displayName: 'Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '000000A9-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentAirPurifierState',
+ displayName: 'Current Air Purifier State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 2,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2]
+ },
+ value: 0
+ },
+ {
+ UUID: '000000A8-0000-1000-8000-0026BB765291',
+ constructorName: 'TargetAirPurifierState',
+ displayName: 'Target Air Purifier State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'AirPurifier',
+ displayName: 'AirPurifier',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '000000A7-0000-1000-8000-0026BB765291',
+ constructorName: 'LockPhysicalControls',
+ displayName: 'Lock Physical Controls',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000029-0000-1000-8000-0026BB765291',
+ constructorName: 'RotationSpeed',
+ displayName: 'Rotation Speed',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'percentage'
+ },
+ value: 0
+ },
+ {
+ UUID: '000000B6-0000-1000-8000-0026BB765291',
+ constructorName: 'SwingMode',
+ displayName: 'Swing Mode',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ AirQualitySensor: {
+ UUID: '0000008D-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000095-0000-1000-8000-0026BB765291',
+ constructorName: 'AirQuality',
+ displayName: 'Air Quality',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 5,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2, 3, 4, 5]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'AirQualitySensor',
+ displayName: 'AirQualitySensor',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '000000C4-0000-1000-8000-0026BB765291',
+ constructorName: 'NitrogenDioxideDensity',
+ displayName: 'Nitrogen Dioxide Density',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 1000,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '000000C3-0000-1000-8000-0026BB765291',
+ constructorName: 'OzoneDensity',
+ displayName: 'Ozone Density',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 1000,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '000000C7-0000-1000-8000-0026BB765291',
+ constructorName: 'PM10Density',
+ displayName: 'PM10 Density',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 1000,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '000000C6-0000-1000-8000-0026BB765291',
+ constructorName: 'PM2_5Density',
+ displayName: 'PM2.5 Density',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 1000,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '000000C5-0000-1000-8000-0026BB765291',
+ constructorName: 'SulphurDioxideDensity',
+ displayName: 'Sulphur Dioxide Density',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 1000,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '000000C8-0000-1000-8000-0026BB765291',
+ constructorName: 'VOCDensity',
+ displayName: 'VOC Density',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 1000,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000075-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusActive',
+ displayName: 'Status Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr']
+ },
+ value: false
+ },
+ {
+ UUID: '00000077-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusFault',
+ displayName: 'Status Fault',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000079-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusLowBattery',
+ displayName: 'Status Low Battery',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000007A-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusTampered',
+ displayName: 'Status Tampered',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ AssetUpdate: {
+ UUID: '00000267-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000269-0000-1000-8000-0026BB765291',
+ constructorName: 'AssetUpdateReadiness',
+ displayName: 'Asset Update Readiness',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint32',
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000268-0000-1000-8000-0026BB765291',
+ constructorName: 'SupportedAssetTypes',
+ displayName: 'Supported Asset Types',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint32',
+ perms: ['pr']
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'AssetUpdate',
+ displayName: 'AssetUpdate',
+ hiddenService: false,
+ optionalCharacteristics: [],
+ primaryService: false
+ },
+ Assistant: {
+ UUID: '0000026A-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '000000B0-0000-1000-8000-0026BB765291',
+ constructorName: 'Active',
+ displayName: 'Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '000000E6-0000-1000-8000-0026BB765291',
+ constructorName: 'Identifier',
+ displayName: 'Identifier',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint32',
+ perms: ['pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: 'Unnamed Service'
+ }
+ ],
+ constructorName: 'Assistant',
+ displayName: 'Assistant',
+ hiddenService: false,
+ optionalCharacteristics: [],
+ primaryService: false
+ },
+ AudioStreamManagement: {
+ UUID: '00000127-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000115-0000-1000-8000-0026BB765291',
+ constructorName: 'SupportedAudioStreamConfiguration',
+ displayName: 'Supported Audio Stream Configuration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000128-0000-1000-8000-0026BB765291',
+ constructorName: 'SelectedAudioStreamConfiguration',
+ displayName: 'Selected Audio Stream Configuration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr', 'pw']
+ },
+ value: ''
+ }
+ ],
+ constructorName: 'AudioStreamManagement',
+ displayName: 'AudioStreamManagement',
+ hiddenService: false,
+ optionalCharacteristics: [],
+ primaryService: false
+ },
+ Battery: {
+ UUID: '00000096-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000079-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusLowBattery',
+ displayName: 'Status Low Battery',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'Battery',
+ displayName: 'Battery',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000068-0000-1000-8000-0026BB765291',
+ constructorName: 'BatteryLevel',
+ displayName: 'Battery Level',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ unit: 'percentage'
+ },
+ value: 0
+ },
+ {
+ UUID: '0000008F-0000-1000-8000-0026BB765291',
+ constructorName: 'ChargingState',
+ displayName: 'Charging State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 2,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ }
+ ],
+ primaryService: false
+ },
+ BatteryService: {
+ nrchkbDisabledText: 'BatteryService (deprecated, replaced by Battery)'
+ },
+ BridgeConfiguration: {
+ nrchkbDisabledText: 'BridgeConfiguration (deprecated, unused)'
+ },
+ BridgingState: {
+ nrchkbDisabledText: 'BridgingState (deprecated, unused)'
+ },
+ CameraControl: {
+ nrchkbDisabledText: 'CameraControl (deprecated, replaced by)'
+ },
+ CameraEventRecordingManagement: {
+ nrchkbDisabledText:
+ 'CameraEventRecordingManagement (deprecated, replaced by CameraRecordingManagement)'
+ },
+ CameraOperatingMode: {
+ UUID: '0000021A-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000223-0000-1000-8000-0026BB765291',
+ constructorName: 'EventSnapshotsActive',
+ displayName: 'Event Snapshots Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000021B-0000-1000-8000-0026BB765291',
+ constructorName: 'HomeKitCameraActive',
+ displayName: 'HomeKit Camera Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'CameraOperatingMode',
+ displayName: 'CameraOperatingMode',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '0000021D-0000-1000-8000-0026BB765291',
+ constructorName: 'CameraOperatingModeIndicator',
+ displayName: 'Camera Operating Mode Indicator',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr', 'pw', 'tw']
+ },
+ value: false
+ },
+ {
+ UUID: '00000227-0000-1000-8000-0026BB765291',
+ constructorName: 'ManuallyDisabled',
+ displayName: 'Manually Disabled',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr']
+ },
+ value: false
+ },
+ {
+ UUID: '0000011B-0000-1000-8000-0026BB765291',
+ constructorName: 'NightVision',
+ displayName: 'Night Vision',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr', 'pw', 'tw']
+ },
+ value: false
+ },
+ {
+ UUID: '00000225-0000-1000-8000-0026BB765291',
+ constructorName: 'PeriodicSnapshotsActive',
+ displayName: 'Periodic Snapshots Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000021C-0000-1000-8000-0026BB765291',
+ constructorName: 'ThirdPartyCameraActive',
+ displayName: 'Third Party Camera Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000224-0000-1000-8000-0026BB765291',
+ constructorName: 'DiagonalFieldOfView',
+ displayName: 'Diagonal Field Of View',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 360,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ unit: 'arcdegrees'
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ CameraRTPStreamManagement: {
+ UUID: '00000110-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000117-0000-1000-8000-0026BB765291',
+ constructorName: 'SelectedRTPStreamConfiguration',
+ displayName: 'Selected RTP Stream Configuration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr', 'pw']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000118-0000-1000-8000-0026BB765291',
+ constructorName: 'SetupEndpoints',
+ displayName: 'Setup Endpoints',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr', 'pw']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000120-0000-1000-8000-0026BB765291',
+ constructorName: 'StreamingStatus',
+ displayName: 'Streaming Status',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['ev', 'pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000115-0000-1000-8000-0026BB765291',
+ constructorName: 'SupportedAudioStreamConfiguration',
+ displayName: 'Supported Audio Stream Configuration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000116-0000-1000-8000-0026BB765291',
+ constructorName: 'SupportedRTPConfiguration',
+ displayName: 'Supported RTP Configuration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000114-0000-1000-8000-0026BB765291',
+ constructorName: 'SupportedVideoStreamConfiguration',
+ displayName: 'Supported Video Stream Configuration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr']
+ },
+ value: ''
+ }
+ ],
+ constructorName: 'CameraRTPStreamManagement',
+ displayName: 'CameraRTPStreamManagement',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '000000B0-0000-1000-8000-0026BB765291',
+ constructorName: 'Active',
+ displayName: 'Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ CameraRecordingManagement: {
+ UUID: '00000204-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '000000B0-0000-1000-8000-0026BB765291',
+ constructorName: 'Active',
+ displayName: 'Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000209-0000-1000-8000-0026BB765291',
+ constructorName: 'SelectedCameraRecordingConfiguration',
+ displayName: 'Selected Camera Recording Configuration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000207-0000-1000-8000-0026BB765291',
+ constructorName: 'SupportedAudioRecordingConfiguration',
+ displayName: 'Supported Audio Recording Configuration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['ev', 'pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000205-0000-1000-8000-0026BB765291',
+ constructorName: 'SupportedCameraRecordingConfiguration',
+ displayName: 'Supported Camera Recording Configuration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['ev', 'pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000206-0000-1000-8000-0026BB765291',
+ constructorName: 'SupportedVideoRecordingConfiguration',
+ displayName: 'Supported Video Recording Configuration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['ev', 'pr']
+ },
+ value: ''
+ }
+ ],
+ constructorName: 'CameraRecordingManagement',
+ displayName: 'CameraRecordingManagement',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000226-0000-1000-8000-0026BB765291',
+ constructorName: 'RecordingAudioActive',
+ displayName: 'Recording Audio Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ perms: ['ev', 'pr', 'pw', 'tw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ CarbonDioxideSensor: {
+ UUID: '00000097-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000092-0000-1000-8000-0026BB765291',
+ constructorName: 'CarbonDioxideDetected',
+ displayName: 'Carbon Dioxide Detected',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'CarbonDioxideSensor',
+ displayName: 'CarbonDioxideSensor',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000093-0000-1000-8000-0026BB765291',
+ constructorName: 'CarbonDioxideLevel',
+ displayName: 'Carbon Dioxide Level',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 100000,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000094-0000-1000-8000-0026BB765291',
+ constructorName: 'CarbonDioxidePeakLevel',
+ displayName: 'Carbon Dioxide Peak Level',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 100000,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000075-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusActive',
+ displayName: 'Status Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr']
+ },
+ value: false
+ },
+ {
+ UUID: '00000077-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusFault',
+ displayName: 'Status Fault',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000079-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusLowBattery',
+ displayName: 'Status Low Battery',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000007A-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusTampered',
+ displayName: 'Status Tampered',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ CarbonMonoxideSensor: {
+ UUID: '0000007F-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000069-0000-1000-8000-0026BB765291',
+ constructorName: 'CarbonMonoxideDetected',
+ displayName: 'Carbon Monoxide Detected',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'CarbonMonoxideSensor',
+ displayName: 'CarbonMonoxideSensor',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000090-0000-1000-8000-0026BB765291',
+ constructorName: 'CarbonMonoxideLevel',
+ displayName: 'Carbon Monoxide Level',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000091-0000-1000-8000-0026BB765291',
+ constructorName: 'CarbonMonoxidePeakLevel',
+ displayName: 'Carbon Monoxide Peak Level',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000075-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusActive',
+ displayName: 'Status Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr']
+ },
+ value: false
+ },
+ {
+ UUID: '00000077-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusFault',
+ displayName: 'Status Fault',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000079-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusLowBattery',
+ displayName: 'Status Low Battery',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000007A-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusTampered',
+ displayName: 'Status Tampered',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ CloudRelay: {
+ UUID: '0000005A-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '0000005E-0000-1000-8000-0026BB765291',
+ constructorName: 'RelayControlPoint',
+ displayName: 'Relay Control Point',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: ''
+ },
+ {
+ UUID: '0000005C-0000-1000-8000-0026BB765291',
+ constructorName: 'RelayState',
+ displayName: 'Relay State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 5,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '0000005B-0000-1000-8000-0026BB765291',
+ constructorName: 'RelayEnabled',
+ displayName: 'Relay Enabled',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: false
+ }
+ ],
+ constructorName: 'CloudRelay',
+ displayName: 'CloudRelay',
+ hiddenService: false,
+ optionalCharacteristics: [],
+ primaryService: false
+ },
+ ContactSensor: {
+ UUID: '00000080-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '0000006A-0000-1000-8000-0026BB765291',
+ constructorName: 'ContactSensorState',
+ displayName: 'Contact Sensor State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'ContactSensor',
+ displayName: 'ContactSensor',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000075-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusActive',
+ displayName: 'Status Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr']
+ },
+ value: false
+ },
+ {
+ UUID: '00000077-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusFault',
+ displayName: 'Status Fault',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000079-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusLowBattery',
+ displayName: 'Status Low Battery',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000007A-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusTampered',
+ displayName: 'Status Tampered',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ DataStreamTransportManagement: {
+ UUID: '00000129-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000131-0000-1000-8000-0026BB765291',
+ constructorName: 'SetupDataStreamTransport',
+ displayName: 'Setup Data Stream Transport',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr', 'pw', 'wr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000130-0000-1000-8000-0026BB765291',
+ constructorName: 'SupportedDataStreamTransportConfiguration',
+ displayName: 'Supported Data Stream Transport Configuration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000037-0000-1000-8000-0026BB765291',
+ constructorName: 'Version',
+ displayName: 'Version',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ }
+ ],
+ constructorName: 'DataStreamTransportManagement',
+ displayName: 'DataStreamTransportManagement',
+ hiddenService: false,
+ optionalCharacteristics: [],
+ primaryService: false
+ },
+ Diagnostics: {
+ UUID: '00000237-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000238-0000-1000-8000-0026BB765291',
+ constructorName: 'SupportedDiagnosticsSnapshot',
+ displayName: 'Supported Diagnostics Snapshot',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr']
+ },
+ value: ''
+ }
+ ],
+ constructorName: 'Diagnostics',
+ displayName: 'Diagnostics',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '0000024D-0000-1000-8000-0026BB765291',
+ constructorName: 'SelectedDiagnosticsModes',
+ displayName: 'Selected Diagnostics Modes',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint32',
+ perms: ['pr', 'pw']
+ },
+ value: 0
+ },
+ {
+ UUID: '0000024C-0000-1000-8000-0026BB765291',
+ constructorName: 'SupportedDiagnosticsModes',
+ displayName: 'Supported Diagnostics Modes',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint32',
+ perms: ['pr']
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ Door: {
+ UUID: '00000081-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '0000006D-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentPosition',
+ displayName: 'Current Position',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ unit: 'percentage'
+ },
+ value: 0
+ },
+ {
+ UUID: '00000072-0000-1000-8000-0026BB765291',
+ constructorName: 'PositionState',
+ displayName: 'Position State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 2,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000007C-0000-1000-8000-0026BB765291',
+ constructorName: 'TargetPosition',
+ displayName: 'Target Position',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'percentage'
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'Door',
+ displayName: 'Door',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000024-0000-1000-8000-0026BB765291',
+ constructorName: 'ObstructionDetected',
+ displayName: 'Obstruction Detected',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr']
+ },
+ value: false
+ },
+ {
+ UUID: '0000006F-0000-1000-8000-0026BB765291',
+ constructorName: 'HoldPosition',
+ displayName: 'Hold Position',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['pw']
+ },
+ value: false
+ }
+ ],
+ primaryService: false
+ },
+ Doorbell: {
+ UUID: '00000121-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000073-0000-1000-8000-0026BB765291',
+ constructorName: 'ProgrammableSwitchEvent',
+ displayName: 'Programmable Switch Event',
+ eventOnlyCharacteristic: true,
+ props: {
+ format: 'uint8',
+ maxValue: 2,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'Doorbell',
+ displayName: 'Doorbell',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000008-0000-1000-8000-0026BB765291',
+ constructorName: 'Brightness',
+ displayName: 'Brightness',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'int',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'percentage'
+ },
+ value: 0
+ },
+ {
+ UUID: '0000011A-0000-1000-8000-0026BB765291',
+ constructorName: 'Mute',
+ displayName: 'Mute',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: false
+ },
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000232-0000-1000-8000-0026BB765291',
+ constructorName: 'OperatingStateResponse',
+ displayName: 'Operating State Response',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['ev', 'pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000119-0000-1000-8000-0026BB765291',
+ constructorName: 'Volume',
+ displayName: 'Volume',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'percentage'
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ Fan: {
+ UUID: '00000040-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000025-0000-1000-8000-0026BB765291',
+ constructorName: 'On',
+ displayName: 'On',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: false
+ }
+ ],
+ constructorName: 'Fan',
+ displayName: 'Fan',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000028-0000-1000-8000-0026BB765291',
+ constructorName: 'RotationDirection',
+ displayName: 'Rotation Direction',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'int',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000029-0000-1000-8000-0026BB765291',
+ constructorName: 'RotationSpeed',
+ displayName: 'Rotation Speed',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'percentage'
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ Fanv2: {
+ UUID: '000000B7-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '000000B0-0000-1000-8000-0026BB765291',
+ constructorName: 'Active',
+ displayName: 'Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'Fanv2',
+ displayName: 'Fanv2',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '000000AF-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentFanState',
+ displayName: 'Current Fan State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 2,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2]
+ },
+ value: 0
+ },
+ {
+ UUID: '000000BF-0000-1000-8000-0026BB765291',
+ constructorName: 'TargetFanState',
+ displayName: 'Target Fan State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '000000A7-0000-1000-8000-0026BB765291',
+ constructorName: 'LockPhysicalControls',
+ displayName: 'Lock Physical Controls',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000028-0000-1000-8000-0026BB765291',
+ constructorName: 'RotationDirection',
+ displayName: 'Rotation Direction',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'int',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000029-0000-1000-8000-0026BB765291',
+ constructorName: 'RotationSpeed',
+ displayName: 'Rotation Speed',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'percentage'
+ },
+ value: 0
+ },
+ {
+ UUID: '000000B6-0000-1000-8000-0026BB765291',
+ constructorName: 'SwingMode',
+ displayName: 'Swing Mode',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ Faucet: {
+ UUID: '000000D7-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '000000B0-0000-1000-8000-0026BB765291',
+ constructorName: 'Active',
+ displayName: 'Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'Faucet',
+ displayName: 'Faucet',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000077-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusFault',
+ displayName: 'Status Fault',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ FilterMaintenance: {
+ UUID: '000000BA-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '000000AC-0000-1000-8000-0026BB765291',
+ constructorName: 'FilterChangeIndication',
+ displayName: 'Filter Change Indication',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'FilterMaintenance',
+ displayName: 'FilterMaintenance',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '000000AB-0000-1000-8000-0026BB765291',
+ constructorName: 'FilterLifeLevel',
+ displayName: 'Filter Life Level',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '000000AD-0000-1000-8000-0026BB765291',
+ constructorName: 'ResetFilterIndication',
+ displayName: 'Reset Filter Indication',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 1,
+ perms: ['pw']
+ },
+ value: 1
+ },
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ }
+ ],
+ primaryService: false
+ },
+ FirmwareUpdate: {
+ UUID: '00000236-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000234-0000-1000-8000-0026BB765291',
+ constructorName: 'FirmwareUpdateReadiness',
+ displayName: 'Firmware Update Readiness',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['ev', 'pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000235-0000-1000-8000-0026BB765291',
+ constructorName: 'FirmwareUpdateStatus',
+ displayName: 'Firmware Update Status',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['ev', 'pr']
+ },
+ value: ''
+ }
+ ],
+ constructorName: 'FirmwareUpdate',
+ displayName: 'FirmwareUpdate',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '0000026F-0000-1000-8000-0026BB765291',
+ constructorName: 'FirmwareUpdateProtocolList',
+ displayName: 'Firmware Update Protocol List',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '0000026E-0000-1000-8000-0026BB765291',
+ constructorName: 'MatterFirmwareUpdateStatus',
+ displayName: 'Matter Firmware Update Status',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['ev', 'pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000249-0000-1000-8000-0026BB765291',
+ constructorName: 'StagedFirmwareVersion',
+ displayName: 'Staged Firmware Version',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ perms: ['ev', 'pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000233-0000-1000-8000-0026BB765291',
+ constructorName: 'SupportedFirmwareUpdateConfiguration',
+ displayName: 'Supported Firmware Update Configuration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr']
+ },
+ value: ''
+ }
+ ],
+ primaryService: false
+ },
+ GarageDoorOpener: {
+ UUID: '00000041-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '0000000E-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentDoorState',
+ displayName: 'Current Door State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 4,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2, 3, 4]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000032-0000-1000-8000-0026BB765291',
+ constructorName: 'TargetDoorState',
+ displayName: 'Target Door State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000024-0000-1000-8000-0026BB765291',
+ constructorName: 'ObstructionDetected',
+ displayName: 'Obstruction Detected',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr']
+ },
+ value: false
+ }
+ ],
+ constructorName: 'GarageDoorOpener',
+ displayName: 'GarageDoorOpener',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '0000001D-0000-1000-8000-0026BB765291',
+ constructorName: 'LockCurrentState',
+ displayName: 'Lock Current State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 3,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2, 3]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000001E-0000-1000-8000-0026BB765291',
+ constructorName: 'LockTargetState',
+ displayName: 'Lock Target State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ }
+ ],
+ primaryService: false
+ },
+ HeaterCooler: {
+ UUID: '000000BC-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '000000B0-0000-1000-8000-0026BB765291',
+ constructorName: 'Active',
+ displayName: 'Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '000000B1-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentHeaterCoolerState',
+ displayName: 'Current Heater-Cooler State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 3,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2, 3]
+ },
+ value: 0
+ },
+ {
+ UUID: '000000B2-0000-1000-8000-0026BB765291',
+ constructorName: 'TargetHeaterCoolerState',
+ displayName: 'Target Heater-Cooler State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 2,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1, 2]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000011-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentTemperature',
+ displayName: 'Current Temperature',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 100,
+ minStep: 0.1,
+ minValue: -270,
+ perms: ['ev', 'pr'],
+ unit: 'celsius'
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'HeaterCooler',
+ displayName: 'HeaterCooler',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '000000A7-0000-1000-8000-0026BB765291',
+ constructorName: 'LockPhysicalControls',
+ displayName: 'Lock Physical Controls',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000029-0000-1000-8000-0026BB765291',
+ constructorName: 'RotationSpeed',
+ displayName: 'Rotation Speed',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'percentage'
+ },
+ value: 0
+ },
+ {
+ UUID: '000000B6-0000-1000-8000-0026BB765291',
+ constructorName: 'SwingMode',
+ displayName: 'Swing Mode',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000000D-0000-1000-8000-0026BB765291',
+ constructorName: 'CoolingThresholdTemperature',
+ displayName: 'Cooling Threshold Temperature',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 35,
+ minStep: 0.1,
+ minValue: 10,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'celsius'
+ },
+ value: 10
+ },
+ {
+ UUID: '00000012-0000-1000-8000-0026BB765291',
+ constructorName: 'HeatingThresholdTemperature',
+ displayName: 'Heating Threshold Temperature',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 25,
+ minStep: 0.1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'celsius'
+ },
+ value: 0
+ },
+ {
+ UUID: '00000036-0000-1000-8000-0026BB765291',
+ constructorName: 'TemperatureDisplayUnits',
+ displayName: 'Temperature Display Units',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ HumidifierDehumidifier: {
+ UUID: '000000BD-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '000000B0-0000-1000-8000-0026BB765291',
+ constructorName: 'Active',
+ displayName: 'Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '000000B3-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentHumidifierDehumidifierState',
+ displayName: 'Current Humidifier-Dehumidifier State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 3,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2, 3]
+ },
+ value: 0
+ },
+ {
+ UUID: '000000B4-0000-1000-8000-0026BB765291',
+ constructorName: 'TargetHumidifierDehumidifierState',
+ displayName: 'Target Humidifier-Dehumidifier State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 2,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1, 2]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000010-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentRelativeHumidity',
+ displayName: 'Current Relative Humidity',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ unit: 'percentage'
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'HumidifierDehumidifier',
+ displayName: 'HumidifierDehumidifier',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '000000A7-0000-1000-8000-0026BB765291',
+ constructorName: 'LockPhysicalControls',
+ displayName: 'Lock Physical Controls',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '000000C9-0000-1000-8000-0026BB765291',
+ constructorName: 'RelativeHumidityDehumidifierThreshold',
+ displayName: 'Relative Humidity Dehumidifier Threshold',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'percentage'
+ },
+ value: 0
+ },
+ {
+ UUID: '000000CA-0000-1000-8000-0026BB765291',
+ constructorName: 'RelativeHumidityHumidifierThreshold',
+ displayName: 'Relative Humidity Humidifier Threshold',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'percentage'
+ },
+ value: 0
+ },
+ {
+ UUID: '00000029-0000-1000-8000-0026BB765291',
+ constructorName: 'RotationSpeed',
+ displayName: 'Rotation Speed',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'percentage'
+ },
+ value: 0
+ },
+ {
+ UUID: '000000B6-0000-1000-8000-0026BB765291',
+ constructorName: 'SwingMode',
+ displayName: 'Swing Mode',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '000000B5-0000-1000-8000-0026BB765291',
+ constructorName: 'WaterLevel',
+ displayName: 'Water Level',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ unit: 'percentage'
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ HumiditySensor: {
+ UUID: '00000082-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000010-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentRelativeHumidity',
+ displayName: 'Current Relative Humidity',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ unit: 'percentage'
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'HumiditySensor',
+ displayName: 'HumiditySensor',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000075-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusActive',
+ displayName: 'Status Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr']
+ },
+ value: false
+ },
+ {
+ UUID: '00000077-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusFault',
+ displayName: 'Status Fault',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000079-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusLowBattery',
+ displayName: 'Status Low Battery',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000007A-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusTampered',
+ displayName: 'Status Tampered',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ InputSource: {
+ UUID: '000000D9-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '000000E3-0000-1000-8000-0026BB765291',
+ constructorName: 'ConfiguredName',
+ displayName: 'Configured Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: ''
+ },
+ {
+ UUID: '000000DB-0000-1000-8000-0026BB765291',
+ constructorName: 'InputSourceType',
+ displayName: 'Input Source Type',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 10,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ },
+ value: 0
+ },
+ {
+ UUID: '000000D6-0000-1000-8000-0026BB765291',
+ constructorName: 'IsConfigured',
+ displayName: 'Is Configured',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: 'Unnamed Service'
+ },
+ {
+ UUID: '00000135-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentVisibilityState',
+ displayName: 'Current Visibility State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'InputSource',
+ displayName: 'InputSource',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '000000E6-0000-1000-8000-0026BB765291',
+ constructorName: 'Identifier',
+ displayName: 'Identifier',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint32',
+ perms: ['pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '000000DC-0000-1000-8000-0026BB765291',
+ constructorName: 'InputDeviceType',
+ displayName: 'Input Device Type',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 6,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2, 3, 4, 5, 6]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000134-0000-1000-8000-0026BB765291',
+ constructorName: 'TargetVisibilityState',
+ displayName: 'Target Visibility State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ IrrigationSystem: {
+ UUID: '000000CF-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '000000B0-0000-1000-8000-0026BB765291',
+ constructorName: 'Active',
+ displayName: 'Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '000000D1-0000-1000-8000-0026BB765291',
+ constructorName: 'ProgramMode',
+ displayName: 'Program Mode',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 2,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2]
+ },
+ value: 0
+ },
+ {
+ UUID: '000000D2-0000-1000-8000-0026BB765291',
+ constructorName: 'InUse',
+ displayName: 'In Use',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'IrrigationSystem',
+ displayName: 'IrrigationSystem',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '000000D4-0000-1000-8000-0026BB765291',
+ constructorName: 'RemainingDuration',
+ displayName: 'Remaining Duration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint32',
+ maxValue: 3600,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ unit: 'seconds'
+ },
+ value: 0
+ },
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000077-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusFault',
+ displayName: 'Status Fault',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ LeakSensor: {
+ UUID: '00000083-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000070-0000-1000-8000-0026BB765291',
+ constructorName: 'LeakDetected',
+ displayName: 'Leak Detected',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'LeakSensor',
+ displayName: 'LeakSensor',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000075-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusActive',
+ displayName: 'Status Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr']
+ },
+ value: false
+ },
+ {
+ UUID: '00000077-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusFault',
+ displayName: 'Status Fault',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000079-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusLowBattery',
+ displayName: 'Status Low Battery',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000007A-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusTampered',
+ displayName: 'Status Tampered',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ LightSensor: {
+ UUID: '00000084-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '0000006B-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentAmbientLightLevel',
+ displayName: 'Current Ambient Light Level',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 100000,
+ minValue: 0.0001,
+ perms: ['ev', 'pr'],
+ unit: 'lux'
+ },
+ value: 0.0001
+ }
+ ],
+ constructorName: 'LightSensor',
+ displayName: 'LightSensor',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000075-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusActive',
+ displayName: 'Status Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr']
+ },
+ value: false
+ },
+ {
+ UUID: '00000077-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusFault',
+ displayName: 'Status Fault',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000079-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusLowBattery',
+ displayName: 'Status Low Battery',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000007A-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusTampered',
+ displayName: 'Status Tampered',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ Lightbulb: {
+ UUID: '00000043-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000025-0000-1000-8000-0026BB765291',
+ constructorName: 'On',
+ displayName: 'On',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: false
+ }
+ ],
+ constructorName: 'Lightbulb',
+ displayName: 'Lightbulb',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000008-0000-1000-8000-0026BB765291',
+ constructorName: 'Brightness',
+ displayName: 'Brightness',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'int',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'percentage'
+ },
+ value: 0
+ },
+ {
+ UUID: '0000024B-0000-1000-8000-0026BB765291',
+ constructorName: 'CharacteristicValueActiveTransitionCount',
+ displayName: 'Characteristic Value Active Transition Count',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000143-0000-1000-8000-0026BB765291',
+ constructorName: 'CharacteristicValueTransitionControl',
+ displayName: 'Characteristic Value Transition Control',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr', 'pw', 'wr']
+ },
+ value: ''
+ },
+ {
+ UUID: '000000CE-0000-1000-8000-0026BB765291',
+ constructorName: 'ColorTemperature',
+ displayName: 'Color Temperature',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'int',
+ maxValue: 500,
+ minStep: 1,
+ minValue: 140,
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: 140
+ },
+ {
+ UUID: '00000013-0000-1000-8000-0026BB765291',
+ constructorName: 'Hue',
+ displayName: 'Hue',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 360,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'arcdegrees'
+ },
+ value: 0
+ },
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '0000002F-0000-1000-8000-0026BB765291',
+ constructorName: 'Saturation',
+ displayName: 'Saturation',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'percentage'
+ },
+ value: 0
+ },
+ {
+ UUID: '00000144-0000-1000-8000-0026BB765291',
+ constructorName: 'SupportedCharacteristicValueTransitionConfiguration',
+ displayName: 'Supported Characteristic Value Transition Configuration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr']
+ },
+ value: ''
+ }
+ ],
+ primaryService: false
+ },
+ LockManagement: {
+ UUID: '00000044-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000019-0000-1000-8000-0026BB765291',
+ constructorName: 'LockControlPoint',
+ displayName: 'Lock Control Point',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pw']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000037-0000-1000-8000-0026BB765291',
+ constructorName: 'Version',
+ displayName: 'Version',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ }
+ ],
+ constructorName: 'LockManagement',
+ displayName: 'LockManagement',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000001-0000-1000-8000-0026BB765291',
+ constructorName: 'AdministratorOnlyAccess',
+ displayName: 'Administrator Only Access',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: false
+ },
+ {
+ UUID: '00000005-0000-1000-8000-0026BB765291',
+ constructorName: 'AudioFeedback',
+ displayName: 'Audio Feedback',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: false
+ },
+ {
+ UUID: '0000000E-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentDoorState',
+ displayName: 'Current Door State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 4,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2, 3, 4]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000001A-0000-1000-8000-0026BB765291',
+ constructorName: 'LockManagementAutoSecurityTimeout',
+ displayName: 'Lock Management Auto Security Timeout',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint32',
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'seconds'
+ },
+ value: 0
+ },
+ {
+ UUID: '0000001C-0000-1000-8000-0026BB765291',
+ constructorName: 'LockLastKnownAction',
+ displayName: 'Lock Last Known Action',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 10,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000001F-0000-1000-8000-0026BB765291',
+ constructorName: 'Logs',
+ displayName: 'Logs',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['ev', 'pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000022-0000-1000-8000-0026BB765291',
+ constructorName: 'MotionDetected',
+ displayName: 'Motion Detected',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr']
+ },
+ value: false
+ }
+ ],
+ primaryService: false
+ },
+ LockMechanism: {
+ UUID: '00000045-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '0000001D-0000-1000-8000-0026BB765291',
+ constructorName: 'LockCurrentState',
+ displayName: 'Lock Current State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 3,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2, 3]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000001E-0000-1000-8000-0026BB765291',
+ constructorName: 'LockTargetState',
+ displayName: 'Lock Target State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'LockMechanism',
+ displayName: 'LockMechanism',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ }
+ ],
+ primaryService: false
+ },
+ Microphone: {
+ UUID: '00000112-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '0000011A-0000-1000-8000-0026BB765291',
+ constructorName: 'Mute',
+ displayName: 'Mute',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: false
+ }
+ ],
+ constructorName: 'Microphone',
+ displayName: 'Microphone',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000119-0000-1000-8000-0026BB765291',
+ constructorName: 'Volume',
+ displayName: 'Volume',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'percentage'
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ MotionSensor: {
+ UUID: '00000085-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000022-0000-1000-8000-0026BB765291',
+ constructorName: 'MotionDetected',
+ displayName: 'Motion Detected',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr']
+ },
+ value: false
+ }
+ ],
+ constructorName: 'MotionSensor',
+ displayName: 'MotionSensor',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000075-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusActive',
+ displayName: 'Status Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr']
+ },
+ value: false
+ },
+ {
+ UUID: '00000077-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusFault',
+ displayName: 'Status Fault',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000079-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusLowBattery',
+ displayName: 'Status Low Battery',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000007A-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusTampered',
+ displayName: 'Status Tampered',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ NFCAccess: {
+ UUID: '00000266-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000263-0000-1000-8000-0026BB765291',
+ constructorName: 'ConfigurationState',
+ displayName: 'Configuration State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint16',
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000264-0000-1000-8000-0026BB765291',
+ constructorName: 'NFCAccessControlPoint',
+ displayName: 'NFC Access Control Point',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr', 'pw', 'wr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000265-0000-1000-8000-0026BB765291',
+ constructorName: 'NFCAccessSupportedConfiguration',
+ displayName: 'NFC Access Supported Configuration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr']
+ },
+ value: ''
+ }
+ ],
+ constructorName: 'NFCAccess',
+ displayName: 'NFCAccess',
+ hiddenService: false,
+ optionalCharacteristics: [],
+ primaryService: false
+ },
+ OccupancySensor: {
+ UUID: '00000086-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000071-0000-1000-8000-0026BB765291',
+ constructorName: 'OccupancyDetected',
+ displayName: 'Occupancy Detected',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'OccupancySensor',
+ displayName: 'OccupancySensor',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000075-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusActive',
+ displayName: 'Status Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr']
+ },
+ value: false
+ },
+ {
+ UUID: '00000077-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusFault',
+ displayName: 'Status Fault',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000079-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusLowBattery',
+ displayName: 'Status Low Battery',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000007A-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusTampered',
+ displayName: 'Status Tampered',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ Outlet: {
+ UUID: '00000047-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000025-0000-1000-8000-0026BB765291',
+ constructorName: 'On',
+ displayName: 'On',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: false
+ }
+ ],
+ constructorName: 'Outlet',
+ displayName: 'Outlet',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000026-0000-1000-8000-0026BB765291',
+ constructorName: 'OutletInUse',
+ displayName: 'Outlet In Use',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr']
+ },
+ value: false
+ }
+ ],
+ primaryService: false
+ },
+ Pairing: {
+ UUID: '00000055-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000050-0000-1000-8000-0026BB765291',
+ constructorName: 'ListPairings',
+ displayName: 'List Pairings',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr', 'pw']
+ },
+ value: ''
+ },
+ {
+ UUID: '0000004C-0000-1000-8000-0026BB765291',
+ constructorName: 'PairSetup',
+ displayName: 'Pair Setup',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr', 'pw']
+ },
+ value: ''
+ },
+ {
+ UUID: '0000004E-0000-1000-8000-0026BB765291',
+ constructorName: 'PairVerify',
+ displayName: 'Pair Verify',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr', 'pw']
+ },
+ value: ''
+ },
+ {
+ UUID: '0000004F-0000-1000-8000-0026BB765291',
+ constructorName: 'PairingFeatures',
+ displayName: 'Pairing Features',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ perms: ['pr']
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'Pairing',
+ displayName: 'Pairing',
+ hiddenService: false,
+ optionalCharacteristics: [],
+ primaryService: false
+ },
+ PowerManagement: {
+ UUID: '00000221-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000222-0000-1000-8000-0026BB765291',
+ constructorName: 'WakeConfiguration',
+ displayName: 'Wake Configuration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr']
+ },
+ value: ''
+ }
+ ],
+ constructorName: 'PowerManagement',
+ displayName: 'PowerManagement',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000252-0000-1000-8000-0026BB765291',
+ constructorName: 'SelectedSleepConfiguration',
+ displayName: 'Selected Sleep Configuration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['ev', 'pr', 'pw', 'wr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000251-0000-1000-8000-0026BB765291',
+ constructorName: 'SupportedSleepConfiguration',
+ displayName: 'Supported Sleep Configuration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr']
+ },
+ value: ''
+ }
+ ],
+ primaryService: false
+ },
+ ProtocolInformation: {
+ UUID: '000000A2-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000037-0000-1000-8000-0026BB765291',
+ constructorName: 'Version',
+ displayName: 'Version',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ }
+ ],
+ constructorName: 'ProtocolInformation',
+ displayName: 'ProtocolInformation',
+ hiddenService: false,
+ optionalCharacteristics: [],
+ primaryService: false
+ },
+ Relay: {
+ nrchkbDisabledText: 'Relay (deprecated, replaced by CloudRelay)'
+ },
+ SecuritySystem: {
+ UUID: '0000007E-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000066-0000-1000-8000-0026BB765291',
+ constructorName: 'SecuritySystemCurrentState',
+ displayName: 'Security System Current State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 4,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2, 3, 4]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000067-0000-1000-8000-0026BB765291',
+ constructorName: 'SecuritySystemTargetState',
+ displayName: 'Security System Target State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 3,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1, 2, 3]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'SecuritySystem',
+ displayName: 'SecuritySystem',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '0000008E-0000-1000-8000-0026BB765291',
+ constructorName: 'SecuritySystemAlarmType',
+ displayName: 'Security System Alarm Type',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ validValues: [0, 1],
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000077-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusFault',
+ displayName: 'Status Fault',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000007A-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusTampered',
+ displayName: 'Status Tampered',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ ServiceLabel: {
+ UUID: '000000CC-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '000000CD-0000-1000-8000-0026BB765291',
+ constructorName: 'ServiceLabelNamespace',
+ displayName: 'Service Label Namespace',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'ServiceLabel',
+ displayName: 'ServiceLabel',
+ hiddenService: false,
+ optionalCharacteristics: [],
+ primaryService: false
+ },
+ Siri: {
+ UUID: '00000133-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000132-0000-1000-8000-0026BB765291',
+ constructorName: 'SiriInputType',
+ displayName: 'Siri Input Type',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 0,
+ minValue: 0,
+ perms: ['pr'],
+ validValues: [0]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'Siri',
+ displayName: 'Siri',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '0000026B-0000-1000-8000-0026BB765291',
+ constructorName: 'MultifunctionButton',
+ displayName: 'Multifunction Button',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minValue: 0,
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000255-0000-1000-8000-0026BB765291',
+ constructorName: 'SiriEnable',
+ displayName: 'Siri Enable',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: 0
+ },
+ {
+ UUID: '0000025A-0000-1000-8000-0026BB765291',
+ constructorName: 'SiriEngineVersion',
+ displayName: 'Siri Engine Version',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000258-0000-1000-8000-0026BB765291',
+ constructorName: 'SiriLightOnUse',
+ displayName: 'Siri Light On Use',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000256-0000-1000-8000-0026BB765291',
+ constructorName: 'SiriListening',
+ displayName: 'Siri Listening',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000257-0000-1000-8000-0026BB765291',
+ constructorName: 'SiriTouchToUse',
+ displayName: 'Siri Touch To Use',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ SiriEndpoint: {
+ UUID: '00000253-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000254-0000-1000-8000-0026BB765291',
+ constructorName: 'SiriEndpointSessionStatus',
+ displayName: 'Siri Endpoint Session Status',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['ev', 'pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000037-0000-1000-8000-0026BB765291',
+ constructorName: 'Version',
+ displayName: 'Version',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ }
+ ],
+ constructorName: 'SiriEndpoint',
+ displayName: 'SiriEndpoint',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '000000E7-0000-1000-8000-0026BB765291',
+ constructorName: 'ActiveIdentifier',
+ displayName: 'Active Identifier',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint32',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000227-0000-1000-8000-0026BB765291',
+ constructorName: 'ManuallyDisabled',
+ displayName: 'Manually Disabled',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr']
+ },
+ value: false
+ }
+ ],
+ primaryService: false
+ },
+ Slat: {
+ nrchkbDisabledText: 'Slat (deprecated, replaced by Slats)'
+ },
+ Slats: {
+ UUID: '000000B9-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '000000AA-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentSlatState',
+ displayName: 'Current Slat State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 2,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2]
+ },
+ value: 0
+ },
+ {
+ UUID: '000000C0-0000-1000-8000-0026BB765291',
+ constructorName: 'SlatType',
+ displayName: 'Slat Type',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'Slats',
+ displayName: 'Slats',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '000000B6-0000-1000-8000-0026BB765291',
+ constructorName: 'SwingMode',
+ displayName: 'Swing Mode',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '000000C1-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentTiltAngle',
+ displayName: 'Current Tilt Angle',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'int',
+ maxValue: 90,
+ minStep: 1,
+ minValue: -90,
+ perms: ['ev', 'pr'],
+ unit: 'arcdegrees'
+ },
+ value: -90
+ },
+ {
+ UUID: '000000C2-0000-1000-8000-0026BB765291',
+ constructorName: 'TargetTiltAngle',
+ displayName: 'Target Tilt Angle',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'int',
+ maxValue: 90,
+ minStep: 1,
+ minValue: -90,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'arcdegrees'
+ },
+ value: -90
+ }
+ ],
+ primaryService: false
+ },
+ SmartSpeaker: {
+ UUID: '00000228-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '000000E0-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentMediaState',
+ displayName: 'Current Media State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 5,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2, 4, 5]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000137-0000-1000-8000-0026BB765291',
+ constructorName: 'TargetMediaState',
+ displayName: 'Target Media State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 2,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1, 2]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'SmartSpeaker',
+ displayName: 'SmartSpeaker',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '0000025B-0000-1000-8000-0026BB765291',
+ constructorName: 'AirPlayEnable',
+ displayName: 'AirPlay Enable',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: 0
+ },
+ {
+ UUID: '000000E3-0000-1000-8000-0026BB765291',
+ constructorName: 'ConfiguredName',
+ displayName: 'Configured Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: ''
+ },
+ {
+ UUID: '0000011A-0000-1000-8000-0026BB765291',
+ constructorName: 'Mute',
+ displayName: 'Mute',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: false
+ },
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000119-0000-1000-8000-0026BB765291',
+ constructorName: 'Volume',
+ displayName: 'Volume',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'percentage'
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ SmokeSensor: {
+ UUID: '00000087-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000076-0000-1000-8000-0026BB765291',
+ constructorName: 'SmokeDetected',
+ displayName: 'Smoke Detected',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'SmokeSensor',
+ displayName: 'SmokeSensor',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000075-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusActive',
+ displayName: 'Status Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr']
+ },
+ value: false
+ },
+ {
+ UUID: '00000077-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusFault',
+ displayName: 'Status Fault',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000079-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusLowBattery',
+ displayName: 'Status Low Battery',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000007A-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusTampered',
+ displayName: 'Status Tampered',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ Speaker: {
+ UUID: '00000113-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '0000011A-0000-1000-8000-0026BB765291',
+ constructorName: 'Mute',
+ displayName: 'Mute',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: false
+ }
+ ],
+ constructorName: 'Speaker',
+ displayName: 'Speaker',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '000000B0-0000-1000-8000-0026BB765291',
+ constructorName: 'Active',
+ displayName: 'Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000119-0000-1000-8000-0026BB765291',
+ constructorName: 'Volume',
+ displayName: 'Volume',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'percentage'
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ StatefulProgrammableSwitch: {
+ UUID: '00000088-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000073-0000-1000-8000-0026BB765291',
+ constructorName: 'ProgrammableSwitchEvent',
+ displayName: 'Programmable Switch Event',
+ eventOnlyCharacteristic: true,
+ props: {
+ format: 'uint8',
+ maxValue: 2,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000074-0000-1000-8000-0026BB765291',
+ constructorName: 'ProgrammableSwitchOutputState',
+ displayName: 'Programmable Switch Output State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'StatefulProgrammableSwitch',
+ displayName: 'StatefulProgrammableSwitch',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ }
+ ],
+ primaryService: false
+ },
+ StatelessProgrammableSwitch: {
+ UUID: '00000089-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000073-0000-1000-8000-0026BB765291',
+ constructorName: 'ProgrammableSwitchEvent',
+ displayName: 'Programmable Switch Event',
+ eventOnlyCharacteristic: true,
+ props: {
+ format: 'uint8',
+ maxValue: 2,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'StatelessProgrammableSwitch',
+ displayName: 'StatelessProgrammableSwitch',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '000000CB-0000-1000-8000-0026BB765291',
+ constructorName: 'ServiceLabelIndex',
+ displayName: 'Service Label Index',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 255,
+ minStep: 1,
+ minValue: 1,
+ perms: ['pr']
+ },
+ value: 1
+ }
+ ],
+ primaryService: false
+ },
+ Switch: {
+ UUID: '00000049-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000025-0000-1000-8000-0026BB765291',
+ constructorName: 'On',
+ displayName: 'On',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: false
+ }
+ ],
+ constructorName: 'Switch',
+ displayName: 'Switch',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ }
+ ],
+ primaryService: false
+ },
+ TapManagement: {
+ UUID: '0000022E-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '000000B0-0000-1000-8000-0026BB765291',
+ constructorName: 'Active',
+ displayName: 'Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000250-0000-1000-8000-0026BB765291',
+ constructorName: 'CryptoHash',
+ displayName: 'Crypto Hash',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pw', 'wr']
+ },
+ value: ''
+ },
+ {
+ UUID: '0000022F-0000-1000-8000-0026BB765291',
+ constructorName: 'TapType',
+ displayName: 'Tap Type',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint16',
+ perms: ['pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000231-0000-1000-8000-0026BB765291',
+ constructorName: 'Token',
+ displayName: 'Token',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'data',
+ perms: ['pw']
+ },
+ value: ''
+ }
+ ],
+ constructorName: 'TapManagement',
+ displayName: 'TapManagement',
+ hiddenService: false,
+ optionalCharacteristics: [],
+ primaryService: false
+ },
+ TargetControl: {
+ UUID: '00000125-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '000000B0-0000-1000-8000-0026BB765291',
+ constructorName: 'Active',
+ displayName: 'Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '000000E7-0000-1000-8000-0026BB765291',
+ constructorName: 'ActiveIdentifier',
+ displayName: 'Active Identifier',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint32',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000126-0000-1000-8000-0026BB765291',
+ constructorName: 'ButtonEvent',
+ displayName: 'Button Event',
+ eventOnlyCharacteristic: false,
+ props: {
+ adminOnlyAccess: [2],
+ format: 'tlv8',
+ perms: ['ev', 'pr']
+ },
+ value: ''
+ }
+ ],
+ constructorName: 'TargetControl',
+ displayName: 'TargetControl',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ }
+ ],
+ primaryService: false
+ },
+ TargetControlManagement: {
+ UUID: '00000122-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000123-0000-1000-8000-0026BB765291',
+ constructorName: 'TargetControlSupportedConfiguration',
+ displayName: 'Target Control Supported Configuration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000124-0000-1000-8000-0026BB765291',
+ constructorName: 'TargetControlList',
+ displayName: 'Target Control List',
+ eventOnlyCharacteristic: false,
+ props: {
+ adminOnlyAccess: [0, 1],
+ format: 'tlv8',
+ perms: ['pr', 'pw', 'wr']
+ },
+ value: ''
+ }
+ ],
+ constructorName: 'TargetControlManagement',
+ displayName: 'TargetControlManagement',
+ hiddenService: false,
+ optionalCharacteristics: [],
+ primaryService: false
+ },
+ Television: {
+ UUID: '000000D8-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '000000B0-0000-1000-8000-0026BB765291',
+ constructorName: 'Active',
+ displayName: 'Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '000000E7-0000-1000-8000-0026BB765291',
+ constructorName: 'ActiveIdentifier',
+ displayName: 'Active Identifier',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint32',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: 0
+ },
+ {
+ UUID: '000000E3-0000-1000-8000-0026BB765291',
+ constructorName: 'ConfiguredName',
+ displayName: 'Configured Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: ''
+ },
+ {
+ UUID: '000000E1-0000-1000-8000-0026BB765291',
+ constructorName: 'RemoteKey',
+ displayName: 'Remote Key',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 16,
+ minStep: 1,
+ minValue: 0,
+ perms: ['pw'],
+ validValues: [
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
+ ]
+ },
+ value: 0
+ },
+ {
+ UUID: '000000E8-0000-1000-8000-0026BB765291',
+ constructorName: 'SleepDiscoveryMode',
+ displayName: 'Sleep Discovery Mode',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'Television',
+ displayName: 'Television',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000008-0000-1000-8000-0026BB765291',
+ constructorName: 'Brightness',
+ displayName: 'Brightness',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'int',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'percentage'
+ },
+ value: 0
+ },
+ {
+ UUID: '000000DD-0000-1000-8000-0026BB765291',
+ constructorName: 'ClosedCaptions',
+ displayName: 'Closed Captions',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000136-0000-1000-8000-0026BB765291',
+ constructorName: 'DisplayOrder',
+ displayName: 'Display Order',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: ''
+ },
+ {
+ UUID: '000000E0-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentMediaState',
+ displayName: 'Current Media State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 5,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2, 4, 5]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000137-0000-1000-8000-0026BB765291',
+ constructorName: 'TargetMediaState',
+ displayName: 'Target Media State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 2,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1, 2]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '000000E2-0000-1000-8000-0026BB765291',
+ constructorName: 'PictureMode',
+ displayName: 'Picture Mode',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 13,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
+ },
+ value: 0
+ },
+ {
+ UUID: '000000DF-0000-1000-8000-0026BB765291',
+ constructorName: 'PowerModeSelection',
+ displayName: 'Power Mode Selection',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ TelevisionSpeaker: {
+ UUID: '00000113-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '0000011A-0000-1000-8000-0026BB765291',
+ constructorName: 'Mute',
+ displayName: 'Mute',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: false
+ }
+ ],
+ constructorName: 'TelevisionSpeaker',
+ displayName: 'TelevisionSpeaker',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '000000B0-0000-1000-8000-0026BB765291',
+ constructorName: 'Active',
+ displayName: 'Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000119-0000-1000-8000-0026BB765291',
+ constructorName: 'Volume',
+ displayName: 'Volume',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'percentage'
+ },
+ value: 0
+ },
+ {
+ UUID: '000000E9-0000-1000-8000-0026BB765291',
+ constructorName: 'VolumeControlType',
+ displayName: 'Volume Control Type',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 3,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2, 3]
+ },
+ value: 0
+ },
+ {
+ UUID: '000000EA-0000-1000-8000-0026BB765291',
+ constructorName: 'VolumeSelector',
+ displayName: 'Volume Selector',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ TemperatureSensor: {
+ UUID: '0000008A-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000011-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentTemperature',
+ displayName: 'Current Temperature',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 100,
+ minStep: 0.1,
+ minValue: -270,
+ perms: ['ev', 'pr'],
+ unit: 'celsius'
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'TemperatureSensor',
+ displayName: 'TemperatureSensor',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000075-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusActive',
+ displayName: 'Status Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr']
+ },
+ value: false
+ },
+ {
+ UUID: '00000077-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusFault',
+ displayName: 'Status Fault',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000079-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusLowBattery',
+ displayName: 'Status Low Battery',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000007A-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusTampered',
+ displayName: 'Status Tampered',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ Thermostat: {
+ UUID: '0000004A-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '0000000F-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentHeatingCoolingState',
+ displayName: 'Current Heating Cooling State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 2,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000033-0000-1000-8000-0026BB765291',
+ constructorName: 'TargetHeatingCoolingState',
+ displayName: 'Target Heating Cooling State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 3,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1, 2, 3]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000011-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentTemperature',
+ displayName: 'Current Temperature',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 100,
+ minStep: 0.1,
+ minValue: -270,
+ perms: ['ev', 'pr'],
+ unit: 'celsius'
+ },
+ value: 0
+ },
+ {
+ UUID: '00000035-0000-1000-8000-0026BB765291',
+ constructorName: 'TargetTemperature',
+ displayName: 'Target Temperature',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 38,
+ minStep: 0.1,
+ minValue: 10,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'celsius'
+ },
+ value: 10
+ },
+ {
+ UUID: '00000036-0000-1000-8000-0026BB765291',
+ constructorName: 'TemperatureDisplayUnits',
+ displayName: 'Temperature Display Units',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'Thermostat',
+ displayName: 'Thermostat',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000010-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentRelativeHumidity',
+ displayName: 'Current Relative Humidity',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ unit: 'percentage'
+ },
+ value: 0
+ },
+ {
+ UUID: '00000034-0000-1000-8000-0026BB765291',
+ constructorName: 'TargetRelativeHumidity',
+ displayName: 'Target Relative Humidity',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'percentage'
+ },
+ value: 0
+ },
+ {
+ UUID: '0000000D-0000-1000-8000-0026BB765291',
+ constructorName: 'CoolingThresholdTemperature',
+ displayName: 'Cooling Threshold Temperature',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 35,
+ minStep: 0.1,
+ minValue: 10,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'celsius'
+ },
+ value: 10
+ },
+ {
+ UUID: '00000012-0000-1000-8000-0026BB765291',
+ constructorName: 'HeatingThresholdTemperature',
+ displayName: 'Heating Threshold Temperature',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'float',
+ maxValue: 25,
+ minStep: 0.1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'celsius'
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ ThreadTransport: {
+ UUID: '00000701-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '0000022B-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentTransport',
+ displayName: 'Current Transport',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['pr']
+ },
+ value: false
+ },
+ {
+ UUID: '00000704-0000-1000-8000-0026BB765291',
+ constructorName: 'ThreadControlPoint',
+ displayName: 'Thread Control Point',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pw']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000702-0000-1000-8000-0026BB765291',
+ constructorName: 'ThreadNodeCapabilities',
+ displayName: 'Thread Node Capabilities',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint16',
+ maxValue: 31,
+ minStep: 1,
+ minValue: 0,
+ perms: ['pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000703-0000-1000-8000-0026BB765291',
+ constructorName: 'ThreadStatus',
+ displayName: 'Thread Status',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint16',
+ maxValue: 6,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'ThreadTransport',
+ displayName: 'ThreadTransport',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000246-0000-1000-8000-0026BB765291',
+ constructorName: 'CCAEnergyDetectThreshold',
+ displayName: 'CCA Energy Detect Threshold',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'int',
+ perms: ['pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000245-0000-1000-8000-0026BB765291',
+ constructorName: 'CCASignalDetectThreshold',
+ displayName: 'CCA Signal Detect Threshold',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'int',
+ perms: ['pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '0000023D-0000-1000-8000-0026BB765291',
+ constructorName: 'EventRetransmissionMaximum',
+ displayName: 'Event Retransmission Maximum',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ perms: ['pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '0000023E-0000-1000-8000-0026BB765291',
+ constructorName: 'EventTransmissionCounters',
+ displayName: 'Event Transmission Counters',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint32',
+ perms: ['pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000247-0000-1000-8000-0026BB765291',
+ constructorName: 'MACRetransmissionMaximum',
+ displayName: 'MAC Retransmission Maximum',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ perms: ['pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000248-0000-1000-8000-0026BB765291',
+ constructorName: 'MACTransmissionCounters',
+ displayName: 'MAC Transmission Counters',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'data',
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000244-0000-1000-8000-0026BB765291',
+ constructorName: 'ReceiverSensitivity',
+ displayName: 'Receiver Sensitivity',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'int',
+ perms: ['pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '0000023F-0000-1000-8000-0026BB765291',
+ constructorName: 'ReceivedSignalStrengthIndication',
+ displayName: 'Received Signal Strength Indication',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'int',
+ perms: ['pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000241-0000-1000-8000-0026BB765291',
+ constructorName: 'SignalToNoiseRatio',
+ displayName: 'Signal To Noise Ratio',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'int',
+ perms: ['pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000706-0000-1000-8000-0026BB765291',
+ constructorName: 'ThreadOpenThreadVersion',
+ displayName: 'Thread OpenThread Version',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000242-0000-1000-8000-0026BB765291',
+ constructorName: 'TransmitPower',
+ displayName: 'Transmit Power',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'int',
+ perms: ['pr']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000243-0000-1000-8000-0026BB765291',
+ constructorName: 'MaximumTransmitPower',
+ displayName: 'Maximum Transmit Power',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'int',
+ perms: ['pr']
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ TimeInformation: {
+ nrchkbDisabledText: 'TimeInformation (deprecated, unused)'
+ },
+ TransferTransportManagement: {
+ UUID: '00000203-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000202-0000-1000-8000-0026BB765291',
+ constructorName: 'SupportedTransferTransportConfiguration',
+ displayName: 'Supported Transfer Transport Configuration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000201-0000-1000-8000-0026BB765291',
+ constructorName: 'SetupTransferTransport',
+ displayName: 'Setup Transfer Transport',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pw', 'wr']
+ },
+ value: ''
+ }
+ ],
+ constructorName: 'TransferTransportManagement',
+ displayName: 'TransferTransportManagement',
+ hiddenService: false,
+ optionalCharacteristics: [],
+ primaryService: false
+ },
+ Tunnel: {
+ UUID: '00000056-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '00000057-0000-1000-8000-0026BB765291',
+ constructorName: 'AccessoryIdentifier',
+ displayName: 'Accessory Identifier',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000061-0000-1000-8000-0026BB765291',
+ constructorName: 'TunnelConnectionTimeout',
+ displayName: 'Tunnel Connection Timeout',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'int',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: 0
+ },
+ {
+ UUID: '00000060-0000-1000-8000-0026BB765291',
+ constructorName: 'TunneledAccessoryAdvertising',
+ displayName: 'Tunneled Accessory Advertising',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: false
+ },
+ {
+ UUID: '00000059-0000-1000-8000-0026BB765291',
+ constructorName: 'TunneledAccessoryConnected',
+ displayName: 'Tunneled Accessory Connected',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: false
+ },
+ {
+ UUID: '00000058-0000-1000-8000-0026BB765291',
+ constructorName: 'TunneledAccessoryStateNumber',
+ displayName: 'Tunneled Accessory State Number',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'int',
+ perms: ['ev', 'pr']
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'Tunnel',
+ displayName: 'Tunnel',
+ hiddenService: false,
+ optionalCharacteristics: [],
+ primaryService: false
+ },
+ TunneledBTLEAccessoryService: {
+ nrchkbDisabledText:
+ 'TunneledBTLEAccessoryService (deprecated, replaced by Tunnel)'
+ },
+ Valve: {
+ UUID: '000000D0-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '000000B0-0000-1000-8000-0026BB765291',
+ constructorName: 'Active',
+ displayName: 'Active',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '000000D2-0000-1000-8000-0026BB765291',
+ constructorName: 'InUse',
+ displayName: 'In Use',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '000000D5-0000-1000-8000-0026BB765291',
+ constructorName: 'ValveType',
+ displayName: 'Valve Type',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 3,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2, 3]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'Valve',
+ displayName: 'Valve',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '000000D6-0000-1000-8000-0026BB765291',
+ constructorName: 'IsConfigured',
+ displayName: 'Is Configured',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '000000D4-0000-1000-8000-0026BB765291',
+ constructorName: 'RemainingDuration',
+ displayName: 'Remaining Duration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint32',
+ maxValue: 3600,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ unit: 'seconds'
+ },
+ value: 0
+ },
+ {
+ UUID: '000000CB-0000-1000-8000-0026BB765291',
+ constructorName: 'ServiceLabelIndex',
+ displayName: 'Service Label Index',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 255,
+ minStep: 1,
+ minValue: 1,
+ perms: ['pr']
+ },
+ value: 1
+ },
+ {
+ UUID: '000000D3-0000-1000-8000-0026BB765291',
+ constructorName: 'SetDuration',
+ displayName: 'Set Duration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint32',
+ maxValue: 3600,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'seconds'
+ },
+ value: 0
+ },
+ {
+ UUID: '00000077-0000-1000-8000-0026BB765291',
+ constructorName: 'StatusFault',
+ displayName: 'Status Fault',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ }
+ ],
+ primaryService: false
+ },
+ WiFiRouter: {
+ UUID: '0000020A-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '000000E3-0000-1000-8000-0026BB765291',
+ constructorName: 'ConfiguredName',
+ displayName: 'Configured Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ perms: ['ev', 'pr', 'pw']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000215-0000-1000-8000-0026BB765291',
+ constructorName: 'ManagedNetworkEnable',
+ displayName: 'Managed Network Enable',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw', 'tw'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000021F-0000-1000-8000-0026BB765291',
+ constructorName: 'NetworkAccessViolationControl',
+ displayName: 'Network Access Violation Control',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['ev', 'pr', 'pw', 'tw', 'wr']
+ },
+ value: ''
+ },
+ {
+ UUID: '0000020C-0000-1000-8000-0026BB765291',
+ constructorName: 'NetworkClientProfileControl',
+ displayName: 'Network Client Profile Control',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['ev', 'pr', 'pw', 'tw', 'wr']
+ },
+ value: ''
+ },
+ {
+ UUID: '0000020D-0000-1000-8000-0026BB765291',
+ constructorName: 'NetworkClientStatusControl',
+ displayName: 'Network Client Status Control',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr', 'pw', 'wr']
+ },
+ value: ''
+ },
+ {
+ UUID: '0000020E-0000-1000-8000-0026BB765291',
+ constructorName: 'RouterStatus',
+ displayName: 'Router Status',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1]
+ },
+ value: 0
+ },
+ {
+ UUID: '00000210-0000-1000-8000-0026BB765291',
+ constructorName: 'SupportedRouterConfiguration',
+ displayName: 'Supported Router Configuration',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000211-0000-1000-8000-0026BB765291',
+ constructorName: 'WANConfigurationList',
+ displayName: 'WAN Configuration List',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['ev', 'pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000212-0000-1000-8000-0026BB765291',
+ constructorName: 'WANStatusList',
+ displayName: 'WAN Status List',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['ev', 'pr']
+ },
+ value: ''
+ }
+ ],
+ constructorName: 'WiFiRouter',
+ displayName: 'WiFiRouter',
+ hiddenService: false,
+ optionalCharacteristics: [],
+ primaryService: false
+ },
+ WiFiSatellite: {
+ UUID: '0000020F-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '0000021E-0000-1000-8000-0026BB765291',
+ constructorName: 'WiFiSatelliteStatus',
+ displayName: 'Wi-Fi Satellite Status',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 2,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2]
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'WiFiSatellite',
+ displayName: 'WiFiSatellite',
+ hiddenService: false,
+ optionalCharacteristics: [],
+ primaryService: false
+ },
+ WiFiTransport: {
+ UUID: '0000022A-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '0000022B-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentTransport',
+ displayName: 'Current Transport',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['pr']
+ },
+ value: false
+ },
+ {
+ UUID: '0000022C-0000-1000-8000-0026BB765291',
+ constructorName: 'WiFiCapabilities',
+ displayName: 'Wi-Fi Capabilities',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint32',
+ perms: ['pr']
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'WiFiTransport',
+ displayName: 'WiFiTransport',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '0000022D-0000-1000-8000-0026BB765291',
+ constructorName: 'WiFiConfigurationControl',
+ displayName: 'Wi-Fi Configuration Control',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'tlv8',
+ perms: ['ev', 'pr', 'pw', 'tw', 'wr']
+ },
+ value: ''
+ }
+ ],
+ primaryService: false
+ },
+ Window: {
+ UUID: '0000008B-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '0000006D-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentPosition',
+ displayName: 'Current Position',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ unit: 'percentage'
+ },
+ value: 0
+ },
+ {
+ UUID: '00000072-0000-1000-8000-0026BB765291',
+ constructorName: 'PositionState',
+ displayName: 'Position State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 2,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000007C-0000-1000-8000-0026BB765291',
+ constructorName: 'TargetPosition',
+ displayName: 'Target Position',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'percentage'
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'Window',
+ displayName: 'Window',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000024-0000-1000-8000-0026BB765291',
+ constructorName: 'ObstructionDetected',
+ displayName: 'Obstruction Detected',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr']
+ },
+ value: false
+ },
+ {
+ UUID: '0000006F-0000-1000-8000-0026BB765291',
+ constructorName: 'HoldPosition',
+ displayName: 'Hold Position',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['pw']
+ },
+ value: false
+ }
+ ],
+ primaryService: false
+ },
+ WindowCovering: {
+ UUID: '0000008C-0000-1000-8000-0026BB765291',
+ characteristics: [
+ {
+ UUID: '0000006D-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentPosition',
+ displayName: 'Current Position',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ unit: 'percentage'
+ },
+ value: 0
+ },
+ {
+ UUID: '00000072-0000-1000-8000-0026BB765291',
+ constructorName: 'PositionState',
+ displayName: 'Position State',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 2,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr'],
+ validValues: [0, 1, 2]
+ },
+ value: 0
+ },
+ {
+ UUID: '0000007C-0000-1000-8000-0026BB765291',
+ constructorName: 'TargetPosition',
+ displayName: 'Target Position',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'uint8',
+ maxValue: 100,
+ minStep: 1,
+ minValue: 0,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'percentage'
+ },
+ value: 0
+ }
+ ],
+ constructorName: 'WindowCovering',
+ displayName: 'WindowCovering',
+ hiddenService: false,
+ optionalCharacteristics: [
+ {
+ UUID: '0000006C-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentHorizontalTiltAngle',
+ displayName: 'Current Horizontal Tilt Angle',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'int',
+ maxValue: 90,
+ minStep: 1,
+ minValue: -90,
+ perms: ['ev', 'pr'],
+ unit: 'arcdegrees'
+ },
+ value: -90
+ },
+ {
+ UUID: '0000007B-0000-1000-8000-0026BB765291',
+ constructorName: 'TargetHorizontalTiltAngle',
+ displayName: 'Target Horizontal Tilt Angle',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'int',
+ maxValue: 90,
+ minStep: 1,
+ minValue: -90,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'arcdegrees'
+ },
+ value: -90
+ },
+ {
+ UUID: '00000023-0000-1000-8000-0026BB765291',
+ constructorName: 'Name',
+ displayName: 'Name',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'string',
+ maxLen: 64,
+ perms: ['pr']
+ },
+ value: ''
+ },
+ {
+ UUID: '00000024-0000-1000-8000-0026BB765291',
+ constructorName: 'ObstructionDetected',
+ displayName: 'Obstruction Detected',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['ev', 'pr']
+ },
+ value: false
+ },
+ {
+ UUID: '0000006F-0000-1000-8000-0026BB765291',
+ constructorName: 'HoldPosition',
+ displayName: 'Hold Position',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'bool',
+ perms: ['pw']
+ },
+ value: false
+ },
+ {
+ UUID: '0000006E-0000-1000-8000-0026BB765291',
+ constructorName: 'CurrentVerticalTiltAngle',
+ displayName: 'Current Vertical Tilt Angle',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'int',
+ maxValue: 90,
+ minStep: 1,
+ minValue: -90,
+ perms: ['ev', 'pr'],
+ unit: 'arcdegrees'
+ },
+ value: -90
+ },
+ {
+ UUID: '0000007D-0000-1000-8000-0026BB765291',
+ constructorName: 'TargetVerticalTiltAngle',
+ displayName: 'Target Vertical Tilt Angle',
+ eventOnlyCharacteristic: false,
+ props: {
+ format: 'int',
+ maxValue: 90,
+ minStep: 1,
+ minValue: -90,
+ perms: ['ev', 'pr', 'pw'],
+ unit: 'arcdegrees'
+ },
+ value: -90
+ }
+ ],
+ primaryService: false
+ }
}
diff --git a/src/test/test-utils/data/switch.service.bridge.flow.ts b/src/test/test-utils/data/switch.service.bridge.flow.ts
index 87ef7cbc..3b490f44 100644
--- a/src/test/test-utils/data/switch.service.bridge.flow.ts
+++ b/src/test/test-utils/data/switch.service.bridge.flow.ts
@@ -1,86 +1,86 @@
-import helper from 'node-red-node-test-helper'
+import type helper from 'node-red-node-test-helper'
export const switchServiceBridgeFlow = () => {
- const serviceId = `s1.${Date.now()}`
- const bridgeId = `b1.${Date.now()}`
- const flowId = `f1.${Date.now()}`
+ const serviceId = `s1.${Date.now()}`
+ const bridgeId = `b1.${Date.now()}`
+ const flowId = `f1.${Date.now()}`
- return {
- serviceId,
- bridgeId,
- flowId,
- flow: [
- {
- id: serviceId,
- type: 'homekit-service',
- z: flowId,
- isParent: true,
- hostType: '0',
- bridge: bridgeId,
- accessoryId: '',
- parentService: '',
- name: 'Example Switch',
- serviceName: 'Switch',
- topic: '',
- filter: false,
- manufacturer: 'NRCHKB',
- model: '0.130.7',
- serialNo: 'Default Serial Number',
- firmwareRev: '0.130.7',
- hardwareRev: '0.130.7',
- softwareRev: '0.130.7',
- cameraConfigVideoProcessor: 'ffmpeg',
- cameraConfigSource: '',
- cameraConfigStillImageSource: '',
- cameraConfigMaxStreams: 2,
- cameraConfigMaxWidth: 1280,
- cameraConfigMaxHeight: 720,
- cameraConfigMaxFPS: 10,
- cameraConfigMaxBitrate: 300,
- cameraConfigVideoCodec: 'libx264',
- cameraConfigAudioCodec: 'libfdk_aac',
- cameraConfigAudio: false,
- cameraConfigPacketSize: 1316,
- cameraConfigVerticalFlip: false,
- cameraConfigHorizontalFlip: false,
- cameraConfigMapVideo: '0:0',
- cameraConfigMapAudio: '0:1',
- cameraConfigVideoFilter: 'scale=1280:720',
- cameraConfigAdditionalCommandLine: '-tune zerolatency',
- cameraConfigDebug: false,
- cameraConfigSnapshotOutput: 'disabled',
- cameraConfigInterfaceName: '',
- characteristicProperties: '{}',
- waitForSetupMsg: false,
- outputs: 2,
- x: 350,
- y: 240,
- wires: [['h1'], ['h1']],
- },
- {
- id: bridgeId,
- type: 'homekit-bridge',
- bridgeName: 'Example Bridge',
- pinCode: '1111-1111',
- port: '',
- allowInsecureRequest: false,
- manufacturer: 'NRCHKB',
- model: '0.130.7',
- serialNo: 'Default Serial Number',
- firmwareRev: '0.130.7',
- hardwareRev: '0.130.7',
- softwareRev: '0.130.7',
- customMdnsConfig: false,
- mdnsMulticast: true,
- mdnsInterface: '',
- mdnsPort: '',
- mdnsIp: '',
- mdnsTtl: '',
- mdnsLoopback: true,
- mdnsReuseAddr: true,
- allowMessagePassthrough: true,
- },
- { id: 'h1', type: 'helper' },
- ] as helper.TestFlows,
- }
+ return {
+ serviceId,
+ bridgeId,
+ flowId,
+ flow: [
+ {
+ id: serviceId,
+ type: 'homekit-service',
+ z: flowId,
+ isParent: true,
+ hostType: '0',
+ bridge: bridgeId,
+ accessoryId: '',
+ parentService: '',
+ name: 'Example Switch',
+ serviceName: 'Switch',
+ topic: '',
+ filter: false,
+ manufacturer: 'NRCHKB',
+ model: '0.130.7',
+ serialNo: 'Default Serial Number',
+ firmwareRev: '0.130.7',
+ hardwareRev: '0.130.7',
+ softwareRev: '0.130.7',
+ cameraConfigVideoProcessor: 'ffmpeg',
+ cameraConfigSource: '',
+ cameraConfigStillImageSource: '',
+ cameraConfigMaxStreams: 2,
+ cameraConfigMaxWidth: 1280,
+ cameraConfigMaxHeight: 720,
+ cameraConfigMaxFPS: 10,
+ cameraConfigMaxBitrate: 300,
+ cameraConfigVideoCodec: 'libx264',
+ cameraConfigAudioCodec: 'libfdk_aac',
+ cameraConfigAudio: false,
+ cameraConfigPacketSize: 1316,
+ cameraConfigVerticalFlip: false,
+ cameraConfigHorizontalFlip: false,
+ cameraConfigMapVideo: '0:0',
+ cameraConfigMapAudio: '0:1',
+ cameraConfigVideoFilter: 'scale=1280:720',
+ cameraConfigAdditionalCommandLine: '-tune zerolatency',
+ cameraConfigDebug: false,
+ cameraConfigSnapshotOutput: 'disabled',
+ cameraConfigInterfaceName: '',
+ characteristicProperties: '{}',
+ waitForSetupMsg: false,
+ outputs: 2,
+ x: 350,
+ y: 240,
+ wires: [['h1'], ['h1']]
+ },
+ {
+ id: bridgeId,
+ type: 'homekit-bridge',
+ bridgeName: 'Example Bridge',
+ pinCode: '1111-1111',
+ port: '',
+ allowInsecureRequest: false,
+ manufacturer: 'NRCHKB',
+ model: '0.130.7',
+ serialNo: 'Default Serial Number',
+ firmwareRev: '0.130.7',
+ hardwareRev: '0.130.7',
+ softwareRev: '0.130.7',
+ customMdnsConfig: false,
+ mdnsMulticast: true,
+ mdnsInterface: '',
+ mdnsPort: '',
+ mdnsIp: '',
+ mdnsTtl: '',
+ mdnsLoopback: true,
+ mdnsReuseAddr: true,
+ allowMessagePassthrough: true
+ },
+ { id: 'h1', type: 'helper' }
+ ] as helper.TestFlows
+ }
}
diff --git a/src/test/test-utils/data/switch.service2.bridge.flow.ts b/src/test/test-utils/data/switch.service2.bridge.flow.ts
index 7307d7b3..34a8009a 100644
--- a/src/test/test-utils/data/switch.service2.bridge.flow.ts
+++ b/src/test/test-utils/data/switch.service2.bridge.flow.ts
@@ -1,87 +1,87 @@
-import helper from 'node-red-node-test-helper'
+import type helper from 'node-red-node-test-helper'
export const switchService2BridgeFlow = () => {
- const serviceId = `s1.${Date.now()}`
- const bridgeId = `b1.${Date.now()}`
- const flowId = `f1.${Date.now()}`
+ const serviceId = `s1.${Date.now()}`
+ const bridgeId = `b1.${Date.now()}`
+ const flowId = `f1.${Date.now()}`
- return {
- serviceId,
- bridgeId,
- flowId,
- flow: [
- {
- id: serviceId,
- type: 'homekit-service2',
- z: flowId,
- isParent: true,
- hostType: '0',
- bridge: bridgeId,
- accessoryId: '',
- parentService: '',
- name: 'Example Switch',
- serviceName: 'Switch',
- topic: '',
- filter: false,
- manufacturer: 'NRCHKB',
- model: '1.4.3',
- serialNo: 'Default Serial Number',
- firmwareRev: '1.4.3',
- hardwareRev: '1.4.3',
- softwareRev: '1.4.3',
- cameraConfigVideoProcessor: 'ffmpeg',
- cameraConfigSource: '',
- cameraConfigStillImageSource: '',
- cameraConfigMaxStreams: 2,
- cameraConfigMaxWidth: 1280,
- cameraConfigMaxHeight: 720,
- cameraConfigMaxFPS: 10,
- cameraConfigMaxBitrate: 300,
- cameraConfigVideoCodec: 'libx264',
- cameraConfigAudioCodec: 'libfdk_aac',
- cameraConfigAudio: false,
- cameraConfigPacketSize: 1316,
- cameraConfigVerticalFlip: false,
- cameraConfigHorizontalFlip: false,
- cameraConfigMapVideo: '0:0',
- cameraConfigMapAudio: '0:1',
- cameraConfigVideoFilter: 'scale=1280:720',
- cameraConfigAdditionalCommandLine: '-tune zerolatency',
- cameraConfigDebug: false,
- cameraConfigSnapshotOutput: 'disabled',
- cameraConfigInterfaceName: '',
- characteristicProperties: '{}',
- waitForSetupMsg: false,
- useEventCallback: false,
- outputs: 1,
- x: 1290,
- y: 340,
- wires: [['h1'], ['h1']],
- },
- {
- id: bridgeId,
- type: 'homekit-bridge',
- bridgeName: 'Example Bridge',
- pinCode: '1111-1111',
- port: '',
- allowInsecureRequest: false,
- manufacturer: 'NRCHKB',
- model: '0.130.7',
- serialNo: 'Default Serial Number',
- firmwareRev: '0.130.7',
- hardwareRev: '0.130.7',
- softwareRev: '0.130.7',
- customMdnsConfig: false,
- mdnsMulticast: true,
- mdnsInterface: '',
- mdnsPort: '',
- mdnsIp: '',
- mdnsTtl: '',
- mdnsLoopback: true,
- mdnsReuseAddr: true,
- allowMessagePassthrough: true,
- },
- { id: 'h1', type: 'helper' },
- ] as helper.TestFlows,
- }
+ return {
+ serviceId,
+ bridgeId,
+ flowId,
+ flow: [
+ {
+ id: serviceId,
+ type: 'homekit-service2',
+ z: flowId,
+ isParent: true,
+ hostType: '0',
+ bridge: bridgeId,
+ accessoryId: '',
+ parentService: '',
+ name: 'Example Switch',
+ serviceName: 'Switch',
+ topic: '',
+ filter: false,
+ manufacturer: 'NRCHKB',
+ model: '1.4.3',
+ serialNo: 'Default Serial Number',
+ firmwareRev: '1.4.3',
+ hardwareRev: '1.4.3',
+ softwareRev: '1.4.3',
+ cameraConfigVideoProcessor: 'ffmpeg',
+ cameraConfigSource: '',
+ cameraConfigStillImageSource: '',
+ cameraConfigMaxStreams: 2,
+ cameraConfigMaxWidth: 1280,
+ cameraConfigMaxHeight: 720,
+ cameraConfigMaxFPS: 10,
+ cameraConfigMaxBitrate: 300,
+ cameraConfigVideoCodec: 'libx264',
+ cameraConfigAudioCodec: 'libfdk_aac',
+ cameraConfigAudio: false,
+ cameraConfigPacketSize: 1316,
+ cameraConfigVerticalFlip: false,
+ cameraConfigHorizontalFlip: false,
+ cameraConfigMapVideo: '0:0',
+ cameraConfigMapAudio: '0:1',
+ cameraConfigVideoFilter: 'scale=1280:720',
+ cameraConfigAdditionalCommandLine: '-tune zerolatency',
+ cameraConfigDebug: false,
+ cameraConfigSnapshotOutput: 'disabled',
+ cameraConfigInterfaceName: '',
+ characteristicProperties: '{}',
+ waitForSetupMsg: false,
+ useEventCallback: false,
+ outputs: 1,
+ x: 1290,
+ y: 340,
+ wires: [['h1'], ['h1']]
+ },
+ {
+ id: bridgeId,
+ type: 'homekit-bridge',
+ bridgeName: 'Example Bridge',
+ pinCode: '1111-1111',
+ port: '',
+ allowInsecureRequest: false,
+ manufacturer: 'NRCHKB',
+ model: '0.130.7',
+ serialNo: 'Default Serial Number',
+ firmwareRev: '0.130.7',
+ hardwareRev: '0.130.7',
+ softwareRev: '0.130.7',
+ customMdnsConfig: false,
+ mdnsMulticast: true,
+ mdnsInterface: '',
+ mdnsPort: '',
+ mdnsIp: '',
+ mdnsTtl: '',
+ mdnsLoopback: true,
+ mdnsReuseAddr: true,
+ allowMessagePassthrough: true
+ },
+ { id: 'h1', type: 'helper' }
+ ] as helper.TestFlows
+ }
}
diff --git a/tsconfig.json b/tsconfig.json
index a819d3b8..0477607c 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -2,9 +2,7 @@
"compilerOptions": {
"target": "es6",
"module": "commonjs",
- "lib": [
- "es2020.string"
- ],
+ "lib": ["ES2023"],
"skipLibCheck": true,
"allowJs": true,
"checkJs": false,
@@ -28,12 +26,6 @@
"resolveJsonModule": true,
"declaration": true
},
- "include": [
- "src"
- ],
- "exclude": [
- "node_modules",
- "**/test/*",
- "build"
- ]
+ "include": ["src"],
+ "exclude": ["node_modules", "**/test/*", "build"]
}