From e861216c14accb4e9217dc7b11eaa20186f25da3 Mon Sep 17 00:00:00 2001
From: pledou <57828629+pledou@users.noreply.github.com>
Date: Fri, 16 Jan 2026 13:37:17 +0000
Subject: [PATCH 01/12] Ajouter des tests de validation de plage pour les
enregistrements Int32 et UInt32
---
test/unit/modbus_data_tools.test.ts | 173 ++++++++++++++++++++++++++++
1 file changed, 173 insertions(+)
diff --git a/test/unit/modbus_data_tools.test.ts b/test/unit/modbus_data_tools.test.ts
index 9f8cb1e..6040012 100644
--- a/test/unit/modbus_data_tools.test.ts
+++ b/test/unit/modbus_data_tools.test.ts
@@ -132,6 +132,179 @@ describe('Data Tools', () => {
});
});
+ describe('Int32BE (signed 32-bit big-endian)', () => {
+ const entry = { type: 'integer', register: 'Int32BE', offset: undefined };
+ const validBuffer = Buffer.alloc(8);
+
+ it('should write valid positive value (2147483647 - max)', () => {
+ expect(() => {
+ util.writeToRegister(entry, 2147483647, validBuffer, 0);
+ }).to.not.throw();
+ expect(validBuffer.readInt32BE(0)).to.equal(2147483647);
+ });
+
+ it('should write valid negative value (-2147483648 - min)', () => {
+ expect(() => {
+ util.writeToRegister(entry, -2147483648, validBuffer, 0);
+ }).to.not.throw();
+ expect(validBuffer.readInt32BE(0)).to.equal(-2147483648);
+ });
+
+ it('should write zero', () => {
+ expect(() => {
+ util.writeToRegister(entry, 0, validBuffer, 0);
+ }).to.not.throw();
+ expect(validBuffer.readInt32BE(0)).to.equal(0);
+ });
+
+ it('should write positive mid-range value (1000000)', () => {
+ expect(() => {
+ util.writeToRegister(entry, 1000000, validBuffer, 0);
+ }).to.not.throw();
+ expect(validBuffer.readInt32BE(0)).to.equal(1000000);
+ });
+
+ it('should write negative mid-range value (-1000000)', () => {
+ expect(() => {
+ util.writeToRegister(entry, -1000000, validBuffer, 0);
+ }).to.not.throw();
+ expect(validBuffer.readInt32BE(0)).to.equal(-1000000);
+ });
+
+ it('should throw OutOfRangeError for value > 2147483647', () => {
+ expect(() => {
+ util.writeToRegister(entry, 2147483648, validBuffer, 0);
+ }).to.throw(/OutOfRangeError|out of range|Out of range/i);
+ });
+
+ it('should throw OutOfRangeError for value < -2147483648', () => {
+ expect(() => {
+ util.writeToRegister(entry, -2147483649, validBuffer, 0);
+ }).to.throw(/OutOfRangeError|out of range|Out of range/i);
+ });
+ });
+
+ describe('Int32LE (signed 32-bit little-endian)', () => {
+ const entry = { type: 'integer', register: 'Int32LE', offset: undefined };
+ const validBuffer = Buffer.alloc(8);
+
+ it('should write valid positive value (2147483647 - max)', () => {
+ expect(() => {
+ util.writeToRegister(entry, 2147483647, validBuffer, 0);
+ }).to.not.throw();
+ expect(validBuffer.readInt32LE(0)).to.equal(2147483647);
+ });
+
+ it('should write valid negative value (-2147483648 - min)', () => {
+ expect(() => {
+ util.writeToRegister(entry, -2147483648, validBuffer, 0);
+ }).to.not.throw();
+ expect(validBuffer.readInt32LE(0)).to.equal(-2147483648);
+ });
+
+ it('should write zero', () => {
+ expect(() => {
+ util.writeToRegister(entry, 0, validBuffer, 0);
+ }).to.not.throw();
+ expect(validBuffer.readInt32LE(0)).to.equal(0);
+ });
+
+ it('should throw OutOfRangeError for value > 2147483647', () => {
+ expect(() => {
+ util.writeToRegister(entry, 2147483648, validBuffer, 0);
+ }).to.throw(/OutOfRangeError|out of range|Out of range/i);
+ });
+
+ it('should throw OutOfRangeError for value < -2147483648', () => {
+ expect(() => {
+ util.writeToRegister(entry, -2147483649, validBuffer, 0);
+ }).to.throw(/OutOfRangeError|out of range|Out of range/i);
+ });
+ });
+
+ describe('UInt32BE (unsigned 32-bit big-endian)', () => {
+ const entry = { type: 'integer', register: 'UInt32BE', offset: undefined };
+ const validBuffer = Buffer.alloc(8);
+
+ it('should write valid max unsigned value (4294967295)', () => {
+ expect(() => {
+ util.writeToRegister(entry, 4294967295, validBuffer, 0);
+ }).to.not.throw();
+ expect(validBuffer.readUInt32BE(0)).to.equal(4294967295);
+ });
+
+ it('should write zero', () => {
+ expect(() => {
+ util.writeToRegister(entry, 0, validBuffer, 0);
+ }).to.not.throw();
+ expect(validBuffer.readUInt32BE(0)).to.equal(0);
+ });
+
+ it('should write mid-range value (2147483648)', () => {
+ expect(() => {
+ util.writeToRegister(entry, 2147483648, validBuffer, 0);
+ }).to.not.throw();
+ expect(validBuffer.readUInt32BE(0)).to.equal(2147483648);
+ });
+
+ it('should write large value (3000000000)', () => {
+ expect(() => {
+ util.writeToRegister(entry, 3000000000, validBuffer, 0);
+ }).to.not.throw();
+ expect(validBuffer.readUInt32BE(0)).to.equal(3000000000);
+ });
+
+ it('should throw OutOfRangeError for value > 4294967295', () => {
+ expect(() => {
+ util.writeToRegister(entry, 4294967296, validBuffer, 0);
+ }).to.throw(/OutOfRangeError|out of range|Out of range/i);
+ });
+
+ it('should throw OutOfRangeError for negative value', () => {
+ expect(() => {
+ util.writeToRegister(entry, -1, validBuffer, 0);
+ }).to.throw(/OutOfRangeError|out of range|Out of range/i);
+ });
+ });
+
+ describe('UInt32LE (unsigned 32-bit little-endian)', () => {
+ const entry = { type: 'integer', register: 'UInt32LE', offset: undefined };
+ const validBuffer = Buffer.alloc(8);
+
+ it('should write valid max unsigned value (4294967295)', () => {
+ expect(() => {
+ util.writeToRegister(entry, 4294967295, validBuffer, 0);
+ }).to.not.throw();
+ expect(validBuffer.readUInt32LE(0)).to.equal(4294967295);
+ });
+
+ it('should write zero', () => {
+ expect(() => {
+ util.writeToRegister(entry, 0, validBuffer, 0);
+ }).to.not.throw();
+ expect(validBuffer.readUInt32LE(0)).to.equal(0);
+ });
+
+ it('should write mid-range value (2147483648)', () => {
+ expect(() => {
+ util.writeToRegister(entry, 2147483648, validBuffer, 0);
+ }).to.not.throw();
+ expect(validBuffer.readUInt32LE(0)).to.equal(2147483648);
+ });
+
+ it('should throw OutOfRangeError for value > 4294967295', () => {
+ expect(() => {
+ util.writeToRegister(entry, 4294967296, validBuffer, 0);
+ }).to.throw(/OutOfRangeError|out of range|Out of range/i);
+ });
+
+ it('should throw OutOfRangeError for negative value', () => {
+ expect(() => {
+ util.writeToRegister(entry, -1, validBuffer, 0);
+ }).to.throw(/OutOfRangeError|out of range|Out of range/i);
+ });
+ });
+
describe('Default (Int16BE when register not specified)', () => {
const entry = { type: 'integer', register: undefined, offset: undefined };
const validBuffer = Buffer.alloc(4);
From f946428266994f5104663b0da85d64844ea1172a Mon Sep 17 00:00:00 2001
From: Pierre Leduc
Date: Mon, 19 Jan 2026 09:58:20 +0100
Subject: [PATCH 02/12] Update Mocha configuration for CI vs local
---
.mocharc.ci.json | 10 ++++++++++
.mocharc.json | 4 ++--
package.json | 5 +++--
3 files changed, 15 insertions(+), 4 deletions(-)
create mode 100644 .mocharc.ci.json
diff --git a/.mocharc.ci.json b/.mocharc.ci.json
new file mode 100644
index 0000000..e706101
--- /dev/null
+++ b/.mocharc.ci.json
@@ -0,0 +1,10 @@
+{
+ "extensions": ["ts"],
+ "spec": ["test/unit/**/*.test.ts"],
+ "timeout": 5000,
+ "color": true,
+ "loader": "ts-node/esm",
+ "node-option": [
+ "loader=ts-node/esm"
+ ]
+}
diff --git a/.mocharc.json b/.mocharc.json
index e706101..0e67743 100644
--- a/.mocharc.json
+++ b/.mocharc.json
@@ -1,7 +1,7 @@
{
"extensions": ["ts"],
- "spec": ["test/unit/**/*.test.ts"],
- "timeout": 5000,
+ "spec": ["test/**/*.test.ts"],
+ "timeout": 10000,
"color": true,
"loader": "ts-node/esm",
"node-option": [
diff --git a/package.json b/package.json
index ed05171..9f919eb 100644
--- a/package.json
+++ b/package.json
@@ -9,8 +9,9 @@
"readme": "readme.md",
"scripts": {
"test": "mocha",
- "test:unit": "mocha test/unit/*.test.ts",
- "test:integration": "mocha test/integration/*.test.ts",
+ "test:ci": "mocha --config .mocharc.ci.json",
+ "test:unit": "mocha test/unit/*.test.ts --config .mocharc.ci.json",
+ "test:integration": "mocha test/integration/*.test.ts --config .mocharc.ci.json",
"test:e2e": "mocha test/e2e/*.test.ts",
"start:mqtt": "node scripts/mqtt-broker.js",
"start:slave": "node ModbusSimulator.js examples/e2e/slave-appconfig.json",
From f1faeec53ce6e8ed4457331b20ccec6dbba11ef0 Mon Sep 17 00:00:00 2001
From: Pierre Leduc
Date: Mon, 19 Jan 2026 10:41:37 +0100
Subject: [PATCH 03/12] Rename modbus_data_tools.js to modbus_data_tools.ts and
keep TypeScript source
---
src/utils/modbus_data_tools.js | 221 -------------------------
src/utils/modbus_data_tools.ts | 288 +++++++++++++++++++++++++++++++++
2 files changed, 288 insertions(+), 221 deletions(-)
delete mode 100644 src/utils/modbus_data_tools.js
create mode 100644 src/utils/modbus_data_tools.ts
diff --git a/src/utils/modbus_data_tools.js b/src/utils/modbus_data_tools.js
deleted file mode 100644
index 4ed8fcd..0000000
--- a/src/utils/modbus_data_tools.js
+++ /dev/null
@@ -1,221 +0,0 @@
-// @ts-check
-'use strict'
-
-/**
- * Custom error for values outside valid register range
- */
-class OutOfRangeError extends Error {
- constructor(value, registerType, minValue, maxValue) {
- super(`Value ${value} is out of range for ${registerType} (valid: ${minValue} to ${maxValue})`);
- this.name = 'OutOfRangeError';
- this.value = value;
- this.registerType = registerType;
- this.minValue = minValue;
- this.maxValue = maxValue;
- }
-}
-
-/**
- * Get the valid range for a register type
- * @param {string} registerType - Buffer method name without 'write'/'read' prefix (e.g., 'Int16BE', 'UInt16BE')
- * @returns {{min: number, max: number}} Valid range for the register type
- */
-function getRegisterRange(registerType) {
- const ranges = {
- 'Int8': { min: -128, max: 127 },
- 'UInt8': { min: 0, max: 255 },
- 'Int16BE': { min: -32768, max: 32767 },
- 'Int16LE': { min: -32768, max: 32767 },
- 'UInt16BE': { min: 0, max: 65535 },
- 'UInt16LE': { min: 0, max: 65535 },
- 'Int32BE': { min: -2147483648, max: 2147483647 },
- 'Int32LE': { min: -2147483648, max: 2147483647 },
- 'UInt32BE': { min: 0, max: 4294967295 },
- 'UInt32LE': { min: 0, max: 4294967295 },
- };
- return ranges[registerType] || null;
-}
-
-/**
- * Validate that a value is within the valid range for a register type
- * @param {number} value - The value to validate
- * @param {string} registerType - The register type (e.g., 'Int16BE', 'UInt16BE')
- * @throws {OutOfRangeError} If value is outside valid range
- */
-function validateRegisterRange(value, registerType) {
- const range = getRegisterRange(registerType);
- if (!range) {
- // If register type is unknown, skip validation (trust Buffer methods to handle it)
- return;
- }
-
- if (value < range.min || value > range.max) {
- throw new OutOfRangeError(value, registerType, range.min, range.max);
- }
-}
-
-/**
-* Ecriture en registre (AI-AO)
-* @param {*} entry
-* @param {*} value
-* @param {Buffer} register Buffer to update
-* @param {number} address buffer address (modbus*2)
-*/
-function writeToRegister(entry, value, register, address) {
- let setValue;
- switch (entry.type) { //Homie Convention type
- case "boolean":
- setValue = (typeof value === 'boolean') ? value : (typeof value === 'string' && value === 'false') ? false : true;
- setBitToBuffer(register, address, entry.offset, setValue);
- break;
- case "integer":
- case "string":
- setValue = parseInt(value, (entry.encodeInt) ? entry.encodeInt : 10);
- const registerType = entry.register || "Int16BE"; // Default to Int16BE (was UInt16BE but should be signed)
-
- // Validate value is within range for this register type
- validateRegisterRange(setValue, registerType);
-
- register['write' + registerType](setValue, address);
- break;
- case "float":
- case "enum":
- default:
- throw new Error(`Setting value ${value} as ${entry.type} is not implemented for ${entry.label}`);
- }
-}
-
-/**
-* Set a bit at position on Uint8Array
-* @param {Uint8Array | Uint16Array} array
-* @param {number} bitAddress
-* @param {boolean} state
-*/
-function setBit(array, bitAddress, state) {
- if (state === false) {
- array[Math.floor(bitAddress / 8)] &= ~(1 << bitAddress % 8);
- } else {
- array[Math.floor(bitAddress / 8)] |= (1 << bitAddress % 8);
- }
-}
-
-/**
- * Read a bit at position on Uint8Array
- * @param {Uint8Array | Uint16Array} array
- * @param {number} bitAddress
- * @param {number} nbBit 8/16
- * @return {boolean}
- */
-function readBit(array, bitAddress, nbBit) {
- return (array[Math.floor(bitAddress / nbBit)] & (1 << bitAddress % nbBit)) === (1 << bitAddress % nbBit);
-}
-
-/**
- * Update a bit in a Buffer
- * @param {Buffer} register
- * @param {number} address register address
- * @param {number} offset
- * @param {boolean} state
- */
-function setBitToBuffer(register, address, offset, state) {
- if (state === false) {
- register[address] &= ~(1 << offset % 8);
- } else {
- register[address] |= (1 << offset % 8);
- }
-}
-
-/**
-* Extract address number from field name
-* @param {string} key
-* @param {number} address from config
-* @param {number} address_offset global address offset depending on constructors
-* @returns {number} address number
-*/
-function getRegisterAddress(key, address, address_offset=0) {
- return (address !== null && address !== undefined) ? address - address_offset : parseInt(key.replace(/[^0-9\.]/g, ''), 10) - address_offset;
-}
-
-/**
- * Get buffer address from field name
- * @param {string} key
- * @param {number | undefined} address
- * @param {number} address_offset
- * @param {number | undefined} register_offset
- * @returns {number} address number
- */
-function getBufferAddress(key, address, address_offset, register_offset) {
- let addr = getRegisterAddress(key, address, address_offset) * 2;
- if (register_offset !== undefined) {
- if (register_offset < 0 || register_offset > 15) {
- throw new Error(`Offset ${register_offset} not implemented in getBufferAddress for key ${key}`);
- }
- addr += register_offset < 8 ? 1 : 0; // 8-15 -> +0 / 0-7 -> +1
- }
- return addr;
-}
-
- /**
- * read property value from Uint16BE value according to it's type
- * @param {*} entry propertie options
- * @param {*} value
- * @param {*} callback
- */
- function getValueFromRegistery(entry, value, callback) {
- if (typeof value === 'boolean') { //bit
- callback(value);
- }
- else if (typeof value === 'number') {
- let val;
- switch (entry.type) {
- case "boolean":
- if (typeof entry.offset === 'number') {
- val = readBit(new Uint16Array([value]), entry.offset, 16); //ici la valeur provient du Buffer mais elle est lue registre par registre
- callback(val);
- }
- break;
- case "string":
- case "integer":
- default:
- val = value;
- if (typeof entry.offset === 'number') {
- if (entry.offset === 0) {
- val = value & 0xff;
- }
- else {
- val = (value >> entry.offset);
- }
- }
- callback(val);
- break;
- }
- }
- // else { throw new Error(`updateNodeKeyValue not implemented for ${typeof value}`)} //possible on registery writed but not red
- }
-
- /**
- * Check that offset and register properties are consistent
- * @param {*} entry
- */
- function CheckOffsetReadWriteProperties(entry) {
- if (entry.register && (!Buffer.prototype['write' + entry.register] || !Buffer.prototype['read' + entry.register])) {
- throw new Error(`Register parameter not appliable as Buffer.write${entry.register} or Buffer.read${entry.register}`);
- }
- if (typeof entry.offset === 'number' && (['string', 'integer'].indexOf(entry.type) >= 0 && [0, 8].indexOf(entry.offset) < 0 || ['string', 'integer', 'boolean'].indexOf(entry.type) < 0)) {
- throw new Error(`Offset ${entry.offset} not implemented for ${entry.type}`);
- }
-}
-
-
-module.exports = {
- setBit,
- readBit,
- writeToRegister,
- getRegisterAddress,
- getBufferAddress,
- getValueFromRegistery,
- CheckOffsetReadWriteProperties,
- OutOfRangeError,
- getRegisterRange,
- validateRegisterRange
-}
\ No newline at end of file
diff --git a/src/utils/modbus_data_tools.ts b/src/utils/modbus_data_tools.ts
new file mode 100644
index 0000000..a8d97b7
--- /dev/null
+++ b/src/utils/modbus_data_tools.ts
@@ -0,0 +1,288 @@
+/**
+ * Custom error for values outside valid register range
+ */
+export class OutOfRangeError extends Error {
+ value: number;
+ registerType: string;
+ minValue: number;
+ maxValue: number;
+
+ constructor(value: number, registerType: string, minValue: number, maxValue: number) {
+ super(`Value ${value} is out of range for ${registerType} (valid: ${minValue} to ${maxValue})`);
+ this.name = 'OutOfRangeError';
+ this.value = value;
+ this.registerType = registerType;
+ this.minValue = minValue;
+ this.maxValue = maxValue;
+ }
+}
+
+/**
+ * Register type definition
+ */
+export type RegisterType =
+ | 'Int8' | 'UInt8'
+ | 'Int16BE' | 'Int16LE' | 'UInt16BE' | 'UInt16LE'
+ | 'Int32BE' | 'Int32LE' | 'UInt32BE' | 'UInt32LE';
+
+/**
+ * Range definition for register types
+ */
+interface RegisterRange {
+ min: number;
+ max: number;
+}
+
+/**
+ * Entry configuration for register operations
+ */
+export interface RegisterEntry {
+ type: 'boolean' | 'integer' | 'string' | 'float' | 'enum';
+ register?: RegisterType | string;
+ offset?: number;
+ encodeInt?: number;
+ label?: string;
+ address?: number;
+}
+
+/**
+ * Get the valid range for a register type
+ * @param registerType - Buffer method name without 'write'/'read' prefix (e.g., 'Int16BE', 'UInt16BE')
+ * @returns Valid range for the register type
+ */
+export function getRegisterRange(registerType: string): RegisterRange | null {
+ const ranges: Record = {
+ 'Int8': { min: -128, max: 127 },
+ 'UInt8': { min: 0, max: 255 },
+ 'Int16BE': { min: -32768, max: 32767 },
+ 'Int16LE': { min: -32768, max: 32767 },
+ 'UInt16BE': { min: 0, max: 65535 },
+ 'UInt16LE': { min: 0, max: 65535 },
+ 'Int32BE': { min: -2147483648, max: 2147483647 },
+ 'Int32LE': { min: -2147483648, max: 2147483647 },
+ 'UInt32BE': { min: 0, max: 4294967295 },
+ 'UInt32LE': { min: 0, max: 4294967295 },
+ };
+ return ranges[registerType] || null;
+}
+
+/**
+ * Get the size in bytes for a register type
+ * @param registerType - Buffer method name without 'write'/'read' prefix (e.g., 'Int16BE', 'UInt16BE')
+ * @returns Size in bytes
+ */
+export function getRegisterSize(registerType: string): number {
+ if (registerType.includes('8')) return 1;
+ if (registerType.includes('16')) return 2;
+ if (registerType.includes('32')) return 4;
+ if (registerType.includes('64')) return 8;
+ return 2; // Default to 2 bytes for unknown types
+}
+
+/**
+ * Validate that a value is within the valid range for a register type
+ * @param value - The value to validate
+ * @param registerType - The register type (e.g., 'Int16BE', 'UInt16BE')
+ * @throws {OutOfRangeError} If value is outside valid range
+ */
+export function validateRegisterRange(value: number, registerType: string): void {
+ const range = getRegisterRange(registerType);
+ if (!range) {
+ // If register type is unknown, skip validation (trust Buffer methods to handle it)
+ return;
+ }
+
+ if (value < range.min || value > range.max) {
+ throw new OutOfRangeError(value, registerType, range.min, range.max);
+ }
+}
+
+/**
+ * Read a numeric value from a buffer using the appropriate register type
+ * @param registerType - The register type (e.g., 'Int16BE', 'UInt32BE')
+ * @param buffer - The buffer to read from
+ * @param offset - The offset in the buffer (default: 0)
+ * @returns The value read from the buffer
+ */
+export function readFromRegister(registerType: string, buffer: Buffer, offset: number = 0): number {
+ return (buffer as any)['read' + registerType](offset);
+}
+
+/**
+ * Write to register (AI-AO) using entry configuration
+ * @param entry - Entry configuration object
+ * @param value - Value to write
+ * @param register - Buffer to update
+ * @param address - Buffer address (modbus*2)
+ */
+export function writeValueToRegister(entry: RegisterEntry, value: any, register: Buffer, address: number): void {
+ let setValue: any;
+ switch (entry.type) { // Homie Convention type
+ case "boolean":
+ setValue = (typeof value === 'boolean') ? value : (typeof value === 'string' && value === 'false') ? false : true;
+ setBitToBuffer(register, address, entry.offset!, setValue);
+ break;
+ case "integer":
+ case "string":
+ setValue = parseInt(value, (entry.encodeInt) ? entry.encodeInt : 10);
+ const registerType = entry.register || "Int16BE"; // Default to Int16BE (was UInt16BE but should be signed)
+
+ // Validate value is within range for this register type
+ validateRegisterRange(setValue, registerType);
+
+ (register as any)['write' + registerType](setValue, address);
+ break;
+ case "float":
+ case "enum":
+ default:
+ throw new Error(`Setting value ${value} as ${entry.type} is not implemented for ${entry.label}`);
+ }
+}
+
+/**
+ * Set a bit at position on Uint8Array
+ * @param array - Array to update
+ * @param bitAddress - Bit address
+ * @param state - Bit state
+ */
+export function setBit(array: Uint8Array | Uint16Array, bitAddress: number, state: boolean): void {
+ if (state === false) {
+ array[Math.floor(bitAddress / 8)] &= ~(1 << bitAddress % 8);
+ } else {
+ array[Math.floor(bitAddress / 8)] |= (1 << bitAddress % 8);
+ }
+}
+
+/**
+ * Read a bit at position on Uint8Array
+ * @param array - Array to read from
+ * @param bitAddress - Bit address
+ * @param nbBit - Number of bits (8/16)
+ * @returns Bit state
+ */
+export function readBit(array: Uint8Array | Uint16Array, bitAddress: number, nbBit: number): boolean {
+ return (array[Math.floor(bitAddress / nbBit)] & (1 << bitAddress % nbBit)) === (1 << bitAddress % nbBit);
+}
+
+/**
+ * Update a bit in a Buffer
+ * @param register - Register buffer
+ * @param address - Register address
+ * @param offset - Bit offset
+ * @param state - Bit state
+ */
+export function setBitToBuffer(register: Buffer, address: number, offset: number, state: boolean): void {
+ if (state === false) {
+ register[address] &= ~(1 << offset % 8);
+ } else {
+ register[address] |= (1 << offset % 8);
+ }
+}
+
+/**
+ * Extract address number from field name
+ * @param key - Field key
+ * @param address - Address from config
+ * @param address_offset - Global address offset depending on constructors
+ * @returns Address number
+ */
+export function getRegisterAddress(key: string, address: number | null | undefined, address_offset: number = 0): number {
+ return (address !== null && address !== undefined)
+ ? address - address_offset
+ : parseInt(key.replace(/[^0-9\.]/g, ''), 10) - address_offset;
+}
+
+/**
+ * Get buffer address from field name
+ * @param key - Field key
+ * @param address - Address from config
+ * @param address_offset - Global address offset
+ * @param register_offset - Register bit offset
+ * @returns Address number
+ */
+export function getBufferAddress(
+ key: string,
+ address: number | undefined,
+ address_offset: number,
+ register_offset?: number
+): number {
+ let addr = getRegisterAddress(key, address, address_offset) * 2;
+ if (register_offset !== undefined) {
+ if (register_offset < 0 || register_offset > 15) {
+ throw new Error(`Offset ${register_offset} not implemented in getBufferAddress for key ${key}`);
+ }
+ addr += register_offset < 8 ? 1 : 0; // 8-15 -> +0 / 0-7 -> +1
+ }
+ return addr;
+}
+
+/**
+ * Read property value from Uint16BE value according to its type
+ * @param entry - Property options
+ * @param value - Value to read
+ * @param callback - Callback function
+ */
+export function getValueFromRegistery(
+ entry: RegisterEntry,
+ value: boolean | number,
+ callback: (val: any) => void
+): void {
+ if (typeof value === 'boolean') { // bit
+ callback(value);
+ }
+ else if (typeof value === 'number') {
+ let val: any;
+ switch (entry.type) {
+ case "boolean":
+ if (typeof entry.offset === 'number') {
+ val = readBit(new Uint16Array([value]), entry.offset, 16); // Value comes from Buffer but is read register by register
+ callback(val);
+ }
+ break;
+ case "string":
+ case "integer":
+ default:
+ val = value;
+ if (typeof entry.offset === 'number') {
+ if (entry.offset === 0) {
+ val = value & 0xff;
+ }
+ else {
+ val = (value >> entry.offset);
+ }
+ }
+ callback(val);
+ break;
+ }
+ }
+ // else { throw new Error(`updateNodeKeyValue not implemented for ${typeof value}`)} // Possible on registry written but not read
+}
+
+/**
+ * Check that offset and register properties are consistent
+ * @param entry - Entry configuration
+ */
+export function CheckOffsetReadWriteProperties(entry: RegisterEntry): void {
+ if (entry.register && (!(Buffer.prototype as any)['write' + entry.register] || !(Buffer.prototype as any)['read' + entry.register])) {
+ throw new Error(`Register parameter not appliable as Buffer.write${entry.register} or Buffer.read${entry.register}`);
+ }
+ if (typeof entry.offset === 'number' && (['string', 'integer'].indexOf(entry.type) >= 0 && [0, 8].indexOf(entry.offset) < 0 || ['string', 'integer', 'boolean'].indexOf(entry.type) < 0)) {
+ throw new Error(`Offset ${entry.offset} not implemented for ${entry.type}`);
+ }
+}
+
+// Export as CommonJS for backward compatibility
+module.exports = {
+ setBit,
+ readBit,
+ writeValueToRegister,
+ readFromRegister,
+ getRegisterAddress,
+ getBufferAddress,
+ getValueFromRegistery,
+ CheckOffsetReadWriteProperties,
+ OutOfRangeError,
+ getRegisterRange,
+ validateRegisterRange,
+ getRegisterSize
+};
From de1a605a092e0d24e0ce0447bff9eaf347eb86eb Mon Sep 17 00:00:00 2001
From: Pierre Leduc
Date: Mon, 19 Jan 2026 17:08:44 +0100
Subject: [PATCH 04/12] Add tests and prepare refacto
---
examples/e2e/inputs_e2e.json | 4 +-
src/config/slave_config.js | 4 +-
src/utils/modbus_data_tools.js | 291 ++++++++++++++++++++++++++++
src/utils/modbus_data_tools.ts | 64 ++++--
test/e2e/modbus-mqtt.test.ts | 78 ++++++++
test/unit/basic.test.ts | 2 +-
test/unit/buffer_roundtrip.test.ts | 64 ++++++
test/unit/master_config.test.ts | 4 +-
test/unit/modbus_data_tools.test.ts | 150 ++++++++------
9 files changed, 585 insertions(+), 76 deletions(-)
create mode 100644 src/utils/modbus_data_tools.js
create mode 100644 test/unit/buffer_roundtrip.test.ts
diff --git a/examples/e2e/inputs_e2e.json b/examples/e2e/inputs_e2e.json
index 2a1fa82..8b8aa4a 100644
--- a/examples/e2e/inputs_e2e.json
+++ b/examples/e2e/inputs_e2e.json
@@ -14,6 +14,8 @@
},
"AO": {
"AO-00": { "label": "Test Analog Output 1", "type": "integer", "default": 0, "register": "UInt16BE" },
- "AO-01": { "label": "Test Analog Output 2", "type": "integer", "default": 0, "register": "UInt16BE" }
+ "AO-01": { "label": "Test Analog Output 2", "type": "integer", "default": 0, "register": "UInt16BE" },
+ "AO-INT32-00": { "label": "Test Int32 Output 1", "type": "integer", "default": 0, "register": "Int32BE", "address": 2 },
+ "AO-INT32-01": { "label": "Test Int32 Output 2", "type": "integer", "default": 0, "register": "Int32BE", "address": 4 }
}
}
\ No newline at end of file
diff --git a/src/config/slave_config.js b/src/config/slave_config.js
index f27472e..d698830 100644
--- a/src/config/slave_config.js
+++ b/src/config/slave_config.js
@@ -115,7 +115,7 @@ function setUnitToData(unittodata, mqttclient) {
let buf_address = util.getBufferAddress(key, entries[key].address, ADR_OFFSET, entries[key].offset);
const modbus_address = util.getRegisterAddress(key, entries[key].address, ADR_OFFSET);
if (entries[key].default) {
- util.writeToRegister(entries[key], entries[key].default, register, buf_address);
+ util.writeValueToRegister(entries[key], entries[key].default, register, buf_address);
}
if (addresschanged.findIndex(a => a.modbus === modbus_address) < 0
&& (
@@ -160,7 +160,7 @@ function setUnitToData(unittodata, mqttclient) {
node.advertise(key).setName(entries[key].libelle).setDatatype(entries[key].type).settable(function (range, value) {
node.setProperty(key).setRetained(true).send(value.toString());
//valeur binaire
- util.writeToRegister(entries[key], value, register, buf_address);
+ util.writeValueToRegister(entries[key], value, register, buf_address);
});
});
}
diff --git a/src/utils/modbus_data_tools.js b/src/utils/modbus_data_tools.js
new file mode 100644
index 0000000..a5ad415
--- /dev/null
+++ b/src/utils/modbus_data_tools.js
@@ -0,0 +1,291 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.OutOfRangeError = void 0;
+exports.getRegisterRange = getRegisterRange;
+exports.getRegisterSize = getRegisterSize;
+exports.validateRegisterRange = validateRegisterRange;
+exports.readFromRegister = readFromRegister;
+exports.writeValueToRegister = writeValueToRegister;
+exports.setBit = setBit;
+exports.readBit = readBit;
+exports.setBitToBuffer = setBitToBuffer;
+exports.getBitFromBuffer = getBitFromBuffer;
+exports.getRegisterAddress = getRegisterAddress;
+exports.getBufferAddress = getBufferAddress;
+exports.getValueFromRegistery = getValueFromRegistery;
+exports.CheckOffsetReadWriteProperties = CheckOffsetReadWriteProperties;
+
+// Boolean helpers kept local to avoid duplication between read/write paths
+const normalizeBoolean = (value) => (typeof value === 'boolean') ? value : (typeof value === 'string' && value === 'false') ? false : true;
+const readBooleanFromWord = (word, offset) => readBit(new Uint16Array([word]), offset, 16);
+
+/**
+ * Custom error for values outside valid register range
+ */
+class OutOfRangeError extends Error {
+ constructor(value, registerType, minValue, maxValue) {
+ super(`Value ${value} is out of range for ${registerType} (valid: ${minValue} to ${maxValue})`);
+ this.name = 'OutOfRangeError';
+ this.value = value;
+ this.registerType = registerType;
+ this.minValue = minValue;
+ this.maxValue = maxValue;
+ }
+}
+exports.OutOfRangeError = OutOfRangeError;
+/**
+ * Get the valid range for a register type
+ * @param registerType - Buffer method name without 'write'/'read' prefix (e.g., 'Int16BE', 'UInt16BE')
+ * @returns Valid range for the register type
+ */
+function getRegisterRange(registerType) {
+ const ranges = {
+ 'Int8': { min: -128, max: 127 },
+ 'UInt8': { min: 0, max: 255 },
+ 'Int16BE': { min: -32768, max: 32767 },
+ 'Int16LE': { min: -32768, max: 32767 },
+ 'UInt16BE': { min: 0, max: 65535 },
+ 'UInt16LE': { min: 0, max: 65535 },
+ 'Int32BE': { min: -2147483648, max: 2147483647 },
+ 'Int32LE': { min: -2147483648, max: 2147483647 },
+ 'UInt32BE': { min: 0, max: 4294967295 },
+ 'UInt32LE': { min: 0, max: 4294967295 },
+ };
+ return ranges[registerType] || null;
+}
+/**
+ * Get the size in bytes for a register type
+ * @param registerType - Buffer method name without 'write'/'read' prefix (e.g., 'Int16BE', 'UInt16BE')
+ * @returns Size in bytes
+ */
+function getRegisterSize(registerType) {
+ if (registerType.includes('8'))
+ return 1;
+ if (registerType.includes('16'))
+ return 2;
+ if (registerType.includes('32'))
+ return 4;
+ if (registerType.includes('64'))
+ return 8;
+ return 2; // Default to 2 bytes for unknown types
+}
+/**
+ * Validate that a value is within the valid range for a register type
+ * @param value - The value to validate
+ * @param registerType - The register type (e.g., 'Int16BE', 'UInt16BE')
+ * @throws {OutOfRangeError} If value is outside valid range
+ */
+function validateRegisterRange(value, registerType) {
+ const range = getRegisterRange(registerType);
+ if (!range) {
+ // If register type is unknown, skip validation (trust Buffer methods to handle it)
+ return;
+ }
+ if (value < range.min || value > range.max) {
+ throw new OutOfRangeError(value, registerType, range.min, range.max);
+ }
+}
+/**
+ * Read a value from a buffer using the appropriate register type
+ * @param entry - Entry configuration object
+ * @param buffer - The buffer to read from
+ * @returns The value read from the buffer
+ */
+function readFromRegister(entry, buffer) {
+ // Handle undefined entry
+ if (!entry) {
+ throw new Error('readFromRegister requires a valid entry parameter');
+ }
+
+ // registerType by default is 'Int16BE' if not specified
+ const registerType = entry.register || 'Int16BE';
+ const address = entry.address || 0;
+
+ // We should handle boolean type here
+ if (entry.type === 'boolean') {
+ return getBitFromBuffer(buffer, address, entry.offset || 0);
+ }
+ return (buffer)['read' + registerType](address);
+}
+/**
+ * Write to register (AI-AO) using entry configuration
+ * @param entry - Entry configuration object
+ * @param value - Value to write
+ * @param register - Buffer to update
+ */
+function writeValueToRegister(entry, value, register) {
+ const address = entry.address || 0;
+ let setValue;
+ switch (entry.type) { // Homie Convention type
+ case "boolean":
+ setValue = normalizeBoolean(value);
+ setBitToBuffer(register, address, entry.offset || 0, setValue);
+ break;
+ case "integer":
+ case "string":
+ setValue = parseInt(value, (entry.encodeInt) ? entry.encodeInt : 10);
+ let registerType = entry.register || "Int16BE"; // Default to Int16BE (was UInt16BE but should be signed)
+ // Validate value is within range for this register type
+ validateRegisterRange(setValue, registerType);
+ // Validate buffer has enough space for the write operation
+ const registerSize = getRegisterSize(registerType);
+ if (address + registerSize > register.length) {
+ throw new RangeError(`Buffer overflow: trying to write ${registerSize} bytes at offset ${address} ` +
+ `in buffer of size ${register.length}. Buffer needs to be at least ${address + registerSize} bytes.`);
+ }
+ register['write' + registerType](setValue, address);
+ break;
+ case "float":
+ case "enum":
+ default:
+ throw new Error(`Setting value ${value} as ${entry.type} is not implemented for ${entry.label}`);
+ }
+}
+
+/**
+ * Set a bit at position on Uint8Array
+ * @param array - Array to update
+ * @param bitAddress - Bit address
+ * @param state - Bit state
+ */
+function setBit(array, bitAddress, state) {
+ if (state === false) {
+ array[Math.floor(bitAddress / 8)] &= ~(1 << bitAddress % 8);
+ }
+ else {
+ array[Math.floor(bitAddress / 8)] |= (1 << bitAddress % 8);
+ }
+}
+
+/**
+ * Read a bit at position on Uint8Array
+ * @param array - Array to read from
+ * @param bitAddress - Bit address
+ * @param nbBit - Number of bits (8/16)
+ * @returns Bit state
+ */
+function readBit(array, bitAddress, nbBit) {
+ return (array[Math.floor(bitAddress / nbBit)] & (1 << bitAddress % nbBit)) === (1 << bitAddress % nbBit);
+}
+
+/**
+ * Update a bit in a Buffer
+ * @param register - Register buffer
+ * @param address - Register address
+ * @param offset - Bit offset
+ * @param state - Bit state
+ */
+function setBitToBuffer(register, address, offset, state) {
+ if (state === false) {
+ register[address] &= ~(1 << offset % 8);
+ } else {
+ register[address] |= (1 << offset % 8);
+ }
+}
+
+/**
+ * Get a bit from a Buffer
+ * @param register - Register buffer
+ * @param address - Register address
+ * @param offset - Bit offset
+ * @returns Bit state
+ */
+function getBitFromBuffer(register, address, offset) {
+ return (register[address] & (1 << offset % 8)) === (1 << offset % 8);
+}
+
+/**
+ * Extract address number from field name
+ * @param key - Field key
+ * @param address - Address from config
+ * @param address_offset - Global address offset depending on constructors
+ * @returns Address number
+ */
+function getRegisterAddress(key, address, address_offset = 0) {
+ return (address !== null && address !== undefined)
+ ? address - address_offset
+ : parseInt(key.replace(/[^0-9\.]/g, ''), 10) - address_offset;
+}
+/**
+ * Get buffer address from field name
+ * @param key - Field key
+ * @param address - Address from config
+ * @param address_offset - Global address offset
+ * @param register_offset - Register bit offset
+ * @returns Address number
+ */
+function getBufferAddress(key, address, address_offset, register_offset) {
+ let addr = getRegisterAddress(key, address, address_offset) * 2;
+ if (register_offset !== undefined) {
+ if (register_offset < 0 || register_offset > 15) {
+ throw new Error(`Offset ${register_offset} not implemented in getBufferAddress for key ${key}`);
+ }
+ addr += register_offset < 8 ? 1 : 0; // 8-15 -> +0 / 0-7 -> +1
+ }
+ return addr;
+}
+
+/**
+ * Read property value from Uint16BE value according to its type
+ * @param entry - Property options
+ * @param value - Value to read
+ * @param callback - Callback function
+ */
+function getValueFromRegistery(entry, value, callback) {
+ if (typeof value === 'boolean') { // bit
+ callback(value);
+ }
+ else if (typeof value === 'number') {
+ let val;
+ switch (entry.type) {
+ case "boolean":
+ if (typeof entry.offset === 'number') {
+ val = readBooleanFromWord(value, entry.offset); // Value comes from Buffer but is read register by register
+ callback(val);
+ }
+ break;
+ case "string":
+ case "integer":
+ default:
+ val = value;
+ if (typeof entry.offset === 'number') {
+ if (entry.offset === 0) {
+ val = value & 0xff;
+ }
+ else {
+ val = (value >> entry.offset);
+ }
+ }
+ callback(val);
+ break;
+ }
+ }
+ // else { throw new Error(`updateNodeKeyValue not implemented for ${typeof value}`)} // Possible on registry written but not read
+}
+/**
+ * Check that offset and register properties are consistent
+ * @param entry - Entry configuration
+ */
+function CheckOffsetReadWriteProperties(entry) {
+ if (entry.register && (!Buffer.prototype['write' + entry.register] || !Buffer.prototype['read' + entry.register])) {
+ throw new Error(`Register parameter not appliable as Buffer.write${entry.register} or Buffer.read${entry.register}`);
+ }
+ if (typeof entry.offset === 'number' && (['string', 'integer'].indexOf(entry.type) >= 0 && [0, 8].indexOf(entry.offset) < 0 || ['string', 'integer', 'boolean'].indexOf(entry.type) < 0)) {
+ throw new Error(`Offset ${entry.offset} not implemented for ${entry.type}`);
+ }
+}
+// Export as CommonJS for backward compatibility
+module.exports = {
+ setBit,
+ readBit,
+ writeValueToRegister,
+ readFromRegister,
+ getRegisterAddress,
+ getBufferAddress,
+ getValueFromRegistery,
+ CheckOffsetReadWriteProperties,
+ OutOfRangeError,
+ getRegisterRange,
+ validateRegisterRange,
+ getRegisterSize
+};
diff --git a/src/utils/modbus_data_tools.ts b/src/utils/modbus_data_tools.ts
index a8d97b7..1623df8 100644
--- a/src/utils/modbus_data_tools.ts
+++ b/src/utils/modbus_data_tools.ts
@@ -1,3 +1,7 @@
+// Boolean helpers kept local to avoid duplication between read/write paths
+const normalizeBoolean = (value) => (typeof value === 'boolean') ? value : (typeof value === 'string' && value === 'false') ? false : true;
+const readBooleanFromWord = (word, offset) => readBit(new Uint16Array([word]), offset, 16);
+
/**
* Custom error for values outside valid register range
*/
@@ -38,7 +42,7 @@ interface RegisterRange {
*/
export interface RegisterEntry {
type: 'boolean' | 'integer' | 'string' | 'float' | 'enum';
- register?: RegisterType | string;
+ register?: RegisterType;
offset?: number;
encodeInt?: number;
label?: string;
@@ -71,7 +75,10 @@ export function getRegisterRange(registerType: string): RegisterRange | null {
* @param registerType - Buffer method name without 'write'/'read' prefix (e.g., 'Int16BE', 'UInt16BE')
* @returns Size in bytes
*/
-export function getRegisterSize(registerType: string): number {
+export function getRegisterSize(registerType: string | undefined): number {
+ if (!registerType) {
+ registerType = 'Int16BE';
+ }
if (registerType.includes('8')) return 1;
if (registerType.includes('16')) return 2;
if (registerType.includes('32')) return 4;
@@ -85,7 +92,7 @@ export function getRegisterSize(registerType: string): number {
* @param registerType - The register type (e.g., 'Int16BE', 'UInt16BE')
* @throws {OutOfRangeError} If value is outside valid range
*/
-export function validateRegisterRange(value: number, registerType: string): void {
+export function validateRegisterRange(value: number, registerType: RegisterType): void {
const range = getRegisterRange(registerType);
if (!range) {
// If register type is unknown, skip validation (trust Buffer methods to handle it)
@@ -99,13 +106,25 @@ export function validateRegisterRange(value: number, registerType: string): void
/**
* Read a numeric value from a buffer using the appropriate register type
- * @param registerType - The register type (e.g., 'Int16BE', 'UInt32BE')
+ * @param entry - Entry configuration object
* @param buffer - The buffer to read from
- * @param offset - The offset in the buffer (default: 0)
* @returns The value read from the buffer
*/
-export function readFromRegister(registerType: string, buffer: Buffer, offset: number = 0): number {
- return (buffer as any)['read' + registerType](offset);
+export function readFromRegister(entry: RegisterEntry | undefined, buffer: Buffer): any {
+ // Handle undefined entry
+ if (!entry) {
+ throw new Error('readFromRegister requires a valid entry parameter');
+ }
+
+ // registerType by default is 'Int16BE' if not specified
+ const registerType = entry.register || 'Int16BE';
+ const address = entry.address || 0;
+
+ // We should handle boolean type here
+ if (entry.type === 'boolean') {
+ return getBitFromBuffer(buffer, address, entry.offset || 0);
+ }
+ return (buffer as any)['read' + registerType](address);
}
/**
@@ -113,23 +132,27 @@ export function readFromRegister(registerType: string, buffer: Buffer, offset: n
* @param entry - Entry configuration object
* @param value - Value to write
* @param register - Buffer to update
- * @param address - Buffer address (modbus*2)
*/
-export function writeValueToRegister(entry: RegisterEntry, value: any, register: Buffer, address: number): void {
+export function writeValueToRegister(entry: RegisterEntry, value: any, register: Buffer): void {
+ const address = entry.address || 0;
let setValue: any;
switch (entry.type) { // Homie Convention type
case "boolean":
- setValue = (typeof value === 'boolean') ? value : (typeof value === 'string' && value === 'false') ? false : true;
- setBitToBuffer(register, address, entry.offset!, setValue);
+ setValue = normalizeBoolean(value);
+ setBitToBuffer(register, address, entry.offset || 0, setValue);
break;
case "integer":
case "string":
setValue = parseInt(value, (entry.encodeInt) ? entry.encodeInt : 10);
- const registerType = entry.register || "Int16BE"; // Default to Int16BE (was UInt16BE but should be signed)
-
+ let registerType = entry.register || "Int16BE"; // Default to Int16BE (was UInt16BE but should be signed)
// Validate value is within range for this register type
validateRegisterRange(setValue, registerType);
-
+ // Validate buffer has enough space for the write operation
+ const registerSize = getRegisterSize(registerType);
+ if (address + registerSize > register.length) {
+ throw new RangeError(`Buffer overflow: trying to write ${registerSize} bytes at offset ${address} ` +
+ `in buffer of size ${register.length}. Buffer needs to be at least ${address + registerSize} bytes.`);
+ }
(register as any)['write' + registerType](setValue, address);
break;
case "float":
@@ -179,6 +202,17 @@ export function setBitToBuffer(register: Buffer, address: number, offset: number
}
}
+/**
+ * Get a bit from a Buffer
+ * @param register - Register buffer
+ * @param address - Register address
+ * @param offset - Bit offset
+ * @returns Bit state
+ */
+export function getBitFromBuffer(register: Buffer, address: number, offset: number): boolean {
+ return (register[address] & (1 << offset % 8)) === (1 << offset % 8);
+}
+
/**
* Extract address number from field name
* @param key - Field key
@@ -235,7 +269,7 @@ export function getValueFromRegistery(
switch (entry.type) {
case "boolean":
if (typeof entry.offset === 'number') {
- val = readBit(new Uint16Array([value]), entry.offset, 16); // Value comes from Buffer but is read register by register
+ val = readBooleanFromWord(value, entry.offset); // Value comes from Buffer but is read register by register
callback(val);
}
break;
diff --git a/test/e2e/modbus-mqtt.test.ts b/test/e2e/modbus-mqtt.test.ts
index 26c05b5..7b46920 100644
--- a/test/e2e/modbus-mqtt.test.ts
+++ b/test/e2e/modbus-mqtt.test.ts
@@ -199,6 +199,8 @@ describe('ModbusSimulator - E2E Tests', function () {
const resets: Array<[string, string]> = [
['homie/E2E_SLAVE/AO/AO-00/set', '0'],
['homie/E2E_SLAVE/AO/AO-01/set', '0'],
+ ['homie/E2E_SLAVE/AO/AO-INT32-00/set', '0'],
+ ['homie/E2E_SLAVE/AO/AO-INT32-01/set', '0'],
['homie/E2E_SLAVE/DO/DO-00/set', 'false'],
['homie/E2E_SLAVE/DO/DO-01/set', 'false'],
['homie/E2E_SLAVE/AI/AI-00/set', '0'],
@@ -350,6 +352,58 @@ describe('ModbusSimulator - E2E Tests', function () {
complete(new Error('Modbus read timeout'));
}, 4000);
});
+
+ it('should read Int32 data from slave via Modbus TCP', function (done) {
+ this.timeout(5000);
+
+ const client = new net.Socket();
+ let completed = false;
+
+ const complete = (err?: Error) => {
+ if (!completed) {
+ completed = true;
+ client.destroy();
+ done(err);
+ }
+ };
+
+ client.connect(1502, 'localhost', () => {
+ // Send Modbus TCP request to read Int32 register (Read Holding Registers)
+ // Int32 requires 2 consecutive 16-bit registers
+ // Transaction ID: 0x0002, Protocol ID: 0x0000, Length: 0x0006
+ // Unit ID: 0x01, Function Code: 0x03 (Read Holding Registers)
+ // Starting Address: 0x0002 (offset for AO-INT32-00), Quantity: 0x0002 (2 registers for Int32)
+ const request = Buffer.from([
+ 0x00, 0x02, // Transaction ID
+ 0x00, 0x00, // Protocol ID
+ 0x00, 0x06, // Length
+ 0x01, // Unit ID
+ 0x03, // Function Code
+ 0x00, 0x02, // Starting Address (register 2)
+ 0x00, 0x02 // Quantity (2 registers for Int32)
+ ]);
+
+ client.write(request);
+ });
+
+ client.on('data', (data: Buffer) => {
+ expect(data.length).to.be.greaterThan(7);
+ // Validate Modbus response for Int32
+ expect(data[0]).to.equal(0x00); // Transaction ID high byte
+ expect(data[1]).to.equal(0x02); // Transaction ID low byte
+ expect(data[7]).to.equal(0x03); // Function Code (at index 7 in response)
+ expect(data[8]).to.equal(0x04); // Byte count (4 bytes for Int32)
+ complete();
+ });
+
+ client.on('error', (err: Error) => {
+ complete(err);
+ });
+
+ setTimeout(() => {
+ complete(new Error('Modbus read timeout'));
+ }, 4000);
+ });
});
describe('Master-Slave Interaction', () => {
@@ -365,6 +419,18 @@ describe('ModbusSimulator - E2E Tests', function () {
expect(masterMsg!.message).to.equal('12345');
});
+ it('should have master read updated Int32 value from slave', async function () {
+ this.timeout(12000);
+ // Test with negative Int32 value to verify signed integer support
+ await new Promise((resolve, reject) => {
+ mqttClient.publish('homie/E2E_SLAVE/AO/AO-INT32-00/set', '-123456', {}, (err) => err ? reject(err) : resolve());
+ });
+
+ const masterMsg = await retrieveMessageAsync(m => masterTopicEndsWith(m.topic, 'AO/AO-INT32-00'));
+ expect(masterMsg).to.exist;
+ expect(masterMsg!.message).to.equal('-123456');
+ });
+
it('should have slave read updated AO value from master', async function () {
this.timeout(10000);
await new Promise((resolve, reject) => {
@@ -376,6 +442,18 @@ describe('ModbusSimulator - E2E Tests', function () {
expect(slaveMsg!.message).to.equal('12345');
});
+ it('should have slave read updated Int32 value from master', async function () {
+ this.timeout(10000);
+ // Test with large positive Int32 value
+ await new Promise((resolve, reject) => {
+ mqttClient.publish('homie/E2E_MASTER/R1-AO/AO-INT32-01/set', '987654', {}, (err) => err ? reject(err) : resolve());
+ });
+
+ const slaveMsg = await retrieveMessageAsync(m => m.topic === 'homie/E2E_SLAVE/AO/AO-INT32-01');
+ expect(slaveMsg).to.exist;
+ expect(slaveMsg!.message).to.equal('987654');
+ });
+
it('should have master write to slave coil', async function () {
this.timeout(10000);
await new Promise((resolve, reject) => {
diff --git a/test/unit/basic.test.ts b/test/unit/basic.test.ts
index 9c9acc6..03c3b24 100644
--- a/test/unit/basic.test.ts
+++ b/test/unit/basic.test.ts
@@ -1,7 +1,7 @@
import { describe, it } from 'mocha';
import { expect } from 'chai';
import config from '../../src/config/config.js';
-import tools from '../../src/utils/modbus_data_tools.js';
+import * as tools from '../../src/utils/modbus_data_tools.js';
/**
* Sample unit test - tests basic functionality
diff --git a/test/unit/buffer_roundtrip.test.ts b/test/unit/buffer_roundtrip.test.ts
new file mode 100644
index 0000000..68bd616
--- /dev/null
+++ b/test/unit/buffer_roundtrip.test.ts
@@ -0,0 +1,64 @@
+import { expect } from 'chai';
+import * as util from '../../src/utils/modbus_data_tools.js';
+
+// Helper to perform a write/read round-trip using current address/buffer helpers
+/**
+ * Performs a round-trip test by writing a value to a buffer and reading it back.
+ * @param entry - The register entry configuration containing type and offset information
+ * @param address - The register address
+ * @param value - The value to write to the register
+ * @returns The value read back from the buffer, either as a bit (for boolean types) or using the appropriate Buffer read method
+ */
+function roundTrip(entry: util.RegisterEntry, value: any) {
+ const registerSize = util.getRegisterSize(entry.register);
+ const registerCount = Math.ceil(registerSize / 2);
+ const buf = Buffer.alloc(registerCount * 2+ (entry.address || 0) + registerSize );
+ util.writeValueToRegister(entry, value, buf);
+ return util.readFromRegister(entry, buf);
+}
+
+describe('Data Tools - buffer round-trip', () => {
+ it('UInt16 round-trips with direct address', () => {
+ const entry: util.RegisterEntry = { type: 'integer', register: "UInt16BE" };
+ const result = roundTrip(entry, 1234);
+ expect(result).to.equal(1234);
+ });
+
+ it('Int32 round-trips with later address', () => {
+ const entry: util.RegisterEntry = { type: 'integer', register: "Int32BE", address: 2 };
+ const result = roundTrip(entry, -123456);
+ expect(result).to.equal(-123456);
+ });
+
+ it('UInt32 round-trips with later address', () => {
+ const entry: util.RegisterEntry = { type: 'integer', register: "UInt32BE", address: 10 };
+ // adrOffset shifts the register index; ensure buffer math is still correct
+ const result = roundTrip(entry, 3000000000);
+ expect(result).to.equal(3000000000);
+ });
+
+ it('Boolean bit at offset 0 round-trips', () => {
+ const entry: util.RegisterEntry = { type: 'boolean', register: 'Int16BE', offset: 0 };
+ const result = roundTrip(entry, true);
+ expect(result).to.equal(true);
+ });
+
+ it('Boolean bit at offset 9 round-trips', () => {
+ const entry: util.RegisterEntry = { type: 'boolean', register: 'Int16BE', offset: 9 };
+ const result = roundTrip(entry, true);
+ expect(result).to.equal(true);
+ });
+
+ it('Default register (Int16BE) parses string payloads', () => {
+ const entry: util.RegisterEntry = { type: 'string', register: 'Int16BE' };
+ const result = roundTrip(entry, '42');
+ expect(result).to.equal(42);
+ });
+
+ it('Respects register boundaries for Int32 at non-zero buffer offset', () => {
+ const entry: util.RegisterEntry = { type: 'integer', register: 'Int32BE', address: 3 };
+ // Address 3 -> byte offset 6; ensure the slice fits and value survives
+ const result = roundTrip(entry, 987654);
+ expect(result).to.equal(987654);
+ });
+});
diff --git a/test/unit/master_config.test.ts b/test/unit/master_config.test.ts
index decb717..1cd17bb 100644
--- a/test/unit/master_config.test.ts
+++ b/test/unit/master_config.test.ts
@@ -1,5 +1,5 @@
import mc from "../../src/config/master_config.js";
-import util from "../../src/utils/modbus_data_tools.js";
+import * as util from "../../src/utils/modbus_data_tools.js";
import assert from "assert";
/**
@@ -87,7 +87,7 @@ describe('Master_config', () => {
* Tests that CheckOffsetReadWriteProperties validates property configurations
*/
it('should validate property configuration', () => {
- const testProp = {
+ const testProp: util.RegisterEntry = {
type: 'integer',
label: 'Test Property',
address: 0
diff --git a/test/unit/modbus_data_tools.test.ts b/test/unit/modbus_data_tools.test.ts
index 6040012..cb3941c 100644
--- a/test/unit/modbus_data_tools.test.ts
+++ b/test/unit/modbus_data_tools.test.ts
@@ -9,347 +9,387 @@ describe('Data Tools', () => {
*/
describe('Int16BE (signed 16-bit big-endian)', () => {
- const entry = { type: 'integer', register: 'Int16BE', offset: undefined };
+ const entry: util.RegisterEntry = { type: 'integer', register: 'Int16BE', offset: undefined };
const validBuffer = Buffer.alloc(4);
it('should write valid positive value (32767)', () => {
expect(() => {
- util.writeToRegister(entry, 32767, validBuffer, 0);
+ util.writeValueToRegister(entry, 32767, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readInt16BE(0)).to.equal(32767);
});
it('should write valid negative value (-32768)', () => {
expect(() => {
- util.writeToRegister(entry, -32768, validBuffer, 0);
+ util.writeValueToRegister(entry, -32768, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readInt16BE(0)).to.equal(-32768);
});
it('should write zero', () => {
expect(() => {
- util.writeToRegister(entry, 0, validBuffer, 0);
+ util.writeValueToRegister(entry, 0, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readInt16BE(0)).to.equal(0);
});
it('should throw OutOfRangeError for value > 32767', () => {
expect(() => {
- util.writeToRegister(entry, 32768, validBuffer, 0);
+ util.writeValueToRegister(entry, 32768, validBuffer, 0);
}).to.throw(/OutOfRangeError|out of range|Out of range/i);
});
it('should throw OutOfRangeError for value < -32768', () => {
expect(() => {
- util.writeToRegister(entry, -32769, validBuffer, 0);
+ util.writeValueToRegister(entry, -32769, validBuffer, 0);
}).to.throw(/OutOfRangeError|out of range|Out of range/i);
});
it('should throw OutOfRangeError for 54321 (example from issue)', () => {
expect(() => {
- util.writeToRegister(entry, 54321, validBuffer, 0);
+ util.writeValueToRegister(entry, 54321, validBuffer, 0);
}).to.throw(/OutOfRangeError|out of range|Out of range/i);
});
});
describe('Int16LE (signed 16-bit little-endian)', () => {
- const entry = { type: 'integer', register: 'Int16LE', offset: undefined };
+ const entry: util.RegisterEntry = { type: 'integer', register: 'Int16LE', offset: undefined };
const validBuffer = Buffer.alloc(4);
it('should write valid positive value (32767)', () => {
expect(() => {
- util.writeToRegister(entry, 32767, validBuffer, 0);
+ util.writeValueToRegister(entry, 32767, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readInt16LE(0)).to.equal(32767);
});
it('should throw OutOfRangeError for value > 32767', () => {
expect(() => {
- util.writeToRegister(entry, 32768, validBuffer, 0);
+ util.writeValueToRegister(entry, 32768, validBuffer, 0);
}).to.throw(/OutOfRangeError|out of range|Out of range/i);
});
});
describe('UInt16BE (unsigned 16-bit big-endian)', () => {
- const entry = { type: 'integer', register: 'UInt16BE', offset: undefined };
+ const entry: util.RegisterEntry = { type: 'integer', register: 'UInt16BE', offset: undefined };
const validBuffer = Buffer.alloc(4);
it('should write valid max unsigned value (65535)', () => {
expect(() => {
- util.writeToRegister(entry, 65535, validBuffer, 0);
+ util.writeValueToRegister(entry, 65535, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readUInt16BE(0)).to.equal(65535);
});
it('should write zero', () => {
expect(() => {
- util.writeToRegister(entry, 0, validBuffer, 0);
+ util.writeValueToRegister(entry, 0, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readUInt16BE(0)).to.equal(0);
});
it('should throw OutOfRangeError for value > 65535', () => {
expect(() => {
- util.writeToRegister(entry, 65536, validBuffer, 0);
+ util.writeValueToRegister(entry, 65536, validBuffer, 0);
}).to.throw(/OutOfRangeError|out of range|Out of range/i);
});
it('should throw OutOfRangeError for negative value', () => {
expect(() => {
- util.writeToRegister(entry, -1, validBuffer, 0);
+ util.writeValueToRegister(entry, -1, validBuffer, 0);
}).to.throw(/OutOfRangeError|out of range|Out of range/i);
});
it('should throw OutOfRangeError for 54321 (example from issue)', () => {
expect(() => {
- util.writeToRegister(entry, 54321, validBuffer, 0);
+ util.writeValueToRegister(entry, 54321, validBuffer, 0);
}).to.not.throw(); // 54321 is actually valid for UInt16BE (< 65535)
expect(validBuffer.readUInt16BE(0)).to.equal(54321);
});
});
describe('UInt16LE (unsigned 16-bit little-endian)', () => {
- const entry = { type: 'integer', register: 'UInt16LE', offset: undefined };
+ const entry: util.RegisterEntry = { type: 'integer', register: 'UInt16LE', offset: undefined };
const validBuffer = Buffer.alloc(4);
it('should write valid max unsigned value (65535)', () => {
expect(() => {
- util.writeToRegister(entry, 65535, validBuffer, 0);
+ util.writeValueToRegister(entry, 65535, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readUInt16LE(0)).to.equal(65535);
});
it('should throw OutOfRangeError for value > 65535', () => {
expect(() => {
- util.writeToRegister(entry, 65536, validBuffer, 0);
+ util.writeValueToRegister(entry, 65536, validBuffer, 0);
}).to.throw(/OutOfRangeError|out of range|Out of range/i);
});
it('should throw OutOfRangeError for negative value', () => {
expect(() => {
- util.writeToRegister(entry, -1, validBuffer, 0);
+ util.writeValueToRegister(entry, -1, validBuffer, 0);
}).to.throw(/OutOfRangeError|out of range|Out of range/i);
});
});
describe('Int32BE (signed 32-bit big-endian)', () => {
- const entry = { type: 'integer', register: 'Int32BE', offset: undefined };
+ const entry: util.RegisterEntry = { type: 'integer', register: 'Int32BE', offset: undefined };
const validBuffer = Buffer.alloc(8);
it('should write valid positive value (2147483647 - max)', () => {
expect(() => {
- util.writeToRegister(entry, 2147483647, validBuffer, 0);
+ util.writeValueToRegister(entry, 2147483647, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readInt32BE(0)).to.equal(2147483647);
});
it('should write valid negative value (-2147483648 - min)', () => {
expect(() => {
- util.writeToRegister(entry, -2147483648, validBuffer, 0);
+ util.writeValueToRegister(entry, -2147483648, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readInt32BE(0)).to.equal(-2147483648);
});
it('should write zero', () => {
expect(() => {
- util.writeToRegister(entry, 0, validBuffer, 0);
+ util.writeValueToRegister(entry, 0, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readInt32BE(0)).to.equal(0);
});
it('should write positive mid-range value (1000000)', () => {
expect(() => {
- util.writeToRegister(entry, 1000000, validBuffer, 0);
+ util.writeValueToRegister(entry, 1000000, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readInt32BE(0)).to.equal(1000000);
});
it('should write negative mid-range value (-1000000)', () => {
expect(() => {
- util.writeToRegister(entry, -1000000, validBuffer, 0);
+ util.writeValueToRegister(entry, -1000000, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readInt32BE(0)).to.equal(-1000000);
});
it('should throw OutOfRangeError for value > 2147483647', () => {
expect(() => {
- util.writeToRegister(entry, 2147483648, validBuffer, 0);
+ util.writeValueToRegister(entry, 2147483648, validBuffer, 0);
}).to.throw(/OutOfRangeError|out of range|Out of range/i);
});
it('should throw OutOfRangeError for value < -2147483648', () => {
expect(() => {
- util.writeToRegister(entry, -2147483649, validBuffer, 0);
+ util.writeValueToRegister(entry, -2147483649, validBuffer, 0);
}).to.throw(/OutOfRangeError|out of range|Out of range/i);
});
});
describe('Int32LE (signed 32-bit little-endian)', () => {
- const entry = { type: 'integer', register: 'Int32LE', offset: undefined };
+ const entry: util.RegisterEntry = { type: 'integer', register: 'Int32LE', offset: undefined };
const validBuffer = Buffer.alloc(8);
it('should write valid positive value (2147483647 - max)', () => {
expect(() => {
- util.writeToRegister(entry, 2147483647, validBuffer, 0);
+ util.writeValueToRegister(entry, 2147483647, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readInt32LE(0)).to.equal(2147483647);
});
it('should write valid negative value (-2147483648 - min)', () => {
expect(() => {
- util.writeToRegister(entry, -2147483648, validBuffer, 0);
+ util.writeValueToRegister(entry, -2147483648, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readInt32LE(0)).to.equal(-2147483648);
});
it('should write zero', () => {
expect(() => {
- util.writeToRegister(entry, 0, validBuffer, 0);
+ util.writeValueToRegister(entry, 0, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readInt32LE(0)).to.equal(0);
});
it('should throw OutOfRangeError for value > 2147483647', () => {
expect(() => {
- util.writeToRegister(entry, 2147483648, validBuffer, 0);
+ util.writeValueToRegister(entry, 2147483648, validBuffer, 0);
}).to.throw(/OutOfRangeError|out of range|Out of range/i);
});
it('should throw OutOfRangeError for value < -2147483648', () => {
expect(() => {
- util.writeToRegister(entry, -2147483649, validBuffer, 0);
+ util.writeValueToRegister(entry, -2147483649, validBuffer, 0);
}).to.throw(/OutOfRangeError|out of range|Out of range/i);
});
});
describe('UInt32BE (unsigned 32-bit big-endian)', () => {
- const entry = { type: 'integer', register: 'UInt32BE', offset: undefined };
+ const entry: util.RegisterEntry = { type: 'integer', register: 'UInt32BE', offset: undefined };
const validBuffer = Buffer.alloc(8);
it('should write valid max unsigned value (4294967295)', () => {
expect(() => {
- util.writeToRegister(entry, 4294967295, validBuffer, 0);
+ util.writeValueToRegister(entry, 4294967295, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readUInt32BE(0)).to.equal(4294967295);
});
it('should write zero', () => {
expect(() => {
- util.writeToRegister(entry, 0, validBuffer, 0);
+ util.writeValueToRegister(entry, 0, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readUInt32BE(0)).to.equal(0);
});
it('should write mid-range value (2147483648)', () => {
expect(() => {
- util.writeToRegister(entry, 2147483648, validBuffer, 0);
+ util.writeValueToRegister(entry, 2147483648, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readUInt32BE(0)).to.equal(2147483648);
});
it('should write large value (3000000000)', () => {
expect(() => {
- util.writeToRegister(entry, 3000000000, validBuffer, 0);
+ util.writeValueToRegister(entry, 3000000000, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readUInt32BE(0)).to.equal(3000000000);
});
it('should throw OutOfRangeError for value > 4294967295', () => {
expect(() => {
- util.writeToRegister(entry, 4294967296, validBuffer, 0);
+ util.writeValueToRegister(entry, 4294967296, validBuffer, 0);
}).to.throw(/OutOfRangeError|out of range|Out of range/i);
});
it('should throw OutOfRangeError for negative value', () => {
expect(() => {
- util.writeToRegister(entry, -1, validBuffer, 0);
+ util.writeValueToRegister(entry, -1, validBuffer, 0);
}).to.throw(/OutOfRangeError|out of range|Out of range/i);
});
});
describe('UInt32LE (unsigned 32-bit little-endian)', () => {
- const entry = { type: 'integer', register: 'UInt32LE', offset: undefined };
+ const entry: util.RegisterEntry = { type: 'integer', register: 'UInt32LE', offset: undefined };
const validBuffer = Buffer.alloc(8);
it('should write valid max unsigned value (4294967295)', () => {
expect(() => {
- util.writeToRegister(entry, 4294967295, validBuffer, 0);
+ util.writeValueToRegister(entry, 4294967295, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readUInt32LE(0)).to.equal(4294967295);
});
it('should write zero', () => {
expect(() => {
- util.writeToRegister(entry, 0, validBuffer, 0);
+ util.writeValueToRegister(entry, 0, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readUInt32LE(0)).to.equal(0);
});
it('should write mid-range value (2147483648)', () => {
expect(() => {
- util.writeToRegister(entry, 2147483648, validBuffer, 0);
+ util.writeValueToRegister(entry, 2147483648, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readUInt32LE(0)).to.equal(2147483648);
});
it('should throw OutOfRangeError for value > 4294967295', () => {
expect(() => {
- util.writeToRegister(entry, 4294967296, validBuffer, 0);
+ util.writeValueToRegister(entry, 4294967296, validBuffer, 0);
}).to.throw(/OutOfRangeError|out of range|Out of range/i);
});
it('should throw OutOfRangeError for negative value', () => {
expect(() => {
- util.writeToRegister(entry, -1, validBuffer, 0);
+ util.writeValueToRegister(entry, -1, validBuffer, 0);
}).to.throw(/OutOfRangeError|out of range|Out of range/i);
});
});
describe('Default (Int16BE when register not specified)', () => {
- const entry = { type: 'integer', register: undefined, offset: undefined };
+ const entry: util.RegisterEntry = { type: 'integer', register: undefined, offset: undefined };
const validBuffer = Buffer.alloc(4);
it('should use Int16BE as default', () => {
expect(() => {
- util.writeToRegister(entry, 12345, validBuffer, 0);
+ util.writeValueToRegister(entry, 12345, validBuffer, 0);
}).to.not.throw();
expect(validBuffer.readInt16BE(0)).to.equal(12345);
});
it('should apply Int16BE range to default', () => {
expect(() => {
- util.writeToRegister(entry, 32768, validBuffer, 0);
+ util.writeValueToRegister(entry, 32768, validBuffer, 0);
}).to.throw(/OutOfRangeError|out of range|Out of range/i);
});
});
describe('Boolean type (should not apply numeric bounds)', () => {
- const entry = { type: 'boolean', offset: 0 };
+ const entry: util.RegisterEntry = { type: 'boolean', offset: 0 };
const validBuffer = Buffer.alloc(4);
it('should accept boolean true', () => {
expect(() => {
- util.writeToRegister(entry, true, validBuffer, 0);
+ util.writeValueToRegister(entry, true, validBuffer, 0);
}).to.not.throw();
});
it('should accept boolean false', () => {
expect(() => {
- util.writeToRegister(entry, false, validBuffer, 0);
+ util.writeValueToRegister(entry, false, validBuffer, 0);
}).to.not.throw();
});
it('should accept truthy values', () => {
expect(() => {
- util.writeToRegister(entry, 1, validBuffer, 0);
+ util.writeValueToRegister(entry, 1, validBuffer, 0);
}).to.not.throw();
});
it('should accept falsy values', () => {
expect(() => {
- util.writeToRegister(entry, 0, validBuffer, 0);
+ util.writeValueToRegister(entry, 0, validBuffer, 0);
}).to.not.throw();
});
});
+
+ describe('Buffer boundary validation for 32-bit types', () => {
+ it('should throw when writing Int32BE at offset 8 in 10-byte buffer', () => {
+ const entry: util.RegisterEntry = { type: 'integer', register: 'Int32BE' };
+ const buffer = Buffer.alloc(10); // 5 registers
+
+ expect(() => {
+ util.writeValueToRegister(entry, 987654, buffer, 8);
+ }).to.throw(/out of range|Buffer overflow/i);
+ });
+
+ it('should successfully write Int32BE at offset 8 in 12-byte buffer', () => {
+ const entry: util.RegisterEntry = { type: 'integer', register: 'Int32BE' };
+ const buffer = Buffer.alloc(12); // 6 registers
+
+ expect(() => {
+ util.writeValueToRegister(entry, 987654, buffer, 8);
+ }).to.not.throw();
+ expect(buffer.readInt32BE(8)).to.equal(987654);
+ });
+
+ it('should throw when writing UInt32BE at offset 6 in 8-byte buffer', () => {
+ const entry: util.RegisterEntry = { type: 'integer', register: 'UInt32BE' };
+ const buffer = Buffer.alloc(8); // 4 registers
+
+ expect(() => {
+ util.writeValueToRegister(entry, 123456, buffer, 6);
+ }).to.throw(/out of range|Buffer overflow/i);
+ });
+
+ it('should successfully write UInt32BE at offset 6 in 10-byte buffer', () => {
+ const entry: util.RegisterEntry = { type: 'integer', register: 'UInt32BE' };
+ const buffer = Buffer.alloc(10); // 5 registers
+
+ expect(() => {
+ util.writeValueToRegister(entry, 123456, buffer, 6);
+ }).to.not.throw();
+ expect(buffer.readUInt32BE(6)).to.equal(123456);
+ });
+ });
});
});
From 32065641ccec4c2be0066f632b085ced5ed82d67 Mon Sep 17 00:00:00 2001
From: Pierre Leduc
Date: Mon, 19 Jan 2026 17:40:38 +0100
Subject: [PATCH 05/12] switch to ts, with @ts-nocheck
---
.gitignore | 6 +
.mocharc.json | 3 +-
ModbusSimulator.js => ModbusSimulator.ts | 3 +-
package.json | 5 +
src/config/{config.js => config.ts} | 2 +-
.../{master_config.js => master_config.ts} | 49 ++-
.../{slave_config.js => slave_config.ts} | 2 +-
src/core/{master.js => master.ts} | 2 +-
src/core/{slave.js => slave.ts} | 2 +-
src/core/{stats.js => stats.ts} | 0
src/utils/modbus_data_tools.js | 291 ------------------
src/utils/modbus_data_tools.ts | 45 ++-
test/unit/buffer_roundtrip.test.ts | 2 +-
test/unit/master_config.test.ts | 1 +
tsconfig.json | 22 +-
tsconfig.mocha.json | 9 +-
16 files changed, 105 insertions(+), 339 deletions(-)
rename ModbusSimulator.js => ModbusSimulator.ts (97%)
rename src/config/{config.js => config.ts} (99%)
rename src/config/{master_config.js => master_config.ts} (92%)
rename src/config/{slave_config.js => slave_config.ts} (99%)
rename src/core/{master.js => master.ts} (99%)
rename src/core/{slave.js => slave.ts} (99%)
rename src/core/{stats.js => stats.ts} (100%)
delete mode 100644 src/utils/modbus_data_tools.js
diff --git a/.gitignore b/.gitignore
index ef2f6e7..a680440 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,9 @@
/node_modules
/Releases
build-output.log
+
+# TypeScript compiled output
+/src/**/*.js
+/src/**/*.js.map
+# But keep test infrastructure JavaScript files
+!/test/**/*.js
diff --git a/.mocharc.json b/.mocharc.json
index 0e67743..77240e1 100644
--- a/.mocharc.json
+++ b/.mocharc.json
@@ -6,5 +6,6 @@
"loader": "ts-node/esm",
"node-option": [
"loader=ts-node/esm"
- ]
+ ],
+ "require": "ts-node/register/transpile-only"
}
diff --git a/ModbusSimulator.js b/ModbusSimulator.ts
similarity index 97%
rename from ModbusSimulator.js
rename to ModbusSimulator.ts
index 16d7ee1..ff20456 100644
--- a/ModbusSimulator.js
+++ b/ModbusSimulator.ts
@@ -1,9 +1,10 @@
-// @ts-check
+// @ts-nocheck
'use strict';
const pjson = require('./package.json');
const Master = require('./src/core/master');
const Slave = require('./src/core/slave');
+// @ts-ignore - TODO: fix variable name conflict with master_config
const { config, runInPKG } = require('./src/config/config');
const MASTER_CONFIGFILE = config.master && config.master.script && typeof config.master.script === 'string'
? './' + config.master.script
diff --git a/package.json b/package.json
index 9f919eb..0989836 100644
--- a/package.json
+++ b/package.json
@@ -8,15 +8,20 @@
"license": "MIT",
"readme": "readme.md",
"scripts": {
+ "compile": "tsc",
+ "pretest": "npm run compile",
"test": "mocha",
"test:ci": "mocha --config .mocharc.ci.json",
"test:unit": "mocha test/unit/*.test.ts --config .mocharc.ci.json",
"test:integration": "mocha test/integration/*.test.ts --config .mocharc.ci.json",
"test:e2e": "mocha test/e2e/*.test.ts",
"start:mqtt": "node scripts/mqtt-broker.js",
+ "prestart:slave": "npm run compile",
"start:slave": "node ModbusSimulator.js examples/e2e/slave-appconfig.json",
+ "prestart:master": "npm run compile",
"start:master": "node ModbusSimulator.js examples/e2e/master-appconfig.json",
"start:hodd": "node scripts/hodd-server.js",
+ "prebuild": "npm run compile",
"build": "node scripts/build_pkg.js",
"docker-build": "docker build -t modbussimulator .",
"docker-run": "docker run -p 502:502/udp modbussimulator"
diff --git a/src/config/config.js b/src/config/config.ts
similarity index 99%
rename from src/config/config.js
rename to src/config/config.ts
index 62227a4..8cd154e 100644
--- a/src/config/config.js
+++ b/src/config/config.ts
@@ -1,4 +1,4 @@
-// @ts-check
+// @ts-nocheck
'use strict';
const { isAbsolute, resolve, join, parse, relative, sep, dirname } = require('path');
diff --git a/src/config/master_config.js b/src/config/master_config.ts
similarity index 92%
rename from src/config/master_config.js
rename to src/config/master_config.ts
index 925fe08..231947e 100644
--- a/src/config/master_config.js
+++ b/src/config/master_config.ts
@@ -1,4 +1,4 @@
-// @ts-check
+// @ts-nocheck
'use strict';
/**
@@ -30,6 +30,7 @@ const FunctionCode = {
/**
* @type {{ master: { interval: any; timeout: any; addressingoffset: any; requests: any[]; unit_id: number; }; mqtt: { debug: any; }; }}
*/
+// @ts-ignore - TODO: fix variable name conflict
const config = require('./config').default.config;
const util = require('../utils/modbus_data_tools');
@@ -299,7 +300,10 @@ function setRequest(master, mqttclient) {
* @param {ModbusParams} [params] optional but required if not already set
* @returns {void}
*/
- function setTransaction(id, params) {
+ function setTransaction(id: string , params?: any) {
+ if (!params) {
+ params = requests_params.get(id);
+ }
const t = readWrite_timeouts.get(id)
if (t) {
clearTimeout(t);
@@ -345,7 +349,7 @@ function setRequest(master, mqttclient) {
Object.keys(params.properties).forEach(prop => undefineNodeKeyValue(params.nodeName, prop, params.properties[prop]));
//init cache in order to process write modifications
if (!modbus_lastvalue[id]) {
- if (params.readCode === FunctionCode.ReadCoils || params.reandCode === FunctionCode.ReadDiscreteInputs) {
+ if (params.readCode === FunctionCode.ReadCoils || params.readCode === FunctionCode.ReadDiscreteInputs) {
modbus_lastvalue[id] = new Array(params.qte);
}
else {
@@ -382,12 +386,17 @@ function setRequest(master, mqttclient) {
value = values[util.getRegisterAddress(prop, entry.address, ADR_OFFSET) - start_address];
}
else if (Buffer.isBuffer(values)) {
- if (values.length === 2) {
- value = values.readUInt16BE(); //Contains only one register
+ const registerType = entry.register || 'UInt16BE'; // Default to UInt16BE for backward compatibility
+ const entryForRead = Object.assign({}, entry, { register: registerType });
+ const registerSize = util.getRegisterSize(registerType);
+
+ if (values.length === registerSize) {
+ // Buffer contains only one register value
+ value = util.readValueFromRegister(entryForRead, values, 0);
} else {
+ // Buffer contains multiple registers, extract the specific one
const responseBufferAddress = util.getBufferAddress(prop, entry.address, start_address + ADR_OFFSET);
- //on retourne le registre complet soit 2 octets
- value = values.slice(responseBufferAddress, responseBufferAddress + 2).readUInt16BE();
+ value = util.readValueFromRegister(entryForRead, values, responseBufferAddress);
}
}
return value;
@@ -452,8 +461,14 @@ function setRequest(master, mqttclient) {
* @returns {number}
*/
function getQte(prprts, cfg) {
- return util.getRegisterAddress(prprts[prprts.length - 1], cfg[prprts[prprts.length - 1]].address)
- - util.getRegisterAddress(prprts[0], cfg[prprts[0]].address) + 1;
+ const lastProp = prprts[prprts.length - 1];
+ const lastEntry = cfg[lastProp];
+ const lastRegisterType = lastEntry.register || 'UInt16BE';
+ const lastRegisterSize = util.getRegisterSize(lastRegisterType);
+ const lastRegisterCount = Math.ceil(lastRegisterSize / 2); // Convert bytes to 16-bit registers
+
+ return util.getRegisterAddress(lastProp, lastEntry.address)
+ - util.getRegisterAddress(prprts[0], cfg[prprts[0]].address) + lastRegisterCount;
}
/**
@@ -495,7 +510,7 @@ function setRequest(master, mqttclient) {
const tmp = getResponseData(modbus_lastvalue[id], prop, entry, start_address);
util.getValueFromRegistery(entry, tmp, (v) => oldv = v);
- if (oldv !== null && value === oldv.toString()) { callback(); }
+ if (oldv !== null && value === oldv.toString()) { callback(); } //no change
else {
/**we will save updated data to
* -write them by modbus at next read write request
@@ -509,20 +524,22 @@ function setRequest(master, mqttclient) {
}
else {
if (typeof modbus_lastvalue[id] === 'number') {
- const tmp = Buffer.alloc(2);
- tmp.writeUInt16BE(modbus_lastvalue[id]);
- util.writeToRegister(entry, value, tmp, transactionBuffer_address)
- modbus_lastvalue[id] = tmp.readUInt16BE(0);
+ const registerType = entry.register || "Int16BE";
+ const entryForRegister = Object.assign({}, entry, { register: registerType });
+ const bufferSize = util.getRegisterSize(registerType);
+ const tmp = Buffer.alloc(bufferSize);
+ util.writeValueToRegister(entryForRegister, value, tmp, 0);
+ modbus_lastvalue[id] = util.readValueFromRegister(entryForRegister, tmp, 0);
}
else {
- util.writeToRegister(entry, value, modbus_lastvalue[id], transactionBuffer_address);
+ util.writeValueToRegister(entry, value, modbus_lastvalue[id], transactionBuffer_address);
}
}
if (params.readCode !== FunctionCode.ReadWriteMultipleRegisters) {
//sending write request if ther is no read write request
try {
const single = params.qte === 1;
- const write_request = {
+ const write_request: any = {
functionCode: writeCode(!single)
};
if (single) {
diff --git a/src/config/slave_config.js b/src/config/slave_config.ts
similarity index 99%
rename from src/config/slave_config.js
rename to src/config/slave_config.ts
index d698830..3311257 100644
--- a/src/config/slave_config.js
+++ b/src/config/slave_config.ts
@@ -1,4 +1,4 @@
-// @ts-check
+// @ts-nocheck
'use strict'
const config = require('./config').config;
diff --git a/src/core/master.js b/src/core/master.ts
similarity index 99%
rename from src/core/master.js
rename to src/core/master.ts
index e48f6b7..4eda067 100644
--- a/src/core/master.js
+++ b/src/core/master.ts
@@ -1,4 +1,4 @@
-// @ts-check
+// @ts-nocheck
// Part of licensed under
'use strict';
diff --git a/src/core/slave.js b/src/core/slave.ts
similarity index 99%
rename from src/core/slave.js
rename to src/core/slave.ts
index 0aedae9..be0adce 100644
--- a/src/core/slave.js
+++ b/src/core/slave.ts
@@ -1,4 +1,4 @@
-// @ts-check
+// @ts-nocheck
// Part of licensed under
'use strict';
diff --git a/src/core/stats.js b/src/core/stats.ts
similarity index 100%
rename from src/core/stats.js
rename to src/core/stats.ts
diff --git a/src/utils/modbus_data_tools.js b/src/utils/modbus_data_tools.js
deleted file mode 100644
index a5ad415..0000000
--- a/src/utils/modbus_data_tools.js
+++ /dev/null
@@ -1,291 +0,0 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.OutOfRangeError = void 0;
-exports.getRegisterRange = getRegisterRange;
-exports.getRegisterSize = getRegisterSize;
-exports.validateRegisterRange = validateRegisterRange;
-exports.readFromRegister = readFromRegister;
-exports.writeValueToRegister = writeValueToRegister;
-exports.setBit = setBit;
-exports.readBit = readBit;
-exports.setBitToBuffer = setBitToBuffer;
-exports.getBitFromBuffer = getBitFromBuffer;
-exports.getRegisterAddress = getRegisterAddress;
-exports.getBufferAddress = getBufferAddress;
-exports.getValueFromRegistery = getValueFromRegistery;
-exports.CheckOffsetReadWriteProperties = CheckOffsetReadWriteProperties;
-
-// Boolean helpers kept local to avoid duplication between read/write paths
-const normalizeBoolean = (value) => (typeof value === 'boolean') ? value : (typeof value === 'string' && value === 'false') ? false : true;
-const readBooleanFromWord = (word, offset) => readBit(new Uint16Array([word]), offset, 16);
-
-/**
- * Custom error for values outside valid register range
- */
-class OutOfRangeError extends Error {
- constructor(value, registerType, minValue, maxValue) {
- super(`Value ${value} is out of range for ${registerType} (valid: ${minValue} to ${maxValue})`);
- this.name = 'OutOfRangeError';
- this.value = value;
- this.registerType = registerType;
- this.minValue = minValue;
- this.maxValue = maxValue;
- }
-}
-exports.OutOfRangeError = OutOfRangeError;
-/**
- * Get the valid range for a register type
- * @param registerType - Buffer method name without 'write'/'read' prefix (e.g., 'Int16BE', 'UInt16BE')
- * @returns Valid range for the register type
- */
-function getRegisterRange(registerType) {
- const ranges = {
- 'Int8': { min: -128, max: 127 },
- 'UInt8': { min: 0, max: 255 },
- 'Int16BE': { min: -32768, max: 32767 },
- 'Int16LE': { min: -32768, max: 32767 },
- 'UInt16BE': { min: 0, max: 65535 },
- 'UInt16LE': { min: 0, max: 65535 },
- 'Int32BE': { min: -2147483648, max: 2147483647 },
- 'Int32LE': { min: -2147483648, max: 2147483647 },
- 'UInt32BE': { min: 0, max: 4294967295 },
- 'UInt32LE': { min: 0, max: 4294967295 },
- };
- return ranges[registerType] || null;
-}
-/**
- * Get the size in bytes for a register type
- * @param registerType - Buffer method name without 'write'/'read' prefix (e.g., 'Int16BE', 'UInt16BE')
- * @returns Size in bytes
- */
-function getRegisterSize(registerType) {
- if (registerType.includes('8'))
- return 1;
- if (registerType.includes('16'))
- return 2;
- if (registerType.includes('32'))
- return 4;
- if (registerType.includes('64'))
- return 8;
- return 2; // Default to 2 bytes for unknown types
-}
-/**
- * Validate that a value is within the valid range for a register type
- * @param value - The value to validate
- * @param registerType - The register type (e.g., 'Int16BE', 'UInt16BE')
- * @throws {OutOfRangeError} If value is outside valid range
- */
-function validateRegisterRange(value, registerType) {
- const range = getRegisterRange(registerType);
- if (!range) {
- // If register type is unknown, skip validation (trust Buffer methods to handle it)
- return;
- }
- if (value < range.min || value > range.max) {
- throw new OutOfRangeError(value, registerType, range.min, range.max);
- }
-}
-/**
- * Read a value from a buffer using the appropriate register type
- * @param entry - Entry configuration object
- * @param buffer - The buffer to read from
- * @returns The value read from the buffer
- */
-function readFromRegister(entry, buffer) {
- // Handle undefined entry
- if (!entry) {
- throw new Error('readFromRegister requires a valid entry parameter');
- }
-
- // registerType by default is 'Int16BE' if not specified
- const registerType = entry.register || 'Int16BE';
- const address = entry.address || 0;
-
- // We should handle boolean type here
- if (entry.type === 'boolean') {
- return getBitFromBuffer(buffer, address, entry.offset || 0);
- }
- return (buffer)['read' + registerType](address);
-}
-/**
- * Write to register (AI-AO) using entry configuration
- * @param entry - Entry configuration object
- * @param value - Value to write
- * @param register - Buffer to update
- */
-function writeValueToRegister(entry, value, register) {
- const address = entry.address || 0;
- let setValue;
- switch (entry.type) { // Homie Convention type
- case "boolean":
- setValue = normalizeBoolean(value);
- setBitToBuffer(register, address, entry.offset || 0, setValue);
- break;
- case "integer":
- case "string":
- setValue = parseInt(value, (entry.encodeInt) ? entry.encodeInt : 10);
- let registerType = entry.register || "Int16BE"; // Default to Int16BE (was UInt16BE but should be signed)
- // Validate value is within range for this register type
- validateRegisterRange(setValue, registerType);
- // Validate buffer has enough space for the write operation
- const registerSize = getRegisterSize(registerType);
- if (address + registerSize > register.length) {
- throw new RangeError(`Buffer overflow: trying to write ${registerSize} bytes at offset ${address} ` +
- `in buffer of size ${register.length}. Buffer needs to be at least ${address + registerSize} bytes.`);
- }
- register['write' + registerType](setValue, address);
- break;
- case "float":
- case "enum":
- default:
- throw new Error(`Setting value ${value} as ${entry.type} is not implemented for ${entry.label}`);
- }
-}
-
-/**
- * Set a bit at position on Uint8Array
- * @param array - Array to update
- * @param bitAddress - Bit address
- * @param state - Bit state
- */
-function setBit(array, bitAddress, state) {
- if (state === false) {
- array[Math.floor(bitAddress / 8)] &= ~(1 << bitAddress % 8);
- }
- else {
- array[Math.floor(bitAddress / 8)] |= (1 << bitAddress % 8);
- }
-}
-
-/**
- * Read a bit at position on Uint8Array
- * @param array - Array to read from
- * @param bitAddress - Bit address
- * @param nbBit - Number of bits (8/16)
- * @returns Bit state
- */
-function readBit(array, bitAddress, nbBit) {
- return (array[Math.floor(bitAddress / nbBit)] & (1 << bitAddress % nbBit)) === (1 << bitAddress % nbBit);
-}
-
-/**
- * Update a bit in a Buffer
- * @param register - Register buffer
- * @param address - Register address
- * @param offset - Bit offset
- * @param state - Bit state
- */
-function setBitToBuffer(register, address, offset, state) {
- if (state === false) {
- register[address] &= ~(1 << offset % 8);
- } else {
- register[address] |= (1 << offset % 8);
- }
-}
-
-/**
- * Get a bit from a Buffer
- * @param register - Register buffer
- * @param address - Register address
- * @param offset - Bit offset
- * @returns Bit state
- */
-function getBitFromBuffer(register, address, offset) {
- return (register[address] & (1 << offset % 8)) === (1 << offset % 8);
-}
-
-/**
- * Extract address number from field name
- * @param key - Field key
- * @param address - Address from config
- * @param address_offset - Global address offset depending on constructors
- * @returns Address number
- */
-function getRegisterAddress(key, address, address_offset = 0) {
- return (address !== null && address !== undefined)
- ? address - address_offset
- : parseInt(key.replace(/[^0-9\.]/g, ''), 10) - address_offset;
-}
-/**
- * Get buffer address from field name
- * @param key - Field key
- * @param address - Address from config
- * @param address_offset - Global address offset
- * @param register_offset - Register bit offset
- * @returns Address number
- */
-function getBufferAddress(key, address, address_offset, register_offset) {
- let addr = getRegisterAddress(key, address, address_offset) * 2;
- if (register_offset !== undefined) {
- if (register_offset < 0 || register_offset > 15) {
- throw new Error(`Offset ${register_offset} not implemented in getBufferAddress for key ${key}`);
- }
- addr += register_offset < 8 ? 1 : 0; // 8-15 -> +0 / 0-7 -> +1
- }
- return addr;
-}
-
-/**
- * Read property value from Uint16BE value according to its type
- * @param entry - Property options
- * @param value - Value to read
- * @param callback - Callback function
- */
-function getValueFromRegistery(entry, value, callback) {
- if (typeof value === 'boolean') { // bit
- callback(value);
- }
- else if (typeof value === 'number') {
- let val;
- switch (entry.type) {
- case "boolean":
- if (typeof entry.offset === 'number') {
- val = readBooleanFromWord(value, entry.offset); // Value comes from Buffer but is read register by register
- callback(val);
- }
- break;
- case "string":
- case "integer":
- default:
- val = value;
- if (typeof entry.offset === 'number') {
- if (entry.offset === 0) {
- val = value & 0xff;
- }
- else {
- val = (value >> entry.offset);
- }
- }
- callback(val);
- break;
- }
- }
- // else { throw new Error(`updateNodeKeyValue not implemented for ${typeof value}`)} // Possible on registry written but not read
-}
-/**
- * Check that offset and register properties are consistent
- * @param entry - Entry configuration
- */
-function CheckOffsetReadWriteProperties(entry) {
- if (entry.register && (!Buffer.prototype['write' + entry.register] || !Buffer.prototype['read' + entry.register])) {
- throw new Error(`Register parameter not appliable as Buffer.write${entry.register} or Buffer.read${entry.register}`);
- }
- if (typeof entry.offset === 'number' && (['string', 'integer'].indexOf(entry.type) >= 0 && [0, 8].indexOf(entry.offset) < 0 || ['string', 'integer', 'boolean'].indexOf(entry.type) < 0)) {
- throw new Error(`Offset ${entry.offset} not implemented for ${entry.type}`);
- }
-}
-// Export as CommonJS for backward compatibility
-module.exports = {
- setBit,
- readBit,
- writeValueToRegister,
- readFromRegister,
- getRegisterAddress,
- getBufferAddress,
- getValueFromRegistery,
- CheckOffsetReadWriteProperties,
- OutOfRangeError,
- getRegisterRange,
- validateRegisterRange,
- getRegisterSize
-};
diff --git a/src/utils/modbus_data_tools.ts b/src/utils/modbus_data_tools.ts
index 1623df8..0a0820e 100644
--- a/src/utils/modbus_data_tools.ts
+++ b/src/utils/modbus_data_tools.ts
@@ -108,23 +108,35 @@ export function validateRegisterRange(value: number, registerType: RegisterType)
* Read a numeric value from a buffer using the appropriate register type
* @param entry - Entry configuration object
* @param buffer - The buffer to read from
+ * @param addressOverride - Optional address override for position in master request
* @returns The value read from the buffer
*/
-export function readFromRegister(entry: RegisterEntry | undefined, buffer: Buffer): any {
+export function readValueFromRegister(
+ entry: RegisterEntry | undefined,
+ buffer: Buffer,
+ addressOverride?: number
+): any {
// Handle undefined entry
if (!entry) {
throw new Error('readFromRegister requires a valid entry parameter');
}
-
+
// registerType by default is 'Int16BE' if not specified
const registerType = entry.register || 'Int16BE';
- const address = entry.address || 0;
-
- // We should handle boolean type here
+ const resolvedAddress = addressOverride !== undefined ? addressOverride : (entry.address || 0);
+
+ // Handle boolean type
if (entry.type === 'boolean') {
- return getBitFromBuffer(buffer, address, entry.offset || 0);
+ return getBitFromBuffer(buffer, resolvedAddress, entry.offset || 0);
}
- return (buffer as any)['read' + registerType](address);
+ return (buffer as any)['read' + registerType](resolvedAddress);
+}
+
+/**
+ * @deprecated Use readValueFromRegister instead
+ */
+export function readFromRegister(entry: RegisterEntry | undefined, buffer: Buffer, addressOverride?: number): any {
+ return readValueFromRegister(entry, buffer, addressOverride);
}
/**
@@ -132,14 +144,15 @@ export function readFromRegister(entry: RegisterEntry | undefined, buffer: Buffe
* @param entry - Entry configuration object
* @param value - Value to write
* @param register - Buffer to update
+ * @param addressOverride - Optional address override for position in master request
*/
-export function writeValueToRegister(entry: RegisterEntry, value: any, register: Buffer): void {
- const address = entry.address || 0;
+export function writeValueToRegister(entry: RegisterEntry, value: any, register: Buffer, addressOverride?: number): void {
+ const resolvedAddress = (addressOverride !== undefined) ? addressOverride : (entry.address || 0);
let setValue: any;
switch (entry.type) { // Homie Convention type
case "boolean":
setValue = normalizeBoolean(value);
- setBitToBuffer(register, address, entry.offset || 0, setValue);
+ setBitToBuffer(register, resolvedAddress, entry.offset || 0, setValue);
break;
case "integer":
case "string":
@@ -149,11 +162,12 @@ export function writeValueToRegister(entry: RegisterEntry, value: any, register:
validateRegisterRange(setValue, registerType);
// Validate buffer has enough space for the write operation
const registerSize = getRegisterSize(registerType);
- if (address + registerSize > register.length) {
- throw new RangeError(`Buffer overflow: trying to write ${registerSize} bytes at offset ${address} ` +
- `in buffer of size ${register.length}. Buffer needs to be at least ${address + registerSize} bytes.`);
- }
- (register as any)['write' + registerType](setValue, address);
+ if (resolvedAddress + registerSize > register.length) {
+ throw new RangeError(
+ `Buffer overflow: trying to write ${registerSize} bytes at offset ${resolvedAddress} in buffer of size ${register.length}. Buffer needs to be at least ${resolvedAddress + registerSize} bytes.`
+ );
+ }
+ (register as any)['write' + registerType](setValue, resolvedAddress);
break;
case "float":
case "enum":
@@ -310,6 +324,7 @@ module.exports = {
setBit,
readBit,
writeValueToRegister,
+ readValueFromRegister,
readFromRegister,
getRegisterAddress,
getBufferAddress,
diff --git a/test/unit/buffer_roundtrip.test.ts b/test/unit/buffer_roundtrip.test.ts
index 68bd616..a7b0567 100644
--- a/test/unit/buffer_roundtrip.test.ts
+++ b/test/unit/buffer_roundtrip.test.ts
@@ -14,7 +14,7 @@ function roundTrip(entry: util.RegisterEntry, value: any) {
const registerCount = Math.ceil(registerSize / 2);
const buf = Buffer.alloc(registerCount * 2+ (entry.address || 0) + registerSize );
util.writeValueToRegister(entry, value, buf);
- return util.readFromRegister(entry, buf);
+ return util.readValueFromRegister(entry, buf);
}
describe('Data Tools - buffer round-trip', () => {
diff --git a/test/unit/master_config.test.ts b/test/unit/master_config.test.ts
index 1cd17bb..dc30a34 100644
--- a/test/unit/master_config.test.ts
+++ b/test/unit/master_config.test.ts
@@ -1,3 +1,4 @@
+// @ts-ignore - CommonJS module
import mc from "../../src/config/master_config.js";
import * as util from "../../src/utils/modbus_data_tools.js";
import assert from "assert";
diff --git a/tsconfig.json b/tsconfig.json
index c715a1e..5c41e99 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,28 +1,34 @@
{
"compilerOptions": {
- "module": "nodenext",
+ "module": "commonjs",
+ "target": "es2020",
"noImplicitAny": false,
"removeComments": true,
"preserveConstEnums": true,
- "sourceMap": true,
+ "sourceMap": false,
"allowJs": true,
"checkJs": false,
- "moduleResolution": "nodenext",
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "noEmitOnError": false,
+ "isolatedModules": false,
+ "moduleResolution": "node",
"baseUrl": "./",
- "outDir": "./dist", // Specify output directory
+ "outDir": "./",
"paths": {
"json-ref-lite": ["node_modules/json-ref-lite"],
"json5": ["node_modules/json5"]
}
},
"include": [
- "test/*",
- "*"
-, "test/unit/master_config.test.ts" ],
+ "src/**/*.ts",
+ "*.ts"
+ ],
"typeRoots": [
"node_modules/@types"
],
"exclude": [
- "node_modules"
+ "node_modules",
+ "test/**"
]
}
\ No newline at end of file
diff --git a/tsconfig.mocha.json b/tsconfig.mocha.json
index 67c5560..92b1885 100644
--- a/tsconfig.mocha.json
+++ b/tsconfig.mocha.json
@@ -2,14 +2,19 @@
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "ES2020",
- "target": "ES2020"
+ "target": "ES2020",
+ "moduleResolution": "node"
},
"include": [
"test/**/*"
],
+ "exclude": [],
"ts-node": {
"esm": true,
"experimentalEsm": true,
- "transpileOnly": true
+ "transpileOnly": true,
+ "compilerOptions": {
+ "module": "ES2020"
+ }
}
}
From 77cf14df2a56bb6e1d0bde7a102e1f3185eff953 Mon Sep 17 00:00:00 2001
From: Pierre Leduc
Date: Mon, 19 Jan 2026 18:00:43 +0100
Subject: [PATCH 06/12] Enhance handling of multi-register types in Modbus
configuration
---
.gitignore | 1 +
src/config/master_config.ts | 7 ++++++-
src/config/slave_config.ts | 11 +++++++++--
3 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/.gitignore b/.gitignore
index a680440..bbe53d8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,4 @@ build-output.log
/src/**/*.js.map
# But keep test infrastructure JavaScript files
!/test/**/*.js
+*.js
diff --git a/src/config/master_config.ts b/src/config/master_config.ts
index 231947e..78977d2 100644
--- a/src/config/master_config.ts
+++ b/src/config/master_config.ts
@@ -529,7 +529,12 @@ function setRequest(master, mqttclient) {
const bufferSize = util.getRegisterSize(registerType);
const tmp = Buffer.alloc(bufferSize);
util.writeValueToRegister(entryForRegister, value, tmp, 0);
- modbus_lastvalue[id] = util.readValueFromRegister(entryForRegister, tmp, 0);
+ // For multi-register types (Int32, UInt32), keep as Buffer to preserve all bytes
+ if (bufferSize > 2) {
+ modbus_lastvalue[id] = tmp;
+ } else {
+ modbus_lastvalue[id] = util.readValueFromRegister(entryForRegister, tmp, 0);
+ }
}
else {
util.writeValueToRegister(entry, value, modbus_lastvalue[id], transactionBuffer_address);
diff --git a/src/config/slave_config.ts b/src/config/slave_config.ts
index 3311257..d37e689 100644
--- a/src/config/slave_config.ts
+++ b/src/config/slave_config.ts
@@ -85,7 +85,14 @@ function setUnitToData(unittodata, mqttclient) {
function updateNodeValues(nodename, entries, register) {
Object.keys(entries).forEach(key => {
/** @type {any} */ (register).listener.on('change:' + util.getRegisterAddress(key, entries[key].address, ADR_OFFSET), function (value) {
- util.getValueFromRegistery(entries[key], value, (v) =>
+ // For multi-register types (Int32, UInt32), read the full value from the buffer
+ // instead of using the single-register value from the event
+ let finalValue = value;
+ if (Buffer.isBuffer(register) && entries[key].register) {
+ const buf_address = util.getBufferAddress(key, entries[key].address, ADR_OFFSET);
+ finalValue = util.readValueFromRegister(entries[key], register, buf_address);
+ }
+ util.getValueFromRegistery(entries[key], finalValue, (v) =>
mqttclient.nodes[nodename.replace('#', '-')].setProperty(key).setRetained(true).send(v.toString())
);
});
@@ -122,7 +129,7 @@ function setUnitToData(unittodata, mqttclient) {
entries[key].default // valeur changée quel que soit le type
|| entries[key].type === 'boolean')) //présence d'un booleen -> forcer le chargement de la valeur 'false'
{
- buf_address = util.getBufferAddress(key, entries[key].address, ADR_OFFSET,0);//sans offset pour retourner un registre complet
+ buf_address = util.getBufferAddress(key, entries[key].address, ADR_OFFSET);//sans offset pour retourner un registre complet
addresschanged.push({ modbus: modbus_address, buffer: buf_address });
}
});
From 686b6d33aa4e908f24fd01bceb6263176ebc3cdf Mon Sep 17 00:00:00 2001
From: Pierre Leduc
Date: Mon, 19 Jan 2026 18:03:40 +0100
Subject: [PATCH 07/12] Add TypeScript transpile-only requirement to Mocha CI
configuration
---
.mocharc.ci.json | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.mocharc.ci.json b/.mocharc.ci.json
index e706101..1616f21 100644
--- a/.mocharc.ci.json
+++ b/.mocharc.ci.json
@@ -6,5 +6,6 @@
"loader": "ts-node/esm",
"node-option": [
"loader=ts-node/esm"
- ]
+ ],
+ "require": "ts-node/register/transpile-only"
}
From a0b37da225be6d38066200b42ff99b8aafa84002 Mon Sep 17 00:00:00 2001
From: Pierre Leduc
Date: Mon, 19 Jan 2026 20:53:41 +0100
Subject: [PATCH 08/12] make ts work
---
.mocharc.ci.json | 3 +-
.mocharc.json | 3 +-
ModbusSimulator.ts | 115 ++++++++++++---------
package.json | 7 +-
scripts/{build_pkg.js => build_pkg.ts} | 11 +-
scripts/{hodd-server.js => hodd-server.ts} | 28 ++---
scripts/{mqtt-broker.js => mqtt-broker.ts} | 15 +--
src/config/config.ts | 20 ++--
src/config/master_config.ts | 8 +-
src/config/slave_config.ts | 10 +-
src/core/master.ts | 7 +-
src/core/slave.ts | 8 +-
src/core/stats.ts | 4 +-
src/package.json | 3 +
src/utils/modbus_data_tools.ts | 17 +--
test/e2e/modbus-mqtt.test.ts | 8 +-
tsconfig.json | 2 +-
17 files changed, 149 insertions(+), 120 deletions(-)
rename scripts/{build_pkg.js => build_pkg.ts} (86%)
rename scripts/{hodd-server.js => hodd-server.ts} (92%)
rename scripts/{mqtt-broker.js => mqtt-broker.ts} (90%)
create mode 100644 src/package.json
diff --git a/.mocharc.ci.json b/.mocharc.ci.json
index 1616f21..e706101 100644
--- a/.mocharc.ci.json
+++ b/.mocharc.ci.json
@@ -6,6 +6,5 @@
"loader": "ts-node/esm",
"node-option": [
"loader=ts-node/esm"
- ],
- "require": "ts-node/register/transpile-only"
+ ]
}
diff --git a/.mocharc.json b/.mocharc.json
index 77240e1..0e67743 100644
--- a/.mocharc.json
+++ b/.mocharc.json
@@ -6,6 +6,5 @@
"loader": "ts-node/esm",
"node-option": [
"loader=ts-node/esm"
- ],
- "require": "ts-node/register/transpile-only"
+ ]
}
diff --git a/ModbusSimulator.ts b/ModbusSimulator.ts
index ff20456..94e4b8a 100644
--- a/ModbusSimulator.ts
+++ b/ModbusSimulator.ts
@@ -1,18 +1,27 @@
// @ts-nocheck
'use strict';
-const pjson = require('./package.json');
-const Master = require('./src/core/master');
-const Slave = require('./src/core/slave');
+import pjson from './package.json' assert { type: 'json' };
+import Master from './src/core/master.js';
+import Slave from './src/core/slave.js';
// @ts-ignore - TODO: fix variable name conflict with master_config
-const { config, runInPKG } = require('./src/config/config');
+import configDefault from './src/config/config.js';
+import path from 'path';
+import { createRequire } from 'module';
+import { fileURLToPath } from 'url';
+
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
+const require = createRequire(import.meta.url);
+
+const config = configDefault.config;
+const runInPKG = configDefault.runInPKG;
+
const MASTER_CONFIGFILE = config.master && config.master.script && typeof config.master.script === 'string'
? './' + config.master.script
: null; //par défaut pas de script spécifique
const SLAVE_CONFIGFILE = config.slave && config.slave.script && typeof config.slave.script === 'string'
? './' + config.slave.script
: null; //par défaut pas de script spécifique
-const path = require('path');
//add MQTT capacities
const HomieDevice = require('homie-device');
@@ -22,57 +31,62 @@ let mst = null;
process.title = `ModbusSimulator ${config.name}`; //titre de fenetre
-if (config.mqtt) {
- if (config.device_id === undefined) { config.device_id = config.name.replace(" ", "-"); }
- config.mqtt = Object.assign({
- "host": "localhost",
- "port": 1883,
- "base_topic": "homie/",
- "auth": false,
- "username": null,
- "password": null
- },config.mqtt); //Load default options
- mqtt_client = new HomieDevice(config);
- mqtt_client.setFirmware(pjson.name, pjson.version);
-}
-
-if (config.slave) {
- let slave_config = require('./src/config/slave_config.js');
- slv = new Slave(config.slave);//initialisation de l'esclave
- if (config.slave.data) {
- slave_config(slv.UNIT_TO_DATA, mqtt_client); //appel de la config pré-définie en interne
+async function main() {
+ if (config.mqtt) {
+ if (config.device_id === undefined) { config.device_id = config.name.replace(" ", "-"); }
+ config.mqtt = Object.assign({
+ "host": "localhost",
+ "port": 1883,
+ "base_topic": "homie/",
+ "auth": false,
+ "username": null,
+ "password": null
+ },config.mqtt); //Load default options
+ mqtt_client = new HomieDevice(config);
+ mqtt_client.setFirmware(pjson.name, pjson.version);
}
- //Ensuite, en présence d'une demande spécifique dans le fichier de config:
- if (SLAVE_CONFIGFILE) {
- if (runInPKG) {
- const deployPath = path.dirname(process.execPath);
- slave_config = require(path.join(deployPath, SLAVE_CONFIGFILE));
+
+ if (config.slave) {
+ const slaveConfigModule = await import('./src/config/slave_config.js');
+ let slave_config = slaveConfigModule.default;
+ slv = new Slave(config.slave);//initialisation de l'esclave
+ if (config.slave.data) {
+ slave_config(slv.UNIT_TO_DATA, mqtt_client); //appel de la config pré-définie en interne
}
- else {
- slave_config = require(SLAVE_CONFIGFILE);
+ //Ensuite, en présence d'une demande spécifique dans le fichier de config:
+ if (SLAVE_CONFIGFILE) {
+ if (runInPKG) {
+ const deployPath = path.dirname(process.execPath);
+ slave_config = require(path.join(deployPath, SLAVE_CONFIGFILE));
+ }
+ else {
+ slave_config = require(SLAVE_CONFIGFILE);
+ }
+ slave_config(slv.UNIT_TO_DATA, mqtt_client);
}
- slave_config(slv.UNIT_TO_DATA, mqtt_client);
}
-}
-if (config.master) {
- let master_config = require('./src/config/master_config.js');
- mst = new Master(config.master);
- if (config.master.requests) {
- master_config(mst, mqtt_client); //appel de la config pré-définie en interne
- }
- //Ensuite, en présence d'une demande spécifique dans le fichier de config:
- if (MASTER_CONFIGFILE) {
- if (runInPKG) {
- const deployPath = path.dirname(process.execPath);
- master_config = require(path.join(deployPath, MASTER_CONFIGFILE));
- }
- else {
- master_config = require(MASTER_CONFIGFILE);
+ if (config.master) {
+ const masterConfigModule = await import('./src/config/master_config.js');
+ let master_config = masterConfigModule.default;
+ mst = new Master(config.master);
+ if (config.master.requests) {
+ master_config(mst, mqtt_client); //appel de la config pré-définie en interne
}
+ //Ensuite, en présence d'une demande spécifique dans le fichier de config:
+ if (MASTER_CONFIGFILE) {
+ if (runInPKG) {
+ const deployPath = path.dirname(process.execPath);
+ master_config = require(path.join(deployPath, MASTER_CONFIGFILE));
+ }
+ else {
+ master_config = require(MASTER_CONFIGFILE);
+ }
- master_config(mst, mqtt_client);
+ master_config(mst, mqtt_client);
+ }
}
}
+
process.once("SIGINT", exit());
process.once("SIGHUP", exit());
process.once("SIGTERM", exit());
@@ -86,3 +100,8 @@ function exit() {
}
};
}
+
+main().catch(err => {
+ console.error('Initialization error:', err);
+ process.exit(1);
+});
diff --git a/package.json b/package.json
index 0989836..2cfe8f6 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,6 @@
{
"name": "modbussimulator",
+ "type": "module",
"main": "ModbusSimulator.js",
"bin": "ModbusSimulator.js",
"version": "1.0.0",
@@ -15,14 +16,14 @@
"test:unit": "mocha test/unit/*.test.ts --config .mocharc.ci.json",
"test:integration": "mocha test/integration/*.test.ts --config .mocharc.ci.json",
"test:e2e": "mocha test/e2e/*.test.ts",
- "start:mqtt": "node scripts/mqtt-broker.js",
+ "start:mqtt": "node --loader ts-node/esm scripts/mqtt-broker.ts",
"prestart:slave": "npm run compile",
"start:slave": "node ModbusSimulator.js examples/e2e/slave-appconfig.json",
"prestart:master": "npm run compile",
"start:master": "node ModbusSimulator.js examples/e2e/master-appconfig.json",
- "start:hodd": "node scripts/hodd-server.js",
+ "start:hodd": "node --loader ts-node/esm scripts/hodd-server.ts",
"prebuild": "npm run compile",
- "build": "node scripts/build_pkg.js",
+ "build": "node --loader ts-node/esm scripts/build_pkg.ts",
"docker-build": "docker build -t modbussimulator .",
"docker-run": "docker run -p 502:502/udp modbussimulator"
},
diff --git a/scripts/build_pkg.js b/scripts/build_pkg.ts
similarity index 86%
rename from scripts/build_pkg.js
rename to scripts/build_pkg.ts
index 5c60f9c..f8220a4 100644
--- a/scripts/build_pkg.js
+++ b/scripts/build_pkg.ts
@@ -1,8 +1,11 @@
// @ts-check
'use strict'
-const path = require('path');
-const fs = require('fs');
+import path from 'path';
+import fs from 'fs';
+import { fileURLToPath } from 'url';
+
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
(async () => {
const { execa } = await import('execa');
@@ -10,7 +13,7 @@ const fs = require('fs');
const { stdout } = await execa('pkg', ['..', '--out-path', '../Releases'], { cwd: __dirname });
const lines = stdout.split(/[\r\n]+/);
- const addons = [];
+ const addons: string[] = [];
for (let i = 0; i < lines.length - 1; i++) {
const line = lines[i]?.trim();
@@ -37,7 +40,7 @@ const fs = require('fs');
if (addons.length) {
await cpy(addons, path.join(__dirname, '../Releases'));
}
-})().catch((e) => {
+})().catch((e: any) => {
console.error('Build failed with error:');
console.error(e.message || e);
if (e.stderr) console.error('STDERR:', e.stderr);
diff --git a/scripts/hodd-server.js b/scripts/hodd-server.ts
similarity index 92%
rename from scripts/hodd-server.js
rename to scripts/hodd-server.ts
index 943df3b..78b88f7 100644
--- a/scripts/hodd-server.js
+++ b/scripts/hodd-server.ts
@@ -6,12 +6,15 @@
* Downloads and serves Hodd from GitHub if not present
*/
-const http = require('http');
-const fs = require('fs');
-const path = require('path');
-const https = require('https');
-const { spawnSync } = require('child_process');
-const os = require('os');
+import http from 'http';
+import fs from 'fs';
+import path from 'path';
+import https from 'https';
+import { spawnSync } from 'child_process';
+import os from 'os';
+import { fileURLToPath } from 'url';
+
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
const PORT = process.env.HODD_PORT || 8080;
const HODD_DIR = path.join(__dirname, '../.e2e/hodd');
@@ -19,8 +22,7 @@ const HODD_ZIP_URL = 'https://github.com/rroemhild/hodd/archive/refs/heads/maste
const HODD_ZIP_PATH = path.join(os.tmpdir(), 'hodd-master.zip');
// MIME types for static files
-/** @type {Object.} */
-const MIME_TYPES = {
+const MIME_TYPES: Record = {
'.html': 'text/html',
'.css': 'text/css',
'.js': 'application/javascript',
@@ -186,7 +188,7 @@ async function ensureHoddExists() {
await downloadHoddZip();
extractZip();
flattenExtractedFolder();
- } catch (err) {
+ } catch (err: any) {
console.warn(`Hodd auto-download failed: ${err.message}`);
console.warn('Falling back to placeholder UI.');
createPlaceholder(indexPath);
@@ -203,11 +205,11 @@ async function ensureHoddExists() {
* @param {http.ServerResponse} res
* @param {string} filePath
*/
-function serveStaticFile(res, filePath) {
+function serveStaticFile(res: http.ServerResponse, filePath: string) {
const ext = path.extname(filePath);
const contentType = MIME_TYPES[ext] || 'application/octet-stream';
- fs.readFile(filePath, (err, data) => {
+ fs.readFile(filePath, (err: any, data: Buffer) => {
if (err) {
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end('404 Not Found');
@@ -219,8 +221,8 @@ function serveStaticFile(res, filePath) {
}
// Create HTTP server
-const server = http.createServer((req, res) => {
- let filePath = path.join(HODD_DIR, (req.url === '/' || !req.url) ? 'index.html' : req.url);
+const server = http.createServer((req: http.IncomingMessage, res: http.ServerResponse) => {
+ let filePath = path.join(HODD_DIR, (req.url === '/' || !req.url) ? 'index.html' : req.url || '');
// Security: prevent directory traversal
if (!filePath.startsWith(HODD_DIR)) {
diff --git a/scripts/mqtt-broker.js b/scripts/mqtt-broker.ts
similarity index 90%
rename from scripts/mqtt-broker.js
rename to scripts/mqtt-broker.ts
index cdf1104..5e97499 100644
--- a/scripts/mqtt-broker.js
+++ b/scripts/mqtt-broker.ts
@@ -6,12 +6,15 @@
* Runs a local MQTT broker with persistence
*/
-const aedes = require('aedes');
-const net = require('net');
-const http = require('http');
-const ws = require('ws');
-const path = require('path');
-const fs = require('fs');
+import aedes from 'aedes';
+import net from 'net';
+import http from 'http';
+import ws from 'ws';
+import path from 'path';
+import fs from 'fs';
+import { fileURLToPath } from 'url';
+
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
const PORT = process.env.MQTT_PORT || 1883;
const WS_PORT = process.env.MQTT_WS_PORT || 8084;
diff --git a/src/config/config.ts b/src/config/config.ts
index 8cd154e..ae3246b 100644
--- a/src/config/config.ts
+++ b/src/config/config.ts
@@ -1,11 +1,14 @@
// @ts-nocheck
'use strict';
-const { isAbsolute, resolve, join, parse, relative, sep, dirname } = require('path');
-const JsonRef = require('json-ref-lite');
-const json5 = require('json5');
+import { isAbsolute, resolve, join, parse, relative, sep, dirname as pathDirname } from 'path';
+import { fileURLToPath } from 'url';
+import JsonRef from 'json-ref-lite';
+import json5 from 'json5';
const { parse: _parse } = json5;
-const { readFileSync } = require('fs');
+import { readFileSync } from 'fs';
+
+const __dirname = pathDirname(fileURLToPath(import.meta.url));
const readJson = function(/** @type {string} */ jsonpath){
const resolvedPath = isAbsolute(jsonpath) ? jsonpath : resolve(jsonpath);
@@ -16,7 +19,7 @@ const readJson = function(/** @type {string} */ jsonpath){
try {
// Change to the directory of the JSON file to resolve relative $refs correctly
- process.chdir(dirname(resolvedPath));
+ process.chdir(pathDirname(resolvedPath));
const resolver = new JsonRef();
return resolver.resolve(_parse(data.toString()));
@@ -98,8 +101,9 @@ if (typeof process.env.NAME === 'string') {
config.device_id = process.env.NAME;
}
-module.exports = {
+export default {
runInPKG,
- config,
- default: { runInPKG, config }
+ config
};
+
+export { runInPKG, config };
diff --git a/src/config/master_config.ts b/src/config/master_config.ts
index 78977d2..db8d6f6 100644
--- a/src/config/master_config.ts
+++ b/src/config/master_config.ts
@@ -31,8 +31,10 @@ const FunctionCode = {
* @type {{ master: { interval: any; timeout: any; addressingoffset: any; requests: any[]; unit_id: number; }; mqtt: { debug: any; }; }}
*/
// @ts-ignore - TODO: fix variable name conflict
-const config = require('./config').default.config;
-const util = require('../utils/modbus_data_tools');
+import configDefault from './config.js';
+import * as util from '../utils/modbus_data_tools.js';
+
+const config = configDefault.config;
const INTERVAL = (config.master.interval && typeof config.master.interval === 'number') ? config.master.interval : 1000;//polling delay in ms
const MAXRETRIES = 10;
@@ -584,7 +586,7 @@ function setRequest(master, mqttclient) {
}
}
-module.exports = setRequest;
+export default setRequest;
/**
* Compute node name
diff --git a/src/config/slave_config.ts b/src/config/slave_config.ts
index d37e689..9de5e42 100644
--- a/src/config/slave_config.ts
+++ b/src/config/slave_config.ts
@@ -1,9 +1,11 @@
// @ts-nocheck
'use strict'
-const config = require('./config').config;
-const Slave = require('../core/slave');
-const util = require('../utils/modbus_data_tools');
+import configDefault from './config.js';
+import Slave from '../core/slave.js';
+import * as util from '../utils/modbus_data_tools.js';
+
+const config = configDefault.config;
function setUnitToData(unittodata, mqttclient) {
const ADR_OFFSET = config.slave.addressingoffset && config.slave.addressingoffset && typeof config.slave.addressingoffset === 'number' ? config.slave.addressingoffset : 0;
@@ -175,4 +177,4 @@ function setUnitToData(unittodata, mqttclient) {
}
-module.exports = setUnitToData;
\ No newline at end of file
+export default setUnitToData;
\ No newline at end of file
diff --git a/src/core/master.ts b/src/core/master.ts
index 4eda067..a0a6cdc 100644
--- a/src/core/master.ts
+++ b/src/core/master.ts
@@ -3,10 +3,11 @@
'use strict';
-const modbus = require('h5.modbus');
+import modbus from 'h5.modbus';
+import stats from './stats.js';
+
const CONCURRENT_TRANSACTIONS = 20;
const DEFAULT_UNIT = 1;
-const stats = require('./stats');
/**
* Master implementation of modbus tcp-udp simulator
@@ -141,4 +142,4 @@ class MasterSimulator {
}
}
-module.exports = MasterSimulator;
+export default MasterSimulator;
diff --git a/src/core/slave.ts b/src/core/slave.ts
index be0adce..17d82d1 100644
--- a/src/core/slave.ts
+++ b/src/core/slave.ts
@@ -3,9 +3,9 @@
'use strict';
-const stats = require('./stats');
-const modbus = require('h5.modbus');
-const events = require('events');
+import stats from './stats.js';
+import modbus from 'h5.modbus';
+import * as events from 'events';
const ExceptionCode = modbus.ExceptionCode;
const FunctionCode = modbus.FunctionCode;
const MAX_BUFFER_OVERFLOWS = Number.MAX_SAFE_INTEGER;
@@ -483,4 +483,4 @@ handleReadWriteMultipleRegistersRequest(unit, request, functionData, respond)
*/
}
-module.exports = SlaveSimulator;
+export default SlaveSimulator;
diff --git a/src/core/stats.ts b/src/core/stats.ts
index 6d779cc..6b95602 100644
--- a/src/core/stats.ts
+++ b/src/core/stats.ts
@@ -2,7 +2,7 @@
'use strict'
-module.exports = {
+const stats = {
startTime: Date.now(),
@@ -85,3 +85,5 @@ module.exports = {
}
}
+
+export default stats;
diff --git a/src/package.json b/src/package.json
new file mode 100644
index 0000000..3dbc1ca
--- /dev/null
+++ b/src/package.json
@@ -0,0 +1,3 @@
+{
+ "type": "module"
+}
diff --git a/src/utils/modbus_data_tools.ts b/src/utils/modbus_data_tools.ts
index 0a0820e..1c74f3e 100644
--- a/src/utils/modbus_data_tools.ts
+++ b/src/utils/modbus_data_tools.ts
@@ -319,19 +319,4 @@ export function CheckOffsetReadWriteProperties(entry: RegisterEntry): void {
}
}
-// Export as CommonJS for backward compatibility
-module.exports = {
- setBit,
- readBit,
- writeValueToRegister,
- readValueFromRegister,
- readFromRegister,
- getRegisterAddress,
- getBufferAddress,
- getValueFromRegistery,
- CheckOffsetReadWriteProperties,
- OutOfRangeError,
- getRegisterRange,
- validateRegisterRange,
- getRegisterSize
-};
+// All functions and classes are exported directly above via 'export function/class'
diff --git a/test/e2e/modbus-mqtt.test.ts b/test/e2e/modbus-mqtt.test.ts
index 7b46920..74b393a 100644
--- a/test/e2e/modbus-mqtt.test.ts
+++ b/test/e2e/modbus-mqtt.test.ts
@@ -33,7 +33,11 @@ describe('ModbusSimulator - E2E Tests', function () {
const service = spawn(cmd, args, {
stdio: ['ignore', 'pipe', 'pipe'],
- detached: false
+ detached: false,
+ env: {
+ ...process.env,
+ NODE_OPTIONS: '--loader=ts-node/esm'
+ }
});
service.stdout?.on('data', (data) => {
@@ -69,7 +73,7 @@ describe('ModbusSimulator - E2E Tests', function () {
await startService(
'MQTT Broker',
'node',
- ['scripts/mqtt-broker.js'],
+ ['scripts/mqtt-broker.ts'],
path.join(logDir, 'mqtt', 'mqtt-broker.log'),
1000,
false
diff --git a/tsconfig.json b/tsconfig.json
index 5c41e99..1ea467c 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,6 +1,6 @@
{
"compilerOptions": {
- "module": "commonjs",
+ "module": "esnext",
"target": "es2020",
"noImplicitAny": false,
"removeComments": true,
From 83ac4e0d46d8aaf6cad3f2a7443f867f89f1693d Mon Sep 17 00:00:00 2001
From: Pierre Leduc
Date: Wed, 21 Jan 2026 10:28:24 +0100
Subject: [PATCH 09/12] Switch to bun package
---
.github/workflows/node.js.yml | 1 +
.github/workflows/release.yml | 154 +-
ModbusSimulator.cjs | 12 +
ModbusSimulator.ts | 25 +-
Releases_package.json | 3 +
bun.lock | 915 +++++++
dist/appconfig.json | 17 +
dist/default-config.json | 25 +
dist/package.json | 3 +
package-lock.json | 4584 ---------------------------------
package.json | 22 +-
readme.md | 16 +-
scripts/build_pkg.ts | 112 +-
scripts/mqtt-broker.ts | 6 +-
scripts/package.json | 3 +
test/e2e/modbus-mqtt.test.ts | 6 +-
tsconfig.json | 1 +
tsconfig.pkg.json | 20 +
18 files changed, 1201 insertions(+), 4724 deletions(-)
create mode 100644 ModbusSimulator.cjs
create mode 100644 Releases_package.json
create mode 100644 bun.lock
create mode 100644 dist/appconfig.json
create mode 100644 dist/default-config.json
create mode 100644 dist/package.json
delete mode 100644 package-lock.json
create mode 100644 scripts/package.json
create mode 100644 tsconfig.pkg.json
diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml
index 339fd9b..ea596e8 100644
--- a/.github/workflows/node.js.yml
+++ b/.github/workflows/node.js.yml
@@ -20,6 +20,7 @@ jobs:
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
+ - uses: oven-sh/bun@v2
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index a42a718..8587983 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -6,68 +6,98 @@ on:
- 'v*'
jobs:
- build-and-release:
+ build-linux:
runs-on: ubuntu-latest
-
- strategy:
- matrix:
- node-version: [18.x]
+ steps:
+ - uses: actions/checkout@v4
+ - uses: oven-sh/bun@v2
+
+ - name: Install dependencies (bun)
+ run: bun install
+
+ - name: Run tests (e2e)
+ run: bun run test:e2e
+
+ - name: Build release (linux)
+ run: bun run build
+
+ - name: Package linux artifacts
+ run: |
+ tar -czf linux-release.tar.gz -C Releases .
+
+ - name: Upload linux artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: linux-release
+ path: linux-release.tar.gz
+
+ build-windows:
+ runs-on: windows-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: oven-sh/bun@v2
+
+ - name: Install dependencies (bun)
+ run: bun install
+ - name: Run tests (e2e)
+ run: bun run test:e2e
+
+ - name: Build release (windows)
+ run: bun run build
+
+ - name: Package windows artifacts
+ shell: pwsh
+ run: |
+ Compress-Archive -Path "Releases/*" -DestinationPath windows-release.zip
+
+ - name: Upload windows artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: windows-release
+ path: windows-release.zip
+
+ create-release:
+ runs-on: ubuntu-latest
+ needs: [build-linux, build-windows]
steps:
- - uses: actions/checkout@v4
-
- - name: Use Node.js ${{ matrix.node-version }}
- uses: actions/setup-node@v4
- with:
- node-version: ${{ matrix.node-version }}
- cache: 'npm'
-
- - name: Install dependencies
- run: npm ci
-
- - name: Run tests
- run: npm test
-
- - name: Build release
- run: npm run build
-
- - name: Create Release
- id: create_release
- uses: actions/create-release@v1
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- tag_name: ${{ github.ref_name }}
- release_name: Release ${{ github.ref_name }}
- draft: false
- prerelease: false
-
- - name: Upload Windows executable
- uses: actions/upload-release-asset@v1
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- upload_url: ${{ steps.create_release.outputs.upload_url }}
- asset_path: ./Releases/modbussimulator-win.exe
- asset_name: modbussimulator-win.exe
- asset_content_type: application/octet-stream
-
- - name: Upload Linux executable
- uses: actions/upload-release-asset@v1
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- upload_url: ${{ steps.create_release.outputs.upload_url }}
- asset_path: ./Releases/modbussimulator-linux
- asset_name: modbussimulator-linux
- asset_content_type: application/octet-stream
-
- - name: Upload schema files
- uses: actions/upload-release-asset@v1
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- upload_url: ${{ steps.create_release.outputs.upload_url }}
- asset_path: ./Releases
- asset_name: schemas.tar.gz
- asset_content_type: application/gzip
+ - name: Download linux artifact
+ uses: actions/download-artifact@v4
+ with:
+ name: linux-release
+
+ - name: Download windows artifact
+ uses: actions/download-artifact@v4
+ with:
+ name: windows-release
+
+ - name: Create Release
+ id: create_release
+ uses: actions/create-release@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ tag_name: ${{ github.ref_name }}
+ release_name: Release ${{ github.ref_name }}
+ draft: false
+ prerelease: false
+
+ - name: Upload Linux bundle
+ uses: actions/upload-release-asset@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
+ asset_path: linux-release.tar.gz
+ asset_name: linux-release.tar.gz
+ asset_content_type: application/gzip
+
+ - name: Upload Windows bundle
+ uses: actions/upload-release-asset@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
+ asset_path: windows-release.zip
+ asset_name: windows-release.zip
+ asset_content_type: application/zip
diff --git a/ModbusSimulator.cjs b/ModbusSimulator.cjs
new file mode 100644
index 0000000..96fa7b6
--- /dev/null
+++ b/ModbusSimulator.cjs
@@ -0,0 +1,12 @@
+// Pure CommonJS wrapper for pkg bootstrap
+// This file is only used by pkg; the main app uses ModbusSimulator.js
+// We dynamically import the ES module
+
+(async () => {
+ try {
+ await import('./ModbusSimulator.js');
+ } catch (err) {
+ console.error('Failed to load ModbusSimulator:', err);
+ process.exit(1);
+ }
+})();
diff --git a/ModbusSimulator.ts b/ModbusSimulator.ts
index 94e4b8a..cf0fc37 100644
--- a/ModbusSimulator.ts
+++ b/ModbusSimulator.ts
@@ -1,7 +1,5 @@
// @ts-nocheck
'use strict';
-
-import pjson from './package.json' assert { type: 'json' };
import Master from './src/core/master.js';
import Slave from './src/core/slave.js';
// @ts-ignore - TODO: fix variable name conflict with master_config
@@ -9,9 +7,13 @@ import configDefault from './src/config/config.js';
import path from 'path';
import { createRequire } from 'module';
import { fileURLToPath } from 'url';
+import HomieDevice from 'homie-device';
-const __dirname = path.dirname(fileURLToPath(import.meta.url));
-const require = createRequire(import.meta.url);
+// Handle both ESM and CommonJS environments
+const req = typeof require === 'function'
+ ? require
+ : createRequire(typeof __filename !== 'undefined' ? __filename : import.meta.url);
+const pjson = req('./package.json');
const config = configDefault.config;
const runInPKG = configDefault.runInPKG;
@@ -24,7 +26,6 @@ const SLAVE_CONFIGFILE = config.slave && config.slave.script && typeof config.sl
: null; //par défaut pas de script spécifique
//add MQTT capacities
-const HomieDevice = require('homie-device');
let mqtt_client = null;
let slv = null;
let mst = null;
@@ -47,8 +48,7 @@ async function main() {
}
if (config.slave) {
- const slaveConfigModule = await import('./src/config/slave_config.js');
- let slave_config = slaveConfigModule.default;
+ let slave_config = (await import('./src/config/slave_config.js')).default;
slv = new Slave(config.slave);//initialisation de l'esclave
if (config.slave.data) {
slave_config(slv.UNIT_TO_DATA, mqtt_client); //appel de la config pré-définie en interne
@@ -57,17 +57,16 @@ async function main() {
if (SLAVE_CONFIGFILE) {
if (runInPKG) {
const deployPath = path.dirname(process.execPath);
- slave_config = require(path.join(deployPath, SLAVE_CONFIGFILE));
+ slave_config = req(path.join(deployPath, SLAVE_CONFIGFILE));
}
else {
- slave_config = require(SLAVE_CONFIGFILE);
+ slave_config = (await import(SLAVE_CONFIGFILE)).default;
}
slave_config(slv.UNIT_TO_DATA, mqtt_client);
}
}
if (config.master) {
- const masterConfigModule = await import('./src/config/master_config.js');
- let master_config = masterConfigModule.default;
+ let master_config = (await import('./src/config/master_config.js')).default;
mst = new Master(config.master);
if (config.master.requests) {
master_config(mst, mqtt_client); //appel de la config pré-définie en interne
@@ -76,10 +75,10 @@ async function main() {
if (MASTER_CONFIGFILE) {
if (runInPKG) {
const deployPath = path.dirname(process.execPath);
- master_config = require(path.join(deployPath, MASTER_CONFIGFILE));
+ master_config = req(path.join(deployPath, MASTER_CONFIGFILE));
}
else {
- master_config = require(MASTER_CONFIGFILE);
+ master_config = (await import(MASTER_CONFIGFILE)).default;
}
master_config(mst, mqtt_client);
diff --git a/Releases_package.json b/Releases_package.json
new file mode 100644
index 0000000..3dbc1ca
--- /dev/null
+++ b/Releases_package.json
@@ -0,0 +1,3 @@
+{
+ "type": "module"
+}
diff --git a/bun.lock b/bun.lock
new file mode 100644
index 0000000..4096144
--- /dev/null
+++ b/bun.lock
@@ -0,0 +1,915 @@
+{
+ "lockfileVersion": 1,
+ "configVersion": 0,
+ "workspaces": {
+ "": {
+ "name": "modbussimulator",
+ "dependencies": {
+ "aedes": "^0.51.0",
+ "h5.buffers": "^0.1.1",
+ "h5.modbus": "github:morkai/h5.modbus",
+ "homie-device": "^3.0.1",
+ "json-ref-lite": "^1.0.58",
+ "json5": "^2.2.3",
+ "mqtt": "^5.3.4",
+ "serialport": "^12.0.0",
+ "sync-request": "^6.1.0",
+ "ws": "^8.19.0",
+ },
+ "devDependencies": {
+ "@types/chai": "^4.3.20",
+ "@types/mocha": "^10.0.10",
+ "@types/node": "^20.10.6",
+ "chai": "^4.5.0",
+ "concurrently": "^9.2.1",
+ "cpy": "^11.0.1",
+ "execa": "^8.0.1",
+ "mocha": "^10.8.2",
+ "pkg": "^5.8.1",
+ "ts-node": "^10.9.2",
+ "typescript": "^5.3.3",
+ },
+ },
+ },
+ "packages": {
+ "@babel/generator": ["@babel/generator@7.18.2", "", { "dependencies": { "@babel/types": "^7.18.2", "@jridgewell/gen-mapping": "^0.3.0", "jsesc": "^2.5.1" } }, "sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw=="],
+
+ "@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="],
+
+ "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="],
+
+ "@babel/parser": ["@babel/parser@7.18.4", "", { "bin": { "parser": "bin/babel-parser.js" } }, "sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow=="],
+
+ "@babel/runtime": ["@babel/runtime@7.28.4", "", {}, "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ=="],
+
+ "@babel/types": ["@babel/types@7.19.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.18.10", "@babel/helper-validator-identifier": "^7.18.6", "to-fast-properties": "^2.0.0" } }, "sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA=="],
+
+ "@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="],
+
+ "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
+
+ "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
+
+ "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
+
+ "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.9", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="],
+
+ "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
+
+ "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
+
+ "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
+
+ "@serialport/binding-mock": ["@serialport/binding-mock@10.2.2", "", { "dependencies": { "@serialport/bindings-interface": "^1.2.1", "debug": "^4.3.3" } }, "sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw=="],
+
+ "@serialport/bindings-cpp": ["@serialport/bindings-cpp@12.0.1", "", { "dependencies": { "@serialport/bindings-interface": "1.2.2", "@serialport/parser-readline": "11.0.0", "debug": "4.3.4", "node-addon-api": "7.0.0", "node-gyp-build": "4.6.0" } }, "sha512-r2XOwY2dDvbW7dKqSPIk2gzsr6M6Qpe9+/Ngs94fNaNlcTRCV02PfaoDmRgcubpNVVcLATlxSxPTIDw12dbKOg=="],
+
+ "@serialport/bindings-interface": ["@serialport/bindings-interface@1.2.2", "", {}, "sha512-CJaUd5bLvtM9c5dmO9rPBHPXTa9R2UwpkJ0wdh9JCYcbrPWsKz+ErvR0hBLeo7NPeiFdjFO4sonRljiw4d2XiA=="],
+
+ "@serialport/parser-byte-length": ["@serialport/parser-byte-length@12.0.0", "", {}, "sha512-0ei0txFAj+s6FTiCJFBJ1T2hpKkX8Md0Pu6dqMrYoirjPskDLJRgZGLqoy3/lnU1bkvHpnJO+9oJ3PB9v8rNlg=="],
+
+ "@serialport/parser-cctalk": ["@serialport/parser-cctalk@12.0.0", "", {}, "sha512-0PfLzO9t2X5ufKuBO34DQKLXrCCqS9xz2D0pfuaLNeTkyGUBv426zxoMf3rsMRodDOZNbFblu3Ae84MOQXjnZw=="],
+
+ "@serialport/parser-delimiter": ["@serialport/parser-delimiter@12.0.0", "", {}, "sha512-gu26tVt5lQoybhorLTPsH2j2LnX3AOP2x/34+DUSTNaUTzu2fBXw+isVjQJpUBFWu6aeQRZw5bJol5X9Gxjblw=="],
+
+ "@serialport/parser-inter-byte-timeout": ["@serialport/parser-inter-byte-timeout@12.0.0", "", {}, "sha512-GnCh8K0NAESfhCuXAt+FfBRz1Cf9CzIgXfp7SdMgXwrtuUnCC/yuRTUFWRvuzhYKoAo1TL0hhUo77SFHUH1T/w=="],
+
+ "@serialport/parser-packet-length": ["@serialport/parser-packet-length@12.0.0", "", {}, "sha512-p1hiCRqvGHHLCN/8ZiPUY/G0zrxd7gtZs251n+cfNTn+87rwcdUeu9Dps3Aadx30/sOGGFL6brIRGK4l/t7MuQ=="],
+
+ "@serialport/parser-readline": ["@serialport/parser-readline@12.0.0", "", { "dependencies": { "@serialport/parser-delimiter": "12.0.0" } }, "sha512-O7cywCWC8PiOMvo/gglEBfAkLjp/SENEML46BXDykfKP5mTPM46XMaX1L0waWU6DXJpBgjaL7+yX6VriVPbN4w=="],
+
+ "@serialport/parser-ready": ["@serialport/parser-ready@12.0.0", "", {}, "sha512-ygDwj3O4SDpZlbrRUraoXIoIqb8sM7aMKryGjYTIF0JRnKeB1ys8+wIp0RFMdFbO62YriUDextHB5Um5cKFSWg=="],
+
+ "@serialport/parser-regex": ["@serialport/parser-regex@12.0.0", "", {}, "sha512-dCAVh4P/pZrLcPv9NJ2mvPRBg64L5jXuiRxIlyxxdZGH4WubwXVXY/kBTihQmiAMPxbT3yshSX8f2+feqWsxqA=="],
+
+ "@serialport/parser-slip-encoder": ["@serialport/parser-slip-encoder@12.0.0", "", {}, "sha512-0APxDGR9YvJXTRfY+uRGhzOhTpU5akSH183RUcwzN7QXh8/1jwFsFLCu0grmAUfi+fItCkR+Xr1TcNJLR13VNA=="],
+
+ "@serialport/parser-spacepacket": ["@serialport/parser-spacepacket@12.0.0", "", {}, "sha512-dozONxhPC/78pntuxpz/NOtVps8qIc/UZzdc/LuPvVsqCoJXiRxOg6ZtCP/W58iibJDKPZPAWPGYeZt9DJxI+Q=="],
+
+ "@serialport/stream": ["@serialport/stream@12.0.0", "", { "dependencies": { "@serialport/bindings-interface": "1.2.2", "debug": "4.3.4" } }, "sha512-9On64rhzuqKdOQyiYLYv2lQOh3TZU/D3+IWCR5gk0alPel2nwpp4YwDEGiUBfrQZEdQ6xww0PWkzqth4wqwX3Q=="],
+
+ "@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@2.3.0", "", {}, "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg=="],
+
+ "@tsconfig/node10": ["@tsconfig/node10@1.0.12", "", {}, "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ=="],
+
+ "@tsconfig/node12": ["@tsconfig/node12@1.0.11", "", {}, "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag=="],
+
+ "@tsconfig/node14": ["@tsconfig/node14@1.0.3", "", {}, "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow=="],
+
+ "@tsconfig/node16": ["@tsconfig/node16@1.0.4", "", {}, "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA=="],
+
+ "@types/chai": ["@types/chai@4.3.20", "", {}, "sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ=="],
+
+ "@types/concat-stream": ["@types/concat-stream@1.6.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA=="],
+
+ "@types/form-data": ["@types/form-data@0.0.33", "", { "dependencies": { "@types/node": "*" } }, "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw=="],
+
+ "@types/mocha": ["@types/mocha@10.0.10", "", {}, "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q=="],
+
+ "@types/node": ["@types/node@20.19.28", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-VyKBr25BuFDzBFCK5sUM6ZXiWfqgCTwTAOK8qzGV/m9FCirXYDlmczJ+d5dXBAQALGCdRRdbteKYfJ84NGEusw=="],
+
+ "@types/qs": ["@types/qs@6.14.0", "", {}, "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ=="],
+
+ "@types/readable-stream": ["@types/readable-stream@4.0.23", "", { "dependencies": { "@types/node": "*" } }, "sha512-wwXrtQvbMHxCbBgjHaMGEmImFTQxxpfMOR/ZoQnXxB1woqkUbdLGFDgauo00Py9IudiaqSeiBiulSV9i6XIPig=="],
+
+ "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="],
+
+ "abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="],
+
+ "acorn": ["acorn@8.15.0", "", { "bin": "bin/acorn" }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
+
+ "acorn-walk": ["acorn-walk@8.3.4", "", { "dependencies": { "acorn": "^8.11.0" } }, "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g=="],
+
+ "aedes": ["aedes@0.51.3", "", { "dependencies": { "aedes-packet": "^3.0.0", "aedes-persistence": "^9.1.2", "end-of-stream": "^1.4.4", "fastfall": "^1.5.1", "fastparallel": "^2.4.1", "fastseries": "^2.0.0", "hyperid": "^3.2.0", "mqemitter": "^6.0.0", "mqtt-packet": "^9.0.0", "retimer": "^4.0.0", "reusify": "^1.0.4", "uuid": "^10.0.0" } }, "sha512-aQfiI9w3RbqnowNCdcGMmCtxBFXN9bhJFcuZm24U5/NU06V3MCl42jWK2GUnu8rOypR2Ahi/aEcgq3w7CMcycg=="],
+
+ "aedes-packet": ["aedes-packet@3.0.0", "", { "dependencies": { "mqtt-packet": "^7.0.0" } }, "sha512-swASey0BxGs4/npZGWoiVDmnEyPvVFIRY6l2LVKL4rbiW8IhcIGDLfnb20Qo8U20itXlitAKPQ3MVTEbOGG5ZA=="],
+
+ "aedes-persistence": ["aedes-persistence@9.1.2", "", { "dependencies": { "aedes-packet": "^3.0.0", "qlobber": "^7.0.0" } }, "sha512-2Wlr5pwIK0eQOkiTwb8ZF6C20s8UPUlnsJ4kXYePZ3JlQl0NbBA176mzM8wY294BJ5wybpNc9P5XEQxqadRNcQ=="],
+
+ "agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="],
+
+ "ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="],
+
+ "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
+
+ "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
+
+ "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="],
+
+ "arg": ["arg@4.1.3", "", {}, "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="],
+
+ "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
+
+ "array-union": ["array-union@2.1.0", "", {}, "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw=="],
+
+ "asap": ["asap@2.0.6", "", {}, "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="],
+
+ "assertion-error": ["assertion-error@1.1.0", "", {}, "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw=="],
+
+ "async-limiter": ["async-limiter@1.0.1", "", {}, "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="],
+
+ "asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
+
+ "at-least-node": ["at-least-node@1.0.0", "", {}, "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg=="],
+
+ "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
+
+ "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
+
+ "binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="],
+
+ "bl": ["bl@6.1.6", "", { "dependencies": { "@types/readable-stream": "^4.0.0", "buffer": "^6.0.3", "inherits": "^2.0.4", "readable-stream": "^4.2.0" } }, "sha512-jLsPgN/YSvPUg9UX0Kd73CXpm2Psg9FxMeCSXnk3WBO3CMT10JMwijubhGfHCnFu6TPn1ei3b975dxv7K2pWVg=="],
+
+ "brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
+
+ "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
+
+ "broker-factory": ["broker-factory@3.1.12", "", { "dependencies": { "@babel/runtime": "^7.28.4", "fast-unique-numbers": "^9.0.25", "tslib": "^2.8.1", "worker-factory": "^7.0.47" } }, "sha512-5Bmeki5j2IVO+lE07dSOUMZp1ZGKkE47b3ILv4ZD0nmTdc0iTKVS1CgYPDCy5m0Qb9jIKHBaF9SUrtqg5oW+1A=="],
+
+ "browser-stdout": ["browser-stdout@1.3.1", "", {}, "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw=="],
+
+ "buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
+
+ "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="],
+
+ "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
+
+ "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="],
+
+ "callback-stream": ["callback-stream@1.1.0", "", { "dependencies": { "inherits": "^2.0.1", "readable-stream": "> 1.0.0 < 3.0.0" } }, "sha512-sAZ9kODla+mGACBZ1IpTCAisKoGnv6PykW7fPk1LrM+mMepE18Yz0515yoVcrZy7dQsTUp3uZLQ/9Sx1RnLoHw=="],
+
+ "camelcase": ["camelcase@6.3.0", "", {}, "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="],
+
+ "caseless": ["caseless@0.12.0", "", {}, "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="],
+
+ "chai": ["chai@4.5.0", "", { "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.3", "deep-eql": "^4.1.3", "get-func-name": "^2.0.2", "loupe": "^2.3.6", "pathval": "^1.1.1", "type-detect": "^4.1.0" } }, "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw=="],
+
+ "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
+
+ "check-error": ["check-error@1.0.3", "", { "dependencies": { "get-func-name": "^2.0.2" } }, "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg=="],
+
+ "chokidar": ["chokidar@3.6.0", "", { "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" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="],
+
+ "chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="],
+
+ "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="],
+
+ "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
+
+ "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
+
+ "combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="],
+
+ "commist": ["commist@3.2.0", "", {}, "sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw=="],
+
+ "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
+
+ "concat-stream": ["concat-stream@2.0.0", "", { "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.0.2", "typedarray": "^0.0.6" } }, "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A=="],
+
+ "concurrently": ["concurrently@9.2.1", "", { "dependencies": { "chalk": "4.1.2", "rxjs": "7.8.2", "shell-quote": "1.8.3", "supports-color": "8.1.1", "tree-kill": "1.2.2", "yargs": "17.7.2" }, "bin": { "conc": "dist/bin/concurrently.js", "concurrently": "dist/bin/concurrently.js" } }, "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng=="],
+
+ "copy-file": ["copy-file@11.1.0", "", { "dependencies": { "graceful-fs": "^4.2.11", "p-event": "^6.0.0" } }, "sha512-X8XDzyvYaA6msMyAM575CUoygY5b44QzLcGRKsK3MFmXcOvQa518dNPLsKYwkYsn72g3EiW+LE0ytd/FlqWmyw=="],
+
+ "core-util-is": ["core-util-is@1.0.2", "", {}, "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="],
+
+ "cpy": ["cpy@11.1.0", "", { "dependencies": { "copy-file": "^11.0.0", "globby": "^14.0.2", "junk": "^4.0.1", "micromatch": "^4.0.7", "p-filter": "^4.1.0", "p-map": "^7.0.2" } }, "sha512-QGHetPSSuprVs+lJmMDcivvrBwTKASzXQ5qxFvRC2RFESjjod71bDvFvhxTjDgkNjrrb72AI6JPjfYwxrIy33A=="],
+
+ "create-require": ["create-require@1.1.1", "", {}, "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ=="],
+
+ "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
+
+ "d": ["d@1.0.2", "", { "dependencies": { "es5-ext": "^0.10.64", "type": "^2.7.2" } }, "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw=="],
+
+ "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
+
+ "decamelize": ["decamelize@4.0.0", "", {}, "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ=="],
+
+ "decompress-response": ["decompress-response@6.0.0", "", { "dependencies": { "mimic-response": "^3.1.0" } }, "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ=="],
+
+ "deep-eql": ["deep-eql@4.1.4", "", { "dependencies": { "type-detect": "^4.0.0" } }, "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg=="],
+
+ "deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="],
+
+ "delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
+
+ "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
+
+ "diff": ["diff@5.2.0", "", {}, "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A=="],
+
+ "dir-glob": ["dir-glob@3.0.1", "", { "dependencies": { "path-type": "^4.0.0" } }, "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA=="],
+
+ "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
+
+ "duplexify": ["duplexify@3.7.1", "", { "dependencies": { "end-of-stream": "^1.0.0", "inherits": "^2.0.1", "readable-stream": "^2.0.0", "stream-shift": "^1.0.0" } }, "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g=="],
+
+ "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
+
+ "end-of-stream": ["end-of-stream@1.4.4", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q=="],
+
+ "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
+
+ "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
+
+ "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
+
+ "es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="],
+
+ "es5-ext": ["es5-ext@0.10.64", "", { "dependencies": { "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.3", "esniff": "^2.0.1", "next-tick": "^1.1.0" } }, "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg=="],
+
+ "es6-iterator": ["es6-iterator@2.0.3", "", { "dependencies": { "d": "1", "es5-ext": "^0.10.35", "es6-symbol": "^3.1.1" } }, "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g=="],
+
+ "es6-map": ["es6-map@0.1.5", "", { "dependencies": { "d": "1", "es5-ext": "~0.10.14", "es6-iterator": "~2.0.1", "es6-set": "~0.1.5", "es6-symbol": "~3.1.1", "event-emitter": "~0.3.5" } }, "sha512-mz3UqCh0uPCIqsw1SSAkB/p0rOzF/M0V++vyN7JqlPtSW/VsYgQBvVvqMLmfBuyMzTpLnNqi6JmcSizs4jy19A=="],
+
+ "es6-set": ["es6-set@0.1.6", "", { "dependencies": { "d": "^1.0.1", "es5-ext": "^0.10.62", "es6-iterator": "~2.0.3", "es6-symbol": "^3.1.3", "event-emitter": "^0.3.5", "type": "^2.7.2" } }, "sha512-TE3LgGLDIBX332jq3ypv6bcOpkLO0AslAQo7p2VqX/1N46YNsvIWgvjojjSEnWEGWMhr1qUbYeTSir5J6mFHOw=="],
+
+ "es6-symbol": ["es6-symbol@3.1.4", "", { "dependencies": { "d": "^1.0.2", "ext": "^1.7.0" } }, "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg=="],
+
+ "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
+
+ "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
+
+ "esniff": ["esniff@2.0.1", "", { "dependencies": { "d": "^1.0.1", "es5-ext": "^0.10.62", "event-emitter": "^0.3.5", "type": "^2.7.2" } }, "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg=="],
+
+ "event-emitter": ["event-emitter@0.3.5", "", { "dependencies": { "d": "1", "es5-ext": "~0.10.14" } }, "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA=="],
+
+ "event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="],
+
+ "events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="],
+
+ "execa": ["execa@8.0.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", "human-signals": "^5.0.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", "onetime": "^6.0.0", "signal-exit": "^4.1.0", "strip-final-newline": "^3.0.0" } }, "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg=="],
+
+ "expand-template": ["expand-template@2.0.3", "", {}, "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="],
+
+ "ext": ["ext@1.7.0", "", { "dependencies": { "type": "^2.7.2" } }, "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw=="],
+
+ "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="],
+
+ "fast-glob": ["fast-glob@3.3.3", "", { "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" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
+
+ "fast-unique-numbers": ["fast-unique-numbers@9.0.25", "", { "dependencies": { "@babel/runtime": "^7.28.4", "tslib": "^2.8.1" } }, "sha512-vHLSJfu0jSazb5X1jgYZIbsUd4mztxHxyFxUAPYvaYLkTsvQDn5+NbJRtfp+/tLIsUlMkD/geL2710QBxylH6w=="],
+
+ "fastfall": ["fastfall@1.5.1", "", { "dependencies": { "reusify": "^1.0.0" } }, "sha512-KH6p+Z8AKPXnmA7+Iz2Lh8ARCMr+8WNPVludm1LGkZoD2MjY6LVnRMtTKhkdzI+jr0RzQWXKzKyBJm1zoHEL4Q=="],
+
+ "fastparallel": ["fastparallel@2.4.1", "", { "dependencies": { "reusify": "^1.0.4", "xtend": "^4.0.2" } }, "sha512-qUmhxPgNHmvRjZKBFUNI0oZuuH9OlSIOXmJ98lhKPxMZZ7zS/Fi0wRHOihDSz0R1YiIOjxzOY4bq65YTcdBi2Q=="],
+
+ "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="],
+
+ "fastseries": ["fastseries@2.0.0", "", {}, "sha512-XBU9RXeoYc2/VnvMhplAxEmZLfIk7cvTBu+xwoBuTI8pL19E03cmca17QQycKIdxgwCeFA/a4u27gv1h3ya5LQ=="],
+
+ "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
+
+ "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="],
+
+ "flat": ["flat@5.0.2", "", { "bin": "cli.js" }, "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ=="],
+
+ "form-data": ["form-data@2.5.5", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.35", "safe-buffer": "^5.2.1" } }, "sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A=="],
+
+ "from2": ["from2@2.3.0", "", { "dependencies": { "inherits": "^2.0.1", "readable-stream": "^2.0.0" } }, "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g=="],
+
+ "fs-constants": ["fs-constants@1.0.0", "", {}, "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="],
+
+ "fs-extra": ["fs-extra@9.1.0", "", { "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ=="],
+
+ "fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="],
+
+ "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
+
+ "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
+
+ "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
+
+ "get-func-name": ["get-func-name@2.0.2", "", {}, "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ=="],
+
+ "get-intrinsic": ["get-intrinsic@1.3.0", "", { "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" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
+
+ "get-port": ["get-port@3.2.0", "", {}, "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg=="],
+
+ "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
+
+ "get-stream": ["get-stream@8.0.1", "", {}, "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA=="],
+
+ "github-from-package": ["github-from-package@0.0.0", "", {}, "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="],
+
+ "glob": ["glob@8.1.0", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^5.0.1", "once": "^1.3.0" } }, "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ=="],
+
+ "glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
+
+ "glob-stream": ["glob-stream@6.1.0", "", { "dependencies": { "extend": "^3.0.0", "glob": "^7.1.1", "glob-parent": "^3.1.0", "is-negated-glob": "^1.0.0", "ordered-read-streams": "^1.0.0", "pumpify": "^1.3.5", "readable-stream": "^2.1.5", "remove-trailing-separator": "^1.0.1", "to-absolute-glob": "^2.0.0", "unique-stream": "^2.0.2" } }, "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw=="],
+
+ "globby": ["globby@14.1.0", "", { "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" } }, "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA=="],
+
+ "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
+
+ "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
+
+ "h5.buffers": ["h5.buffers@0.1.1", "", {}, "sha1-JEh3MFMOSwDkm1rxcEldrPpAEb4="],
+
+ "h5.modbus": ["h5.modbus@git+ssh://git@github.com/morkai/h5.modbus.git#feaebad666a05a9626654d5e55742f0986925904", { "dependencies": { "h5.buffers": "0.x.x" } }, "feaebad666a05a9626654d5e55742f0986925904"],
+
+ "has": ["has@1.0.4", "", {}, "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ=="],
+
+ "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
+
+ "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
+
+ "has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
+
+ "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
+
+ "he": ["he@1.2.0", "", { "bin": "bin/he" }, "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="],
+
+ "help-me": ["help-me@5.0.0", "", {}, "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg=="],
+
+ "homie-device": ["homie-device@3.0.1", "", { "dependencies": { "lodash": "^4.13.1", "mqtt": "^2.11.0" } }, "sha512-ajj6kC/AgGKVxjrtg75CQge4e+oSeOaCZ9Rvl5Gy6V0AWHzsHBzm0roiTrVvC0AAZZLeWYjnQZkmUBTS1kYFxw=="],
+
+ "http-basic": ["http-basic@8.1.3", "", { "dependencies": { "caseless": "^0.12.0", "concat-stream": "^1.6.2", "http-response-object": "^3.0.1", "parse-cache-control": "^1.0.1" } }, "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw=="],
+
+ "http-response-object": ["http-response-object@3.0.2", "", { "dependencies": { "@types/node": "^10.0.3" } }, "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA=="],
+
+ "https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="],
+
+ "human-signals": ["human-signals@5.0.0", "", {}, "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ=="],
+
+ "hyperid": ["hyperid@3.3.0", "", { "dependencies": { "buffer": "^5.2.1", "uuid": "^8.3.2", "uuid-parse": "^1.1.0" } }, "sha512-7qhCVT4MJIoEsNcbhglhdmBKb09QtcmJNiIQGq7js/Khf5FtQQ9bzcAuloeqBeee7XD7JqDeve9KNlQya5tSGQ=="],
+
+ "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
+
+ "ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
+
+ "inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="],
+
+ "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
+
+ "ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="],
+
+ "into-stream": ["into-stream@6.0.0", "", { "dependencies": { "from2": "^2.3.0", "p-is-promise": "^3.0.0" } }, "sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA=="],
+
+ "ip-address": ["ip-address@10.1.0", "", {}, "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q=="],
+
+ "is-absolute": ["is-absolute@1.0.0", "", { "dependencies": { "is-relative": "^1.0.0", "is-windows": "^1.0.1" } }, "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA=="],
+
+ "is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="],
+
+ "is-core-module": ["is-core-module@2.9.0", "", { "dependencies": { "has": "^1.0.3" } }, "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A=="],
+
+ "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
+
+ "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
+
+ "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
+
+ "is-negated-glob": ["is-negated-glob@1.0.0", "", {}, "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug=="],
+
+ "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
+
+ "is-plain-obj": ["is-plain-obj@2.1.0", "", {}, "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA=="],
+
+ "is-relative": ["is-relative@1.0.0", "", { "dependencies": { "is-unc-path": "^1.0.0" } }, "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA=="],
+
+ "is-stream": ["is-stream@3.0.0", "", {}, "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="],
+
+ "is-unc-path": ["is-unc-path@1.0.0", "", { "dependencies": { "unc-path-regex": "^0.1.2" } }, "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ=="],
+
+ "is-unicode-supported": ["is-unicode-supported@0.1.0", "", {}, "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw=="],
+
+ "is-windows": ["is-windows@1.0.2", "", {}, "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="],
+
+ "isarray": ["isarray@1.0.0", "", {}, "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="],
+
+ "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
+
+ "js-sdsl": ["js-sdsl@4.3.0", "", {}, "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ=="],
+
+ "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": "bin/js-yaml.js" }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="],
+
+ "jsesc": ["jsesc@2.5.2", "", { "bin": "bin/jsesc" }, "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="],
+
+ "json-ref-lite": ["json-ref-lite@1.0.58", "", {}, "sha512-atr2VDI94j19mKbDF9kp72gfvfUs45BAfiGZUnMYZaeHtfnQu4pfVhkbvkR+sRh2XiWj7s13+ESjqP7EyE4Jrw=="],
+
+ "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="],
+
+ "json5": ["json5@2.2.3", "", { "bin": "lib/cli.js" }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
+
+ "jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="],
+
+ "junk": ["junk@4.0.1", "", {}, "sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ=="],
+
+ "leven": ["leven@2.1.0", "", {}, "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA=="],
+
+ "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
+
+ "lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="],
+
+ "log-symbols": ["log-symbols@4.1.0", "", { "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" } }, "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg=="],
+
+ "loupe": ["loupe@2.3.7", "", { "dependencies": { "get-func-name": "^2.0.1" } }, "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA=="],
+
+ "lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
+
+ "make-error": ["make-error@1.3.6", "", {}, "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="],
+
+ "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
+
+ "merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="],
+
+ "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
+
+ "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
+
+ "mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
+
+ "mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
+
+ "mimic-fn": ["mimic-fn@4.0.0", "", {}, "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw=="],
+
+ "mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="],
+
+ "minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="],
+
+ "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
+
+ "mkdirp-classic": ["mkdirp-classic@0.5.3", "", {}, "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="],
+
+ "mocha": ["mocha@10.8.2", "", { "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" } }, "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg=="],
+
+ "mqemitter": ["mqemitter@6.0.2", "", { "dependencies": { "fastparallel": "^2.4.1", "qlobber": "^8.0.1" } }, "sha512-8RGlznQx/Nb1xC3xKUFXHWov7pn7JdH++YVwlr6SLT6k3ft1h+ImGqZdVudbdKruFckIq9wheq9s4hgCivJDow=="],
+
+ "mqtt": ["mqtt@5.14.1", "", { "dependencies": { "@types/readable-stream": "^4.0.21", "@types/ws": "^8.18.1", "commist": "^3.2.0", "concat-stream": "^2.0.0", "debug": "^4.4.1", "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", "rfdc": "^1.4.1", "socks": "^2.8.6", "split2": "^4.2.0", "worker-timers": "^8.0.23", "ws": "^8.18.3" }, "bin": { "mqtt": "build/bin/mqtt.js", "mqtt_pub": "build/bin/pub.js", "mqtt_sub": "build/bin/sub.js" } }, "sha512-NxkPxE70Uq3Ph7goefQa7ggSsVzHrayCD0OyxlJgITN/EbzlZN+JEPmaAZdxP1LsIT5FamDyILoQTF72W7Nnbw=="],
+
+ "mqtt-packet": ["mqtt-packet@9.0.2", "", { "dependencies": { "bl": "^6.0.8", "debug": "^4.3.4", "process-nextick-args": "^2.0.1" } }, "sha512-MvIY0B8/qjq7bKxdN1eD+nrljoeaai+qjLJgfRn3TiMuz0pamsIWY2bFODPZMSNmabsLANXsLl4EMoWvlaTZWA=="],
+
+ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
+
+ "multistream": ["multistream@4.1.0", "", { "dependencies": { "once": "^1.4.0", "readable-stream": "^3.6.0" } }, "sha512-J1XDiAmmNpRCBfIWJv+n0ymC4ABcf/Pl+5YvC5B/D2f/2+8PtHvCNxMPKiQcZyi922Hq69J2YOpb1pTywfifyw=="],
+
+ "napi-build-utils": ["napi-build-utils@1.0.2", "", {}, "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg=="],
+
+ "next-tick": ["next-tick@1.1.0", "", {}, "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="],
+
+ "node-abi": ["node-abi@3.85.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-zsFhmbkAzwhTft6nd3VxcG0cvJsT70rL+BIGHWVq5fi6MwGrHwzqKaxXE+Hl2GmnGItnDKPPkO5/LQqjVkIdFg=="],
+
+ "node-addon-api": ["node-addon-api@7.0.0", "", {}, "sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA=="],
+
+ "node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="],
+
+ "node-gyp-build": ["node-gyp-build@4.6.0", "", { "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", "node-gyp-build-test": "build-test.js" } }, "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ=="],
+
+ "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],
+
+ "npm-run-path": ["npm-run-path@5.3.0", "", { "dependencies": { "path-key": "^4.0.0" } }, "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ=="],
+
+ "number-allocator": ["number-allocator@1.0.14", "", { "dependencies": { "debug": "^4.3.1", "js-sdsl": "4.3.0" } }, "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA=="],
+
+ "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="],
+
+ "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha1-WDsap3WWHUsROsF9nFC6753Xa9E="],
+
+ "onetime": ["onetime@6.0.0", "", { "dependencies": { "mimic-fn": "^4.0.0" } }, "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ=="],
+
+ "ordered-read-streams": ["ordered-read-streams@1.0.1", "", { "dependencies": { "readable-stream": "^2.0.1" } }, "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw=="],
+
+ "p-event": ["p-event@6.0.1", "", { "dependencies": { "p-timeout": "^6.1.2" } }, "sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w=="],
+
+ "p-filter": ["p-filter@4.1.0", "", { "dependencies": { "p-map": "^7.0.1" } }, "sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw=="],
+
+ "p-is-promise": ["p-is-promise@3.0.0", "", {}, "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ=="],
+
+ "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
+
+ "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
+
+ "p-map": ["p-map@7.0.4", "", {}, "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ=="],
+
+ "p-timeout": ["p-timeout@6.1.4", "", {}, "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg=="],
+
+ "parse-cache-control": ["parse-cache-control@1.0.1", "", {}, "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg=="],
+
+ "path-dirname": ["path-dirname@1.0.2", "", {}, "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q=="],
+
+ "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
+
+ "path-is-absolute": ["path-is-absolute@1.0.1", "", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="],
+
+ "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
+
+ "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="],
+
+ "path-type": ["path-type@6.0.0", "", {}, "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ=="],
+
+ "pathval": ["pathval@1.1.1", "", {}, "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ=="],
+
+ "picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
+
+ "pkg": ["pkg@5.8.1", "", { "dependencies": { "@babel/generator": "7.18.2", "@babel/parser": "7.18.4", "@babel/types": "7.19.0", "chalk": "^4.1.2", "fs-extra": "^9.1.0", "globby": "^11.1.0", "into-stream": "^6.0.0", "is-core-module": "2.9.0", "minimist": "^1.2.6", "multistream": "^4.1.0", "pkg-fetch": "3.4.2", "prebuild-install": "7.1.1", "resolve": "^1.22.0", "stream-meter": "^1.0.4" }, "peerDependencies": { "node-notifier": ">=9.0.1" }, "optionalPeers": ["node-notifier"], "bin": "lib-es5/bin.js" }, "sha512-CjBWtFStCfIiT4Bde9QpJy0KeH19jCfwZRJqHFDFXfhUklCx8JoFmMj3wgnEYIwGmZVNkhsStPHEOnrtrQhEXA=="],
+
+ "pkg-fetch": ["pkg-fetch@3.4.2", "", { "dependencies": { "chalk": "^4.1.2", "fs-extra": "^9.1.0", "https-proxy-agent": "^5.0.0", "node-fetch": "^2.6.6", "progress": "^2.0.3", "semver": "^7.3.5", "tar-fs": "^2.1.1", "yargs": "^16.2.0" }, "bin": "lib-es5/bin.js" }, "sha512-0+uijmzYcnhC0hStDjm/cl2VYdrmVVBpe7Q8k9YBojxmR5tG8mvR9/nooQq3QSXiQqORDVOTY3XqMEqJVIzkHA=="],
+
+ "prebuild-install": ["prebuild-install@7.1.1", "", { "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^1.0.1", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" }, "bin": "bin.js" }, "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw=="],
+
+ "process": ["process@0.11.10", "", {}, "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="],
+
+ "process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="],
+
+ "progress": ["progress@2.0.3", "", {}, "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="],
+
+ "promise": ["promise@8.3.0", "", { "dependencies": { "asap": "~2.0.6" } }, "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg=="],
+
+ "pump": ["pump@3.0.3", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA=="],
+
+ "pumpify": ["pumpify@1.5.1", "", { "dependencies": { "duplexify": "^3.6.0", "inherits": "^2.0.3", "pump": "^2.0.0" } }, "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ=="],
+
+ "qlobber": ["qlobber@7.0.1", "", {}, "sha512-FsFg9lMuMEFNKmTO9nV7tlyPhx8BmskPPjH2akWycuYVTtWaVwhW5yCHLJQ6Q+3mvw5cFX2vMfW2l9z2SiYAbg=="],
+
+ "qs": ["qs@6.14.1", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ=="],
+
+ "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
+
+ "randombytes": ["randombytes@2.1.0", "", { "dependencies": { "safe-buffer": "^5.1.0" } }, "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ=="],
+
+ "rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": "cli.js" }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="],
+
+ "readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="],
+
+ "readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
+
+ "reinterval": ["reinterval@1.1.0", "", {}, "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ=="],
+
+ "remove-trailing-separator": ["remove-trailing-separator@1.1.0", "", {}, "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw=="],
+
+ "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="],
+
+ "resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
+
+ "retimer": ["retimer@4.0.0", "", { "dependencies": { "worker-timers": "^7.0.75" } }, "sha512-fZIVtvbOsQsxNSDhpdPOX4lx5Ss2ni+S72AUBitARpFhtA3UzrAjQ6gDtypB2/+l7L+1VQgAgpvAKY66mElH0w=="],
+
+ "reusify": ["reusify@1.0.4", "", {}, "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw=="],
+
+ "rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="],
+
+ "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
+
+ "rxjs": ["rxjs@7.8.2", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA=="],
+
+ "safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
+
+ "semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
+
+ "serialize-javascript": ["serialize-javascript@6.0.2", "", { "dependencies": { "randombytes": "^2.1.0" } }, "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g=="],
+
+ "serialport": ["serialport@12.0.0", "", { "dependencies": { "@serialport/binding-mock": "10.2.2", "@serialport/bindings-cpp": "12.0.1", "@serialport/parser-byte-length": "12.0.0", "@serialport/parser-cctalk": "12.0.0", "@serialport/parser-delimiter": "12.0.0", "@serialport/parser-inter-byte-timeout": "12.0.0", "@serialport/parser-packet-length": "12.0.0", "@serialport/parser-readline": "12.0.0", "@serialport/parser-ready": "12.0.0", "@serialport/parser-regex": "12.0.0", "@serialport/parser-slip-encoder": "12.0.0", "@serialport/parser-spacepacket": "12.0.0", "@serialport/stream": "12.0.0", "debug": "4.3.4" } }, "sha512-AmH3D9hHPFmnF/oq/rvigfiAouAKyK/TjnrkwZRYSFZxNggJxwvbAbfYrLeuvq7ktUdhuHdVdSjj852Z55R+uA=="],
+
+ "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
+
+ "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
+
+ "shell-quote": ["shell-quote@1.8.3", "", {}, "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw=="],
+
+ "side-channel": ["side-channel@1.1.0", "", { "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" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="],
+
+ "side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="],
+
+ "side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="],
+
+ "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "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" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="],
+
+ "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
+
+ "simple-concat": ["simple-concat@1.0.1", "", {}, "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="],
+
+ "simple-get": ["simple-get@4.0.1", "", { "dependencies": { "decompress-response": "^6.0.0", "once": "^1.3.1", "simple-concat": "^1.0.0" } }, "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA=="],
+
+ "slash": ["slash@5.1.0", "", {}, "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg=="],
+
+ "smart-buffer": ["smart-buffer@4.2.0", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="],
+
+ "socks": ["socks@2.8.7", "", { "dependencies": { "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" } }, "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A=="],
+
+ "split2": ["split2@4.2.0", "", {}, "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="],
+
+ "stream-meter": ["stream-meter@1.0.4", "", { "dependencies": { "readable-stream": "^2.1.4" } }, "sha512-4sOEtrbgFotXwnEuzzsQBYEV1elAeFSO8rSGeTwabuX1RRn/kEq9JVH7I0MRBhKVRR0sJkr0M0QCH7yOLf9fhQ=="],
+
+ "stream-shift": ["stream-shift@1.0.3", "", {}, "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ=="],
+
+ "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
+
+ "string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="],
+
+ "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
+
+ "strip-final-newline": ["strip-final-newline@3.0.0", "", {}, "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw=="],
+
+ "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
+
+ "supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="],
+
+ "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
+
+ "sync-request": ["sync-request@6.1.0", "", { "dependencies": { "http-response-object": "^3.0.1", "sync-rpc": "^1.2.1", "then-request": "^6.0.0" } }, "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw=="],
+
+ "sync-rpc": ["sync-rpc@1.3.6", "", { "dependencies": { "get-port": "^3.1.0" } }, "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw=="],
+
+ "tar-fs": ["tar-fs@2.1.4", "", { "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ=="],
+
+ "tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="],
+
+ "then-request": ["then-request@6.0.2", "", { "dependencies": { "@types/concat-stream": "^1.6.0", "@types/form-data": "0.0.33", "@types/node": "^8.0.0", "@types/qs": "^6.2.31", "caseless": "~0.12.0", "concat-stream": "^1.6.0", "form-data": "^2.2.0", "http-basic": "^8.1.1", "http-response-object": "^3.0.1", "promise": "^8.0.0", "qs": "^6.4.0" } }, "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA=="],
+
+ "through2": ["through2@2.0.5", "", { "dependencies": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" } }, "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ=="],
+
+ "through2-filter": ["through2-filter@3.0.0", "", { "dependencies": { "through2": "~2.0.0", "xtend": "~4.0.0" } }, "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA=="],
+
+ "to-absolute-glob": ["to-absolute-glob@2.0.2", "", { "dependencies": { "is-absolute": "^1.0.0", "is-negated-glob": "^1.0.0" } }, "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA=="],
+
+ "to-fast-properties": ["to-fast-properties@2.0.0", "", {}, "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog=="],
+
+ "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
+
+ "tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="],
+
+ "tree-kill": ["tree-kill@1.2.2", "", { "bin": "cli.js" }, "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A=="],
+
+ "ts-node": ["ts-node@10.9.2", "", { "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" }, "peerDependencies": { "@swc/core": ">=1.2.50", "@swc/wasm": ">=1.2.50", "@types/node": "*", "typescript": ">=2.7" }, "optionalPeers": ["@swc/core", "@swc/wasm"], "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" } }, "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ=="],
+
+ "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
+
+ "tunnel-agent": ["tunnel-agent@0.6.0", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w=="],
+
+ "type": ["type@2.7.3", "", {}, "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ=="],
+
+ "type-detect": ["type-detect@4.1.0", "", {}, "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw=="],
+
+ "typedarray": ["typedarray@0.0.6", "", {}, "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="],
+
+ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
+
+ "unc-path-regex": ["unc-path-regex@0.1.2", "", {}, "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg=="],
+
+ "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
+
+ "unicorn-magic": ["unicorn-magic@0.3.0", "", {}, "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA=="],
+
+ "unique-stream": ["unique-stream@2.4.0", "", { "dependencies": { "json-stable-stringify-without-jsonify": "^1.0.1", "through2-filter": "3.0.0" } }, "sha512-V6QarSfeSgDipGA9EZdoIzu03ZDlOFkk+FbEP5cwgrZXN3iIkYR91IjU2EnM6rB835kGQsqHX8qncObTXV+6KA=="],
+
+ "universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="],
+
+ "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="],
+
+ "uuid": ["uuid@10.0.0", "", { "bin": "dist/bin/uuid" }, "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ=="],
+
+ "uuid-parse": ["uuid-parse@1.1.0", "", {}, "sha512-OdmXxA8rDsQ7YpNVbKSJkNzTw2I+S5WsbMDnCtIWSQaosNAcWtFuI/YK1TjzUI6nbkgiqEyh8gWngfcv8Asd9A=="],
+
+ "v8-compile-cache-lib": ["v8-compile-cache-lib@3.0.1", "", {}, "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg=="],
+
+ "webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="],
+
+ "websocket-stream": ["websocket-stream@5.2.0", "", { "dependencies": { "duplexify": "^3.6.1", "inherits": "^2.0.1", "readable-stream": "^3.0.0", "safe-buffer": "^5.1.2", "ws": "^6.1.2", "xtend": "^4.0.0" } }, "sha512-2ZfiWuEK/bTi8AhXdYh/lFEUwXtGVcbO4vWUy5XJhf7F6nCMAC8hbXXTarxrmv2BFSwdk3P3bhvgiA9wzT+GFQ=="],
+
+ "whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="],
+
+ "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
+
+ "worker-factory": ["worker-factory@7.0.47", "", { "dependencies": { "@babel/runtime": "^7.28.4", "fast-unique-numbers": "^9.0.25", "tslib": "^2.8.1" } }, "sha512-Ga5U8n7hJqovn98nlFnbyuJj66s8dCU4QOQd0dU0bje7uvrGGhOFeKtsTdB3b6fO5BD93F88rHpkBCGzgGloKw=="],
+
+ "worker-timers": ["worker-timers@8.0.28", "", { "dependencies": { "@babel/runtime": "^7.28.4", "tslib": "^2.8.1", "worker-timers-broker": "^8.0.14", "worker-timers-worker": "^9.0.12" } }, "sha512-+AuNePH2P/PuhQURf5I+SIGBty4dq2CzoQEB+bMXIQiPrYj3WhkUtIW2bSzeETFWyXJFUdQGsyFeZtit15LkOw=="],
+
+ "worker-timers-broker": ["worker-timers-broker@8.0.14", "", { "dependencies": { "@babel/runtime": "^7.28.4", "broker-factory": "^3.1.12", "fast-unique-numbers": "^9.0.25", "tslib": "^2.8.1", "worker-timers-worker": "^9.0.12" } }, "sha512-ooCGGWGcAYbWEJY2nkA60K9mZ33atvg/QIOBJ3OzdQJU5Z7/NdPFlEiMLiCYW8dpeP/qLcsaUsZzETrKNgGicg=="],
+
+ "worker-timers-worker": ["worker-timers-worker@9.0.12", "", { "dependencies": { "@babel/runtime": "^7.28.4", "tslib": "^2.8.1", "worker-factory": "^7.0.47" } }, "sha512-NBXCnKB/9CkhjWZz2dITgK94QM5GIJx+7LAlCA8mKeO6whdwmfH9S3iPEwakhn3+NOB9nHE3jQqdpKpZZJI23g=="],
+
+ "workerpool": ["workerpool@6.5.1", "", {}, "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA=="],
+
+ "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
+
+ "wrappy": ["wrappy@1.0.2", "", {}, "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="],
+
+ "ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="],
+
+ "xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="],
+
+ "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
+
+ "yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="],
+
+ "yargs-parser": ["yargs-parser@20.2.9", "", {}, "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="],
+
+ "yargs-unparser": ["yargs-unparser@2.0.0", "", { "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" } }, "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA=="],
+
+ "yn": ["yn@3.1.1", "", {}, "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q=="],
+
+ "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
+
+ "@jridgewell/gen-mapping/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
+
+ "@serialport/bindings-cpp/@serialport/parser-readline": ["@serialport/parser-readline@11.0.0", "", { "dependencies": { "@serialport/parser-delimiter": "11.0.0" } }, "sha512-rRAivhRkT3YO28WjmmG4FQX6L+KMb5/ikhyylRfzWPw0nSXy97+u07peS9CbHqaNvJkMhH1locp2H36aGMOEIA=="],
+
+ "@serialport/bindings-cpp/debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="],
+
+ "@serialport/stream/debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="],
+
+ "aedes-packet/mqtt-packet": ["mqtt-packet@7.1.2", "", { "dependencies": { "bl": "^4.0.2", "debug": "^4.1.1", "process-nextick-args": "^2.0.1" } }, "sha512-FFZbcZ2omsf4c5TxEQfcX9hI+JzDpDKPT46OmeIBpVA7+t32ey25UNqlqNXTmeZOr5BLsSIERpQQLsFWJS94SQ=="],
+
+ "bl/buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="],
+
+ "bl/readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="],
+
+ "callback-stream/readable-stream": ["readable-stream@2.3.6", "", { "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" } }, "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw=="],
+
+ "chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
+
+ "concat-stream/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
+
+ "dir-glob/path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="],
+
+ "duplexify/readable-stream": ["readable-stream@2.3.6", "", { "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" } }, "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw=="],
+
+ "form-data/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
+
+ "from2/readable-stream": ["readable-stream@2.3.6", "", { "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" } }, "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw=="],
+
+ "glob-stream/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
+
+ "glob-stream/glob-parent": ["glob-parent@3.1.0", "", { "dependencies": { "is-glob": "^3.1.0", "path-dirname": "^1.0.0" } }, "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA=="],
+
+ "glob-stream/readable-stream": ["readable-stream@2.3.6", "", { "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" } }, "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw=="],
+
+ "homie-device/mqtt": ["mqtt@2.18.9", "", { "dependencies": { "commist": "^1.0.0", "concat-stream": "^1.6.2", "end-of-stream": "^1.4.1", "es6-map": "^0.1.5", "help-me": "^1.0.1", "inherits": "^2.0.3", "minimist": "^1.2.0", "mqtt-packet": "^5.6.0", "pump": "^3.0.0", "readable-stream": "^2.3.6", "reinterval": "^1.1.0", "split2": "^2.1.1", "websocket-stream": "~5.2.0", "xtend": "^4.0.1" }, "bin": { "mqtt": "mqtt.js", "mqtt_pub": "bin/pub.js", "mqtt_sub": "bin/sub.js" } }, "sha512-ufywki8VAQ8YAERiunbj77TnXgaeVYVlyebnj4o9vhPUQFRjo+d3oUf0rft8kWi7YPYf4O8rkwPkeFc7ndWESg=="],
+
+ "http-basic/concat-stream": ["concat-stream@1.6.2", "", { "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^2.2.2", "typedarray": "^0.0.6" } }, "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw=="],
+
+ "http-response-object/@types/node": ["@types/node@10.17.60", "", {}, "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw=="],
+
+ "hyperid/uuid": ["uuid@8.3.2", "", { "bin": "dist/bin/uuid" }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="],
+
+ "mocha/yargs": ["yargs@16.2.0", "", { "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" } }, "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw=="],
+
+ "mqemitter/qlobber": ["qlobber@8.0.1", "", {}, "sha512-O+Wd1chXj5YE1DwmD+ae0bXiSLehmnS3czlC1R9FL/Nt/3q8uMS1bIHmg2lJfCoiimCxClWM8AAuJrF0EvNiog=="],
+
+ "multistream/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
+
+ "npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="],
+
+ "ordered-read-streams/readable-stream": ["readable-stream@2.3.6", "", { "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" } }, "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw=="],
+
+ "pkg/globby": ["globby@11.1.0", "", { "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" } }, "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g=="],
+
+ "pkg-fetch/yargs": ["yargs@16.2.0", "", { "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" } }, "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw=="],
+
+ "pumpify/pump": ["pump@2.0.1", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA=="],
+
+ "rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="],
+
+ "readable-stream/buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="],
+
+ "resolve/is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="],
+
+ "retimer/worker-timers": ["worker-timers@7.1.8", "", { "dependencies": { "@babel/runtime": "^7.24.5", "tslib": "^2.6.2", "worker-timers-broker": "^6.1.8", "worker-timers-worker": "^7.0.71" } }, "sha512-R54psRKYVLuzff7c1OTFcq/4Hue5Vlz4bFtNEIarpSiCYhpifHU3aIQI29S84o1j87ePCYqbmEJPqwBTf+3sfw=="],
+
+ "serialport/debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="],
+
+ "stream-meter/readable-stream": ["readable-stream@2.3.6", "", { "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" } }, "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw=="],
+
+ "string_decoder/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
+
+ "tar-stream/bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="],
+
+ "tar-stream/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
+
+ "then-request/@types/node": ["@types/node@8.10.66", "", {}, "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw=="],
+
+ "then-request/concat-stream": ["concat-stream@1.6.2", "", { "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^2.2.2", "typedarray": "^0.0.6" } }, "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw=="],
+
+ "through2/readable-stream": ["readable-stream@2.3.6", "", { "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" } }, "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw=="],
+
+ "ts-node/diff": ["diff@4.0.2", "", {}, "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="],
+
+ "websocket-stream/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
+
+ "websocket-stream/ws": ["ws@6.2.3", "", { "dependencies": { "async-limiter": "~1.0.0" } }, "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA=="],
+
+ "yargs/yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
+
+ "@serialport/bindings-cpp/@serialport/parser-readline/@serialport/parser-delimiter": ["@serialport/parser-delimiter@11.0.0", "", {}, "sha512-aZLJhlRTjSmEwllLG7S4J8s8ctRAS0cbvCpO87smLvl3e4BgzbVgF6Z6zaJd3Aji2uSiYgfedCdNc4L6W+1E2g=="],
+
+ "@serialport/bindings-cpp/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="],
+
+ "@serialport/stream/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="],
+
+ "aedes-packet/mqtt-packet/bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="],
+
+ "bl/readable-stream/string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="],
+
+ "callback-stream/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
+
+ "concat-stream/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
+
+ "duplexify/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
+
+ "from2/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
+
+ "glob-stream/glob/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
+
+ "glob-stream/glob-parent/is-glob": ["is-glob@3.1.0", "", { "dependencies": { "is-extglob": "^2.1.0" } }, "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw=="],
+
+ "glob-stream/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
+
+ "homie-device/mqtt/commist": ["commist@1.1.0", "", { "dependencies": { "leven": "^2.1.0", "minimist": "^1.1.0" } }, "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg=="],
+
+ "homie-device/mqtt/concat-stream": ["concat-stream@1.6.2", "", { "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^2.2.2", "typedarray": "^0.0.6" } }, "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw=="],
+
+ "homie-device/mqtt/help-me": ["help-me@1.1.0", "", { "dependencies": { "callback-stream": "^1.0.2", "glob-stream": "^6.1.0", "through2": "^2.0.1", "xtend": "^4.0.0" } }, "sha512-P/IZ8yOMne3SCTHbVY429NZ67B/2bVQlcYGZh2iPPbdLrEQ/qY5aGChn0YTDmt7Sb4IKRI51fypItav+lNl76w=="],
+
+ "homie-device/mqtt/mqtt-packet": ["mqtt-packet@5.6.1", "", { "dependencies": { "bl": "^1.2.1", "inherits": "^2.0.3", "process-nextick-args": "^2.0.0", "safe-buffer": "^5.1.0" } }, "sha512-eaF9rO2uFrIYEHomJxziuKTDkbWW5psLBaIGCazQSKqYsTaB3n4SpvJ1PexKaDBiPnMLPIFWBIiTYT3IfEJfww=="],
+
+ "homie-device/mqtt/readable-stream": ["readable-stream@2.3.6", "", { "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" } }, "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw=="],
+
+ "homie-device/mqtt/split2": ["split2@2.2.0", "", { "dependencies": { "through2": "^2.0.2" } }, "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw=="],
+
+ "http-basic/concat-stream/readable-stream": ["readable-stream@2.3.6", "", { "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" } }, "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw=="],
+
+ "mocha/yargs/cliui": ["cliui@7.0.4", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ=="],
+
+ "multistream/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
+
+ "ordered-read-streams/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
+
+ "pkg-fetch/yargs/cliui": ["cliui@7.0.4", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ=="],
+
+ "pkg/globby/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
+
+ "pkg/globby/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
+
+ "retimer/worker-timers/worker-timers-broker": ["worker-timers-broker@6.1.8", "", { "dependencies": { "@babel/runtime": "^7.24.5", "fast-unique-numbers": "^8.0.13", "tslib": "^2.6.2", "worker-timers-worker": "^7.0.71" } }, "sha512-FUCJu9jlK3A8WqLTKXM9E6kAmI/dR1vAJ8dHYLMisLNB/n3GuaFIjJ7pn16ZcD1zCOf7P6H62lWIEBi+yz/zQQ=="],
+
+ "retimer/worker-timers/worker-timers-worker": ["worker-timers-worker@7.0.71", "", { "dependencies": { "@babel/runtime": "^7.24.5", "tslib": "^2.6.2" } }, "sha512-ks/5YKwZsto1c2vmljroppOKCivB/ma97g9y77MAAz2TBBjPPgpoOiS1qYQKIgvGTr2QYPT3XhJWIB6Rj2MVPQ=="],
+
+ "serialport/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="],
+
+ "stream-meter/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
+
+ "tar-stream/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
+
+ "then-request/concat-stream/readable-stream": ["readable-stream@2.3.6", "", { "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" } }, "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw=="],
+
+ "through2/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
+
+ "websocket-stream/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
+
+ "aedes-packet/mqtt-packet/bl/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
+
+ "bl/readable-stream/string_decoder/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
+
+ "glob-stream/glob/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
+
+ "homie-device/mqtt/mqtt-packet/bl": ["bl@1.2.3", "", { "dependencies": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" } }, "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww=="],
+
+ "homie-device/mqtt/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
+
+ "http-basic/concat-stream/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
+
+ "retimer/worker-timers/worker-timers-broker/fast-unique-numbers": ["fast-unique-numbers@8.0.13", "", { "dependencies": { "@babel/runtime": "^7.23.8", "tslib": "^2.6.2" } }, "sha512-7OnTFAVPefgw2eBJ1xj2PGGR9FwYzSUso9decayHgCDX4sJkHLdcsYTytTg+tYv+wKF3U8gJuSBz2jJpQV4u/g=="],
+
+ "then-request/concat-stream/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
+
+ "aedes-packet/mqtt-packet/bl/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
+ }
+}
diff --git a/dist/appconfig.json b/dist/appconfig.json
new file mode 100644
index 0000000..eb8eda7
--- /dev/null
+++ b/dist/appconfig.json
@@ -0,0 +1,17 @@
+{
+ "$schema": "../../schemas/schema_appconfig.json",
+ "name": "default-slave",
+ "device_id": "default-device",
+ "master": {
+ "type": "udp",
+ "interval": 1000,
+ "timeout": 500,
+ "addressingoffset": 0,
+ "unit_id": 1,
+ "requests": [
+ { "label": "unique", "data": { "$ref": "./inputs.json" } }
+ ]
+ },
+ "slave": { "type": "udp", "data": { "$ref": "./inputs.json" } },
+ "mqtt": { "debug": false }
+}
\ No newline at end of file
diff --git a/dist/default-config.json b/dist/default-config.json
new file mode 100644
index 0000000..a0c3ec1
--- /dev/null
+++ b/dist/default-config.json
@@ -0,0 +1,25 @@
+{
+ "name": "test-device",
+ "device_id": "test-device",
+ "master": {
+ "type": "tcp",
+ "interval": 1000,
+ "timeout": 500,
+ "addressingoffset": 0,
+ "unit_id": 1,
+ "requests": []
+ },
+ "slave": {
+ "type": "tcp",
+ "addressingoffset": 0,
+ "data": {
+ "DI": {},
+ "DO": {},
+ "AI": {},
+ "AO": {}
+ }
+ },
+ "mqtt": {
+ "debug": false
+ }
+}
diff --git a/dist/package.json b/dist/package.json
new file mode 100644
index 0000000..3dbc1ca
--- /dev/null
+++ b/dist/package.json
@@ -0,0 +1,3 @@
+{
+ "type": "module"
+}
diff --git a/package-lock.json b/package-lock.json
deleted file mode 100644
index 905e870..0000000
--- a/package-lock.json
+++ /dev/null
@@ -1,4584 +0,0 @@
-{
- "name": "modbussimulator",
- "version": "1.0.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "modbussimulator",
- "version": "1.0.0",
- "license": "MIT",
- "dependencies": {
- "aedes": "^0.51.0",
- "h5.buffers": "^0.1.1",
- "h5.modbus": "github:morkai/h5.modbus",
- "homie-device": "^3.0.1",
- "json-ref-lite": "^1.0.58",
- "json5": "^2.2.3",
- "mqtt": "^5.3.4",
- "serialport": "^12.0.0",
- "ws": "^8.19.0"
- },
- "bin": {
- "modbussimulator": "ModbusSimulator.js"
- },
- "devDependencies": {
- "@types/chai": "^4.3.20",
- "@types/mocha": "^10.0.10",
- "@types/node": "^20.10.6",
- "chai": "^4.5.0",
- "concurrently": "^9.2.1",
- "cpy": "^11.0.1",
- "execa": "^8.0.1",
- "mocha": "^10.8.2",
- "pkg": "^5.8.1",
- "ts-node": "^10.9.2",
- "typescript": "^5.3.3"
- },
- "engines": {
- "node": ">=20.0.0"
- }
- },
- "node_modules/@babel/generator": {
- "version": "7.18.2",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.2.tgz",
- "integrity": "sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.18.2",
- "@jridgewell/gen-mapping": "^0.3.0",
- "jsesc": "^2.5.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-string-parser": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
- "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
- "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/parser": {
- "version": "7.18.4",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.4.tgz",
- "integrity": "sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "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==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/types": {
- "version": "7.19.0",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.0.tgz",
- "integrity": "sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-string-parser": "^7.18.10",
- "@babel/helper-validator-identifier": "^7.18.6",
- "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,
- "license": "MIT",
- "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,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.0.3",
- "@jridgewell/sourcemap-codec": "^1.4.10"
- }
- },
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.13",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
- "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0",
- "@jridgewell/trace-mapping": "^0.3.24"
- }
- },
- "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.31",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
- "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "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/@serialport/binding-mock": {
- "version": "10.2.2",
- "resolved": "https://registry.npmjs.org/@serialport/binding-mock/-/binding-mock-10.2.2.tgz",
- "integrity": "sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw==",
- "license": "MIT",
- "dependencies": {
- "@serialport/bindings-interface": "^1.2.1",
- "debug": "^4.3.3"
- },
- "engines": {
- "node": ">=12.0.0"
- }
- },
- "node_modules/@serialport/bindings-cpp": {
- "version": "12.0.1",
- "resolved": "https://registry.npmjs.org/@serialport/bindings-cpp/-/bindings-cpp-12.0.1.tgz",
- "integrity": "sha512-r2XOwY2dDvbW7dKqSPIk2gzsr6M6Qpe9+/Ngs94fNaNlcTRCV02PfaoDmRgcubpNVVcLATlxSxPTIDw12dbKOg==",
- "hasInstallScript": true,
- "license": "MIT",
- "dependencies": {
- "@serialport/bindings-interface": "1.2.2",
- "@serialport/parser-readline": "11.0.0",
- "debug": "4.3.4",
- "node-addon-api": "7.0.0",
- "node-gyp-build": "4.6.0"
- },
- "engines": {
- "node": ">=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/serialport/donate"
- }
- },
- "node_modules/@serialport/bindings-cpp/node_modules/@serialport/parser-delimiter": {
- "version": "11.0.0",
- "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-11.0.0.tgz",
- "integrity": "sha512-aZLJhlRTjSmEwllLG7S4J8s8ctRAS0cbvCpO87smLvl3e4BgzbVgF6Z6zaJd3Aji2uSiYgfedCdNc4L6W+1E2g==",
- "license": "MIT",
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/serialport/donate"
- }
- },
- "node_modules/@serialport/bindings-cpp/node_modules/@serialport/parser-readline": {
- "version": "11.0.0",
- "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-11.0.0.tgz",
- "integrity": "sha512-rRAivhRkT3YO28WjmmG4FQX6L+KMb5/ikhyylRfzWPw0nSXy97+u07peS9CbHqaNvJkMhH1locp2H36aGMOEIA==",
- "license": "MIT",
- "dependencies": {
- "@serialport/parser-delimiter": "11.0.0"
- },
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/serialport/donate"
- }
- },
- "node_modules/@serialport/bindings-cpp/node_modules/debug": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
- "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
- "license": "MIT",
- "dependencies": {
- "ms": "2.1.2"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/@serialport/bindings-cpp/node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "license": "MIT"
- },
- "node_modules/@serialport/bindings-interface": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.2.tgz",
- "integrity": "sha512-CJaUd5bLvtM9c5dmO9rPBHPXTa9R2UwpkJ0wdh9JCYcbrPWsKz+ErvR0hBLeo7NPeiFdjFO4sonRljiw4d2XiA==",
- "license": "MIT",
- "engines": {
- "node": "^12.22 || ^14.13 || >=16"
- }
- },
- "node_modules/@serialport/parser-byte-length": {
- "version": "12.0.0",
- "resolved": "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-12.0.0.tgz",
- "integrity": "sha512-0ei0txFAj+s6FTiCJFBJ1T2hpKkX8Md0Pu6dqMrYoirjPskDLJRgZGLqoy3/lnU1bkvHpnJO+9oJ3PB9v8rNlg==",
- "license": "MIT",
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/serialport/donate"
- }
- },
- "node_modules/@serialport/parser-cctalk": {
- "version": "12.0.0",
- "resolved": "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-12.0.0.tgz",
- "integrity": "sha512-0PfLzO9t2X5ufKuBO34DQKLXrCCqS9xz2D0pfuaLNeTkyGUBv426zxoMf3rsMRodDOZNbFblu3Ae84MOQXjnZw==",
- "license": "MIT",
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/serialport/donate"
- }
- },
- "node_modules/@serialport/parser-delimiter": {
- "version": "12.0.0",
- "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-12.0.0.tgz",
- "integrity": "sha512-gu26tVt5lQoybhorLTPsH2j2LnX3AOP2x/34+DUSTNaUTzu2fBXw+isVjQJpUBFWu6aeQRZw5bJol5X9Gxjblw==",
- "license": "MIT",
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/serialport/donate"
- }
- },
- "node_modules/@serialport/parser-inter-byte-timeout": {
- "version": "12.0.0",
- "resolved": "https://registry.npmjs.org/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-12.0.0.tgz",
- "integrity": "sha512-GnCh8K0NAESfhCuXAt+FfBRz1Cf9CzIgXfp7SdMgXwrtuUnCC/yuRTUFWRvuzhYKoAo1TL0hhUo77SFHUH1T/w==",
- "license": "MIT",
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/serialport/donate"
- }
- },
- "node_modules/@serialport/parser-packet-length": {
- "version": "12.0.0",
- "resolved": "https://registry.npmjs.org/@serialport/parser-packet-length/-/parser-packet-length-12.0.0.tgz",
- "integrity": "sha512-p1hiCRqvGHHLCN/8ZiPUY/G0zrxd7gtZs251n+cfNTn+87rwcdUeu9Dps3Aadx30/sOGGFL6brIRGK4l/t7MuQ==",
- "license": "MIT",
- "engines": {
- "node": ">=8.6.0"
- }
- },
- "node_modules/@serialport/parser-readline": {
- "version": "12.0.0",
- "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-12.0.0.tgz",
- "integrity": "sha512-O7cywCWC8PiOMvo/gglEBfAkLjp/SENEML46BXDykfKP5mTPM46XMaX1L0waWU6DXJpBgjaL7+yX6VriVPbN4w==",
- "license": "MIT",
- "dependencies": {
- "@serialport/parser-delimiter": "12.0.0"
- },
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/serialport/donate"
- }
- },
- "node_modules/@serialport/parser-ready": {
- "version": "12.0.0",
- "resolved": "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-12.0.0.tgz",
- "integrity": "sha512-ygDwj3O4SDpZlbrRUraoXIoIqb8sM7aMKryGjYTIF0JRnKeB1ys8+wIp0RFMdFbO62YriUDextHB5Um5cKFSWg==",
- "license": "MIT",
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/serialport/donate"
- }
- },
- "node_modules/@serialport/parser-regex": {
- "version": "12.0.0",
- "resolved": "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-12.0.0.tgz",
- "integrity": "sha512-dCAVh4P/pZrLcPv9NJ2mvPRBg64L5jXuiRxIlyxxdZGH4WubwXVXY/kBTihQmiAMPxbT3yshSX8f2+feqWsxqA==",
- "license": "MIT",
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/serialport/donate"
- }
- },
- "node_modules/@serialport/parser-slip-encoder": {
- "version": "12.0.0",
- "resolved": "https://registry.npmjs.org/@serialport/parser-slip-encoder/-/parser-slip-encoder-12.0.0.tgz",
- "integrity": "sha512-0APxDGR9YvJXTRfY+uRGhzOhTpU5akSH183RUcwzN7QXh8/1jwFsFLCu0grmAUfi+fItCkR+Xr1TcNJLR13VNA==",
- "license": "MIT",
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/serialport/donate"
- }
- },
- "node_modules/@serialport/parser-spacepacket": {
- "version": "12.0.0",
- "resolved": "https://registry.npmjs.org/@serialport/parser-spacepacket/-/parser-spacepacket-12.0.0.tgz",
- "integrity": "sha512-dozONxhPC/78pntuxpz/NOtVps8qIc/UZzdc/LuPvVsqCoJXiRxOg6ZtCP/W58iibJDKPZPAWPGYeZt9DJxI+Q==",
- "license": "MIT",
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/serialport/donate"
- }
- },
- "node_modules/@serialport/stream": {
- "version": "12.0.0",
- "resolved": "https://registry.npmjs.org/@serialport/stream/-/stream-12.0.0.tgz",
- "integrity": "sha512-9On64rhzuqKdOQyiYLYv2lQOh3TZU/D3+IWCR5gk0alPel2nwpp4YwDEGiUBfrQZEdQ6xww0PWkzqth4wqwX3Q==",
- "license": "MIT",
- "dependencies": {
- "@serialport/bindings-interface": "1.2.2",
- "debug": "4.3.4"
- },
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/serialport/donate"
- }
- },
- "node_modules/@serialport/stream/node_modules/debug": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
- "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
- "license": "MIT",
- "dependencies": {
- "ms": "2.1.2"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/@serialport/stream/node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "license": "MIT"
- },
- "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/@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/@types/chai": {
- "version": "4.3.20",
- "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.20.tgz",
- "integrity": "sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==",
- "dev": true,
- "license": "MIT"
- },
- "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": "20.19.28",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.28.tgz",
- "integrity": "sha512-VyKBr25BuFDzBFCK5sUM6ZXiWfqgCTwTAOK8qzGV/m9FCirXYDlmczJ+d5dXBAQALGCdRRdbteKYfJ84NGEusw==",
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "undici-types": "~6.21.0"
- }
- },
- "node_modules/@types/readable-stream": {
- "version": "4.0.23",
- "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.23.tgz",
- "integrity": "sha512-wwXrtQvbMHxCbBgjHaMGEmImFTQxxpfMOR/ZoQnXxB1woqkUbdLGFDgauo00Py9IudiaqSeiBiulSV9i6XIPig==",
- "license": "MIT",
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@types/ws": {
- "version": "8.18.1",
- "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
- "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
- "license": "MIT",
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/abort-controller": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
- "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
- "license": "MIT",
- "dependencies": {
- "event-target-shim": "^5.0.0"
- },
- "engines": {
- "node": ">=6.5"
- }
- },
- "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/aedes": {
- "version": "0.51.3",
- "resolved": "https://registry.npmjs.org/aedes/-/aedes-0.51.3.tgz",
- "integrity": "sha512-aQfiI9w3RbqnowNCdcGMmCtxBFXN9bhJFcuZm24U5/NU06V3MCl42jWK2GUnu8rOypR2Ahi/aEcgq3w7CMcycg==",
- "license": "MIT",
- "dependencies": {
- "aedes-packet": "^3.0.0",
- "aedes-persistence": "^9.1.2",
- "end-of-stream": "^1.4.4",
- "fastfall": "^1.5.1",
- "fastparallel": "^2.4.1",
- "fastseries": "^2.0.0",
- "hyperid": "^3.2.0",
- "mqemitter": "^6.0.0",
- "mqtt-packet": "^9.0.0",
- "retimer": "^4.0.0",
- "reusify": "^1.0.4",
- "uuid": "^10.0.0"
- },
- "engines": {
- "node": ">=16"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/aedes"
- }
- },
- "node_modules/aedes-packet": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/aedes-packet/-/aedes-packet-3.0.0.tgz",
- "integrity": "sha512-swASey0BxGs4/npZGWoiVDmnEyPvVFIRY6l2LVKL4rbiW8IhcIGDLfnb20Qo8U20itXlitAKPQ3MVTEbOGG5ZA==",
- "license": "MIT",
- "dependencies": {
- "mqtt-packet": "^7.0.0"
- },
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/aedes-packet/node_modules/bl": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
- "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
- "license": "MIT",
- "dependencies": {
- "buffer": "^5.5.0",
- "inherits": "^2.0.4",
- "readable-stream": "^3.4.0"
- }
- },
- "node_modules/aedes-packet/node_modules/mqtt-packet": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-7.1.2.tgz",
- "integrity": "sha512-FFZbcZ2omsf4c5TxEQfcX9hI+JzDpDKPT46OmeIBpVA7+t32ey25UNqlqNXTmeZOr5BLsSIERpQQLsFWJS94SQ==",
- "license": "MIT",
- "dependencies": {
- "bl": "^4.0.2",
- "debug": "^4.1.1",
- "process-nextick-args": "^2.0.1"
- }
- },
- "node_modules/aedes-packet/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==",
- "license": "MIT",
- "dependencies": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/aedes-persistence": {
- "version": "9.1.2",
- "resolved": "https://registry.npmjs.org/aedes-persistence/-/aedes-persistence-9.1.2.tgz",
- "integrity": "sha512-2Wlr5pwIK0eQOkiTwb8ZF6C20s8UPUlnsJ4kXYePZ3JlQl0NbBA176mzM8wY294BJ5wybpNc9P5XEQxqadRNcQ==",
- "license": "MIT",
- "dependencies": {
- "aedes-packet": "^3.0.0",
- "qlobber": "^7.0.0"
- },
- "engines": {
- "node": ">=14"
- }
- },
- "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/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/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,
- "license": "ISC",
- "dependencies": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "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,
- "license": "Python-2.0"
- },
- "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/assertion-error": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
- "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "*"
- }
- },
- "node_modules/async-limiter": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
- "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
- "license": "MIT"
- },
- "node_modules/at-least-node": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
- "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": ">= 4.0.0"
- }
- },
- "node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "license": "MIT"
- },
- "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==",
- "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/binary-extensions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
- "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/bl": {
- "version": "6.1.6",
- "resolved": "https://registry.npmjs.org/bl/-/bl-6.1.6.tgz",
- "integrity": "sha512-jLsPgN/YSvPUg9UX0Kd73CXpm2Psg9FxMeCSXnk3WBO3CMT10JMwijubhGfHCnFu6TPn1ei3b975dxv7K2pWVg==",
- "license": "MIT",
- "dependencies": {
- "@types/readable-stream": "^4.0.0",
- "buffer": "^6.0.3",
- "inherits": "^2.0.4",
- "readable-stream": "^4.2.0"
- }
- },
- "node_modules/bl/node_modules/buffer": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
- "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
- "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/bl/node_modules/readable-stream": {
- "version": "4.7.0",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
- "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
- "license": "MIT",
- "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/bl/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/bl/node_modules/string_decoder": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
- "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
- "license": "MIT",
- "dependencies": {
- "safe-buffer": "~5.2.0"
- }
- },
- "node_modules/brace-expansion": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
- "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
- "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/broker-factory": {
- "version": "3.1.12",
- "resolved": "https://registry.npmjs.org/broker-factory/-/broker-factory-3.1.12.tgz",
- "integrity": "sha512-5Bmeki5j2IVO+lE07dSOUMZp1ZGKkE47b3ILv4ZD0nmTdc0iTKVS1CgYPDCy5m0Qb9jIKHBaF9SUrtqg5oW+1A==",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.28.4",
- "fast-unique-numbers": "^9.0.25",
- "tslib": "^2.8.1",
- "worker-factory": "^7.0.47"
- }
- },
- "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": "5.7.1",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
- "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
- "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.1.13"
- }
- },
- "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/callback-stream": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/callback-stream/-/callback-stream-1.1.0.tgz",
- "integrity": "sha512-sAZ9kODla+mGACBZ1IpTCAisKoGnv6PykW7fPk1LrM+mMepE18Yz0515yoVcrZy7dQsTUp3uZLQ/9Sx1RnLoHw==",
- "license": "MIT",
- "dependencies": {
- "inherits": "^2.0.1",
- "readable-stream": "> 1.0.0 < 3.0.0"
- }
- },
- "node_modules/camelcase": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
- "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/chai": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz",
- "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "assertion-error": "^1.1.0",
- "check-error": "^1.0.3",
- "deep-eql": "^4.1.3",
- "get-func-name": "^2.0.2",
- "loupe": "^2.3.6",
- "pathval": "^1.1.1",
- "type-detect": "^4.1.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "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/chalk/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/check-error": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz",
- "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "get-func-name": "^2.0.2"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/chokidar": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
- "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
- "dev": true,
- "license": "MIT",
- "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"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/chownr": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
- "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
- "dev": true,
- "license": "ISC"
- },
- "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,
- "license": "ISC",
- "dependencies": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
- "wrap-ansi": "^7.0.0"
- }
- },
- "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/commist": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/commist/-/commist-3.2.0.tgz",
- "integrity": "sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw==",
- "license": "MIT"
- },
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "license": "MIT"
- },
- "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==",
- "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==",
- "license": "MIT",
- "dependencies": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/concurrently": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.1.tgz",
- "integrity": "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "chalk": "4.1.2",
- "rxjs": "7.8.2",
- "shell-quote": "1.8.3",
- "supports-color": "8.1.1",
- "tree-kill": "1.2.2",
- "yargs": "17.7.2"
- },
- "bin": {
- "conc": "dist/bin/concurrently.js",
- "concurrently": "dist/bin/concurrently.js"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/open-cli-tools/concurrently?sponsor=1"
- }
- },
- "node_modules/concurrently/node_modules/cliui": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
- "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.1",
- "wrap-ansi": "^7.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/concurrently/node_modules/yargs": {
- "version": "17.7.2",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
- "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cliui": "^8.0.1",
- "escalade": "^3.1.1",
- "get-caller-file": "^2.0.5",
- "require-directory": "^2.1.1",
- "string-width": "^4.2.3",
- "y18n": "^5.0.5",
- "yargs-parser": "^21.1.1"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/concurrently/node_modules/yargs-parser": {
- "version": "21.1.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
- "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/copy-file": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/copy-file/-/copy-file-11.1.0.tgz",
- "integrity": "sha512-X8XDzyvYaA6msMyAM575CUoygY5b44QzLcGRKsK3MFmXcOvQa518dNPLsKYwkYsn72g3EiW+LE0ytd/FlqWmyw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "graceful-fs": "^4.2.11",
- "p-event": "^6.0.0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/core-util-is": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
- "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
- },
- "node_modules/cpy": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/cpy/-/cpy-11.1.0.tgz",
- "integrity": "sha512-QGHetPSSuprVs+lJmMDcivvrBwTKASzXQ5qxFvRC2RFESjjod71bDvFvhxTjDgkNjrrb72AI6JPjfYwxrIy33A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "copy-file": "^11.0.0",
- "globby": "^14.0.2",
- "junk": "^4.0.1",
- "micromatch": "^4.0.7",
- "p-filter": "^4.1.0",
- "p-map": "^7.0.2"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "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/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/d": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz",
- "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==",
- "license": "ISC",
- "dependencies": {
- "es5-ext": "^0.10.64",
- "type": "^2.7.2"
- },
- "engines": {
- "node": ">=0.12"
- }
- },
- "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/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,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "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/deep-eql": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz",
- "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "type-detect": "^4.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/deep-extend": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
- "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4.0.0"
- }
- },
- "node_modules/detect-libc": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
- "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=8"
- }
- },
- "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,
- "license": "MIT",
- "dependencies": {
- "path-type": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/dir-glob/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,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/duplexify": {
- "version": "3.7.1",
- "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
- "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
- "license": "MIT",
- "dependencies": {
- "end-of-stream": "^1.0.0",
- "inherits": "^2.0.1",
- "readable-stream": "^2.0.0",
- "stream-shift": "^1.0.0"
- }
- },
- "node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/end-of-stream": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
- "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
- "dependencies": {
- "once": "^1.4.0"
- }
- },
- "node_modules/es5-ext": {
- "version": "0.10.64",
- "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz",
- "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==",
- "hasInstallScript": true,
- "license": "ISC",
- "dependencies": {
- "es6-iterator": "^2.0.3",
- "es6-symbol": "^3.1.3",
- "esniff": "^2.0.1",
- "next-tick": "^1.1.0"
- },
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/es6-iterator": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
- "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
- "license": "MIT",
- "dependencies": {
- "d": "1",
- "es5-ext": "^0.10.35",
- "es6-symbol": "^3.1.1"
- }
- },
- "node_modules/es6-map": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
- "integrity": "sha512-mz3UqCh0uPCIqsw1SSAkB/p0rOzF/M0V++vyN7JqlPtSW/VsYgQBvVvqMLmfBuyMzTpLnNqi6JmcSizs4jy19A==",
- "license": "MIT",
- "dependencies": {
- "d": "1",
- "es5-ext": "~0.10.14",
- "es6-iterator": "~2.0.1",
- "es6-set": "~0.1.5",
- "es6-symbol": "~3.1.1",
- "event-emitter": "~0.3.5"
- }
- },
- "node_modules/es6-set": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.6.tgz",
- "integrity": "sha512-TE3LgGLDIBX332jq3ypv6bcOpkLO0AslAQo7p2VqX/1N46YNsvIWgvjojjSEnWEGWMhr1qUbYeTSir5J6mFHOw==",
- "license": "ISC",
- "dependencies": {
- "d": "^1.0.1",
- "es5-ext": "^0.10.62",
- "es6-iterator": "~2.0.3",
- "es6-symbol": "^3.1.3",
- "event-emitter": "^0.3.5",
- "type": "^2.7.2"
- },
- "engines": {
- "node": ">=0.12"
- }
- },
- "node_modules/es6-symbol": {
- "version": "3.1.4",
- "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz",
- "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==",
- "license": "ISC",
- "dependencies": {
- "d": "^1.0.2",
- "ext": "^1.7.0"
- },
- "engines": {
- "node": ">=0.12"
- }
- },
- "node_modules/escalade": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
- "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "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,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/esniff": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz",
- "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==",
- "license": "ISC",
- "dependencies": {
- "d": "^1.0.1",
- "es5-ext": "^0.10.62",
- "event-emitter": "^0.3.5",
- "type": "^2.7.2"
- },
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/event-emitter": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
- "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==",
- "license": "MIT",
- "dependencies": {
- "d": "1",
- "es5-ext": "~0.10.14"
- }
- },
- "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==",
- "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==",
- "license": "MIT",
- "engines": {
- "node": ">=0.8.x"
- }
- },
- "node_modules/execa": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
- "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cross-spawn": "^7.0.3",
- "get-stream": "^8.0.1",
- "human-signals": "^5.0.0",
- "is-stream": "^3.0.0",
- "merge-stream": "^2.0.0",
- "npm-run-path": "^5.1.0",
- "onetime": "^6.0.0",
- "signal-exit": "^4.1.0",
- "strip-final-newline": "^3.0.0"
- },
- "engines": {
- "node": ">=16.17"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/execa?sponsor=1"
- }
- },
- "node_modules/expand-template": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
- "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
- "dev": true,
- "license": "(MIT OR WTFPL)",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/ext": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz",
- "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
- "license": "ISC",
- "dependencies": {
- "type": "^2.7.2"
- }
- },
- "node_modules/extend": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
- "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
- "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-unique-numbers": {
- "version": "9.0.25",
- "resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-9.0.25.tgz",
- "integrity": "sha512-vHLSJfu0jSazb5X1jgYZIbsUd4mztxHxyFxUAPYvaYLkTsvQDn5+NbJRtfp+/tLIsUlMkD/geL2710QBxylH6w==",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.28.4",
- "tslib": "^2.8.1"
- },
- "engines": {
- "node": ">=18.2.0"
- }
- },
- "node_modules/fastfall": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/fastfall/-/fastfall-1.5.1.tgz",
- "integrity": "sha512-KH6p+Z8AKPXnmA7+Iz2Lh8ARCMr+8WNPVludm1LGkZoD2MjY6LVnRMtTKhkdzI+jr0RzQWXKzKyBJm1zoHEL4Q==",
- "license": "MIT",
- "dependencies": {
- "reusify": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/fastparallel": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/fastparallel/-/fastparallel-2.4.1.tgz",
- "integrity": "sha512-qUmhxPgNHmvRjZKBFUNI0oZuuH9OlSIOXmJ98lhKPxMZZ7zS/Fi0wRHOihDSz0R1YiIOjxzOY4bq65YTcdBi2Q==",
- "license": "ISC",
- "dependencies": {
- "reusify": "^1.0.4",
- "xtend": "^4.0.2"
- }
- },
- "node_modules/fastq": {
- "version": "1.20.1",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
- "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "reusify": "^1.0.4"
- }
- },
- "node_modules/fastseries": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/fastseries/-/fastseries-2.0.0.tgz",
- "integrity": "sha512-XBU9RXeoYc2/VnvMhplAxEmZLfIk7cvTBu+xwoBuTI8pL19E03cmca17QQycKIdxgwCeFA/a4u27gv1h3ya5LQ==",
- "license": "ISC"
- },
- "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/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,
- "license": "MIT",
- "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,
- "license": "BSD-3-Clause",
- "bin": {
- "flat": "cli.js"
- }
- },
- "node_modules/from2": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
- "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "inherits": "^2.0.1",
- "readable-stream": "^2.0.0"
- }
- },
- "node_modules/fs-constants": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
- "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/fs-extra": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
- "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "at-least-node": "^1.0.0",
- "graceful-fs": "^4.2.0",
- "jsonfile": "^6.0.1",
- "universalify": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "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==",
- "license": "ISC"
- },
- "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==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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,
- "license": "ISC",
- "engines": {
- "node": "6.* || 8.* || >= 10.*"
- }
- },
- "node_modules/get-func-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
- "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "*"
- }
- },
- "node_modules/get-stream": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
- "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/github-from-package": {
- "version": "0.0.0",
- "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
- "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/glob": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
- "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
- "deprecated": "Glob versions prior to v9 are no longer supported",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^5.0.1",
- "once": "^1.3.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "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/glob-stream": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz",
- "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==",
- "license": "MIT",
- "dependencies": {
- "extend": "^3.0.0",
- "glob": "^7.1.1",
- "glob-parent": "^3.1.0",
- "is-negated-glob": "^1.0.0",
- "ordered-read-streams": "^1.0.0",
- "pumpify": "^1.3.5",
- "readable-stream": "^2.1.5",
- "remove-trailing-separator": "^1.0.1",
- "to-absolute-glob": "^2.0.0",
- "unique-stream": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/glob-stream/node_modules/brace-expansion": {
- "version": "1.1.12",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
- "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/glob-stream/node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "deprecated": "Glob versions prior to v9 are no longer supported",
- "license": "ISC",
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/glob-stream/node_modules/glob-parent": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
- "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==",
- "license": "ISC",
- "dependencies": {
- "is-glob": "^3.1.0",
- "path-dirname": "^1.0.0"
- }
- },
- "node_modules/glob-stream/node_modules/is-glob": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
- "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==",
- "license": "MIT",
- "dependencies": {
- "is-extglob": "^2.1.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/glob-stream/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "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/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/h5.buffers": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/h5.buffers/-/h5.buffers-0.1.1.tgz",
- "integrity": "sha1-JEh3MFMOSwDkm1rxcEldrPpAEb4="
- },
- "node_modules/h5.modbus": {
- "version": "1.0.0",
- "resolved": "git+ssh://git@github.com/morkai/h5.modbus.git#feaebad666a05a9626654d5e55742f0986925904",
- "integrity": "sha512-9uq1EGpZSyFhEcVlI2UigLO+609KMegSmmJ4suhgHwt0R6GcVemw4YJxjcZjDbXow7wEdRxaH4U6US8vCDmM7A==",
- "license": "MIT",
- "dependencies": {
- "h5.buffers": "0.x.x"
- },
- "engines": {
- "node": ">=8.x.x"
- }
- },
- "node_modules/has": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz",
- "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4.0"
- }
- },
- "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/hasown": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
- "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
- "dev": true,
- "license": "MIT",
- "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==",
- "license": "MIT"
- },
- "node_modules/homie-device": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/homie-device/-/homie-device-3.0.1.tgz",
- "integrity": "sha512-ajj6kC/AgGKVxjrtg75CQge4e+oSeOaCZ9Rvl5Gy6V0AWHzsHBzm0roiTrVvC0AAZZLeWYjnQZkmUBTS1kYFxw==",
- "dependencies": {
- "lodash": "^4.13.1",
- "mqtt": "^2.11.0"
- }
- },
- "node_modules/homie-device/node_modules/bl": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz",
- "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==",
- "license": "MIT",
- "dependencies": {
- "readable-stream": "^2.3.5",
- "safe-buffer": "^5.1.1"
- }
- },
- "node_modules/homie-device/node_modules/commist": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz",
- "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==",
- "license": "MIT",
- "dependencies": {
- "leven": "^2.1.0",
- "minimist": "^1.1.0"
- }
- },
- "node_modules/homie-device/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==",
- "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/homie-device/node_modules/help-me": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/help-me/-/help-me-1.1.0.tgz",
- "integrity": "sha512-P/IZ8yOMne3SCTHbVY429NZ67B/2bVQlcYGZh2iPPbdLrEQ/qY5aGChn0YTDmt7Sb4IKRI51fypItav+lNl76w==",
- "license": "MIT",
- "dependencies": {
- "callback-stream": "^1.0.2",
- "glob-stream": "^6.1.0",
- "through2": "^2.0.1",
- "xtend": "^4.0.0"
- }
- },
- "node_modules/homie-device/node_modules/mqtt": {
- "version": "2.18.9",
- "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-2.18.9.tgz",
- "integrity": "sha512-ufywki8VAQ8YAERiunbj77TnXgaeVYVlyebnj4o9vhPUQFRjo+d3oUf0rft8kWi7YPYf4O8rkwPkeFc7ndWESg==",
- "license": "MIT",
- "dependencies": {
- "commist": "^1.0.0",
- "concat-stream": "^1.6.2",
- "end-of-stream": "^1.4.1",
- "es6-map": "^0.1.5",
- "help-me": "^1.0.1",
- "inherits": "^2.0.3",
- "minimist": "^1.2.0",
- "mqtt-packet": "^5.6.0",
- "pump": "^3.0.0",
- "readable-stream": "^2.3.6",
- "reinterval": "^1.1.0",
- "split2": "^2.1.1",
- "websocket-stream": "~5.2.0",
- "xtend": "^4.0.1"
- },
- "bin": {
- "mqtt": "mqtt.js",
- "mqtt_pub": "bin/pub.js",
- "mqtt_sub": "bin/sub.js"
- },
- "engines": {
- "node": ">=4.0.0"
- }
- },
- "node_modules/homie-device/node_modules/mqtt-packet": {
- "version": "5.6.1",
- "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-5.6.1.tgz",
- "integrity": "sha512-eaF9rO2uFrIYEHomJxziuKTDkbWW5psLBaIGCazQSKqYsTaB3n4SpvJ1PexKaDBiPnMLPIFWBIiTYT3IfEJfww==",
- "license": "MIT",
- "dependencies": {
- "bl": "^1.2.1",
- "inherits": "^2.0.3",
- "process-nextick-args": "^2.0.0",
- "safe-buffer": "^5.1.0"
- }
- },
- "node_modules/homie-device/node_modules/split2": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz",
- "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==",
- "license": "ISC",
- "dependencies": {
- "through2": "^2.0.2"
- }
- },
- "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/human-signals": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
- "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=16.17.0"
- }
- },
- "node_modules/hyperid": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/hyperid/-/hyperid-3.3.0.tgz",
- "integrity": "sha512-7qhCVT4MJIoEsNcbhglhdmBKb09QtcmJNiIQGq7js/Khf5FtQQ9bzcAuloeqBeee7XD7JqDeve9KNlQya5tSGQ==",
- "license": "MIT",
- "dependencies": {
- "buffer": "^5.2.1",
- "uuid": "^8.3.2",
- "uuid-parse": "^1.1.0"
- }
- },
- "node_modules/hyperid/node_modules/uuid": {
- "version": "8.3.2",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
- "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
- "license": "MIT",
- "bin": {
- "uuid": "dist/bin/uuid"
- }
- },
- "node_modules/ieee754": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
- "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
- "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/inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
- "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
- "license": "ISC",
- "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=="
- },
- "node_modules/ini": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
- "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/into-stream": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-6.0.0.tgz",
- "integrity": "sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "from2": "^2.3.0",
- "p-is-promise": "^3.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "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==",
- "license": "MIT",
- "engines": {
- "node": ">= 12"
- }
- },
- "node_modules/is-absolute": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
- "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
- "license": "MIT",
- "dependencies": {
- "is-relative": "^1.0.0",
- "is-windows": "^1.0.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "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,
- "license": "MIT",
- "dependencies": {
- "binary-extensions": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-core-module": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
- "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "has": "^1.0.3"
- },
- "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==",
- "license": "MIT",
- "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,
- "license": "MIT",
- "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,
- "license": "MIT",
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-negated-glob": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz",
- "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "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-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,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-relative": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
- "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
- "license": "MIT",
- "dependencies": {
- "is-unc-path": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-stream": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
- "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
- "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-unc-path": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
- "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
- "license": "MIT",
- "dependencies": {
- "unc-path-regex": "^0.1.2"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "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,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/is-windows": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
- "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "node_modules/isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/js-sdsl": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz",
- "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==",
- "license": "MIT",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/js-sdsl"
- }
- },
- "node_modules/js-yaml": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
- "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
- "dev": true,
- "license": "MIT",
- "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,
- "license": "MIT",
- "bin": {
- "jsesc": "bin/jsesc"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/json-ref-lite": {
- "version": "1.0.58",
- "resolved": "https://registry.npmjs.org/json-ref-lite/-/json-ref-lite-1.0.58.tgz",
- "integrity": "sha512-atr2VDI94j19mKbDF9kp72gfvfUs45BAfiGZUnMYZaeHtfnQu4pfVhkbvkR+sRh2XiWj7s13+ESjqP7EyE4Jrw==",
- "license": "ISC"
- },
- "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==",
- "license": "MIT"
- },
- "node_modules/json5": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
- "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
- "license": "MIT",
- "bin": {
- "json5": "lib/cli.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "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/junk": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/junk/-/junk-4.0.1.tgz",
- "integrity": "sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12.20"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/leven": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz",
- "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "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,
- "license": "MIT",
- "dependencies": {
- "p-locate": "^5.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/lodash": {
- "version": "4.17.21",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
- "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
- "license": "MIT"
- },
- "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,
- "license": "MIT",
- "dependencies": {
- "chalk": "^4.1.0",
- "is-unicode-supported": "^0.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/loupe": {
- "version": "2.3.7",
- "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz",
- "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "get-func-name": "^2.0.1"
- }
- },
- "node_modules/lru-cache": {
- "version": "10.4.3",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
- "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
- "license": "ISC"
- },
- "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/merge-stream": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
- "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
- "dev": true
- },
- "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/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/mimic-fn": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
- "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "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/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/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/mkdirp-classic": {
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
- "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/mocha": {
- "version": "10.8.2",
- "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz",
- "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==",
- "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/mqemitter": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/mqemitter/-/mqemitter-6.0.2.tgz",
- "integrity": "sha512-8RGlznQx/Nb1xC3xKUFXHWov7pn7JdH++YVwlr6SLT6k3ft1h+ImGqZdVudbdKruFckIq9wheq9s4hgCivJDow==",
- "license": "ISC",
- "dependencies": {
- "fastparallel": "^2.4.1",
- "qlobber": "^8.0.1"
- },
- "engines": {
- "node": ">=16"
- }
- },
- "node_modules/mqemitter/node_modules/qlobber": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/qlobber/-/qlobber-8.0.1.tgz",
- "integrity": "sha512-O+Wd1chXj5YE1DwmD+ae0bXiSLehmnS3czlC1R9FL/Nt/3q8uMS1bIHmg2lJfCoiimCxClWM8AAuJrF0EvNiog==",
- "license": "MIT",
- "engines": {
- "node": ">= 16"
- }
- },
- "node_modules/mqtt": {
- "version": "5.14.1",
- "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.14.1.tgz",
- "integrity": "sha512-NxkPxE70Uq3Ph7goefQa7ggSsVzHrayCD0OyxlJgITN/EbzlZN+JEPmaAZdxP1LsIT5FamDyILoQTF72W7Nnbw==",
- "license": "MIT",
- "dependencies": {
- "@types/readable-stream": "^4.0.21",
- "@types/ws": "^8.18.1",
- "commist": "^3.2.0",
- "concat-stream": "^2.0.0",
- "debug": "^4.4.1",
- "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",
- "rfdc": "^1.4.1",
- "socks": "^2.8.6",
- "split2": "^4.2.0",
- "worker-timers": "^8.0.23",
- "ws": "^8.18.3"
- },
- "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==",
- "license": "MIT",
- "dependencies": {
- "bl": "^6.0.8",
- "debug": "^4.3.4",
- "process-nextick-args": "^2.0.1"
- }
- },
- "node_modules/mqtt/node_modules/buffer": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
- "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
- "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/mqtt/node_modules/readable-stream": {
- "version": "4.7.0",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
- "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
- "license": "MIT",
- "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/mqtt/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/mqtt/node_modules/string_decoder": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
- "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
- "license": "MIT",
- "dependencies": {
- "safe-buffer": "~5.2.0"
- }
- },
- "node_modules/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/multistream": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/multistream/-/multistream-4.1.0.tgz",
- "integrity": "sha512-J1XDiAmmNpRCBfIWJv+n0ymC4ABcf/Pl+5YvC5B/D2f/2+8PtHvCNxMPKiQcZyi922Hq69J2YOpb1pTywfifyw==",
- "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": {
- "once": "^1.4.0",
- "readable-stream": "^3.6.0"
- }
- },
- "node_modules/multistream/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/napi-build-utils": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
- "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/next-tick": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
- "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==",
- "license": "ISC"
- },
- "node_modules/node-abi": {
- "version": "3.85.0",
- "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.85.0.tgz",
- "integrity": "sha512-zsFhmbkAzwhTft6nd3VxcG0cvJsT70rL+BIGHWVq5fi6MwGrHwzqKaxXE+Hl2GmnGItnDKPPkO5/LQqjVkIdFg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "semver": "^7.3.5"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/node-addon-api": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.0.0.tgz",
- "integrity": "sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==",
- "license": "MIT"
- },
- "node_modules/node-fetch": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
- "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "whatwg-url": "^5.0.0"
- },
- "engines": {
- "node": "4.x || >=6.0.0"
- },
- "peerDependencies": {
- "encoding": "^0.1.0"
- },
- "peerDependenciesMeta": {
- "encoding": {
- "optional": true
- }
- }
- },
- "node_modules/node-gyp-build": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz",
- "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==",
- "license": "MIT",
- "bin": {
- "node-gyp-build": "bin.js",
- "node-gyp-build-optional": "optional.js",
- "node-gyp-build-test": "build-test.js"
- }
- },
- "node_modules/normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/npm-run-path": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
- "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "path-key": "^4.0.0"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/npm-run-path/node_modules/path-key": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
- "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/number-allocator": {
- "version": "1.0.14",
- "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz",
- "integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.3.1",
- "js-sdsl": "4.3.0"
- }
- },
- "node_modules/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
- "dependencies": {
- "wrappy": "1"
- }
- },
- "node_modules/onetime": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
- "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "mimic-fn": "^4.0.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/ordered-read-streams": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz",
- "integrity": "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==",
- "license": "MIT",
- "dependencies": {
- "readable-stream": "^2.0.1"
- }
- },
- "node_modules/p-event": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/p-event/-/p-event-6.0.1.tgz",
- "integrity": "sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-timeout": "^6.1.2"
- },
- "engines": {
- "node": ">=16.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/p-filter": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-4.1.0.tgz",
- "integrity": "sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-map": "^7.0.1"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/p-is-promise": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz",
- "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "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,
- "license": "MIT",
- "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,
- "license": "MIT",
- "dependencies": {
- "p-limit": "^3.0.2"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "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/p-timeout": {
- "version": "6.1.4",
- "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz",
- "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/path-dirname": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
- "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==",
- "license": "MIT"
- },
- "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,
- "license": "MIT",
- "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==",
- "license": "MIT",
- "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,
- "license": "MIT",
- "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,
- "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/pathval": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
- "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "*"
- }
- },
- "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/pkg": {
- "version": "5.8.1",
- "resolved": "https://registry.npmjs.org/pkg/-/pkg-5.8.1.tgz",
- "integrity": "sha512-CjBWtFStCfIiT4Bde9QpJy0KeH19jCfwZRJqHFDFXfhUklCx8JoFmMj3wgnEYIwGmZVNkhsStPHEOnrtrQhEXA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/generator": "7.18.2",
- "@babel/parser": "7.18.4",
- "@babel/types": "7.19.0",
- "chalk": "^4.1.2",
- "fs-extra": "^9.1.0",
- "globby": "^11.1.0",
- "into-stream": "^6.0.0",
- "is-core-module": "2.9.0",
- "minimist": "^1.2.6",
- "multistream": "^4.1.0",
- "pkg-fetch": "3.4.2",
- "prebuild-install": "7.1.1",
- "resolve": "^1.22.0",
- "stream-meter": "^1.0.4"
- },
- "bin": {
- "pkg": "lib-es5/bin.js"
- },
- "peerDependencies": {
- "node-notifier": ">=9.0.1"
- },
- "peerDependenciesMeta": {
- "node-notifier": {
- "optional": true
- }
- }
- },
- "node_modules/pkg-fetch": {
- "version": "3.4.2",
- "resolved": "https://registry.npmjs.org/pkg-fetch/-/pkg-fetch-3.4.2.tgz",
- "integrity": "sha512-0+uijmzYcnhC0hStDjm/cl2VYdrmVVBpe7Q8k9YBojxmR5tG8mvR9/nooQq3QSXiQqORDVOTY3XqMEqJVIzkHA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "chalk": "^4.1.2",
- "fs-extra": "^9.1.0",
- "https-proxy-agent": "^5.0.0",
- "node-fetch": "^2.6.6",
- "progress": "^2.0.3",
- "semver": "^7.3.5",
- "tar-fs": "^2.1.1",
- "yargs": "^16.2.0"
- },
- "bin": {
- "pkg-fetch": "lib-es5/bin.js"
- }
- },
- "node_modules/pkg/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/pkg/node_modules/ignore": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
- "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/pkg/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/prebuild-install": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
- "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "detect-libc": "^2.0.0",
- "expand-template": "^2.0.3",
- "github-from-package": "0.0.0",
- "minimist": "^1.2.3",
- "mkdirp-classic": "^0.5.3",
- "napi-build-utils": "^1.0.1",
- "node-abi": "^3.3.0",
- "pump": "^3.0.0",
- "rc": "^1.2.7",
- "simple-get": "^4.0.0",
- "tar-fs": "^2.0.0",
- "tunnel-agent": "^0.6.0"
- },
- "bin": {
- "prebuild-install": "bin.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/process": {
- "version": "0.11.10",
- "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
- "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6.0"
- }
- },
- "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=="
- },
- "node_modules/progress": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
- "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/pump": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
- "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==",
- "license": "MIT",
- "dependencies": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
- "node_modules/pumpify": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
- "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
- "license": "MIT",
- "dependencies": {
- "duplexify": "^3.6.0",
- "inherits": "^2.0.3",
- "pump": "^2.0.0"
- }
- },
- "node_modules/pumpify/node_modules/pump": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
- "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
- "license": "MIT",
- "dependencies": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
- "node_modules/qlobber": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/qlobber/-/qlobber-7.0.1.tgz",
- "integrity": "sha512-FsFg9lMuMEFNKmTO9nV7tlyPhx8BmskPPjH2akWycuYVTtWaVwhW5yCHLJQ6Q+3mvw5cFX2vMfW2l9z2SiYAbg==",
- "license": "MIT",
- "engines": {
- "node": ">= 14"
- }
- },
- "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/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/rc": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
- "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
- "dev": true,
- "license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
- "dependencies": {
- "deep-extend": "^0.6.0",
- "ini": "~1.3.0",
- "minimist": "^1.2.0",
- "strip-json-comments": "~2.0.1"
- },
- "bin": {
- "rc": "cli.js"
- }
- },
- "node_modules/rc/node_modules/strip-json-comments": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/readable-stream": {
- "version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
- "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
- "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/readdirp": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "picomatch": "^2.2.1"
- },
- "engines": {
- "node": ">=8.10.0"
- }
- },
- "node_modules/reinterval": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz",
- "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==",
- "license": "MIT"
- },
- "node_modules/remove-trailing-separator": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
- "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==",
- "license": "ISC"
- },
- "node_modules/require-directory": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
- "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/resolve": {
- "version": "1.22.11",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz",
- "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-core-module": "^2.16.1",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- },
- "bin": {
- "resolve": "bin/resolve"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/resolve/node_modules/is-core-module": {
- "version": "2.16.1",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
- "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "hasown": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/retimer": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/retimer/-/retimer-4.0.0.tgz",
- "integrity": "sha512-fZIVtvbOsQsxNSDhpdPOX4lx5Ss2ni+S72AUBitARpFhtA3UzrAjQ6gDtypB2/+l7L+1VQgAgpvAKY66mElH0w==",
- "license": "MIT",
- "dependencies": {
- "worker-timers": "^7.0.75"
- }
- },
- "node_modules/retimer/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==",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.23.8",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.1.0"
- }
- },
- "node_modules/retimer/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==",
- "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/retimer/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==",
- "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/retimer/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==",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.24.5",
- "tslib": "^2.6.2"
- }
- },
- "node_modules/reusify": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
- "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
- "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==",
- "license": "MIT"
- },
- "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/rxjs": {
- "version": "7.8.2",
- "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
- "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "tslib": "^2.1.0"
- }
- },
- "node_modules/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=="
- },
- "node_modules/semver": {
- "version": "7.7.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
- "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "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/serialport": {
- "version": "12.0.0",
- "resolved": "https://registry.npmjs.org/serialport/-/serialport-12.0.0.tgz",
- "integrity": "sha512-AmH3D9hHPFmnF/oq/rvigfiAouAKyK/TjnrkwZRYSFZxNggJxwvbAbfYrLeuvq7ktUdhuHdVdSjj852Z55R+uA==",
- "license": "MIT",
- "dependencies": {
- "@serialport/binding-mock": "10.2.2",
- "@serialport/bindings-cpp": "12.0.1",
- "@serialport/parser-byte-length": "12.0.0",
- "@serialport/parser-cctalk": "12.0.0",
- "@serialport/parser-delimiter": "12.0.0",
- "@serialport/parser-inter-byte-timeout": "12.0.0",
- "@serialport/parser-packet-length": "12.0.0",
- "@serialport/parser-readline": "12.0.0",
- "@serialport/parser-ready": "12.0.0",
- "@serialport/parser-regex": "12.0.0",
- "@serialport/parser-slip-encoder": "12.0.0",
- "@serialport/parser-spacepacket": "12.0.0",
- "@serialport/stream": "12.0.0",
- "debug": "4.3.4"
- },
- "engines": {
- "node": ">=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/serialport/donate"
- }
- },
- "node_modules/serialport/node_modules/debug": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
- "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
- "license": "MIT",
- "dependencies": {
- "ms": "2.1.2"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/serialport/node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "license": "MIT"
- },
- "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,
- "license": "MIT",
- "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,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/shell-quote": {
- "version": "1.8.3",
- "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz",
- "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==",
- "dev": true,
- "license": "MIT",
- "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/simple-concat": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
- "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
- "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/simple-get": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
- "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
- "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": {
- "decompress-response": "^6.0.0",
- "once": "^1.3.1",
- "simple-concat": "^1.0.0"
- }
- },
- "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==",
- "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==",
- "license": "MIT",
- "dependencies": {
- "ip-address": "^10.0.1",
- "smart-buffer": "^4.2.0"
- },
- "engines": {
- "node": ">= 10.0.0",
- "npm": ">= 3.0.0"
- }
- },
- "node_modules/split2": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
- "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
- "license": "ISC",
- "engines": {
- "node": ">= 10.x"
- }
- },
- "node_modules/stream-meter": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/stream-meter/-/stream-meter-1.0.4.tgz",
- "integrity": "sha512-4sOEtrbgFotXwnEuzzsQBYEV1elAeFSO8rSGeTwabuX1RRn/kEq9JVH7I0MRBhKVRR0sJkr0M0QCH7yOLf9fhQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "readable-stream": "^2.1.4"
- }
- },
- "node_modules/stream-shift": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz",
- "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==",
- "license": "MIT"
- },
- "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==",
- "dependencies": {
- "safe-buffer": "~5.1.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,
- "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,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-final-newline": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
- "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
- "dev": true,
- "license": "MIT",
- "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,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "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,
- "license": "MIT",
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/supports-color?sponsor=1"
- }
- },
- "node_modules/supports-preserve-symlinks-flag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
- "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/tar-fs": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz",
- "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "chownr": "^1.1.1",
- "mkdirp-classic": "^0.5.2",
- "pump": "^3.0.0",
- "tar-stream": "^2.1.4"
- }
- },
- "node_modules/tar-stream": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
- "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "bl": "^4.0.3",
- "end-of-stream": "^1.4.1",
- "fs-constants": "^1.0.0",
- "inherits": "^2.0.3",
- "readable-stream": "^3.1.1"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/tar-stream/node_modules/bl": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
- "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "buffer": "^5.5.0",
- "inherits": "^2.0.4",
- "readable-stream": "^3.4.0"
- }
- },
- "node_modules/tar-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/through2": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
- "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
- "license": "MIT",
- "dependencies": {
- "readable-stream": "~2.3.6",
- "xtend": "~4.0.1"
- }
- },
- "node_modules/through2-filter": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz",
- "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==",
- "license": "MIT",
- "dependencies": {
- "through2": "~2.0.0",
- "xtend": "~4.0.0"
- }
- },
- "node_modules/to-absolute-glob": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz",
- "integrity": "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==",
- "license": "MIT",
- "dependencies": {
- "is-absolute": "^1.0.0",
- "is-negated-glob": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/to-fast-properties": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
- "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/tree-kill": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
- "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "tree-kill": "cli.js"
- }
- },
- "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,
- "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/tunnel-agent": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
- "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "safe-buffer": "^5.0.1"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/type": {
- "version": "2.7.3",
- "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz",
- "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==",
- "license": "ISC"
- },
- "node_modules/type-detect": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz",
- "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/typedarray": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
- "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
- "license": "MIT"
- },
- "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",
- "peer": true,
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=14.17"
- }
- },
- "node_modules/unc-path-regex": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
- "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "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==",
- "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/unique-stream": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.4.0.tgz",
- "integrity": "sha512-V6QarSfeSgDipGA9EZdoIzu03ZDlOFkk+FbEP5cwgrZXN3iIkYR91IjU2EnM6rB835kGQsqHX8qncObTXV+6KA==",
- "license": "MIT",
- "dependencies": {
- "json-stable-stringify-without-jsonify": "^1.0.1",
- "through2-filter": "3.0.0"
- }
- },
- "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/util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
- },
- "node_modules/uuid": {
- "version": "10.0.0",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
- "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
- "funding": [
- "https://github.com/sponsors/broofa",
- "https://github.com/sponsors/ctavan"
- ],
- "license": "MIT",
- "bin": {
- "uuid": "dist/bin/uuid"
- }
- },
- "node_modules/uuid-parse": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/uuid-parse/-/uuid-parse-1.1.0.tgz",
- "integrity": "sha512-OdmXxA8rDsQ7YpNVbKSJkNzTw2I+S5WsbMDnCtIWSQaosNAcWtFuI/YK1TjzUI6nbkgiqEyh8gWngfcv8Asd9A==",
- "license": "MIT"
- },
- "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/webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
- "dev": true,
- "license": "BSD-2-Clause"
- },
- "node_modules/websocket-stream": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/websocket-stream/-/websocket-stream-5.2.0.tgz",
- "integrity": "sha512-2ZfiWuEK/bTi8AhXdYh/lFEUwXtGVcbO4vWUy5XJhf7F6nCMAC8hbXXTarxrmv2BFSwdk3P3bhvgiA9wzT+GFQ==",
- "license": "BSD-2-Clause",
- "dependencies": {
- "duplexify": "^3.6.1",
- "inherits": "^2.0.1",
- "readable-stream": "^3.0.0",
- "safe-buffer": "^5.1.2",
- "ws": "^6.1.2",
- "xtend": "^4.0.0"
- }
- },
- "node_modules/websocket-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==",
- "license": "MIT",
- "dependencies": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/websocket-stream/node_modules/ws": {
- "version": "6.2.3",
- "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz",
- "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==",
- "license": "MIT",
- "dependencies": {
- "async-limiter": "~1.0.0"
- }
- },
- "node_modules/whatwg-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
- }
- },
- "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,
- "license": "ISC",
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "node-which": "bin/node-which"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/worker-factory": {
- "version": "7.0.47",
- "resolved": "https://registry.npmjs.org/worker-factory/-/worker-factory-7.0.47.tgz",
- "integrity": "sha512-Ga5U8n7hJqovn98nlFnbyuJj66s8dCU4QOQd0dU0bje7uvrGGhOFeKtsTdB3b6fO5BD93F88rHpkBCGzgGloKw==",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.28.4",
- "fast-unique-numbers": "^9.0.25",
- "tslib": "^2.8.1"
- }
- },
- "node_modules/worker-timers": {
- "version": "8.0.28",
- "resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-8.0.28.tgz",
- "integrity": "sha512-+AuNePH2P/PuhQURf5I+SIGBty4dq2CzoQEB+bMXIQiPrYj3WhkUtIW2bSzeETFWyXJFUdQGsyFeZtit15LkOw==",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.28.4",
- "tslib": "^2.8.1",
- "worker-timers-broker": "^8.0.14",
- "worker-timers-worker": "^9.0.12"
- }
- },
- "node_modules/worker-timers-broker": {
- "version": "8.0.14",
- "resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-8.0.14.tgz",
- "integrity": "sha512-ooCGGWGcAYbWEJY2nkA60K9mZ33atvg/QIOBJ3OzdQJU5Z7/NdPFlEiMLiCYW8dpeP/qLcsaUsZzETrKNgGicg==",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.28.4",
- "broker-factory": "^3.1.12",
- "fast-unique-numbers": "^9.0.25",
- "tslib": "^2.8.1",
- "worker-timers-worker": "^9.0.12"
- }
- },
- "node_modules/worker-timers-worker": {
- "version": "9.0.12",
- "resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-9.0.12.tgz",
- "integrity": "sha512-NBXCnKB/9CkhjWZz2dITgK94QM5GIJx+7LAlCA8mKeO6whdwmfH9S3iPEwakhn3+NOB9nHE3jQqdpKpZZJI23g==",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.28.4",
- "tslib": "^2.8.1",
- "worker-factory": "^7.0.47"
- }
- },
- "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,
- "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/wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
- },
- "node_modules/ws": {
- "version": "8.19.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
- "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
- "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/xtend": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
- "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
- "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,
- "license": "ISC",
- "engines": {
- "node": ">=10"
- }
- },
- "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,
- "license": "MIT",
- "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,
- "license": "MIT",
- "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,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- }
- }
-}
diff --git a/package.json b/package.json
index 2cfe8f6..cf4177b 100644
--- a/package.json
+++ b/package.json
@@ -2,28 +2,23 @@
"name": "modbussimulator",
"type": "module",
"main": "ModbusSimulator.js",
- "bin": "ModbusSimulator.js",
+ "bin": "dist-cjs/ModbusSimulator.js",
"version": "1.0.0",
"description": "Modbus Simulator",
"author": "Pierre Leduc",
"license": "MIT",
"readme": "readme.md",
"scripts": {
- "compile": "tsc",
- "pretest": "npm run compile",
"test": "mocha",
"test:ci": "mocha --config .mocharc.ci.json",
"test:unit": "mocha test/unit/*.test.ts --config .mocharc.ci.json",
"test:integration": "mocha test/integration/*.test.ts --config .mocharc.ci.json",
"test:e2e": "mocha test/e2e/*.test.ts",
- "start:mqtt": "node --loader ts-node/esm scripts/mqtt-broker.ts",
- "prestart:slave": "npm run compile",
- "start:slave": "node ModbusSimulator.js examples/e2e/slave-appconfig.json",
- "prestart:master": "npm run compile",
- "start:master": "node ModbusSimulator.js examples/e2e/master-appconfig.json",
- "start:hodd": "node --loader ts-node/esm scripts/hodd-server.ts",
- "prebuild": "npm run compile",
- "build": "node --loader ts-node/esm scripts/build_pkg.ts",
+ "start:mqtt": "bun --import=ts-node/esm scripts/mqtt-broker.ts",
+ "start:slave": "bun ModbusSimulator.ts examples/e2e/slave-appconfig.json",
+ "start:master": "bun ModbusSimulator.ts examples/e2e/master-appconfig.json",
+ "start:hodd": "bun --import=ts-node/esm scripts/hodd-server.ts",
+ "build": "bun scripts/build_pkg.ts",
"docker-build": "docker build -t modbussimulator .",
"docker-run": "docker run -p 502:502/udp modbussimulator"
},
@@ -50,8 +45,7 @@
"node18-linux-x64"
],
"scripts": [
- "src/config/slave_config.js",
- "src/config/master_config.js",
+ "dist-cjs/**/*.js",
"./node_modules/*"
],
"assets": [
@@ -67,12 +61,12 @@
"json5": "^2.2.3",
"mqtt": "^5.3.4",
"serialport": "^12.0.0",
+ "sync-request": "^6.1.0",
"ws": "^8.19.0"
},
"engines": {
"node": ">=20.0.0"
},
- "type": "commonjs",
"ts-node": {
"esm": true,
"experimentalEsm": true,
diff --git a/readme.md b/readme.md
index ba21ecd..fb157b1 100644
--- a/readme.md
+++ b/readme.md
@@ -5,9 +5,6 @@ It is interfaced whith MQTT to publish and control data points, following the [H
## Prerequisites
-- Node.js (v14 or higher) - required if running from source
-- For serial communication: appropriate serial port drivers
-- For MQTT integration: access to an MQTT broker
## Quick Start
@@ -17,6 +14,19 @@ It is interfaced whith MQTT to publish and control data points, following the [H
See the [examples](examples/) directory for sample configurations.
+### Bun standalone build (with serialport externalized)
+
+- Build the executable with Bun: `bun scripts/build_pkg.ts`
+- The build keeps `serialport` external and copies `node_modules/serialport` into `Releases/node_modules/serialport`.
+- Run the binary from inside the `Releases` directory so the external `serialport` native binding is found:
+
+```powershell
+cd Releases
+./modbussimulator-win-x64.exe ../examples/e2e/slave-appconfig.json
+```
+
+For Linux builds, run the same build script on a Linux host and run from the `Releases` directory in the same way.
+
## Parameters
Modbus Simulator takes a JSON configuration file as a parameter. The default configuration file will be searched in the current path with the following name: `appconfig.json`.
diff --git a/scripts/build_pkg.ts b/scripts/build_pkg.ts
index f8220a4..0162e27 100644
--- a/scripts/build_pkg.ts
+++ b/scripts/build_pkg.ts
@@ -4,49 +4,77 @@
import path from 'path';
import fs from 'fs';
import { fileURLToPath } from 'url';
+import { spawnSync } from 'child_process';
+import os from 'os';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
+const platform = os.platform();
+const arch = os.arch();
-(async () => {
- const { execa } = await import('execa');
- const { default: cpy } = await import('cpy');
-
- const { stdout } = await execa('pkg', ['..', '--out-path', '../Releases'], { cwd: __dirname });
- const lines = stdout.split(/[\r\n]+/);
- const addons: string[] = [];
-
- for (let i = 0; i < lines.length - 1; i++) {
- const line = lines[i]?.trim();
- const next = lines[i + 1]?.trim();
-
- if (
- line?.startsWith('The addon must be distributed') &&
- next?.endsWith('.node')
- ) {
- addons.push(next.replace('%1: ', ''));
- i++; // Skip the next line since we've already processed it
- }
- }
-
- //Add externals:
-
- //json validation
- addons.push(path.join(__dirname, '../schemas/schema_appconfig.json'));
- addons.push(path.join(__dirname, '../schemas/schema_datas.json'));
- addons.push(path.join(__dirname, '../schemas/schema_data.json'));
- addons.push(path.join(__dirname, '../schemas/schema_coils.json'));
- addons.push(path.join(__dirname, '../schemas/schema_registers.json'));
-
- if (addons.length) {
- await cpy(addons, path.join(__dirname, '../Releases'));
- }
-})().catch((e: any) => {
- console.error('Build failed with error:');
- console.error(e.message || e);
- if (e.stderr) console.error('STDERR:', e.stderr);
- if (e.stdout) {
- fs.writeFileSync('build-output.log', e.stdout, 'utf8');
- console.error('Full output written to build-output.log');
- }
- throw e;
+const releasesDir = path.join(__dirname, '../Releases');
+
+if (!fs.existsSync(releasesDir)) {
+ fs.mkdirSync(releasesDir, { recursive: true });
+}
+
+console.log('Building standalone executable with Bun...');
+console.log(`Current platform: ${platform} (${arch})`);
+
+// Build executable for current platform directly from TypeScript
+const outputName = platform === 'win32'
+ ? 'modbussimulator-win-x64.exe'
+ : platform === 'linux'
+ ? 'modbussimulator-linux-x64'
+ : 'modbussimulator';
+
+console.log('Compiling with Bun (TypeScript input)...');
+// Use the current Bun runtime path to avoid PATH issues
+const bunRuntime = process.execPath;
+
+const build = spawnSync(bunRuntime, [
+ 'build',
+ 'ModbusSimulator.ts',
+ '--compile',
+ '--outfile', path.join(releasesDir, outputName),
+ '--external', 'serialport'
+], {
+ cwd: path.join(__dirname, '..'),
+ stdio: 'inherit'
});
+
+if (build.status !== 0) {
+ console.error('Build failed');
+ process.exit(1);
+}
+
+console.log(`✓ Executable created: ${outputName}`);
+
+// Copy schema files
+const schemas = ['schema_appconfig', 'schema_datas', 'schema_data', 'schema_coils', 'schema_registers'];
+for (const schema of schemas) {
+ const src = path.join(__dirname, `../schemas/${schema}.json`);
+ const dst = path.join(releasesDir, `${schema}.json`);
+ if (fs.existsSync(src)) {
+ fs.copyFileSync(src, dst);
+ }
+}
+
+// Externalized native dependency: bundle node_modules/serialport alongside the executable
+const serialportSrc = path.join(__dirname, '../node_modules/serialport');
+const serialportDst = path.join(releasesDir, 'node_modules/serialport');
+if (fs.existsSync(serialportSrc)) {
+ fs.mkdirSync(path.dirname(serialportDst), { recursive: true });
+ fs.cpSync(serialportSrc, serialportDst, { recursive: true });
+}
+
+console.log('');
+console.log('✓ Build complete! Standalone executable is in the Releases directory.');
+console.log('');
+console.log('To use this executable:');
+if (platform === 'win32') {
+ console.log(` ${outputName} `);
+} else {
+ console.log(` ./${outputName} `);
+}
+console.log('');
+console.log('Note: For cross-platform builds, run this build script on each target platform.');
diff --git a/scripts/mqtt-broker.ts b/scripts/mqtt-broker.ts
index 5e97499..cea7e87 100644
--- a/scripts/mqtt-broker.ts
+++ b/scripts/mqtt-broker.ts
@@ -9,7 +9,7 @@
import aedes from 'aedes';
import net from 'net';
import http from 'http';
-import ws from 'ws';
+import { WebSocketServer, createWebSocketStream } from 'ws';
import path from 'path';
import fs from 'fs';
import { fileURLToPath } from 'url';
@@ -67,10 +67,10 @@ server.listen(PORT, () => {
// Create WebSocket server
const httpServer = http.createServer();
-const wsServer = new ws.Server({ server: httpServer });
+const wsServer = new WebSocketServer({ server: httpServer });
wsServer.on('connection', (socket) => {
- const stream = ws.createWebSocketStream(socket);
+ const stream = createWebSocketStream(socket);
broker.handle(stream);
});
diff --git a/scripts/package.json b/scripts/package.json
new file mode 100644
index 0000000..3dbc1ca
--- /dev/null
+++ b/scripts/package.json
@@ -0,0 +1,3 @@
+{
+ "type": "module"
+}
diff --git a/test/e2e/modbus-mqtt.test.ts b/test/e2e/modbus-mqtt.test.ts
index 74b393a..c3d6d8d 100644
--- a/test/e2e/modbus-mqtt.test.ts
+++ b/test/e2e/modbus-mqtt.test.ts
@@ -36,7 +36,7 @@ describe('ModbusSimulator - E2E Tests', function () {
detached: false,
env: {
...process.env,
- NODE_OPTIONS: '--loader=ts-node/esm'
+ NODE_OPTIONS: '--import=ts-node/esm'
}
});
@@ -83,7 +83,7 @@ describe('ModbusSimulator - E2E Tests', function () {
await startService(
'Modbus Slave',
'node',
- ['ModbusSimulator.js', 'examples/e2e/slave-appconfig.json'],
+ ['--import=ts-node/esm', 'ModbusSimulator.ts', 'examples/e2e/slave-appconfig.json'],
path.join(logDir, 'modbus', 'slave', `slave-${timestamp}.log`),
2000,
false
@@ -93,7 +93,7 @@ describe('ModbusSimulator - E2E Tests', function () {
await startService(
'Modbus Master',
'node',
- ['ModbusSimulator.js', 'examples/e2e/master-appconfig.json'],
+ ['--import=ts-node/esm', 'ModbusSimulator.ts', 'examples/e2e/master-appconfig.json'],
path.join(logDir, 'modbus', 'master', `master-${timestamp}.log`),
2000,
false
diff --git a/tsconfig.json b/tsconfig.json
index 1ea467c..f1f92af 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -22,6 +22,7 @@
},
"include": [
"src/**/*.ts",
+ "scripts/**/*.ts",
"*.ts"
],
"typeRoots": [
diff --git a/tsconfig.pkg.json b/tsconfig.pkg.json
new file mode 100644
index 0000000..9d61a9d
--- /dev/null
+++ b/tsconfig.pkg.json
@@ -0,0 +1,20 @@
+{
+ "compilerOptions": {
+ "module": "commonjs",
+ "target": "es2020",
+ "outDir": "dist-cjs",
+ "sourceMap": false,
+ "skipLibCheck": true,
+ "esModuleInterop": true,
+ "allowJs": true,
+ "resolveJsonModule": true
+ },
+ "include": [
+ "ModbusSimulator.ts",
+ "src/**/*.ts"
+ ],
+ "exclude": [
+ "test",
+ "node_modules"
+ ]
+}
From c529eb8a9e9ca282bdf8c1d77dabff1ff9164c0f Mon Sep 17 00:00:00 2001
From: Pierre Leduc
Date: Wed, 21 Jan 2026 10:36:52 +0100
Subject: [PATCH 10/12] Update bun setup action in CI workflows
---
.github/workflows/node.js.yml | 2 +-
.github/workflows/release.yml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml
index ea596e8..01a2fc8 100644
--- a/.github/workflows/node.js.yml
+++ b/.github/workflows/node.js.yml
@@ -20,7 +20,7 @@ jobs:
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- - uses: oven-sh/bun@v2
+ - uses: oven-sh/setup-bun@v2
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 8587983..4ce89a0 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- - uses: oven-sh/bun@v2
+ - uses: oven-sh/setup-bun@v2
- name: Install dependencies (bun)
run: bun install
From 2a27ad0e71e0ca940d889d5e5bab89bbcd7c30de Mon Sep 17 00:00:00 2001
From: Pierre Leduc
Date: Wed, 21 Jan 2026 11:08:43 +0100
Subject: [PATCH 11/12] Update CI workflow to use Bun and enhance README for
standalone executable instructions
---
.github/workflows/node.js.yml | 29 ++++++++++---------------
readme.md | 41 +++++++++++++++++++++++++----------
2 files changed, 41 insertions(+), 29 deletions(-)
diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml
index 01a2fc8..ae01612 100644
--- a/.github/workflows/node.js.yml
+++ b/.github/workflows/node.js.yml
@@ -1,7 +1,7 @@
-# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
+# This workflow tests the ModbusSimulator with Bun
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs
-name: Node.js CI
+name: Bun CI
on:
push:
@@ -14,23 +14,18 @@ jobs:
runs-on: ubuntu-latest
- strategy:
- matrix:
- node-version: [18.x, 20.x, 22.x]
- # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
-
steps:
- - uses: oven-sh/setup-bun@v2
- uses: actions/checkout@v4
- - name: Use Node.js ${{ matrix.node-version }}
- uses: actions/setup-node@v4
- with:
- node-version: ${{ matrix.node-version }}
- cache: 'npm'
- - run: npm ci
- - name: Run tests
- run: npm run test:unit && npm run test:integration
+ - uses: oven-sh/setup-bun@v2
+
+ - name: Install dependencies (bun)
+ run: bun install
+
+ - name: Run unit and integration tests
+ run: bun run test:unit && bun run test:integration
env:
NODE_ENV: test
- - run: npm run build --if-present
+
+ - name: Build release
+ run: bun run build
diff --git a/readme.md b/readme.md
index fb157b1..3e832b4 100644
--- a/readme.md
+++ b/readme.md
@@ -5,27 +5,44 @@ It is interfaced whith MQTT to publish and control data points, following the [H
## Prerequisites
+**For using the standalone executable:**
+- No runtime dependencies required (standalone Bun binary)
+- For serial communication: appropriate serial port drivers
+- For MQTT integration: access to an MQTT broker
+
+**For development/building from source:**
+- [Bun](https://bun.sh/) v1.0+ (for installing dependencies and building)
+- For serial communication: appropriate serial port drivers
## Quick Start
1. Download the portable executable or clone the repository
2. Create an `appconfig.json` file in the same directory
-3. Run with: `modbussimulator-x64.exe` or `node ModbusSimulator.js`
+3. Run the standalone executable (no Node.js or Bun needed):
+ - **Windows:** `modbussimulator-win-x64.exe appconfig.json`
+ - **Linux:** `./modbussimulator-linux-x64 appconfig.json`
See the [examples](examples/) directory for sample configurations.
-### Bun standalone build (with serialport externalized)
+### Building from source (with Bun)
-- Build the executable with Bun: `bun scripts/build_pkg.ts`
-- The build keeps `serialport` external and copies `node_modules/serialport` into `Releases/node_modules/serialport`.
-- Run the binary from inside the `Releases` directory so the external `serialport` native binding is found:
+To build the standalone executable from TypeScript source:
-```powershell
+```bash
+# Install dependencies
+bun install
+
+# Build standalone executables (creates Releases/modbussimulator-{win-x64,linux-x64})
+bun run build
+
+# Run the compiled binary (from Releases directory):
cd Releases
./modbussimulator-win-x64.exe ../examples/e2e/slave-appconfig.json
```
-For Linux builds, run the same build script on a Linux host and run from the `Releases` directory in the same way.
+**Note on serialport:** The standalone binary keeps the native `serialport` module external for compatibility. When distributing the binary, ensure the `Releases/node_modules/serialport` folder is included alongside the executable, or run from the `Releases` directory after building.
+
+For Linux builds, run `bun run build` on a Linux host. For Windows, run on a Windows host.
## Parameters
@@ -33,17 +50,17 @@ Modbus Simulator takes a JSON configuration file as a parameter. The default con
### Launching the Tool
-**Using the portable executable:**
+**Using the standalone executable:**
```bash
-modbussimulator-x64.exe appconfig.json
-modbussimulator-x64.exe ./appconfig.json
+modbussimulator-win-x64.exe appconfig.json
+modbussimulator-win-x64.exe ./appconfig.json
```
-**Using Node.js from source:**
+**For development (running TypeScript directly with Bun):**
```bash
-node ModbusSimulator.js appconfig.json
+bun ModbusSimulator.ts appconfig.json
```
Multiple configuration files can be placed in the same directory, each with a unique name. Only one file can be used by each instance of Modbus Simulator.
From d0fd279902f4be29d209196a8fd7d004bb601b3d Mon Sep 17 00:00:00 2001
From: Pierre Leduc
Date: Wed, 21 Jan 2026 11:26:03 +0100
Subject: [PATCH 12/12] Refactor project structure by removing CommonJS wrapper
and obsolete config files; update package.json for TypeScript entry points
and repository details.
---
.gitignore | 7 -------
ModbusSimulator.cjs | 12 ------------
dist/appconfig.json | 17 -----------------
dist/default-config.json | 25 -------------------------
dist/package.json | 3 ---
package.json | 25 ++++++-------------------
6 files changed, 6 insertions(+), 83 deletions(-)
delete mode 100644 ModbusSimulator.cjs
delete mode 100644 dist/appconfig.json
delete mode 100644 dist/default-config.json
delete mode 100644 dist/package.json
diff --git a/.gitignore b/.gitignore
index bbe53d8..ef2f6e7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,10 +2,3 @@
/node_modules
/Releases
build-output.log
-
-# TypeScript compiled output
-/src/**/*.js
-/src/**/*.js.map
-# But keep test infrastructure JavaScript files
-!/test/**/*.js
-*.js
diff --git a/ModbusSimulator.cjs b/ModbusSimulator.cjs
deleted file mode 100644
index 96fa7b6..0000000
--- a/ModbusSimulator.cjs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Pure CommonJS wrapper for pkg bootstrap
-// This file is only used by pkg; the main app uses ModbusSimulator.js
-// We dynamically import the ES module
-
-(async () => {
- try {
- await import('./ModbusSimulator.js');
- } catch (err) {
- console.error('Failed to load ModbusSimulator:', err);
- process.exit(1);
- }
-})();
diff --git a/dist/appconfig.json b/dist/appconfig.json
deleted file mode 100644
index eb8eda7..0000000
--- a/dist/appconfig.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "$schema": "../../schemas/schema_appconfig.json",
- "name": "default-slave",
- "device_id": "default-device",
- "master": {
- "type": "udp",
- "interval": 1000,
- "timeout": 500,
- "addressingoffset": 0,
- "unit_id": 1,
- "requests": [
- { "label": "unique", "data": { "$ref": "./inputs.json" } }
- ]
- },
- "slave": { "type": "udp", "data": { "$ref": "./inputs.json" } },
- "mqtt": { "debug": false }
-}
\ No newline at end of file
diff --git a/dist/default-config.json b/dist/default-config.json
deleted file mode 100644
index a0c3ec1..0000000
--- a/dist/default-config.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "name": "test-device",
- "device_id": "test-device",
- "master": {
- "type": "tcp",
- "interval": 1000,
- "timeout": 500,
- "addressingoffset": 0,
- "unit_id": 1,
- "requests": []
- },
- "slave": {
- "type": "tcp",
- "addressingoffset": 0,
- "data": {
- "DI": {},
- "DO": {},
- "AI": {},
- "AO": {}
- }
- },
- "mqtt": {
- "debug": false
- }
-}
diff --git a/dist/package.json b/dist/package.json
deleted file mode 100644
index 3dbc1ca..0000000
--- a/dist/package.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "type": "module"
-}
diff --git a/package.json b/package.json
index cf4177b..66b2094 100644
--- a/package.json
+++ b/package.json
@@ -1,8 +1,8 @@
{
"name": "modbussimulator",
"type": "module",
- "main": "ModbusSimulator.js",
- "bin": "dist-cjs/ModbusSimulator.js",
+ "main": "ModbusSimulator.ts",
+ "bin": "ModbusSimulator.ts",
"version": "1.0.0",
"description": "Modbus Simulator",
"author": "Pierre Leduc",
@@ -31,27 +31,14 @@
"cpy": "^11.0.1",
"execa": "^8.0.1",
"mocha": "^10.8.2",
- "pkg": "^5.8.1",
"ts-node": "^10.9.2",
"typescript": "^5.3.3"
},
"repository": {
- "type": "svn",
- "url": "http://ken/svn/PSD/Tools/ModbusSimulator"
- },
- "pkg": {
- "targets": [
- "node18-win-x64",
- "node18-linux-x64"
- ],
- "scripts": [
- "dist-cjs/**/*.js",
- "./node_modules/*"
- ],
- "assets": [
- "./node_modules/**/*.node"
- ]
+ "type": "git",
+ "url": "https://github.com/pledou/ModbusSimulator.git"
},
+
"dependencies": {
"aedes": "^0.51.0",
"h5.buffers": "^0.1.1",
@@ -65,7 +52,7 @@
"ws": "^8.19.0"
},
"engines": {
- "node": ">=20.0.0"
+ "bun": ">=1.0.0"
},
"ts-node": {
"esm": true,