@apocaliss92/nodelink-js 0.1.18 → 0.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{DiagnosticsTools-6WEMO4L4.js → DiagnosticsTools-NUMCYEKQ.js} +2 -2
- package/dist/{chunk-ULSFEQSE.js → chunk-EHWVA3SG.js} +164 -17
- package/dist/chunk-EHWVA3SG.js.map +1 -0
- package/dist/{chunk-ZE7D7LI4.js → chunk-YPU7RAEY.js} +18 -12
- package/dist/{chunk-ZE7D7LI4.js.map → chunk-YPU7RAEY.js.map} +1 -1
- package/dist/cli/rtsp-server.cjs +177 -24
- package/dist/cli/rtsp-server.cjs.map +1 -1
- package/dist/cli/rtsp-server.js +2 -2
- package/dist/index.cjs +213 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +46 -6
- package/dist/index.d.ts +46 -6
- package/dist/index.js +38 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-ULSFEQSE.js.map +0 -1
- /package/dist/{DiagnosticsTools-6WEMO4L4.js.map → DiagnosticsTools-NUMCYEKQ.js.map} +0 -0
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
runMultifocalDiagnosticsConsecutively,
|
|
10
10
|
sampleStreams,
|
|
11
11
|
testChannelStreams
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-YPU7RAEY.js";
|
|
13
13
|
export {
|
|
14
14
|
collectCgiDiagnostics,
|
|
15
15
|
collectMultifocalDiagnostics,
|
|
@@ -22,4 +22,4 @@ export {
|
|
|
22
22
|
sampleStreams,
|
|
23
23
|
testChannelStreams
|
|
24
24
|
};
|
|
25
|
-
//# sourceMappingURL=DiagnosticsTools-
|
|
25
|
+
//# sourceMappingURL=DiagnosticsTools-NUMCYEKQ.js.map
|
|
@@ -136,7 +136,7 @@ import {
|
|
|
136
136
|
talkTraceLog,
|
|
137
137
|
traceLog,
|
|
138
138
|
xmlEscape
|
|
139
|
-
} from "./chunk-
|
|
139
|
+
} from "./chunk-YPU7RAEY.js";
|
|
140
140
|
|
|
141
141
|
// src/protocol/framing.ts
|
|
142
142
|
function encodeHeader(h) {
|
|
@@ -8753,7 +8753,8 @@ var logDebugStreamBlock = (params) => {
|
|
|
8753
8753
|
const bitRateText = getXmlText(raw, "bitRate") ?? getXmlText(raw, "BitRate");
|
|
8754
8754
|
const videoEncTypeText = getXmlText(raw, "videoEncType") ?? getXmlText(raw, "VideoEncType");
|
|
8755
8755
|
const audioText = getXmlText(raw, "audio") ?? getXmlText(raw, "Audio");
|
|
8756
|
-
const
|
|
8756
|
+
const enableCheckRaw = raw.replace(/<smartH265[\s\S]*?<\/smartH265>/g, "");
|
|
8757
|
+
const enableText = getXmlText(enableCheckRaw, "enable") ?? getXmlText(enableCheckRaw, "Enable");
|
|
8757
8758
|
const width = Number(widthText ?? "0");
|
|
8758
8759
|
const height = Number(heightText ?? "0");
|
|
8759
8760
|
const frameRate = Number(frameText ?? "0");
|
|
@@ -8777,7 +8778,8 @@ var buildStream = (params) => {
|
|
|
8777
8778
|
const frameRate = Number(getXmlText(streamXml, "frame") ?? "0");
|
|
8778
8779
|
const bitRate = Number(getXmlText(streamXml, "bitRate") ?? "0");
|
|
8779
8780
|
const audio = Number(getXmlText(streamXml, "audio") ?? "0");
|
|
8780
|
-
const
|
|
8781
|
+
const enableXml = streamXml.replace(/<smartH265[\s\S]*?<\/smartH265>/g, "");
|
|
8782
|
+
const enabled = getXmlText(enableXml, "enable");
|
|
8781
8783
|
const isEnabled = isEnabledFromText(enabled);
|
|
8782
8784
|
if (!isEnabled || !isPlausibleStream({ width, height, frameRate, bitRate }))
|
|
8783
8785
|
return void 0;
|
|
@@ -9454,14 +9456,16 @@ var DUAL_LENS_SINGLE_MOTION_MODELS = /* @__PURE__ */ new Set([
|
|
|
9454
9456
|
"Reolink TrackMix",
|
|
9455
9457
|
"Reolink TrackMix PoE",
|
|
9456
9458
|
"Reolink TrackMix WiFi",
|
|
9457
|
-
"RLC-81MA"
|
|
9459
|
+
"RLC-81MA",
|
|
9460
|
+
"TrackFlex Floodlight WiFi"
|
|
9458
9461
|
]);
|
|
9459
9462
|
var DUAL_LENS_MODELS = /* @__PURE__ */ new Set([
|
|
9460
9463
|
...DUAL_LENS_DUAL_MOTION_MODELS,
|
|
9461
9464
|
...DUAL_LENS_SINGLE_MOTION_MODELS
|
|
9462
9465
|
]);
|
|
9463
9466
|
var isDualLenseModel = (model) => {
|
|
9464
|
-
|
|
9467
|
+
const lower = model.toLowerCase();
|
|
9468
|
+
return Array.from(DUAL_LENS_MODELS).some((m) => m.toLowerCase() === lower) || lower.includes("trackmix") || lower.includes("trackflex");
|
|
9465
9469
|
};
|
|
9466
9470
|
var NVR_HUB_EXACT_TYPES = ["NVR", "WIFI_NVR", "HOMEHUB"];
|
|
9467
9471
|
var NVR_HUB_MODEL_PATTERNS = [
|
|
@@ -9545,6 +9549,14 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
9545
9549
|
* Set via setIsNvr() from the plugin or auto-detected via isNvrDevice().
|
|
9546
9550
|
*/
|
|
9547
9551
|
_isNvr;
|
|
9552
|
+
/**
|
|
9553
|
+
* Cached multi-focal detection result.
|
|
9554
|
+
* - true = dual-lens camera (e.g., TrackMix, TrackFlex) with multiple channels on a single device
|
|
9555
|
+
* - false = single-lens camera
|
|
9556
|
+
* Multi-focal cameras reject concurrent streaming TCP connections (response_code 430),
|
|
9557
|
+
* so all channels must multiplex on the same streaming socket.
|
|
9558
|
+
*/
|
|
9559
|
+
_isMultiFocal;
|
|
9548
9560
|
/** Maximum dedicated sessions allowed before triggering a reboot (default: 7). */
|
|
9549
9561
|
maxDedicatedSessionsBeforeReboot;
|
|
9550
9562
|
sessionGuardRebootInFlight;
|
|
@@ -9575,6 +9587,15 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
9575
9587
|
simpleEventResubscribeTimer;
|
|
9576
9588
|
simpleEventResubscribeInFlight;
|
|
9577
9589
|
simpleEventResubscribeIntervalMs = 5 * 6e4;
|
|
9590
|
+
// Event watchdog: auto-recovery when events stop flowing or subscription fails
|
|
9591
|
+
simpleEventWatchdogTimer;
|
|
9592
|
+
simpleEventLastReceivedAt = 0;
|
|
9593
|
+
simpleEventWatchdogRecoveryAttempts = 0;
|
|
9594
|
+
simpleEventWatchdogLastRecoveryAt = 0;
|
|
9595
|
+
simpleEventWatchdogIntervalMs = 1e4;
|
|
9596
|
+
// check every 10s
|
|
9597
|
+
simpleEventWatchdogSilenceThresholdMs = 5 * 6e4;
|
|
9598
|
+
// 5 min without events
|
|
9578
9599
|
statePollingInterval;
|
|
9579
9600
|
udpSleepInferenceInterval;
|
|
9580
9601
|
udpLastInferredSleepStateByChannel = /* @__PURE__ */ new Map();
|
|
@@ -9959,14 +9980,16 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
9959
9980
|
* Determine the socket tag for a given sessionKey.
|
|
9960
9981
|
* This implements the tag-based allocation strategy:
|
|
9961
9982
|
*
|
|
9962
|
-
* - "general" - commands, events
|
|
9963
|
-
* - "streaming:ch{N}" - main + sub for channel N (
|
|
9964
|
-
* - "streaming:ch{N}:ext" - ext for channel N (
|
|
9983
|
+
* - "general" - commands, events, ext on ch0
|
|
9984
|
+
* - "streaming:ch{N}" - main + sub for channel N (NVR/standalone single-lens)
|
|
9985
|
+
* - "streaming:ch{N}:ext" - ext for channel N (NVR/standalone, N>0)
|
|
9986
|
+
* - "streaming:a" - ch0 main + ch1 sub (multi-focal dedicated socket)
|
|
9987
|
+
* - "general" also carries ch1 main + ch0 sub for multi-focal (merged with commands/events)
|
|
9965
9988
|
* - "replay:deviceId:ch{N}" - dedicated per device+channel for replay
|
|
9966
9989
|
*
|
|
9967
|
-
*
|
|
9968
|
-
*
|
|
9969
|
-
*
|
|
9990
|
+
* Multi-focal cameras (TrackMix, TrackFlex, Duo) reject two main or two sub
|
|
9991
|
+
* streams on the same TCP connection (response_code 430). Cross-channel pairing
|
|
9992
|
+
* ensures each socket always has a valid M+S combination using only 2 TCP connections.
|
|
9970
9993
|
*
|
|
9971
9994
|
* @param sessionKey - The session key (e.g., "live:device:ch0:main", "replay:device:ch1:file")
|
|
9972
9995
|
* @returns The socket pool tag to use
|
|
@@ -9986,9 +10009,16 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
9986
10009
|
if (channel === 0) {
|
|
9987
10010
|
return "general";
|
|
9988
10011
|
}
|
|
9989
|
-
|
|
10012
|
+
if (this._isMultiFocal) {
|
|
10013
|
+
return "general";
|
|
10014
|
+
}
|
|
10015
|
+
return this._isNvr ? `streaming:ch${channel}:ext` : `streaming:ch${channel}:ext`;
|
|
10016
|
+
}
|
|
10017
|
+
if (this._isMultiFocal) {
|
|
10018
|
+
const isSocketA = channel === 0 && profile === "main" || channel === 1 && profile === "sub";
|
|
10019
|
+
return isSocketA ? "streaming:a" : "general";
|
|
9990
10020
|
}
|
|
9991
|
-
return `streaming:ch${channel}`;
|
|
10021
|
+
return this._isNvr ? `streaming:ch${channel}` : `streaming:ch${channel}`;
|
|
9992
10022
|
}
|
|
9993
10023
|
return "general";
|
|
9994
10024
|
}
|
|
@@ -10313,6 +10343,14 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
10313
10343
|
async cleanupDedicatedClients() {
|
|
10314
10344
|
}
|
|
10315
10345
|
dispatchSimpleEvent(evt) {
|
|
10346
|
+
this.simpleEventLastReceivedAt = Date.now();
|
|
10347
|
+
if (this.simpleEventWatchdogRecoveryAttempts > 0) {
|
|
10348
|
+
(this.logger.info ?? this.logger.log).call(
|
|
10349
|
+
this.logger,
|
|
10350
|
+
`[ReolinkBaichuanApi] event watchdog: events flowing again after ${this.simpleEventWatchdogRecoveryAttempts} recovery attempt(s)`
|
|
10351
|
+
);
|
|
10352
|
+
this.simpleEventWatchdogRecoveryAttempts = 0;
|
|
10353
|
+
}
|
|
10316
10354
|
const debugCfg = this.client.getDebugConfig?.();
|
|
10317
10355
|
if (debugCfg) {
|
|
10318
10356
|
const sid = this.client.getSocketSessionId?.();
|
|
@@ -10861,11 +10899,15 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
10861
10899
|
/**
|
|
10862
10900
|
* Subscribe to minimal high-level events.
|
|
10863
10901
|
* The API manages Baichuan subscribe/unsubscribe automatically.
|
|
10902
|
+
* Includes built-in watchdog: if no events arrive for 5 minutes while
|
|
10903
|
+
* the connection is alive, the subscription is automatically renewed.
|
|
10864
10904
|
*/
|
|
10865
10905
|
async onSimpleEvent(callback) {
|
|
10866
10906
|
this.simpleEventListeners.add(callback);
|
|
10867
10907
|
await this.ensureSimpleEventSubscribed();
|
|
10908
|
+
this.simpleEventLastReceivedAt = Date.now();
|
|
10868
10909
|
this.startSimpleEventResubscribeTimer();
|
|
10910
|
+
this.startSimpleEventWatchdog();
|
|
10869
10911
|
}
|
|
10870
10912
|
/**
|
|
10871
10913
|
* Remove one callback, or all callbacks if omitted.
|
|
@@ -10879,6 +10921,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
10879
10921
|
}
|
|
10880
10922
|
if (this.simpleEventListeners.size === 0) {
|
|
10881
10923
|
this.stopSimpleEventResubscribeTimer();
|
|
10924
|
+
this.stopSimpleEventWatchdog();
|
|
10882
10925
|
this.stopUdpSleepInference();
|
|
10883
10926
|
await this.ensureSimpleEventUnsubscribed();
|
|
10884
10927
|
} else {
|
|
@@ -10902,6 +10945,97 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
10902
10945
|
clearInterval(this.simpleEventResubscribeTimer);
|
|
10903
10946
|
this.simpleEventResubscribeTimer = void 0;
|
|
10904
10947
|
}
|
|
10948
|
+
/**
|
|
10949
|
+
* Event watchdog: monitors whether events are flowing and auto-recovers if they stop.
|
|
10950
|
+
*
|
|
10951
|
+
* Handles two failure modes:
|
|
10952
|
+
* 1. Subscription flag is true but no events arrive for 5+ minutes (device dropped subscription silently)
|
|
10953
|
+
* 2. Subscription flag is false because initial/retry subscribe failed, but connection is now alive
|
|
10954
|
+
*
|
|
10955
|
+
* Uses exponential backoff (30s → 60s → 120s → 240s → max 5min) to avoid hammering the device.
|
|
10956
|
+
*/
|
|
10957
|
+
startSimpleEventWatchdog() {
|
|
10958
|
+
if (this.simpleEventWatchdogTimer) return;
|
|
10959
|
+
if (this.simpleEventListeners.size === 0) return;
|
|
10960
|
+
this.simpleEventWatchdogTimer = setInterval(() => {
|
|
10961
|
+
void this.simpleEventWatchdogTick();
|
|
10962
|
+
}, this.simpleEventWatchdogIntervalMs);
|
|
10963
|
+
}
|
|
10964
|
+
stopSimpleEventWatchdog() {
|
|
10965
|
+
if (!this.simpleEventWatchdogTimer) return;
|
|
10966
|
+
clearInterval(this.simpleEventWatchdogTimer);
|
|
10967
|
+
this.simpleEventWatchdogTimer = void 0;
|
|
10968
|
+
this.simpleEventWatchdogRecoveryAttempts = 0;
|
|
10969
|
+
this.simpleEventWatchdogLastRecoveryAt = 0;
|
|
10970
|
+
this.simpleEventLastReceivedAt = 0;
|
|
10971
|
+
}
|
|
10972
|
+
async simpleEventWatchdogTick() {
|
|
10973
|
+
if (this.simpleEventListeners.size === 0) return;
|
|
10974
|
+
if (!this.client.isSocketConnected?.() || !this.client.loggedIn) return;
|
|
10975
|
+
const now = Date.now();
|
|
10976
|
+
if (this.simpleEventSubscribed && this.simpleEventLastReceivedAt > 0) {
|
|
10977
|
+
const silence = now - this.simpleEventLastReceivedAt;
|
|
10978
|
+
if (silence < this.simpleEventWatchdogSilenceThresholdMs) return;
|
|
10979
|
+
(this.logger.warn ?? this.logger.log).call(
|
|
10980
|
+
this.logger,
|
|
10981
|
+
`[ReolinkBaichuanApi] event watchdog: no events for ${Math.round(silence / 6e4)} min, forcing resubscribe`,
|
|
10982
|
+
{ host: this.host, silenceMs: silence }
|
|
10983
|
+
);
|
|
10984
|
+
try {
|
|
10985
|
+
this.simpleEventSubscribed = false;
|
|
10986
|
+
this.client.subscribed = false;
|
|
10987
|
+
await this.ensureSimpleEventSubscribed();
|
|
10988
|
+
this.simpleEventLastReceivedAt = Date.now();
|
|
10989
|
+
this.simpleEventWatchdogRecoveryAttempts = 0;
|
|
10990
|
+
(this.logger.info ?? this.logger.log).call(
|
|
10991
|
+
this.logger,
|
|
10992
|
+
`[ReolinkBaichuanApi] event watchdog: resubscribed successfully after silence`
|
|
10993
|
+
);
|
|
10994
|
+
} catch (e) {
|
|
10995
|
+
(this.logger.debug ?? this.logger.log).call(
|
|
10996
|
+
this.logger,
|
|
10997
|
+
`[ReolinkBaichuanApi] event watchdog: resubscribe after silence failed`,
|
|
10998
|
+
formatErrorForLog(e)
|
|
10999
|
+
);
|
|
11000
|
+
}
|
|
11001
|
+
return;
|
|
11002
|
+
}
|
|
11003
|
+
if (!this.simpleEventSubscribed) {
|
|
11004
|
+
const backoffMs = Math.min(
|
|
11005
|
+
3e4 * Math.pow(2, this.simpleEventWatchdogRecoveryAttempts),
|
|
11006
|
+
this.simpleEventWatchdogSilenceThresholdMs
|
|
11007
|
+
);
|
|
11008
|
+
if (now - this.simpleEventWatchdogLastRecoveryAt < backoffMs) return;
|
|
11009
|
+
this.simpleEventWatchdogRecoveryAttempts++;
|
|
11010
|
+
this.simpleEventWatchdogLastRecoveryAt = now;
|
|
11011
|
+
const nextBackoff = Math.min(
|
|
11012
|
+
3e4 * Math.pow(2, this.simpleEventWatchdogRecoveryAttempts),
|
|
11013
|
+
this.simpleEventWatchdogSilenceThresholdMs
|
|
11014
|
+
);
|
|
11015
|
+
(this.logger.info ?? this.logger.log).call(
|
|
11016
|
+
this.logger,
|
|
11017
|
+
`[ReolinkBaichuanApi] event watchdog: subscription inactive, attempting auto-recovery (attempt #${this.simpleEventWatchdogRecoveryAttempts}, next backoff ${Math.round(nextBackoff / 1e3)}s)`,
|
|
11018
|
+
{ host: this.host }
|
|
11019
|
+
);
|
|
11020
|
+
try {
|
|
11021
|
+
await this.ensureSimpleEventSubscribed();
|
|
11022
|
+
if (this.simpleEventSubscribed) {
|
|
11023
|
+
this.simpleEventLastReceivedAt = Date.now();
|
|
11024
|
+
(this.logger.info ?? this.logger.log).call(
|
|
11025
|
+
this.logger,
|
|
11026
|
+
`[ReolinkBaichuanApi] event watchdog: auto-recovery successful after ${this.simpleEventWatchdogRecoveryAttempts} attempt(s)`
|
|
11027
|
+
);
|
|
11028
|
+
this.simpleEventWatchdogRecoveryAttempts = 0;
|
|
11029
|
+
}
|
|
11030
|
+
} catch (e) {
|
|
11031
|
+
(this.logger.debug ?? this.logger.log).call(
|
|
11032
|
+
this.logger,
|
|
11033
|
+
`[ReolinkBaichuanApi] event watchdog: recovery attempt #${this.simpleEventWatchdogRecoveryAttempts} failed`,
|
|
11034
|
+
formatErrorForLog(e)
|
|
11035
|
+
);
|
|
11036
|
+
}
|
|
11037
|
+
}
|
|
11038
|
+
}
|
|
10905
11039
|
async renewSimpleEventSubscription() {
|
|
10906
11040
|
if (this.simpleEventListeners.size === 0) return;
|
|
10907
11041
|
if (this.simpleEventResubscribeInFlight)
|
|
@@ -11040,6 +11174,17 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
11040
11174
|
this._isNvr = isNvr;
|
|
11041
11175
|
this.logger.debug?.(`[ReolinkBaichuanApi] setIsNvr: ${isNvr}`);
|
|
11042
11176
|
}
|
|
11177
|
+
/**
|
|
11178
|
+
* Set the multi-focal flag explicitly.
|
|
11179
|
+
* Call this early (before streaming) to ensure correct socket pooling.
|
|
11180
|
+
* Multi-focal cameras (TrackMix, TrackFlex, Duo, etc.) reject concurrent
|
|
11181
|
+
* streaming TCP connections, so all channels must share a single streaming socket.
|
|
11182
|
+
* @param isMultiFocal - true if this is a dual-lens/multi-focal camera
|
|
11183
|
+
*/
|
|
11184
|
+
setIsMultiFocal(isMultiFocal) {
|
|
11185
|
+
this._isMultiFocal = isMultiFocal;
|
|
11186
|
+
this.logger.debug?.(`[ReolinkBaichuanApi] setIsMultiFocal: ${isMultiFocal}`);
|
|
11187
|
+
}
|
|
11043
11188
|
/**
|
|
11044
11189
|
* Enable or disable idle disconnect dynamically.
|
|
11045
11190
|
*
|
|
@@ -11090,6 +11235,8 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
11090
11235
|
}
|
|
11091
11236
|
this.stopStatePolling();
|
|
11092
11237
|
this.stopUdpSleepInference();
|
|
11238
|
+
this.stopSimpleEventWatchdog();
|
|
11239
|
+
this.stopSimpleEventResubscribeTimer();
|
|
11093
11240
|
await this.cleanup();
|
|
11094
11241
|
await this.stopAllActiveStreams();
|
|
11095
11242
|
await this.cleanupSocketPool();
|
|
@@ -16541,7 +16688,7 @@ ${xml}`
|
|
|
16541
16688
|
});
|
|
16542
16689
|
model = typeof info.type === "string" ? info.type.toLowerCase() : "";
|
|
16543
16690
|
isMultiFocal = isDualLenseModel(model);
|
|
16544
|
-
isTrackMix = model.includes("trackmix");
|
|
16691
|
+
isTrackMix = model.includes("trackmix") || model.includes("trackflex");
|
|
16545
16692
|
} catch (e) {
|
|
16546
16693
|
logDebug(
|
|
16547
16694
|
"[ReolinkBaichuanApi] buildVideoStreamOptions: getInfo(type) failed",
|
|
@@ -16946,7 +17093,7 @@ ${xml}`
|
|
|
16946
17093
|
* @returns Test results for all stream types and profiles
|
|
16947
17094
|
*/
|
|
16948
17095
|
async testChannelStreams(channel, logger) {
|
|
16949
|
-
const { testChannelStreams } = await import("./DiagnosticsTools-
|
|
17096
|
+
const { testChannelStreams } = await import("./DiagnosticsTools-NUMCYEKQ.js");
|
|
16950
17097
|
return await testChannelStreams({
|
|
16951
17098
|
api: this,
|
|
16952
17099
|
channel: this.normalizeChannel(channel),
|
|
@@ -16962,7 +17109,7 @@ ${xml}`
|
|
|
16962
17109
|
* @returns Complete diagnostics for all channels and streams
|
|
16963
17110
|
*/
|
|
16964
17111
|
async collectMultifocalDiagnostics(logger) {
|
|
16965
|
-
const { collectMultifocalDiagnostics } = await import("./DiagnosticsTools-
|
|
17112
|
+
const { collectMultifocalDiagnostics } = await import("./DiagnosticsTools-NUMCYEKQ.js");
|
|
16966
17113
|
return await collectMultifocalDiagnostics({
|
|
16967
17114
|
api: this,
|
|
16968
17115
|
logger
|
|
@@ -20065,4 +20212,4 @@ export {
|
|
|
20065
20212
|
isTcpFailureThatShouldFallbackToUdp,
|
|
20066
20213
|
autoDetectDeviceType
|
|
20067
20214
|
};
|
|
20068
|
-
//# sourceMappingURL=chunk-
|
|
20215
|
+
//# sourceMappingURL=chunk-EHWVA3SG.js.map
|