@camstack/sdk 0.1.23
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/README.md +57 -0
- package/dist/index.cjs +1169 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +1087 -0
- package/dist/index.js.map +1 -0
- package/package.json +31 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1087 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
|
|
4
|
+
// src/backend-client.ts
|
|
5
|
+
import { createTRPCClient, createWSClient, wsLink, httpLink } from "@trpc/client";
|
|
6
|
+
import superjson from "superjson";
|
|
7
|
+
var BackendClient = class {
|
|
8
|
+
static {
|
|
9
|
+
__name(this, "BackendClient");
|
|
10
|
+
}
|
|
11
|
+
/** Raw tRPC client — for advanced usage / direct path access */
|
|
12
|
+
trpc;
|
|
13
|
+
serverUrl;
|
|
14
|
+
token;
|
|
15
|
+
wsClient = null;
|
|
16
|
+
constructor(config) {
|
|
17
|
+
this.serverUrl = config.serverUrl.replace(/\/+$/, "");
|
|
18
|
+
this.token = config.token;
|
|
19
|
+
const isBrowser = typeof window !== "undefined";
|
|
20
|
+
const useWs = config.useWebSocket ?? isBrowser;
|
|
21
|
+
const headers = /* @__PURE__ */ __name(() => {
|
|
22
|
+
const h = {};
|
|
23
|
+
if (this.token) {
|
|
24
|
+
h["Authorization"] = `Bearer ${this.token}`;
|
|
25
|
+
}
|
|
26
|
+
return h;
|
|
27
|
+
}, "headers");
|
|
28
|
+
if (useWs) {
|
|
29
|
+
const wsUrl = this.serverUrl.replace(/^http/, "ws") + "/trpc";
|
|
30
|
+
this.wsClient = createWSClient({
|
|
31
|
+
url: wsUrl,
|
|
32
|
+
connectionParams: /* @__PURE__ */ __name(() => ({
|
|
33
|
+
token: this.token
|
|
34
|
+
}), "connectionParams"),
|
|
35
|
+
retryDelayMs: /* @__PURE__ */ __name(() => 2e3, "retryDelayMs")
|
|
36
|
+
});
|
|
37
|
+
this.trpc = createTRPCClient({
|
|
38
|
+
links: [
|
|
39
|
+
wsLink({
|
|
40
|
+
client: this.wsClient,
|
|
41
|
+
transformer: superjson
|
|
42
|
+
})
|
|
43
|
+
]
|
|
44
|
+
});
|
|
45
|
+
} else {
|
|
46
|
+
this.trpc = createTRPCClient({
|
|
47
|
+
links: [
|
|
48
|
+
httpLink({
|
|
49
|
+
url: `${this.serverUrl}/trpc`,
|
|
50
|
+
headers,
|
|
51
|
+
transformer: superjson
|
|
52
|
+
})
|
|
53
|
+
]
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/** Update the auth token (e.g. after login) */
|
|
58
|
+
setToken(token) {
|
|
59
|
+
this.token = token;
|
|
60
|
+
}
|
|
61
|
+
/** Close the WebSocket connection (if using WS transport) */
|
|
62
|
+
close() {
|
|
63
|
+
this.wsClient?.close();
|
|
64
|
+
}
|
|
65
|
+
// ─── Auth ──────────────────────────────────────────────────────────
|
|
66
|
+
async login(username, password) {
|
|
67
|
+
return this.trpc.auth.login.mutate({
|
|
68
|
+
username,
|
|
69
|
+
password
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
async getMe() {
|
|
73
|
+
return this.trpc.auth.me.query();
|
|
74
|
+
}
|
|
75
|
+
async logout() {
|
|
76
|
+
return this.trpc.auth.logout.mutate();
|
|
77
|
+
}
|
|
78
|
+
// ─── System ────────────────────────────────────────────────────────
|
|
79
|
+
async getSystemInfo() {
|
|
80
|
+
return this.trpc.system.info.query();
|
|
81
|
+
}
|
|
82
|
+
async getFeatureFlags() {
|
|
83
|
+
return this.trpc.system.featureFlags.query();
|
|
84
|
+
}
|
|
85
|
+
// ─── Providers ─────────────────────────────────────────────────────
|
|
86
|
+
async listProviders() {
|
|
87
|
+
return this.trpc.providers.list.query();
|
|
88
|
+
}
|
|
89
|
+
async getProvider(providerId) {
|
|
90
|
+
return this.trpc.providers.get.query({
|
|
91
|
+
id: providerId
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
async startProvider(providerId) {
|
|
95
|
+
return this.trpc.providers.start.mutate({
|
|
96
|
+
id: providerId
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
async stopProvider(providerId) {
|
|
100
|
+
return this.trpc.providers.stop.mutate({
|
|
101
|
+
id: providerId
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
async listProviderTypes() {
|
|
105
|
+
return this.trpc.providerConfig.getAvailableTypes.query();
|
|
106
|
+
}
|
|
107
|
+
// ─── Devices ───────────────────────────────────────────────────────
|
|
108
|
+
async listDevices() {
|
|
109
|
+
return this.trpc.devices.list.query();
|
|
110
|
+
}
|
|
111
|
+
async getDevice(deviceId) {
|
|
112
|
+
return this.trpc.devices.get.query({
|
|
113
|
+
id: deviceId
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
async discoverDevices(providerId) {
|
|
117
|
+
return this.trpc.devices.discoverDevices.query({
|
|
118
|
+
providerId
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
async adoptDevice(providerId, externalId) {
|
|
122
|
+
return this.trpc.devices.adoptDevice.mutate({
|
|
123
|
+
providerId,
|
|
124
|
+
externalId
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
async createDevice(providerId, config) {
|
|
128
|
+
return this.trpc.devices.createDevice.mutate({
|
|
129
|
+
providerId,
|
|
130
|
+
config
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/** Returns the URL path for a static asset served by an addon. */
|
|
134
|
+
getAddonAssetUrl(addonId, assetPath) {
|
|
135
|
+
return `/api/addon-assets/${addonId}/${assetPath}`;
|
|
136
|
+
}
|
|
137
|
+
// ─── Addons ────────────────────────────────────────────────────────
|
|
138
|
+
async listAddons() {
|
|
139
|
+
return this.trpc.addons.list.query();
|
|
140
|
+
}
|
|
141
|
+
async getAddonConfigSchema(addonId) {
|
|
142
|
+
return this.trpc.addons.getConfigSchema.query({
|
|
143
|
+
addonId
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
async getAddonConfig(addonId) {
|
|
147
|
+
return this.trpc.addons.getConfig.query({
|
|
148
|
+
addonId
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
async updateAddonConfig(addonId, config) {
|
|
152
|
+
return this.trpc.addons.updateConfig.mutate({
|
|
153
|
+
addonId,
|
|
154
|
+
config
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
async getAddonLogs(addonId, options) {
|
|
158
|
+
return this.trpc.addons.getLogs.query({
|
|
159
|
+
addonId,
|
|
160
|
+
...options
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
// ─── Known Faces ───────────────────────────────────────────────────
|
|
164
|
+
async listKnownFaces() {
|
|
165
|
+
return this.trpc.knownFaces.list.query();
|
|
166
|
+
}
|
|
167
|
+
async registerFace(label, cropBase64, group) {
|
|
168
|
+
return this.trpc.knownFaces.register.mutate({
|
|
169
|
+
label,
|
|
170
|
+
cropBase64,
|
|
171
|
+
group
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
// ─── Pipeline ──────────────────────────────────────────────────────
|
|
175
|
+
async listPipelines() {
|
|
176
|
+
return this.trpc.bridgePipeline.listAddons.query();
|
|
177
|
+
}
|
|
178
|
+
async getPipelineStatus(deviceId) {
|
|
179
|
+
return this.trpc.bridgePipeline.getPipeline.query({
|
|
180
|
+
deviceId
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
// ─── Agents ────────────────────────────────────────────────────────
|
|
184
|
+
async listAgents() {
|
|
185
|
+
return this.trpc.agents.listAgents.query();
|
|
186
|
+
}
|
|
187
|
+
async dispatchTask(agentId, task) {
|
|
188
|
+
return this.trpc.agents.dispatchTask.mutate({
|
|
189
|
+
capability: agentId,
|
|
190
|
+
input: task
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
async getProcessTree() {
|
|
194
|
+
return this.trpc.agent.processTree.query();
|
|
195
|
+
}
|
|
196
|
+
// ─── Bridge Pipeline ───────────────────────────────────────────────
|
|
197
|
+
async bridgeListAddons() {
|
|
198
|
+
return this.trpc.bridgePipeline.listAddons.query();
|
|
199
|
+
}
|
|
200
|
+
async bridgeGetPipeline(deviceId) {
|
|
201
|
+
return this.trpc.bridgePipeline.getPipeline.query({
|
|
202
|
+
deviceId
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
async bridgeSetPipeline(deviceId, config) {
|
|
206
|
+
return this.trpc.bridgePipeline.setPipeline.mutate({
|
|
207
|
+
deviceId,
|
|
208
|
+
config
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
async bridgeValidatePipeline(config) {
|
|
212
|
+
return this.trpc.bridgePipeline.validatePipeline.query(config);
|
|
213
|
+
}
|
|
214
|
+
async bridgeGetAddonConfig(addonId) {
|
|
215
|
+
return this.trpc.bridgePipeline.getAddonConfig.query({
|
|
216
|
+
addonId
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
async bridgeSetAddonConfig(addonId, config) {
|
|
220
|
+
return this.trpc.bridgePipeline.setAddonConfig.mutate({
|
|
221
|
+
addonId,
|
|
222
|
+
config
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
// ─── Bridge Addons ─────────────────────────────────────────────────
|
|
226
|
+
async bridgeListPackages() {
|
|
227
|
+
return this.trpc.bridgeAddons.listPackages.query();
|
|
228
|
+
}
|
|
229
|
+
async bridgeListAddonsPackages() {
|
|
230
|
+
return this.trpc.bridgeAddons.listAddons.query();
|
|
231
|
+
}
|
|
232
|
+
async bridgeInstallPackage(packageName, version) {
|
|
233
|
+
return this.trpc.bridgeAddons.installPackage.mutate({
|
|
234
|
+
packageName,
|
|
235
|
+
version
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
async bridgeUninstallPackage(packageName) {
|
|
239
|
+
return this.trpc.bridgeAddons.uninstallPackage.mutate({
|
|
240
|
+
packageName
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
// ─── Recording ─────────────────────────────────────────────────────
|
|
244
|
+
async getRecordingConfig(deviceId) {
|
|
245
|
+
return this.trpc.recording.getConfig.query({
|
|
246
|
+
deviceId
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
async getRecordingPolicy(deviceId) {
|
|
250
|
+
return this.trpc.recording.getPolicy.query({
|
|
251
|
+
deviceId
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
async getRecordingPolicyStatus(deviceId) {
|
|
255
|
+
return this.trpc.recording.getPolicyStatus.query({
|
|
256
|
+
deviceId
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
async getRecordingSegments(deviceId, streamId, startTime, endTime) {
|
|
260
|
+
return this.trpc.recording.getSegments.query({
|
|
261
|
+
deviceId,
|
|
262
|
+
streamId,
|
|
263
|
+
startTime,
|
|
264
|
+
endTime
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
// ─── Events ────────────────────────────────────────────────────────
|
|
268
|
+
async getEvents(deviceId, options) {
|
|
269
|
+
return this.trpc.events.query.query({
|
|
270
|
+
deviceId,
|
|
271
|
+
...options
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
// ─── Logs ──────────────────────────────────────────────────────────
|
|
275
|
+
async getLogs(options) {
|
|
276
|
+
return this.trpc.logs.query.query(options ?? {});
|
|
277
|
+
}
|
|
278
|
+
// ─── REPL ──────────────────────────────────────────────────────────
|
|
279
|
+
async replEval(code, scope) {
|
|
280
|
+
return this.trpc.repl.execute.mutate({
|
|
281
|
+
code,
|
|
282
|
+
scope: scope ?? {
|
|
283
|
+
type: "system"
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
// ─── Users ─────────────────────────────────────────────────────────
|
|
288
|
+
async listUsers() {
|
|
289
|
+
return this.trpc.users.list.query();
|
|
290
|
+
}
|
|
291
|
+
async createUser(username, password, role) {
|
|
292
|
+
return this.trpc.users.create.mutate({
|
|
293
|
+
username,
|
|
294
|
+
password,
|
|
295
|
+
role
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
// ─── Session Tracker ───────────────────────────────────────────────
|
|
299
|
+
async getTrackingSessions(deviceId) {
|
|
300
|
+
return this.trpc.session.getActiveTracks.query({
|
|
301
|
+
deviceId
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
// ─── Processes ─────────────────────────────────────────────────────
|
|
305
|
+
async listProcesses() {
|
|
306
|
+
return this.trpc.processes.listProcesses.query();
|
|
307
|
+
}
|
|
308
|
+
async enableProvider(providerId) {
|
|
309
|
+
return this.trpc.processes.enableProvider.mutate({
|
|
310
|
+
id: providerId
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
async disableProvider(providerId) {
|
|
314
|
+
return this.trpc.processes.disableProvider.mutate({
|
|
315
|
+
id: providerId
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
// ─── Settings ──────────────────────────────────────────────────────
|
|
319
|
+
/** Fetch the UI schema for a single section, or all sections if omitted. */
|
|
320
|
+
async getSettingsSchema(section) {
|
|
321
|
+
return this.trpc.settings.getSchema.query({
|
|
322
|
+
section
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
async getSettings(section) {
|
|
326
|
+
return this.trpc.settings.get.query({
|
|
327
|
+
section
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
async updateSettings(section, data) {
|
|
331
|
+
return this.trpc.settings.update.mutate({
|
|
332
|
+
section,
|
|
333
|
+
data
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
function createBackendClient(config) {
|
|
338
|
+
return new BackendClient(config);
|
|
339
|
+
}
|
|
340
|
+
__name(createBackendClient, "createBackendClient");
|
|
341
|
+
|
|
342
|
+
// src/detection.ts
|
|
343
|
+
var DetectionClass = /* @__PURE__ */ (function(DetectionClass2) {
|
|
344
|
+
DetectionClass2["Motion"] = "motion";
|
|
345
|
+
DetectionClass2["Person"] = "person";
|
|
346
|
+
DetectionClass2["Vehicle"] = "vehicle";
|
|
347
|
+
DetectionClass2["Animal"] = "animal";
|
|
348
|
+
DetectionClass2["Audio"] = "audio";
|
|
349
|
+
DetectionClass2["Face"] = "face";
|
|
350
|
+
DetectionClass2["Plate"] = "plate";
|
|
351
|
+
DetectionClass2["Package"] = "package";
|
|
352
|
+
DetectionClass2["Doorbell"] = "doorbell";
|
|
353
|
+
DetectionClass2["Sensor"] = "sensor";
|
|
354
|
+
return DetectionClass2;
|
|
355
|
+
})({});
|
|
356
|
+
var animalClasses = [
|
|
357
|
+
"animal",
|
|
358
|
+
"dog_cat",
|
|
359
|
+
"dog",
|
|
360
|
+
"cat",
|
|
361
|
+
"horse",
|
|
362
|
+
"sheep",
|
|
363
|
+
"cow",
|
|
364
|
+
"elephant",
|
|
365
|
+
"bear",
|
|
366
|
+
"zebra",
|
|
367
|
+
"giraffe",
|
|
368
|
+
"mouse",
|
|
369
|
+
"rabbit",
|
|
370
|
+
"deer",
|
|
371
|
+
"lion",
|
|
372
|
+
"tiger",
|
|
373
|
+
"bird",
|
|
374
|
+
"eagle",
|
|
375
|
+
"owl",
|
|
376
|
+
"pigeon",
|
|
377
|
+
"fish",
|
|
378
|
+
"whale",
|
|
379
|
+
"dolphin",
|
|
380
|
+
"snake",
|
|
381
|
+
"turtle",
|
|
382
|
+
"lizard"
|
|
383
|
+
];
|
|
384
|
+
var personClasses = [
|
|
385
|
+
"person",
|
|
386
|
+
"people",
|
|
387
|
+
"pedestrian",
|
|
388
|
+
"rider",
|
|
389
|
+
"driver",
|
|
390
|
+
"cyclist",
|
|
391
|
+
"skier",
|
|
392
|
+
"skateboarder",
|
|
393
|
+
"face",
|
|
394
|
+
"hand",
|
|
395
|
+
"head",
|
|
396
|
+
"body"
|
|
397
|
+
];
|
|
398
|
+
var vehicleClasses = [
|
|
399
|
+
"vehicle",
|
|
400
|
+
"car",
|
|
401
|
+
"truck",
|
|
402
|
+
"bus",
|
|
403
|
+
"motorcycle",
|
|
404
|
+
"bicycle",
|
|
405
|
+
"van",
|
|
406
|
+
"ambulance",
|
|
407
|
+
"police_car",
|
|
408
|
+
"fire_truck",
|
|
409
|
+
"train",
|
|
410
|
+
"subway",
|
|
411
|
+
"tram",
|
|
412
|
+
"airplane",
|
|
413
|
+
"boat",
|
|
414
|
+
"ship",
|
|
415
|
+
"helicopter"
|
|
416
|
+
];
|
|
417
|
+
var faceClasses = [
|
|
418
|
+
"face",
|
|
419
|
+
"eyes",
|
|
420
|
+
"nose",
|
|
421
|
+
"mouth",
|
|
422
|
+
"ears",
|
|
423
|
+
"eyebrows",
|
|
424
|
+
"left_eye",
|
|
425
|
+
"right_eye",
|
|
426
|
+
"pupil",
|
|
427
|
+
"iris",
|
|
428
|
+
"eyelid",
|
|
429
|
+
"eye_corner",
|
|
430
|
+
"upper_lip",
|
|
431
|
+
"lower_lip",
|
|
432
|
+
"teeth",
|
|
433
|
+
"chin",
|
|
434
|
+
"cheek",
|
|
435
|
+
"forehead",
|
|
436
|
+
"jaw",
|
|
437
|
+
"glasses",
|
|
438
|
+
"sunglasses",
|
|
439
|
+
"facial_hair",
|
|
440
|
+
"beard",
|
|
441
|
+
"mustache",
|
|
442
|
+
"facial_landmark",
|
|
443
|
+
"facial_keypoint"
|
|
444
|
+
];
|
|
445
|
+
var licensePlateClasses = [
|
|
446
|
+
"plate",
|
|
447
|
+
"license_plate",
|
|
448
|
+
"front_plate",
|
|
449
|
+
"rear_plate",
|
|
450
|
+
"motorcycle_plate",
|
|
451
|
+
"temporary_plate",
|
|
452
|
+
"dealer_plate",
|
|
453
|
+
"licensePlate",
|
|
454
|
+
"plate_number",
|
|
455
|
+
"plate_character",
|
|
456
|
+
"plate_digit",
|
|
457
|
+
"plate_letter",
|
|
458
|
+
"plate_symbol",
|
|
459
|
+
"plate_region",
|
|
460
|
+
"plate_country_identifier",
|
|
461
|
+
"plate_frame",
|
|
462
|
+
"plate_bolt",
|
|
463
|
+
"plate_sticker",
|
|
464
|
+
"plate_validation_tag",
|
|
465
|
+
"damaged_plate",
|
|
466
|
+
"obscured_plate",
|
|
467
|
+
"dirty_plate"
|
|
468
|
+
];
|
|
469
|
+
var motionClasses = [
|
|
470
|
+
"motion",
|
|
471
|
+
"movement",
|
|
472
|
+
"other"
|
|
473
|
+
];
|
|
474
|
+
var packageClasses = [
|
|
475
|
+
"package",
|
|
476
|
+
"packet"
|
|
477
|
+
];
|
|
478
|
+
var audioClasses = [
|
|
479
|
+
"audio"
|
|
480
|
+
];
|
|
481
|
+
var audioLabelClasses = [
|
|
482
|
+
"speech",
|
|
483
|
+
"scream",
|
|
484
|
+
"babbling",
|
|
485
|
+
"yell",
|
|
486
|
+
"bellow",
|
|
487
|
+
"whoop",
|
|
488
|
+
"whispering",
|
|
489
|
+
"laughter",
|
|
490
|
+
"snicker",
|
|
491
|
+
"crying",
|
|
492
|
+
"cry",
|
|
493
|
+
"sigh",
|
|
494
|
+
"singing",
|
|
495
|
+
"choir",
|
|
496
|
+
"chant",
|
|
497
|
+
"mantra",
|
|
498
|
+
"child_singing",
|
|
499
|
+
"rapping",
|
|
500
|
+
"humming",
|
|
501
|
+
"groan",
|
|
502
|
+
"grunt",
|
|
503
|
+
"whistling",
|
|
504
|
+
"breathing",
|
|
505
|
+
"wheeze",
|
|
506
|
+
"snoring",
|
|
507
|
+
"gasp",
|
|
508
|
+
"pant",
|
|
509
|
+
"snort",
|
|
510
|
+
"cough",
|
|
511
|
+
"throat_clearing",
|
|
512
|
+
"sneeze",
|
|
513
|
+
"sniff",
|
|
514
|
+
"cheering",
|
|
515
|
+
"applause",
|
|
516
|
+
"chatter",
|
|
517
|
+
"crowd",
|
|
518
|
+
"children_playing",
|
|
519
|
+
"bark",
|
|
520
|
+
"yip",
|
|
521
|
+
"howl",
|
|
522
|
+
"bow-wow",
|
|
523
|
+
"growling",
|
|
524
|
+
"whimper_dog",
|
|
525
|
+
"purr",
|
|
526
|
+
"meow",
|
|
527
|
+
"hiss",
|
|
528
|
+
"caterwaul",
|
|
529
|
+
"pets",
|
|
530
|
+
"livestock",
|
|
531
|
+
"doorbell",
|
|
532
|
+
"ding-dong",
|
|
533
|
+
"door",
|
|
534
|
+
"slam",
|
|
535
|
+
"knock",
|
|
536
|
+
"alarm",
|
|
537
|
+
"telephone",
|
|
538
|
+
"music",
|
|
539
|
+
"dog",
|
|
540
|
+
"dogs"
|
|
541
|
+
];
|
|
542
|
+
var doorbellClasses = [
|
|
543
|
+
"doorbell",
|
|
544
|
+
"ring"
|
|
545
|
+
];
|
|
546
|
+
var sensorLabelClasses = [
|
|
547
|
+
"lock",
|
|
548
|
+
"binary",
|
|
549
|
+
"flood",
|
|
550
|
+
"entry",
|
|
551
|
+
"door",
|
|
552
|
+
"leak",
|
|
553
|
+
"door_open",
|
|
554
|
+
"flooded",
|
|
555
|
+
"entry_open"
|
|
556
|
+
];
|
|
557
|
+
var detectionClassesDefaultMap = {
|
|
558
|
+
...animalClasses.reduce((tot, curr) => ({
|
|
559
|
+
...tot,
|
|
560
|
+
[curr]: "animal"
|
|
561
|
+
}), {}),
|
|
562
|
+
...personClasses.reduce((tot, curr) => ({
|
|
563
|
+
...tot,
|
|
564
|
+
[curr]: "person"
|
|
565
|
+
}), {}),
|
|
566
|
+
...vehicleClasses.reduce((tot, curr) => ({
|
|
567
|
+
...tot,
|
|
568
|
+
[curr]: "vehicle"
|
|
569
|
+
}), {}),
|
|
570
|
+
...motionClasses.reduce((tot, curr) => ({
|
|
571
|
+
...tot,
|
|
572
|
+
[curr]: "motion"
|
|
573
|
+
}), {}),
|
|
574
|
+
...packageClasses.reduce((tot, curr) => ({
|
|
575
|
+
...tot,
|
|
576
|
+
[curr]: "package"
|
|
577
|
+
}), {}),
|
|
578
|
+
...faceClasses.reduce((tot, curr) => ({
|
|
579
|
+
...tot,
|
|
580
|
+
[curr]: "face"
|
|
581
|
+
}), {}),
|
|
582
|
+
...licensePlateClasses.reduce((tot, curr) => ({
|
|
583
|
+
...tot,
|
|
584
|
+
[curr]: "plate"
|
|
585
|
+
}), {}),
|
|
586
|
+
...audioClasses.reduce((tot, curr) => ({
|
|
587
|
+
...tot,
|
|
588
|
+
[curr]: "audio"
|
|
589
|
+
}), {}),
|
|
590
|
+
...audioLabelClasses.reduce((tot, curr) => ({
|
|
591
|
+
...tot,
|
|
592
|
+
[curr]: "audio"
|
|
593
|
+
}), {}),
|
|
594
|
+
...doorbellClasses.reduce((tot, curr) => ({
|
|
595
|
+
...tot,
|
|
596
|
+
[curr]: "doorbell"
|
|
597
|
+
}), {}),
|
|
598
|
+
...sensorLabelClasses.reduce((tot, curr) => ({
|
|
599
|
+
...tot,
|
|
600
|
+
[curr]: "sensor"
|
|
601
|
+
}), {})
|
|
602
|
+
};
|
|
603
|
+
var isFaceClassname = /* @__PURE__ */ __name((c) => faceClasses.includes(c), "isFaceClassname");
|
|
604
|
+
var isPlateClassname = /* @__PURE__ */ __name((c) => licensePlateClasses.includes(c), "isPlateClassname");
|
|
605
|
+
var isAnimalClassname = /* @__PURE__ */ __name((c) => animalClasses.includes(c), "isAnimalClassname");
|
|
606
|
+
var isPersonClassname = /* @__PURE__ */ __name((c) => personClasses.includes(c), "isPersonClassname");
|
|
607
|
+
var isVehicleClassname = /* @__PURE__ */ __name((c) => vehicleClasses.includes(c), "isVehicleClassname");
|
|
608
|
+
var isMotionClassname = /* @__PURE__ */ __name((c) => motionClasses.includes(c), "isMotionClassname");
|
|
609
|
+
var isDoorbellClassname = /* @__PURE__ */ __name((c) => doorbellClasses.includes(c), "isDoorbellClassname");
|
|
610
|
+
var isPackageClassname = /* @__PURE__ */ __name((c) => packageClasses.includes(c), "isPackageClassname");
|
|
611
|
+
var isAudioClassname = /* @__PURE__ */ __name((c) => audioClasses.includes(c) || audioLabelClasses.includes(c), "isAudioClassname");
|
|
612
|
+
var isSensorLabelClassname = /* @__PURE__ */ __name((c) => sensorLabelClasses.includes(c), "isSensorLabelClassname");
|
|
613
|
+
var isLabelDetection = /* @__PURE__ */ __name((c) => isFaceClassname(c) || isPlateClassname(c), "isLabelDetection");
|
|
614
|
+
var getParentClass = /* @__PURE__ */ __name((className) => detectionClassesDefaultMap[className], "getParentClass");
|
|
615
|
+
var getParentDetectionClass = /* @__PURE__ */ __name((det) => {
|
|
616
|
+
const { className } = det;
|
|
617
|
+
const baseMap = {
|
|
618
|
+
["face"]: "person",
|
|
619
|
+
["plate"]: "vehicle"
|
|
620
|
+
};
|
|
621
|
+
const parentGroup = detectionClassesDefaultMap[className];
|
|
622
|
+
if (parentGroup && parentGroup !== className) return parentGroup;
|
|
623
|
+
return baseMap[className];
|
|
624
|
+
}, "getParentDetectionClass");
|
|
625
|
+
var defaultDetectionClasses = Object.values(DetectionClass);
|
|
626
|
+
var DEFAULT_ENABLED_CLASSES = defaultDetectionClasses.filter((c) => c !== "motion");
|
|
627
|
+
var TIMELINE_PRESET_CRITICAL = [
|
|
628
|
+
"person",
|
|
629
|
+
"doorbell",
|
|
630
|
+
"package"
|
|
631
|
+
];
|
|
632
|
+
var TIMELINE_PRESET_IMPORTANT = [
|
|
633
|
+
...TIMELINE_PRESET_CRITICAL,
|
|
634
|
+
"vehicle",
|
|
635
|
+
"animal",
|
|
636
|
+
"audio",
|
|
637
|
+
"face",
|
|
638
|
+
"plate"
|
|
639
|
+
];
|
|
640
|
+
var TIMELINE_PRESET_ALL = [
|
|
641
|
+
...DEFAULT_ENABLED_CLASSES
|
|
642
|
+
];
|
|
643
|
+
function getClassesForTimelinePreset(preset, customClasses) {
|
|
644
|
+
switch (preset) {
|
|
645
|
+
case "critical":
|
|
646
|
+
return TIMELINE_PRESET_CRITICAL;
|
|
647
|
+
case "important":
|
|
648
|
+
return TIMELINE_PRESET_IMPORTANT;
|
|
649
|
+
case "all":
|
|
650
|
+
return TIMELINE_PRESET_ALL;
|
|
651
|
+
case "custom":
|
|
652
|
+
return customClasses?.length ? customClasses : DEFAULT_ENABLED_CLASSES;
|
|
653
|
+
default:
|
|
654
|
+
return DEFAULT_ENABLED_CLASSES;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
__name(getClassesForTimelinePreset, "getClassesForTimelinePreset");
|
|
658
|
+
|
|
659
|
+
// src/devices.ts
|
|
660
|
+
var RAW_TO_CANONICAL = {
|
|
661
|
+
// Scrypted PascalCase
|
|
662
|
+
Light: "light",
|
|
663
|
+
Switch: "switch",
|
|
664
|
+
WindowCovering: "cover",
|
|
665
|
+
Lock: "lock",
|
|
666
|
+
SecuritySystem: "alarm",
|
|
667
|
+
Buttons: "button",
|
|
668
|
+
Select: "select",
|
|
669
|
+
Siren: "siren",
|
|
670
|
+
Sensor: "sensor",
|
|
671
|
+
Entry: "entry",
|
|
672
|
+
Program: "script",
|
|
673
|
+
MediaPlayer: "media_player",
|
|
674
|
+
Outlet: "switch",
|
|
675
|
+
// Home Assistant lowercase domains
|
|
676
|
+
light: "light",
|
|
677
|
+
switch: "switch",
|
|
678
|
+
input_boolean: "switch",
|
|
679
|
+
cover: "cover",
|
|
680
|
+
lock: "lock",
|
|
681
|
+
alarm_control_panel: "alarm",
|
|
682
|
+
input_button: "button",
|
|
683
|
+
button: "button",
|
|
684
|
+
input_select: "select",
|
|
685
|
+
select: "select",
|
|
686
|
+
siren: "siren",
|
|
687
|
+
sensor: "sensor",
|
|
688
|
+
media_player: "media_player",
|
|
689
|
+
script: "script"
|
|
690
|
+
};
|
|
691
|
+
var HA_DOMAIN_TYPE_MAP = {
|
|
692
|
+
light: "light",
|
|
693
|
+
switch: "switch",
|
|
694
|
+
input_boolean: "switch",
|
|
695
|
+
cover: "cover",
|
|
696
|
+
lock: "lock",
|
|
697
|
+
alarm_control_panel: "alarm",
|
|
698
|
+
input_button: "button",
|
|
699
|
+
button: "button",
|
|
700
|
+
input_select: "select",
|
|
701
|
+
select: "select",
|
|
702
|
+
siren: "siren",
|
|
703
|
+
sensor: "sensor",
|
|
704
|
+
binary_sensor: "sensor",
|
|
705
|
+
media_player: "media_player",
|
|
706
|
+
script: "script",
|
|
707
|
+
climate: "climate",
|
|
708
|
+
camera: "camera",
|
|
709
|
+
fan: "fan",
|
|
710
|
+
vacuum: "vacuum",
|
|
711
|
+
automation: "automation",
|
|
712
|
+
scene: "scene",
|
|
713
|
+
input_number: "sensor",
|
|
714
|
+
person: "person",
|
|
715
|
+
device_tracker: "tracker",
|
|
716
|
+
weather: "weather",
|
|
717
|
+
water_heater: "climate"
|
|
718
|
+
};
|
|
719
|
+
var SCRYPTED_TYPE_TO_CANONICAL = {
|
|
720
|
+
Light: "light",
|
|
721
|
+
Switch: "switch",
|
|
722
|
+
WindowCovering: "cover",
|
|
723
|
+
Lock: "lock",
|
|
724
|
+
SecuritySystem: "alarm",
|
|
725
|
+
Buttons: "button",
|
|
726
|
+
Select: "select",
|
|
727
|
+
Siren: "siren",
|
|
728
|
+
Sensor: "sensor",
|
|
729
|
+
Entry: "entry",
|
|
730
|
+
Program: "script",
|
|
731
|
+
MediaPlayer: "media_player",
|
|
732
|
+
Camera: "camera",
|
|
733
|
+
Doorbell: "doorbell",
|
|
734
|
+
Fan: "fan",
|
|
735
|
+
Outlet: "switch"
|
|
736
|
+
};
|
|
737
|
+
function getCanonicalDeviceType(rawType) {
|
|
738
|
+
const canonical = RAW_TO_CANONICAL[rawType];
|
|
739
|
+
if (canonical) return canonical;
|
|
740
|
+
const lower = rawType.toLowerCase();
|
|
741
|
+
return RAW_TO_CANONICAL[lower] ?? null;
|
|
742
|
+
}
|
|
743
|
+
__name(getCanonicalDeviceType, "getCanonicalDeviceType");
|
|
744
|
+
var ELIGIBLE_SCRYPTED_DEVICE_TYPES = [
|
|
745
|
+
"Entry",
|
|
746
|
+
"Light",
|
|
747
|
+
"Switch",
|
|
748
|
+
"Lock",
|
|
749
|
+
"SecuritySystem",
|
|
750
|
+
"Buttons",
|
|
751
|
+
"WindowCovering",
|
|
752
|
+
"Siren",
|
|
753
|
+
"Sensor",
|
|
754
|
+
"Select",
|
|
755
|
+
"Program"
|
|
756
|
+
];
|
|
757
|
+
var ELIGIBLE_SCRYPTED_DEVICE_TYPES_SET = new Set(ELIGIBLE_SCRYPTED_DEVICE_TYPES);
|
|
758
|
+
var ELIGIBLE_HA_DOMAINS = [
|
|
759
|
+
"light",
|
|
760
|
+
"switch",
|
|
761
|
+
"input_boolean",
|
|
762
|
+
"cover",
|
|
763
|
+
"lock",
|
|
764
|
+
"alarm_control_panel",
|
|
765
|
+
"input_button",
|
|
766
|
+
"button",
|
|
767
|
+
"input_select",
|
|
768
|
+
"select",
|
|
769
|
+
"siren",
|
|
770
|
+
"media_player",
|
|
771
|
+
"script"
|
|
772
|
+
];
|
|
773
|
+
var ELIGIBLE_HA_DOMAINS_SET = new Set(ELIGIBLE_HA_DOMAINS);
|
|
774
|
+
|
|
775
|
+
// src/features.ts
|
|
776
|
+
var FEATURE_MATRIX = [
|
|
777
|
+
{
|
|
778
|
+
id: "liveStream",
|
|
779
|
+
label: "Live Stream",
|
|
780
|
+
sources: {
|
|
781
|
+
frigate: true,
|
|
782
|
+
scrypted: true,
|
|
783
|
+
rtsp: true
|
|
784
|
+
},
|
|
785
|
+
adapterMethod: "getLiveStream"
|
|
786
|
+
},
|
|
787
|
+
{
|
|
788
|
+
id: "multiResolution",
|
|
789
|
+
label: "Multi-Resolution",
|
|
790
|
+
sources: {
|
|
791
|
+
frigate: true,
|
|
792
|
+
scrypted: true,
|
|
793
|
+
rtsp: false
|
|
794
|
+
},
|
|
795
|
+
adapterMethod: "getResolutions"
|
|
796
|
+
},
|
|
797
|
+
{
|
|
798
|
+
id: "motion",
|
|
799
|
+
label: "Motion Detection",
|
|
800
|
+
sources: {
|
|
801
|
+
frigate: false,
|
|
802
|
+
scrypted: true,
|
|
803
|
+
rtsp: false
|
|
804
|
+
},
|
|
805
|
+
adapterMethod: "getMotion"
|
|
806
|
+
},
|
|
807
|
+
{
|
|
808
|
+
id: "objectDetection",
|
|
809
|
+
label: "Object Detection",
|
|
810
|
+
sources: {
|
|
811
|
+
frigate: false,
|
|
812
|
+
scrypted: true,
|
|
813
|
+
rtsp: false
|
|
814
|
+
},
|
|
815
|
+
adapterMethod: "getObjectDetections"
|
|
816
|
+
},
|
|
817
|
+
{
|
|
818
|
+
id: "audioVolume",
|
|
819
|
+
label: "Audio Level",
|
|
820
|
+
sources: {
|
|
821
|
+
frigate: false,
|
|
822
|
+
scrypted: true,
|
|
823
|
+
rtsp: false
|
|
824
|
+
},
|
|
825
|
+
adapterMethod: "getAudioVolume"
|
|
826
|
+
},
|
|
827
|
+
{
|
|
828
|
+
id: "audioVolumes",
|
|
829
|
+
label: "Audio Volumes (dBFS)",
|
|
830
|
+
sources: {
|
|
831
|
+
frigate: false,
|
|
832
|
+
scrypted: true,
|
|
833
|
+
rtsp: false
|
|
834
|
+
},
|
|
835
|
+
adapterMethod: "getAudioVolumes"
|
|
836
|
+
},
|
|
837
|
+
{
|
|
838
|
+
id: "ptz",
|
|
839
|
+
label: "PTZ Control",
|
|
840
|
+
sources: {
|
|
841
|
+
frigate: false,
|
|
842
|
+
scrypted: true,
|
|
843
|
+
rtsp: false
|
|
844
|
+
},
|
|
845
|
+
adapterMethod: "getPTZ"
|
|
846
|
+
},
|
|
847
|
+
{
|
|
848
|
+
id: "intercom",
|
|
849
|
+
label: "Intercom (Mic)",
|
|
850
|
+
sources: {
|
|
851
|
+
frigate: false,
|
|
852
|
+
scrypted: true,
|
|
853
|
+
rtsp: false
|
|
854
|
+
},
|
|
855
|
+
adapterMethod: "getIntercomSupport"
|
|
856
|
+
},
|
|
857
|
+
{
|
|
858
|
+
id: "deviceStatus",
|
|
859
|
+
label: "Device Status",
|
|
860
|
+
sources: {
|
|
861
|
+
frigate: false,
|
|
862
|
+
scrypted: true,
|
|
863
|
+
rtsp: false
|
|
864
|
+
},
|
|
865
|
+
adapterMethod: "getStatus"
|
|
866
|
+
},
|
|
867
|
+
{
|
|
868
|
+
id: "timeline",
|
|
869
|
+
label: "Detection Timeline",
|
|
870
|
+
sources: {
|
|
871
|
+
frigate: true,
|
|
872
|
+
scrypted: true,
|
|
873
|
+
rtsp: false
|
|
874
|
+
},
|
|
875
|
+
adapterMethod: "getCameraDayData"
|
|
876
|
+
},
|
|
877
|
+
{
|
|
878
|
+
id: "clusteredTimeline",
|
|
879
|
+
label: "Clustered Timeline",
|
|
880
|
+
sources: {
|
|
881
|
+
frigate: true,
|
|
882
|
+
scrypted: true,
|
|
883
|
+
rtsp: false
|
|
884
|
+
},
|
|
885
|
+
requiresBackend: true,
|
|
886
|
+
adapterMethod: "getClusteredDayData"
|
|
887
|
+
},
|
|
888
|
+
{
|
|
889
|
+
id: "detectionClasses",
|
|
890
|
+
label: "Detection Classes",
|
|
891
|
+
sources: {
|
|
892
|
+
frigate: true,
|
|
893
|
+
scrypted: true,
|
|
894
|
+
rtsp: false
|
|
895
|
+
},
|
|
896
|
+
adapterMethod: "getDetectionClasses"
|
|
897
|
+
},
|
|
898
|
+
{
|
|
899
|
+
id: "videoClips",
|
|
900
|
+
label: "Video Clips",
|
|
901
|
+
sources: {
|
|
902
|
+
frigate: true,
|
|
903
|
+
scrypted: true,
|
|
904
|
+
rtsp: false
|
|
905
|
+
},
|
|
906
|
+
adapterMethod: "getVideoClips"
|
|
907
|
+
},
|
|
908
|
+
{
|
|
909
|
+
id: "nvrPlayback",
|
|
910
|
+
label: "NVR Playback",
|
|
911
|
+
sources: {
|
|
912
|
+
frigate: true,
|
|
913
|
+
scrypted: true,
|
|
914
|
+
rtsp: false
|
|
915
|
+
},
|
|
916
|
+
adapterMethod: "getNvrPlaybackSupported"
|
|
917
|
+
},
|
|
918
|
+
{
|
|
919
|
+
id: "nvrScrub",
|
|
920
|
+
label: "NVR Scrub/Seek",
|
|
921
|
+
sources: {
|
|
922
|
+
frigate: false,
|
|
923
|
+
scrypted: true,
|
|
924
|
+
rtsp: false
|
|
925
|
+
},
|
|
926
|
+
adapterMethod: "seekRecordingStream"
|
|
927
|
+
},
|
|
928
|
+
{
|
|
929
|
+
id: "recordingThumbnail",
|
|
930
|
+
label: "Recording Thumbnails",
|
|
931
|
+
sources: {
|
|
932
|
+
frigate: true,
|
|
933
|
+
scrypted: true,
|
|
934
|
+
rtsp: false
|
|
935
|
+
},
|
|
936
|
+
adapterMethod: "getRecordingStreamThumbnail"
|
|
937
|
+
},
|
|
938
|
+
{
|
|
939
|
+
id: "nvrSeekToLive",
|
|
940
|
+
label: "Seek to Live",
|
|
941
|
+
sources: {
|
|
942
|
+
frigate: false,
|
|
943
|
+
scrypted: true,
|
|
944
|
+
rtsp: false
|
|
945
|
+
},
|
|
946
|
+
adapterMethod: "seekNvrToLive"
|
|
947
|
+
}
|
|
948
|
+
];
|
|
949
|
+
function isFeatureAvailable(featureId, source, platform) {
|
|
950
|
+
const entry = FEATURE_MATRIX.find((f) => f.id === featureId);
|
|
951
|
+
if (!entry) return false;
|
|
952
|
+
if (!entry.sources[source]) return false;
|
|
953
|
+
if (entry.platforms && entry.platforms[platform] === false) return false;
|
|
954
|
+
return true;
|
|
955
|
+
}
|
|
956
|
+
__name(isFeatureAvailable, "isFeatureAvailable");
|
|
957
|
+
function getSourceFeatures(source) {
|
|
958
|
+
return FEATURE_MATRIX.filter((f) => f.sources[source]);
|
|
959
|
+
}
|
|
960
|
+
__name(getSourceFeatures, "getSourceFeatures");
|
|
961
|
+
function getBackendRequiredFeatures() {
|
|
962
|
+
return FEATURE_MATRIX.filter((f) => f.requiresBackend);
|
|
963
|
+
}
|
|
964
|
+
__name(getBackendRequiredFeatures, "getBackendRequiredFeatures");
|
|
965
|
+
|
|
966
|
+
// src/adaptive-stream.ts
|
|
967
|
+
function selectOptimalStream(streams, constraints, defaultTransport) {
|
|
968
|
+
if (streams.length === 0) return null;
|
|
969
|
+
const viewportPixels = constraints.viewportWidth * constraints.viewportHeight * (constraints.pixelRatio ?? 1);
|
|
970
|
+
const bw = constraints.bandwidthMbps ?? 100;
|
|
971
|
+
const loss = constraints.packetLoss ?? 0;
|
|
972
|
+
const rtt = constraints.rttMs ?? 50;
|
|
973
|
+
let targetTier = "high";
|
|
974
|
+
if (constraints.maxResolution === "low" || constraints.isCellular || bw < 1 || loss > 0.05) {
|
|
975
|
+
targetTier = "low";
|
|
976
|
+
} else if (constraints.maxResolution === "medium" || bw < 5 || viewportPixels < 5e5 || rtt > 200) {
|
|
977
|
+
targetTier = "medium";
|
|
978
|
+
} else if (constraints.maxResolution === "high" || viewportPixels > 2e6) {
|
|
979
|
+
targetTier = "high";
|
|
980
|
+
}
|
|
981
|
+
const PROFILE_TIER = {
|
|
982
|
+
main: "high",
|
|
983
|
+
sub: "medium",
|
|
984
|
+
ext: "low"
|
|
985
|
+
};
|
|
986
|
+
const preferTransport = defaultTransport ?? "native";
|
|
987
|
+
const scored = streams.map((s) => {
|
|
988
|
+
let score = 0;
|
|
989
|
+
const streamTier = PROFILE_TIER[s.profile] ?? "medium";
|
|
990
|
+
if (streamTier === targetTier) score += 100;
|
|
991
|
+
else if (targetTier === "high" && streamTier === "medium" || targetTier === "medium" && streamTier === "high" || targetTier === "medium" && streamTier === "low" || targetTier === "low" && streamTier === "medium") score += 50;
|
|
992
|
+
if (s.transport === preferTransport) score += 30;
|
|
993
|
+
else if (s.transport === "native") score += 20;
|
|
994
|
+
else if (s.transport === "rtsp") score += 15;
|
|
995
|
+
else if (s.transport === "rtmp") score += 10;
|
|
996
|
+
if (s.metadata?.width && s.metadata?.height) {
|
|
997
|
+
const streamPixels = s.metadata.width * s.metadata.height;
|
|
998
|
+
const ratio = streamPixels / Math.max(viewportPixels, 1);
|
|
999
|
+
if (ratio >= 0.8 && ratio <= 2) score += 25;
|
|
1000
|
+
else if (ratio >= 0.5 && ratio <= 3) score += 15;
|
|
1001
|
+
if (ratio > 4 && bw < 10) score -= 20;
|
|
1002
|
+
}
|
|
1003
|
+
if (s.metadata?.codec) {
|
|
1004
|
+
if (bw < 5 && s.metadata.codec.includes("265")) score += 10;
|
|
1005
|
+
if (bw >= 10 && s.metadata.codec.includes("264")) score += 5;
|
|
1006
|
+
}
|
|
1007
|
+
return {
|
|
1008
|
+
...s,
|
|
1009
|
+
score,
|
|
1010
|
+
targetTier
|
|
1011
|
+
};
|
|
1012
|
+
});
|
|
1013
|
+
scored.sort((a, b) => b.score - a.score);
|
|
1014
|
+
const best = scored[0];
|
|
1015
|
+
const tierNames = {
|
|
1016
|
+
high: "main",
|
|
1017
|
+
medium: "sub",
|
|
1018
|
+
low: "ext"
|
|
1019
|
+
};
|
|
1020
|
+
return {
|
|
1021
|
+
streamName: best.streamName,
|
|
1022
|
+
profile: best.profile,
|
|
1023
|
+
transport: best.transport,
|
|
1024
|
+
label: best.label,
|
|
1025
|
+
metadata: best.metadata,
|
|
1026
|
+
reason: `${best.targetTier} quality \u2192 ${best.profile}/${best.transport} (score: ${best.score})`
|
|
1027
|
+
};
|
|
1028
|
+
}
|
|
1029
|
+
__name(selectOptimalStream, "selectOptimalStream");
|
|
1030
|
+
function getNextEvalInterval(constraints, wasSwitch) {
|
|
1031
|
+
if (wasSwitch) return 10;
|
|
1032
|
+
if (constraints.isCellular) return 15;
|
|
1033
|
+
if ((constraints.packetLoss ?? 0) > 0.02) return 15;
|
|
1034
|
+
return 30;
|
|
1035
|
+
}
|
|
1036
|
+
__name(getNextEvalInterval, "getNextEvalInterval");
|
|
1037
|
+
export {
|
|
1038
|
+
BackendClient,
|
|
1039
|
+
DEFAULT_ENABLED_CLASSES,
|
|
1040
|
+
DetectionClass,
|
|
1041
|
+
ELIGIBLE_HA_DOMAINS,
|
|
1042
|
+
ELIGIBLE_HA_DOMAINS_SET,
|
|
1043
|
+
ELIGIBLE_SCRYPTED_DEVICE_TYPES,
|
|
1044
|
+
ELIGIBLE_SCRYPTED_DEVICE_TYPES_SET,
|
|
1045
|
+
FEATURE_MATRIX,
|
|
1046
|
+
HA_DOMAIN_TYPE_MAP,
|
|
1047
|
+
RAW_TO_CANONICAL,
|
|
1048
|
+
SCRYPTED_TYPE_TO_CANONICAL,
|
|
1049
|
+
TIMELINE_PRESET_ALL,
|
|
1050
|
+
TIMELINE_PRESET_CRITICAL,
|
|
1051
|
+
TIMELINE_PRESET_IMPORTANT,
|
|
1052
|
+
animalClasses,
|
|
1053
|
+
audioClasses,
|
|
1054
|
+
audioLabelClasses,
|
|
1055
|
+
createBackendClient,
|
|
1056
|
+
defaultDetectionClasses,
|
|
1057
|
+
detectionClassesDefaultMap,
|
|
1058
|
+
doorbellClasses,
|
|
1059
|
+
faceClasses,
|
|
1060
|
+
getBackendRequiredFeatures,
|
|
1061
|
+
getCanonicalDeviceType,
|
|
1062
|
+
getClassesForTimelinePreset,
|
|
1063
|
+
getNextEvalInterval,
|
|
1064
|
+
getParentClass,
|
|
1065
|
+
getParentDetectionClass,
|
|
1066
|
+
getSourceFeatures,
|
|
1067
|
+
isAnimalClassname,
|
|
1068
|
+
isAudioClassname,
|
|
1069
|
+
isDoorbellClassname,
|
|
1070
|
+
isFaceClassname,
|
|
1071
|
+
isFeatureAvailable,
|
|
1072
|
+
isLabelDetection,
|
|
1073
|
+
isMotionClassname,
|
|
1074
|
+
isPackageClassname,
|
|
1075
|
+
isPersonClassname,
|
|
1076
|
+
isPlateClassname,
|
|
1077
|
+
isSensorLabelClassname,
|
|
1078
|
+
isVehicleClassname,
|
|
1079
|
+
licensePlateClasses,
|
|
1080
|
+
motionClasses,
|
|
1081
|
+
packageClasses,
|
|
1082
|
+
personClasses,
|
|
1083
|
+
selectOptimalStream,
|
|
1084
|
+
sensorLabelClasses,
|
|
1085
|
+
vehicleClasses
|
|
1086
|
+
};
|
|
1087
|
+
//# sourceMappingURL=index.js.map
|