@camstack/addon-agent-ui 1.2.256 → 1.2.258
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/addon.js +238 -62
- package/dist/assets/{MotionZonesSettings-CocLozQl.js → MotionZonesSettings-D-QY_nEV.js} +1 -1
- package/dist/assets/{PrivacyMaskSettings-CI6gN6Ov.js → PrivacyMaskSettings-B5PJjPxr.js} +1 -1
- package/dist/assets/{SceneMonitorEditor-CJJRR_dY.js → SceneMonitorEditor-2TSBZie4.js} +1 -1
- package/dist/assets/index-_DGBR6-x.js +112 -0
- package/dist/index.html +1 -1
- package/package.json +1 -1
- package/dist/assets/index-C2EQHp3p.js +0 -112
package/dist/addon.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
|
-
//#region ../types/dist/event-category-
|
|
3
|
+
//#region ../types/dist/event-category-BfJwUd2S.mjs
|
|
4
4
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
5
5
|
EventCategory["SystemBoot"] = "system.boot";
|
|
6
6
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -317,6 +317,15 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
317
317
|
*/
|
|
318
318
|
EventCategory["PipelineDetectionBlind"] = "pipeline.detection-blind";
|
|
319
319
|
/**
|
|
320
|
+
* A camera's motion source has fired constantly with no subject for an hour
|
|
321
|
+
* (motion duty or session count over the bar, zero detections) — it is not
|
|
322
|
+
* blind, its motion zones or sensitivity want tuning (D907). Paired with
|
|
323
|
+
* {@link PipelineMotionCalm}.
|
|
324
|
+
*/
|
|
325
|
+
EventCategory["PipelineMotionNoisy"] = "pipeline.motion-noisy";
|
|
326
|
+
/** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
|
|
327
|
+
EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
|
|
328
|
+
/**
|
|
320
329
|
* Per-camera pipeline config was mutated by the orchestrator
|
|
321
330
|
* (3-level settings change via `setAgentAddonDefaults` /
|
|
322
331
|
* `setCameraStepToggle` / `setCameraPipelineForAgent` or a
|
|
@@ -688,6 +697,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
688
697
|
EventCategory["BackupRestored"] = "backup.restored";
|
|
689
698
|
EventCategory["NotificationDispatched"] = "notification.dispatched";
|
|
690
699
|
EventCategory["NotificationFailed"] = "notification.failed";
|
|
700
|
+
/**
|
|
701
|
+
* A notification rule that cannot work (D905): its stored row does not load,
|
|
702
|
+
* or it still names a device / delivery target the prune CONFIRMED deleted.
|
|
703
|
+
* One edge per rule per distinct set of reasons; never on an unanswered read.
|
|
704
|
+
*/
|
|
705
|
+
EventCategory["NotificationRuleBroken"] = "notification.rule-broken";
|
|
706
|
+
/** The clear of {@link NotificationRuleBroken}: the rule loads and names nothing deleted. */
|
|
707
|
+
EventCategory["NotificationRuleRepaired"] = "notification.rule-repaired";
|
|
691
708
|
EventCategory["DeviceUpdated"] = "device.updated";
|
|
692
709
|
/**
|
|
693
710
|
* Transport-level connectivity. Emitted by the device driver when
|
|
@@ -5415,7 +5432,7 @@ var ZodIssueCode = {
|
|
|
5415
5432
|
var ZodFirstPartyTypeKind;
|
|
5416
5433
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5417
5434
|
//#endregion
|
|
5418
|
-
//#region ../types/dist/sleep-
|
|
5435
|
+
//#region ../types/dist/sleep-DJFUfKvA.mjs
|
|
5419
5436
|
/**
|
|
5420
5437
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5421
5438
|
* window to float samples (D455).
|
|
@@ -7877,7 +7894,7 @@ var EntryDescriptorSchema = object({
|
|
|
7877
7894
|
/** JSON Schema of the entry body; `secret: true` marks a password field. */
|
|
7878
7895
|
fields: record(string(), unknown())
|
|
7879
7896
|
}).strict();
|
|
7880
|
-
/** What crosses the wire
|
|
7897
|
+
/** What crosses the wire from an addon: JSON only, no Zod. An unknown key is refused. */
|
|
7881
7898
|
var RecordKindDeclarationSchema = object({
|
|
7882
7899
|
database: _enum(RECORD_DATABASES).default("settings"),
|
|
7883
7900
|
class: _enum(RECORD_CLASSES),
|
|
@@ -7896,14 +7913,6 @@ var RecordKindDeclarationSchema = object({
|
|
|
7896
7913
|
secretPaths: array(string().min(1)).default([]),
|
|
7897
7914
|
/** The id key of each array that carries a secret (`{ headers: 'name' }`). */
|
|
7898
7915
|
secretArrayKeys: record(string(), string()).default({}),
|
|
7899
|
-
/**
|
|
7900
|
-
* RETIRED (D900): the legacy table a kind adopted from during the records
|
|
7901
|
-
* migration. Nothing declares it any more and nothing reads it; the schema
|
|
7902
|
-
* still ACCEPTS it because the catalog rows the migration wrote carry it
|
|
7903
|
-
* (an orphaned kind is never redeclared) and an addon built before the
|
|
7904
|
-
* removal still sends it. Never set it.
|
|
7905
|
-
*/
|
|
7906
|
-
adoptsFrom: string().min(1).optional(),
|
|
7907
7916
|
/** Kinds that must agree through `transact` sit in one file under one family name. */
|
|
7908
7917
|
transactFamily: string().min(1).optional(),
|
|
7909
7918
|
entry: EntryDescriptorSchema.optional()
|
|
@@ -12585,17 +12594,6 @@ object({
|
|
|
12585
12594
|
createdAt: number(),
|
|
12586
12595
|
updatedAt: number()
|
|
12587
12596
|
});
|
|
12588
|
-
object({
|
|
12589
|
-
id: string(),
|
|
12590
|
-
label: string(),
|
|
12591
|
-
isAdmin: boolean().default(false),
|
|
12592
|
-
allowedProviders: AllowedProviderSchema,
|
|
12593
|
-
allowedDevices: AllowedDevicesSchema,
|
|
12594
|
-
tokenHash: string(),
|
|
12595
|
-
tokenPrefix: string(),
|
|
12596
|
-
createdAt: number(),
|
|
12597
|
-
lastUsedAt: number().optional()
|
|
12598
|
-
});
|
|
12599
12597
|
object({
|
|
12600
12598
|
id: string(),
|
|
12601
12599
|
userId: string(),
|
|
@@ -16471,16 +16469,36 @@ var RecordKindStateSchema = _enum([
|
|
|
16471
16469
|
var DeclareKindResultSchema = object({
|
|
16472
16470
|
kindId: number().int(),
|
|
16473
16471
|
state: RecordKindStateSchema,
|
|
16474
|
-
createdIndexes: array(string())
|
|
16475
|
-
/**
|
|
16476
|
-
* RETIRED (D900): always `null`. It carried the records-migration boot guard;
|
|
16477
|
-
* it stays on the wire, null, because an addon built before the removal reads
|
|
16478
|
-
* an ABSENT field as "adoption pending" and refuses to start.
|
|
16479
|
-
*/
|
|
16480
|
-
adoptionPending: _null()
|
|
16472
|
+
createdIndexes: array(string())
|
|
16481
16473
|
});
|
|
16482
16474
|
/** Keychain refs a write released (the old marker is gone from the row): the owner deletes the values. */
|
|
16483
16475
|
var SecretRefsList = array(string());
|
|
16476
|
+
/**
|
|
16477
|
+
* One op of a `transact`: the single-row writes, each on a kind of the caller.
|
|
16478
|
+
* All ops of one call share ONE database file and ONE `transactFamily`.
|
|
16479
|
+
*/
|
|
16480
|
+
var RecordTransactOpSchema = discriminatedUnion("op", [
|
|
16481
|
+
object({
|
|
16482
|
+
op: literal("put"),
|
|
16483
|
+
kind: RecordKindNameSchema,
|
|
16484
|
+
record: RecordInputSchema,
|
|
16485
|
+
ifRev: number().int().min(0).optional()
|
|
16486
|
+
}),
|
|
16487
|
+
object({
|
|
16488
|
+
op: literal("patch"),
|
|
16489
|
+
kind: RecordKindNameSchema,
|
|
16490
|
+
id: RecordIdSchema,
|
|
16491
|
+
data: RecordBodySchema,
|
|
16492
|
+
at: number().int().nullable().optional(),
|
|
16493
|
+
expiresAt: number().int().nullable().optional(),
|
|
16494
|
+
ifRev: number().int().min(1).optional()
|
|
16495
|
+
}),
|
|
16496
|
+
object({
|
|
16497
|
+
op: literal("delete"),
|
|
16498
|
+
kind: RecordKindNameSchema,
|
|
16499
|
+
id: RecordIdSchema
|
|
16500
|
+
})
|
|
16501
|
+
]);
|
|
16484
16502
|
var RecordSecretRefsSchema = record(string(), record(string(), string()));
|
|
16485
16503
|
method(object({ kinds: record(RecordKindNameSchema, RecordKindDeclarationSchema) }), object({ kinds: record(string(), DeclareKindResultSchema) }), {
|
|
16486
16504
|
kind: "mutation",
|
|
@@ -16587,6 +16605,16 @@ method(object({ kinds: record(RecordKindNameSchema, RecordKindDeclarationSchema)
|
|
|
16587
16605
|
}), {
|
|
16588
16606
|
kind: "mutation",
|
|
16589
16607
|
auth: "admin"
|
|
16608
|
+
}), method(object({ ops: array(RecordTransactOpSchema).min(1).max(RECORD_BATCH_MAX) }), object({
|
|
16609
|
+
results: array(object({
|
|
16610
|
+
rev: number().int().nullable(),
|
|
16611
|
+
deleted: boolean()
|
|
16612
|
+
})),
|
|
16613
|
+
releasedRefs: SecretRefsList,
|
|
16614
|
+
secretRefs: SecretRefsList
|
|
16615
|
+
}), {
|
|
16616
|
+
kind: "mutation",
|
|
16617
|
+
auth: "admin"
|
|
16590
16618
|
}), method(object({
|
|
16591
16619
|
deviceId: number().int(),
|
|
16592
16620
|
kinds: array(RecordKindNameSchema).optional()
|
|
@@ -41945,9 +41973,13 @@ var NcSystemEventKindSchema = _enum([
|
|
|
41945
41973
|
"node-updating",
|
|
41946
41974
|
"node-inference-unavailable",
|
|
41947
41975
|
"detection-blind",
|
|
41976
|
+
"motion-noisy",
|
|
41977
|
+
"motion-calm",
|
|
41948
41978
|
"recording-stalled",
|
|
41949
41979
|
"recording-healthy",
|
|
41950
41980
|
"recording-degraded",
|
|
41981
|
+
"device-attention-required",
|
|
41982
|
+
"device-attention-resolved",
|
|
41951
41983
|
"storage-location-low",
|
|
41952
41984
|
"storage-location-critical",
|
|
41953
41985
|
"storage-location-ok",
|
|
@@ -41971,6 +42003,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
41971
42003
|
"alert-critical",
|
|
41972
42004
|
"alert-error",
|
|
41973
42005
|
"alert-critical-resolved",
|
|
42006
|
+
"rule-broken",
|
|
42007
|
+
"rule-repaired",
|
|
41974
42008
|
"camera-online",
|
|
41975
42009
|
"camera-offline",
|
|
41976
42010
|
"camera-disabled",
|
|
@@ -54402,6 +54436,16 @@ object({
|
|
|
54402
54436
|
powerState: string().nullable(),
|
|
54403
54437
|
saltLevel: DishwasherConsumableLevelSchema.nullable(),
|
|
54404
54438
|
rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
|
|
54439
|
+
/**
|
|
54440
|
+
* True while the appliance asks for its filter to be cleaned (smart-filter, filter-system or
|
|
54441
|
+
* combined care-and-filter reminder raised); false when every such reminder reads clear; null
|
|
54442
|
+
* when none is reported. A cleared reminder is not an unknown one.
|
|
54443
|
+
*/
|
|
54444
|
+
filterCleaningDue: boolean().nullable(),
|
|
54445
|
+
/** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
|
|
54446
|
+
machineCareDue: boolean().nullable(),
|
|
54447
|
+
/** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
|
|
54448
|
+
machineCareRemainingRuns: number().int().nonnegative().nullable(),
|
|
54405
54449
|
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
54406
54450
|
halfLoad: boolean().nullable(),
|
|
54407
54451
|
hygienePlus: boolean().nullable(),
|
|
@@ -61019,16 +61063,6 @@ var UpdateUserInputSchema = object({
|
|
|
61019
61063
|
allowedDevices: record(string(), union([array(string()), literal("*")])).optional(),
|
|
61020
61064
|
scopes: array(TokenScopeSchema).optional()
|
|
61021
61065
|
});
|
|
61022
|
-
var ApiKeySummarySchema = object({
|
|
61023
|
-
id: string(),
|
|
61024
|
-
label: string(),
|
|
61025
|
-
isAdmin: boolean().default(false),
|
|
61026
|
-
allowedProviders: union([array(string()), literal("*")]).optional(),
|
|
61027
|
-
allowedDevices: record(string(), union([array(string()), literal("*")])).optional(),
|
|
61028
|
-
tokenPrefix: string(),
|
|
61029
|
-
createdAt: number(),
|
|
61030
|
-
lastUsedAt: number().optional()
|
|
61031
|
-
});
|
|
61032
61066
|
var OauthSessionSummarySchema = object({
|
|
61033
61067
|
id: string(),
|
|
61034
61068
|
userId: string(),
|
|
@@ -61050,8 +61084,7 @@ var TotpStatusSchema = object({
|
|
|
61050
61084
|
confirmedAt: number().nullable()
|
|
61051
61085
|
});
|
|
61052
61086
|
/**
|
|
61053
|
-
* user-management — singleton capability for user accounts
|
|
61054
|
-
* legacy API-key rows.
|
|
61087
|
+
* user-management — singleton capability for user accounts.
|
|
61055
61088
|
*
|
|
61056
61089
|
* v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
|
|
61057
61090
|
* — the subset check on `setUserScopes` is moot
|
|
@@ -61107,10 +61140,6 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
|
|
|
61107
61140
|
}), UserSummarySchema.extend({ passwordHash: string() }).nullable(), {
|
|
61108
61141
|
kind: "mutation",
|
|
61109
61142
|
access: "view"
|
|
61110
|
-
}), method(_void(), array(ApiKeySummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: literal(true) }), {
|
|
61111
|
-
kind: "mutation",
|
|
61112
|
-
auth: "admin",
|
|
61113
|
-
access: "delete"
|
|
61114
61143
|
}), method(object({ userId: string() }), TotpSetupResultSchema, {
|
|
61115
61144
|
kind: "mutation",
|
|
61116
61145
|
auth: "admin",
|
|
@@ -68623,6 +68652,12 @@ Object.freeze({
|
|
|
68623
68652
|
addonId: null,
|
|
68624
68653
|
access: "view"
|
|
68625
68654
|
},
|
|
68655
|
+
"records.transact": {
|
|
68656
|
+
capName: "records",
|
|
68657
|
+
capScope: "system",
|
|
68658
|
+
addonId: null,
|
|
68659
|
+
access: "create"
|
|
68660
|
+
},
|
|
68626
68661
|
"sceneMonitor.captureReference": {
|
|
68627
68662
|
capName: "scene-monitor",
|
|
68628
68663
|
capScope: "device",
|
|
@@ -69955,12 +69990,6 @@ Object.freeze({
|
|
|
69955
69990
|
addonId: null,
|
|
69956
69991
|
access: "view"
|
|
69957
69992
|
},
|
|
69958
|
-
"userManagement.listApiKeys": {
|
|
69959
|
-
capName: "user-management",
|
|
69960
|
-
capScope: "system",
|
|
69961
|
-
addonId: null,
|
|
69962
|
-
access: "view"
|
|
69963
|
-
},
|
|
69964
69993
|
"userManagement.listExternalIdentities": {
|
|
69965
69994
|
capName: "user-management",
|
|
69966
69995
|
capScope: "system",
|
|
@@ -70015,12 +70044,6 @@ Object.freeze({
|
|
|
70015
70044
|
addonId: null,
|
|
70016
70045
|
access: "create"
|
|
70017
70046
|
},
|
|
70018
|
-
"userManagement.revokeApiKey": {
|
|
70019
|
-
capName: "user-management",
|
|
70020
|
-
capScope: "system",
|
|
70021
|
-
addonId: null,
|
|
70022
|
-
access: "delete"
|
|
70023
|
-
},
|
|
70024
70047
|
"userManagement.revokeOauthSession": {
|
|
70025
70048
|
capName: "user-management",
|
|
70026
70049
|
capScope: "system",
|
|
@@ -73385,9 +73408,13 @@ new Map(Object.entries({
|
|
|
73385
73408
|
"stream-online": "device-events",
|
|
73386
73409
|
"stream-offline": "device-events",
|
|
73387
73410
|
"detection-blind": "device-events",
|
|
73411
|
+
"motion-noisy": "device-events",
|
|
73412
|
+
"motion-calm": "device-events",
|
|
73388
73413
|
"recording-stalled": "device-events",
|
|
73389
73414
|
"recording-healthy": "device-events",
|
|
73390
73415
|
"recording-degraded": "device-events",
|
|
73416
|
+
"device-attention-required": "device-events",
|
|
73417
|
+
"device-attention-resolved": "device-events",
|
|
73391
73418
|
"node-online": "system",
|
|
73392
73419
|
"node-offline": "system",
|
|
73393
73420
|
"node-restarting": "system",
|
|
@@ -73404,6 +73431,8 @@ new Map(Object.entries({
|
|
|
73404
73431
|
"alert-critical": "system",
|
|
73405
73432
|
"alert-error": "system",
|
|
73406
73433
|
"alert-critical-resolved": "system",
|
|
73434
|
+
"rule-broken": "system",
|
|
73435
|
+
"rule-repaired": "system",
|
|
73407
73436
|
"storage-location-low": "system",
|
|
73408
73437
|
"storage-location-critical": "system",
|
|
73409
73438
|
"storage-location-ok": "system",
|
|
@@ -73468,6 +73497,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
73468
73497
|
label: "Detecting nothing",
|
|
73469
73498
|
kinds: ["detection-blind"]
|
|
73470
73499
|
},
|
|
73500
|
+
{
|
|
73501
|
+
id: "motion-noise",
|
|
73502
|
+
family: "device-events",
|
|
73503
|
+
label: "Motion without a subject",
|
|
73504
|
+
kinds: ["motion-noisy", "motion-calm"]
|
|
73505
|
+
},
|
|
73471
73506
|
{
|
|
73472
73507
|
id: "recording",
|
|
73473
73508
|
family: "device-events",
|
|
@@ -73478,6 +73513,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
73478
73513
|
"recording-degraded"
|
|
73479
73514
|
]
|
|
73480
73515
|
},
|
|
73516
|
+
{
|
|
73517
|
+
id: "device-attention",
|
|
73518
|
+
family: "device-events",
|
|
73519
|
+
label: "Needs attention",
|
|
73520
|
+
kinds: ["device-attention-required", "device-attention-resolved"]
|
|
73521
|
+
},
|
|
73481
73522
|
{
|
|
73482
73523
|
id: "nodes",
|
|
73483
73524
|
family: "system",
|
|
@@ -73538,6 +73579,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
73538
73579
|
"alert-critical-resolved"
|
|
73539
73580
|
]
|
|
73540
73581
|
},
|
|
73582
|
+
{
|
|
73583
|
+
id: "rule-health",
|
|
73584
|
+
family: "system",
|
|
73585
|
+
label: "Notification rules",
|
|
73586
|
+
kinds: ["rule-broken", "rule-repaired"]
|
|
73587
|
+
},
|
|
73541
73588
|
{
|
|
73542
73589
|
id: "alarm",
|
|
73543
73590
|
family: "alarm",
|
|
@@ -73611,6 +73658,7 @@ var ALERT_EPISODE = [
|
|
|
73611
73658
|
"alert-error",
|
|
73612
73659
|
"alert-critical-resolved"
|
|
73613
73660
|
];
|
|
73661
|
+
var DEVICE_ATTENTION = ["device-attention-required", "device-attention-resolved"];
|
|
73614
73662
|
var UPDATES = [
|
|
73615
73663
|
"addon-update-available",
|
|
73616
73664
|
"server-update-available",
|
|
@@ -73640,9 +73688,12 @@ var DEVICE_EVENTS = [
|
|
|
73640
73688
|
"stream-online",
|
|
73641
73689
|
"stream-offline",
|
|
73642
73690
|
"detection-blind",
|
|
73691
|
+
"motion-noisy",
|
|
73692
|
+
"motion-calm",
|
|
73643
73693
|
"recording-stalled",
|
|
73644
73694
|
"recording-healthy",
|
|
73645
73695
|
"recording-degraded",
|
|
73696
|
+
...DEVICE_ATTENTION,
|
|
73646
73697
|
...ALARM
|
|
73647
73698
|
];
|
|
73648
73699
|
/** Every kind a summary may speak about — the two summarisable families. */
|
|
@@ -73810,7 +73861,13 @@ var STATE_SUMMARY_VARS = [
|
|
|
73810
73861
|
[...RULE_TEXT],
|
|
73811
73862
|
[...RULE_TEXT],
|
|
73812
73863
|
[...RULE_TEXT],
|
|
73813
|
-
|
|
73864
|
+
[...RULE_TEXT],
|
|
73865
|
+
[...RULE_TEXT],
|
|
73866
|
+
([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
|
|
73867
|
+
[...RULE_TEXT],
|
|
73868
|
+
[...RULE_TEXT],
|
|
73869
|
+
[...RULE_TEXT],
|
|
73870
|
+
[...RULE_TEXT],
|
|
73814
73871
|
[...RULE_TEXT],
|
|
73815
73872
|
[...RULE_TEXT],
|
|
73816
73873
|
[...RULE_TEXT],
|
|
@@ -73828,11 +73885,11 @@ var STATE_SUMMARY_VARS = [
|
|
|
73828
73885
|
[...RULE_TEXT],
|
|
73829
73886
|
[...RULE_TEXT],
|
|
73830
73887
|
[...RULE_TEXT],
|
|
73888
|
+
([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
|
|
73831
73889
|
([...RULE_TEXT], [...ALERT_EPISODE]),
|
|
73890
|
+
([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
|
|
73832
73891
|
([...RULE_TEXT], [...ALERT_EPISODE]),
|
|
73833
|
-
([...RULE_TEXT], [...ALERT_EPISODE]),
|
|
73834
|
-
([...RULE_TEXT], [...ALERT_EPISODE]),
|
|
73835
|
-
([...RULE_TEXT], [...ALERT_EPISODE]),
|
|
73892
|
+
([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
|
|
73836
73893
|
[...RULE_TEXT],
|
|
73837
73894
|
[...RULE_TEXT],
|
|
73838
73895
|
[...RULE_TEXT],
|
|
@@ -73853,6 +73910,125 @@ var STATE_SUMMARY_VARS = [
|
|
|
73853
73910
|
[...RULE_TEXT],
|
|
73854
73911
|
...STATE_SUMMARY_VARS
|
|
73855
73912
|
];
|
|
73913
|
+
new Map([
|
|
73914
|
+
{
|
|
73915
|
+
id: "device-connectivity",
|
|
73916
|
+
family: "device-events",
|
|
73917
|
+
label: "Device connectivity (offline / back online)",
|
|
73918
|
+
bad: ["device-offline"],
|
|
73919
|
+
recovery: ["device-online"],
|
|
73920
|
+
snapshotLabel: "Devices offline now",
|
|
73921
|
+
snapshotSection: "device-state"
|
|
73922
|
+
},
|
|
73923
|
+
{
|
|
73924
|
+
id: "device-switch",
|
|
73925
|
+
family: "device-events",
|
|
73926
|
+
label: "Device switched off / back on",
|
|
73927
|
+
bad: ["device-disabled"],
|
|
73928
|
+
recovery: ["device-enabled"],
|
|
73929
|
+
snapshotLabel: "Devices switched off now",
|
|
73930
|
+
snapshotSection: "device-state"
|
|
73931
|
+
},
|
|
73932
|
+
{
|
|
73933
|
+
id: "stream-connectivity",
|
|
73934
|
+
family: "device-events",
|
|
73935
|
+
label: "Stream connectivity (offline / back online)",
|
|
73936
|
+
bad: ["stream-offline"],
|
|
73937
|
+
recovery: ["stream-online"],
|
|
73938
|
+
snapshotLabel: "Streams offline now",
|
|
73939
|
+
snapshotSection: "streams"
|
|
73940
|
+
},
|
|
73941
|
+
{
|
|
73942
|
+
id: "battery",
|
|
73943
|
+
family: "device-events",
|
|
73944
|
+
label: "Battery (low / back to normal)",
|
|
73945
|
+
bad: ["device-battery-low"],
|
|
73946
|
+
recovery: ["device-battery-normal"],
|
|
73947
|
+
snapshotLabel: "Batteries low now",
|
|
73948
|
+
snapshotSection: "battery"
|
|
73949
|
+
},
|
|
73950
|
+
{
|
|
73951
|
+
id: "consumables",
|
|
73952
|
+
family: "device-events",
|
|
73953
|
+
label: "Consumables (low / replaced)",
|
|
73954
|
+
bad: ["device-consumable-low"],
|
|
73955
|
+
recovery: ["device-consumable-normal"],
|
|
73956
|
+
snapshotLabel: "Consumables low now",
|
|
73957
|
+
snapshotSection: "consumables"
|
|
73958
|
+
},
|
|
73959
|
+
{
|
|
73960
|
+
id: "tanks",
|
|
73961
|
+
family: "device-events",
|
|
73962
|
+
label: "Tanks (low or full / back to normal)",
|
|
73963
|
+
bad: ["device-tank-low", "device-tank-full"],
|
|
73964
|
+
recovery: ["device-tank-normal"],
|
|
73965
|
+
snapshotLabel: "Tanks low or full now",
|
|
73966
|
+
snapshotSection: "tanks"
|
|
73967
|
+
},
|
|
73968
|
+
{
|
|
73969
|
+
id: "motion-noise",
|
|
73970
|
+
family: "device-events",
|
|
73971
|
+
label: "Motion without a subject (constant / calm again)",
|
|
73972
|
+
bad: ["motion-noisy"],
|
|
73973
|
+
recovery: ["motion-calm"],
|
|
73974
|
+
snapshotLabel: "Cameras with constant motion now",
|
|
73975
|
+
snapshotSection: null
|
|
73976
|
+
},
|
|
73977
|
+
{
|
|
73978
|
+
id: "recording-health",
|
|
73979
|
+
family: "device-events",
|
|
73980
|
+
label: "Recording health (stalled or degraded / recording again)",
|
|
73981
|
+
bad: ["recording-stalled", "recording-degraded"],
|
|
73982
|
+
recovery: ["recording-healthy"],
|
|
73983
|
+
snapshotLabel: "Recordings stalled now",
|
|
73984
|
+
snapshotSection: null
|
|
73985
|
+
},
|
|
73986
|
+
{
|
|
73987
|
+
id: "device-attention",
|
|
73988
|
+
family: "device-events",
|
|
73989
|
+
label: "Device needs attention (raised / resolved)",
|
|
73990
|
+
bad: ["device-attention-required"],
|
|
73991
|
+
recovery: ["device-attention-resolved"],
|
|
73992
|
+
snapshotLabel: "Devices needing attention now",
|
|
73993
|
+
snapshotSection: null
|
|
73994
|
+
},
|
|
73995
|
+
{
|
|
73996
|
+
id: "node-connectivity",
|
|
73997
|
+
family: "system",
|
|
73998
|
+
label: "Node connectivity (offline / back online)",
|
|
73999
|
+
bad: ["node-offline"],
|
|
74000
|
+
recovery: ["node-online"],
|
|
74001
|
+
snapshotLabel: "Nodes offline now",
|
|
74002
|
+
snapshotSection: "nodes"
|
|
74003
|
+
},
|
|
74004
|
+
{
|
|
74005
|
+
id: "storage-space",
|
|
74006
|
+
family: "system",
|
|
74007
|
+
label: "Storage space (low or critical / ok again)",
|
|
74008
|
+
bad: ["storage-location-low", "storage-location-critical"],
|
|
74009
|
+
recovery: ["storage-location-ok"],
|
|
74010
|
+
snapshotLabel: "Storage locations low now",
|
|
74011
|
+
snapshotSection: null
|
|
74012
|
+
},
|
|
74013
|
+
{
|
|
74014
|
+
id: "critical-alerts",
|
|
74015
|
+
family: "system",
|
|
74016
|
+
label: "Critical alerts (raised / resolved)",
|
|
74017
|
+
bad: ["alert-critical"],
|
|
74018
|
+
recovery: ["alert-critical-resolved"],
|
|
74019
|
+
snapshotLabel: "Critical alerts open now",
|
|
74020
|
+
snapshotSection: null
|
|
74021
|
+
},
|
|
74022
|
+
{
|
|
74023
|
+
id: "rule-health",
|
|
74024
|
+
family: "system",
|
|
74025
|
+
label: "Rule health (broken / repaired)",
|
|
74026
|
+
bad: ["rule-broken"],
|
|
74027
|
+
recovery: ["rule-repaired"],
|
|
74028
|
+
snapshotLabel: "Notification rules broken now",
|
|
74029
|
+
snapshotSection: null
|
|
74030
|
+
}
|
|
74031
|
+
].flatMap((spec) => [...spec.bad, ...spec.recovery].map((kind) => [kind, spec])));
|
|
73856
74032
|
new Set([
|
|
73857
74033
|
"disarmed",
|
|
73858
74034
|
"armed_home",
|
|
@@ -74393,7 +74569,7 @@ var AgentUIAddon = class extends BaseAddon {
|
|
|
74393
74569
|
capability: adminUiCapability,
|
|
74394
74570
|
provider: {
|
|
74395
74571
|
getStaticDir: async () => ({ staticDir: path.resolve(__dirname) }),
|
|
74396
|
-
getVersion: async () => ({ version: "1.2.
|
|
74572
|
+
getVersion: async () => ({ version: "1.2.258" })
|
|
74397
74573
|
}
|
|
74398
74574
|
}];
|
|
74399
74575
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,i as t,l as n,n as r,o as i}from"./scheduler-0XZJE03d.js";import{C as a,c as o,d as s,h as c,l,p as u,t as ee}from"./index-
|
|
1
|
+
import{a as e,i as t,l as n,n as r,o as i}from"./scheduler-0XZJE03d.js";import{C as a,c as o,d as s,h as c,l,p as u,t as ee}from"./index-_DGBR6-x.js";import{MaskShapeCanvas as d}from"./MaskShapeCanvas-BTvl6Rin.js";var f=a(`grid-2x2`,[[`path`,{d:`M12 3v18`,key:`108xh3`}],[`path`,{d:`M3 12h18`,key:`1i2n21`}],[`rect`,{x:`3`,y:`3`,width:`18`,height:`18`,rx:`2`,key:`h1oib`}]]),p=n(i(),1),m=n(e(),1),h=110,g=`motion-zones`,_=0,te=[1,2,3],v=1,y=`rounded-md border border-border bg-surface px-2 py-1 text-[11px] font-medium text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors`,b=`rounded-md border border-primary/50 bg-primary/15 px-2.5 py-1 text-[11px] font-medium text-primary hover:bg-primary/25 disabled:opacity-40 transition-colors`;function x(e,t,n){let r=t*n,i=Array.from({length:r});for(let t=0;t<r;t+=1)i[t]=e[t]===!0;return i}function S(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1)if(e[n]!==t[n])return!1;return!0}function C(e,t){return Math.ceil(e/t)}function w(e,t,n){return Math.min(n-1,Math.floor((e+.5)/t*n))}function T(e,t,n,r){let i=C(t,r),a=C(n,r),o=Array.from({length:i*a},()=>!1);for(let r=0;r<n;r+=1){let s=w(r,n,a);for(let n=0;n<t;n+=1)e[r*t+n]===!0&&(o[s*i+w(n,t,i)]=!0)}return o}function E(e,t,n,r){let i=C(t,r),a=C(n,r),o=Array.from({length:t*n},()=>!1);for(let r=0;r<n;r+=1){let s=w(r,n,a);for(let n=0;n<t;n+=1)o[r*t+n]=e[s*i+w(n,t,i)]===!0}return o}function D({deviceId:e}){let n=t(),i=s(c().trpcClient,e),[a,w]=(0,p.useState)(null),[D,O]=(0,p.useState)(!1),[k,A]=(0,p.useState)(null),[j,M]=(0,p.useState)(null),[N,P]=(0,p.useState)(v),[F,I]=(0,p.useState)(!1),[L,R]=(0,p.useState)(!1),z=(0,p.useRef)(!1);(0,p.useEffect)(()=>{if(!i)return;let e=!1;return z.current=!1,w(null),O(!1),A(null),M(null),P(v),R(!1),(async()=>{try{let t=await i.motionZones?.getOptions({});if(e)return;if(!t)throw Error(`device proxy not ready`);if(w(t),z.current)return;let n=await i.motionZones?.getStatus({});if(e)return;if(!n)throw Error(`device proxy not ready`);z.current=!0;let r=n.regions.find(e=>e.shape.kind===`grid`),a=x(r?r.shape.cells:[],t.grid.width,t.grid.height);M(a),A(T(a,t.grid.width,t.grid.height,v))}catch(t){if(e)return;l(t)?O(!0):console.error(`Motion Zones load failed`,t)}})(),()=>{e=!0}},[i]);let B=a?a.grid.width:0,V=a?a.grid.height:0,H=C(B,N),U=C(V,N),W=(0,p.useMemo)(()=>k&&a?E(k,B,V,N):null,[k,a,B,V,N]),G=(0,p.useMemo)(()=>W!==null&&j!==null&&!S(W,j),[W,j]),K=(0,p.useMemo)(()=>W?W.reduce((e,t)=>t?e+1:e,0):0,[W]),q=B*V,J=H*U,Y=(0,p.useCallback)(e=>{J>0&&A(Array.from({length:J},()=>e))},[J]),X=(0,p.useCallback)(()=>{A(e=>e&&e.map(e=>!e))},[]),Z=(0,p.useCallback)(()=>{j&&a&&A(T(j,B,V,N))},[j,a,B,V,N]),ne=(0,p.useCallback)(e=>{e===N||!a||A(t=>{if(!t)return P(e),t;let n=T(E(t,B,V,N),B,V,e);return P(e),n})},[N,a,B,V]),Q=(0,p.useMemo)(()=>a&&k?[{id:_,shape:{kind:`grid`,gridWidth:H,gridHeight:U,cells:[...k]}}]:[],[a,k,H,U]),$=(0,p.useCallback)((e,t)=>{t.kind===`grid`&&A(t.cells)},[]),re=(0,p.useCallback)(async()=>{if(!(!i||!k||!a)){I(!0);try{let e=E(k,a.grid.width,a.grid.height,N),t={kind:`grid`,gridWidth:a.grid.width,gridHeight:a.grid.height,cells:e};await i.motionZones?.setZone({patch:{regions:[{id:_,enabled:!0,shape:t}]}});let n=await i.motionZones?.getStatus({});if(n){let e=n.regions.find(e=>e.shape.kind===`grid`),t=x(e?e.shape.cells:[],a.grid.width,a.grid.height);M(t),A(T(t,a.grid.width,a.grid.height,N))}}catch(e){console.error(`Motion Zones save failed`,e)}finally{I(!1)}}},[i,k,a,N]);ee((0,p.useMemo)(()=>L&&!D&&a&&k?{id:g,order:h,node:(0,m.jsx)(d,{transparent:!0,items:Q,supportedShapes:[`grid`],grid:{width:H,height:U},selectedId:_,onSelect:()=>{},onShapeChange:$,onDrawComplete:()=>{},drawingKind:null})}:null,[L,D,a,k,Q,$,H,U]));let ie=!D&&a!==null&&k!==null;return i?(0,m.jsx)(u,{title:n(`uiLibrary.motionZones.title`,`Motion Zones`),icon:(0,m.jsx)(f,{className:`h-3.5 w-3.5 text-foreground-subtle`}),children:(0,m.jsx)(`div`,{className:`flex flex-col gap-3`,children:D?(0,m.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.motionZones.unsupported`,`This camera doesn't expose an on-board motion zones grid.`)}):ie?(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(`p`,{className:`${o} leading-relaxed`,children:(0,m.jsx)(r,{uiKey:`uiLibrary.motionZones.intro`,fallback:`Toggle <0>Edit grid</0> to paint the region directly on the live frame, then <1>Save</1> to push the mask to the camera. Pick a bigger <2>Cell size</2> for quicker, broad-stroke painting — it's resampled to the camera's native {{width}}×{{height}} grid on save (×1 is the finest).`,components:[(0,m.jsx)(`strong`,{className:`text-foreground`},`e`),(0,m.jsx)(`strong`,{className:`text-foreground`},`s`),(0,m.jsx)(`strong`,{className:`text-foreground`},`c`)],values:{width:a.grid.width,height:a.grid.height}})}),(0,m.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,m.jsx)(`button`,{type:`button`,onClick:()=>R(e=>!e),disabled:F,"aria-pressed":L,className:L?b:y,children:L?n(`uiLibrary.motionZones.doneEditing`,`Done editing`):n(`uiLibrary.motionZones.editGrid`,`Edit grid`)}),(0,m.jsx)(`button`,{type:`button`,onClick:()=>Y(!0),disabled:F,className:y,children:n(`uiLibrary.motionZones.allOn`,`All on`)}),(0,m.jsx)(`button`,{type:`button`,onClick:()=>Y(!1),disabled:F,className:y,children:n(`uiLibrary.motionZones.allOff`,`All off`)}),(0,m.jsx)(`button`,{type:`button`,onClick:X,disabled:F,className:y,children:n(`uiLibrary.motionZones.invert`,`Invert`)}),(0,m.jsxs)(`div`,{className:`flex items-center gap-1 ml-1`,role:`group`,"aria-label":n(`uiLibrary.motionZones.cellSize`,`Cell size`),children:[(0,m.jsx)(`span`,{className:`${o} mr-0.5`,children:n(`uiLibrary.motionZones.cellSize`,`Cell size`)}),te.map(e=>(0,m.jsxs)(`button`,{type:`button`,onClick:()=>ne(e),disabled:F,"aria-pressed":N===e,title:e===1?n(`uiLibrary.motionZones.cameraGrid`,`Camera grid {{width}}×{{height}} (finest)`,{width:B,height:V}):n(`uiLibrary.motionZones.paintingGrid`,`{{width}}×{{height}} painting grid · cells ×{{factor}} bigger`,{width:C(B,e),height:C(V,e),factor:e}),className:N===e?b:y,children:[`×`,e]},e))]}),(0,m.jsxs)(`span`,{className:`${o} ml-1 tabular-nums`,children:[n(`uiLibrary.motionZones.cells`,`{{active}} / {{total}} cells · {{width}}×{{height}}`,{active:K,total:q,width:a.grid.width,height:a.grid.height}),N===1?``:n(`uiLibrary.motionZones.paintSuffix`,` · paint {{width}}×{{height}}`,{width:H,height:U})]}),(0,m.jsx)(`span`,{className:`flex-1`}),(0,m.jsx)(`button`,{type:`button`,onClick:Z,disabled:F||!G,className:`rounded-md border border-border bg-surface px-2 py-1 text-[11px] text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors`,children:n(`uiLibrary.motionZones.revert`,`Revert`)}),(0,m.jsx)(`button`,{type:`button`,onClick:()=>void re(),disabled:F||!G,className:b,children:F?n(`uiLibrary.motionZones.saving`,`Saving…`):n(`uiLibrary.motionZones.save`,`Save`)})]})]}):(0,m.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.motionZones.loading`,`Loading the camera's grid…`)})})}):null}export{D as MotionZonesSettings};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,i as t,l as n,n as r,o as i}from"./scheduler-0XZJE03d.js";import{C as a,_ as ee,c as o,d as te,g as ne,h as s,l as c,p as re,t as l,x as u,y as d}from"./index-C2EQHp3p.js";import{MaskShapeCanvas as ie}from"./MaskShapeCanvas-BTvl6Rin.js";var ae=a(`hexagon`,[[`path`,{d:`M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z`,key:`yt0hxn`}]]),oe=a(`mic-off`,[[`path`,{d:`M12 19v3`,key:`npa21l`}],[`path`,{d:`M15 9.34V5a3 3 0 0 0-5.68-1.33`,key:`1gzdoj`}],[`path`,{d:`M16.95 16.95A7 7 0 0 1 5 12v-2`,key:`cqa7eg`}],[`path`,{d:`M18.89 13.23A7 7 0 0 0 19 12v-2`,key:`16hl24`}],[`path`,{d:`m2 2 20 20`,key:`1ooewy`}],[`path`,{d:`M9 9v3a3 3 0 0 0 5.12 2.12`,key:`r2i35w`}]]),f=n(i(),1),p=`Microphone`,m=`The camera encodes no audio at all — live view, recordings, exports and the audio analyzer are all silent.`;function se(e){let t=e.supportsAudioMute===!0,n=t?e.audioEnabled:null,r=e.pendingOn??null;return{label:p,supported:t,on:n===null?null:r??n,available:t&&n!==null,costWhenOff:m}}function ce(e){return!e.available||e.on===null?null:{enabled:!e.on}}var h=n(e(),1),le=120,ue=`privacy-mask`,g=`rounded-md border border-border bg-surface px-2 py-1 text-[11px] font-medium text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors`,_=`rounded-md border border-primary/50 bg-primary/15 px-2.5 py-1 text-[11px] font-medium text-primary hover:bg-primary/25 disabled:opacity-40 transition-colors`;function v(e){return e.kind===`rect`||e.kind===`polygon`?e:null}function de(e){let t=new Set(e.map(e=>e.id)),n=0;for(;t.has(n);)n+=1;return n}function fe(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1)if(JSON.stringify(e[n])!==JSON.stringify(t[n]))return!1;return!0}function y({deviceId:e}){let n=t(),i=te(s().trpcClient,e),[a,p]=(0,f.useState)(null),[m,y]=(0,f.useState)(!1),[b,x]=(0,f.useState)(!1),[S,C]=(0,f.useState)(null),[w,T]=(0,f.useState)(null),[E,D]=(0,f.useState)(!1),[O,k]=(0,f.useState)(!1),[A,j]=(0,f.useState)(null),[M,N]=(0,f.useState)(null),[pe,P]=(0,f.useState)(null),[F,I]=(0,f.useState)(null),[L,R]=(0,f.useState)(null),z=(0,f.useRef)(!1);(0,f.useEffect)(()=>{if(!i)return;let e=!1;return z.current=!1,p(null),y(!1),x(!1),C(null),T(null),k(!1),j(null),N(null),P(null),I(null),R(null),(async()=>{try{let t=await i.privacyMask?.getOptions({});if(e)return;if(!t)throw Error(`device proxy not ready`);if(p(t),z.current)return;let n=await i.privacyMask?.getStatus({});if(e)return;if(!n)throw Error(`device proxy not ready`);if(n.regions===null){x(!0),P(n.audioEnabled);return}z.current=!0;let r={enabled:n.enabled,regions:n.regions};T(r),C(r),P(n.audioEnabled)}catch(t){if(e)return;c(t)?y(!0):console.error(`Privacy Mask load failed`,t)}})(),()=>{e=!0}},[i]);let B=(0,f.useMemo)(()=>S!==null&&w!==null&&(S.enabled!==w.enabled||!fe(S.regions,w.regions)),[S,w]),V=S?S.regions.length:0,H=a?a.maxRegions:0,U=(0,f.useRef)(0);(0,f.useEffect)(()=>{U.current=H},[H]);let W=H>0&&V>=H,me=(0,f.useCallback)(()=>{C(e=>e&&{...e,enabled:!e.enabled})},[]),G=(0,f.useCallback)(e=>{j(typeof e==`number`?e:null)},[]),K=(0,f.useMemo)(()=>S?S.regions.map(e=>({id:e.id,shape:e.shape,enabled:e.enabled,label:n(`uiLibrary.privacyMaskSettings.zoneN`,`Zone {{id}}`,{id:e.id})})):[],[S,n]),q=(0,f.useCallback)((e,t)=>{let n=v(t);n&&C(t=>t&&{...t,regions:t.regions.map(t=>t.id===e?{...t,shape:n}:t)})},[]),J=(0,f.useCallback)(e=>{let t=v(e);t&&(N(null),C(e=>{if(!e)return e;let n=U.current;if(n>0&&e.regions.length>=n)return e;let r=de(e.regions),i={id:r,enabled:!0,shape:t};return j(r),{...e,regions:[...e.regions,i]}}))},[]),Y=(0,f.useCallback)(e=>{k(!0),j(null),N(e)},[]),he=(0,f.useCallback)(e=>{k(!0),N(null),j(e)},[]),ge=(0,f.useCallback)(e=>{j(t=>t===e?null:t),C(t=>t&&{...t,regions:t.regions.filter(t=>t.id!==e)})},[]),_e=(0,f.useCallback)(()=>{N(null),j(null),w&&C({enabled:w.enabled,regions:w.regions})},[w]),X=(0,f.useCallback)(async()=>{if(!(!i||!S)){D(!0);try{await i.privacyMask?.setMask({patch:{enabled:S.enabled,regions:[...S.regions]}});let e=await i.privacyMask?.getStatus({});if(e&&e.regions!==null){let t={enabled:e.enabled,regions:e.regions};T(t),C(t)}}catch(e){console.error(`Privacy Mask save failed`,e)}finally{D(!1)}}},[i,S]),Z=se({supportsAudioMute:a===null?null:a.supportsAudioMute,audioEnabled:pe,pendingOn:F}),ve=(0,f.useCallback)(async()=>{let e=ce(Z);if(!(!i||e===null)){I(e.enabled),R(null);try{await i.privacyMask?.setAudioEnabled(e);let t=await i.privacyMask?.getStatus({});t&&P(t.audioEnabled)}catch(e){console.error(`Privacy microphone write failed — reverting`,e),R(e instanceof Error?e.message:String(e))}finally{I(null)}}},[i,Z]),ye=(0,f.useCallback)(()=>{k(e=>(e&&(N(null),j(null)),!e))},[]),Q=a?.supportedShapes??[];l((0,f.useMemo)(()=>O&&!m&&a&&S?{id:ue,order:le,node:(0,h.jsx)(ie,{transparent:!0,items:K,supportedShapes:Q,polygonVertices:a.polygonVertices,selectedId:A,onSelect:G,onShapeChange:q,onDrawComplete:J,drawingKind:M})}:null,[O,m,a,S,K,Q,A,G,q,J,M]));let be=a?.supportedShapes.includes(`rect`)??!1,xe=a?.supportedShapes.includes(`polygon`)??!1,$=a!==null&&(a.maxRegions<=0||a.supportedShapes.length===0),Se=!m&&!$&&!b&&a!==null&&S!==null;return i?(0,h.jsx)(re,{title:n(`uiLibrary.privacyMaskSettings.title`,`Privacy Mask`),icon:(0,h.jsx)(u,{className:`h-3.5 w-3.5 text-foreground-subtle`}),children:(0,h.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[m||$?(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.privacyMaskSettings.unsupported`,`This camera doesn't support an on-board privacy mask.`)}):b?(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.privacyMaskSettings.unreadable`,`This camera hasn't answered, so what it currently masks is unknown — the editor stays closed rather than showing an empty frame you could save over. A battery camera answers once it wakes; otherwise check that it is reachable.`)}):Se?(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:(0,h.jsx)(r,{uiKey:`uiLibrary.privacyMaskSettings.help`,fallback:`Toggle <0>Edit mask</0> to draw blanked-out zones on the live frame, then <1>Save</1> to push them to the camera. Drag a rectangle to move, its corner to resize; drag polygon vertices, click an edge midpoint to add one, or right-click a vertex to remove it.`,components:[(0,h.jsx)(`strong`,{className:`text-foreground`},`edit`),(0,h.jsx)(`strong`,{className:`text-foreground`},`save`)]})}),(0,h.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,h.jsx)(`button`,{type:`button`,onClick:ye,disabled:E,"aria-pressed":O,className:O?_:g,children:O?n(`uiLibrary.privacyMaskSettings.doneEditing`,`Done editing`):n(`uiLibrary.privacyMaskSettings.editMask`,`Edit mask`)}),(0,h.jsx)(`button`,{type:`button`,onClick:me,disabled:E,"aria-pressed":S.enabled,className:S.enabled?_:g,children:S.enabled?n(`uiLibrary.privacyMaskSettings.maskOn`,`Mask on`):n(`uiLibrary.privacyMaskSettings.maskOff`,`Mask off`)}),be&&(0,h.jsx)(`button`,{type:`button`,onClick:()=>Y(`rect`),disabled:E||W,"aria-pressed":M===`rect`,className:M===`rect`?_:g,title:W?n(`uiLibrary.privacyMaskSettings.maxZones`,`Maximum zones reached`):n(`uiLibrary.privacyMaskSettings.addRect`,`Add a rectangle zone`),children:n(`uiLibrary.privacyMaskSettings.rectButton`,`+ Rect`)}),xe&&(0,h.jsx)(`button`,{type:`button`,onClick:()=>Y(`polygon`),disabled:E||W,"aria-pressed":M===`polygon`,className:M===`polygon`?_:g,title:W?n(`uiLibrary.privacyMaskSettings.maxZones`,`Maximum zones reached`):n(`uiLibrary.privacyMaskSettings.addPolygon`,`Add a polygon zone`),children:n(`uiLibrary.privacyMaskSettings.polygonButton`,`+ Polygon`)}),(0,h.jsx)(`span`,{className:`${o} ml-1 tabular-nums`,children:n(`uiLibrary.privacyMaskSettings.zoneCount`,`{{active}} / {{max}} zones`,{active:V,max:H})}),(0,h.jsx)(`span`,{className:`flex-1`}),(0,h.jsx)(`button`,{type:`button`,onClick:_e,disabled:E||!B,className:`rounded-md border border-border bg-surface px-2 py-1 text-[11px] text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors`,children:n(`uiLibrary.privacyMaskSettings.revert`,`Revert`)}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>void X(),disabled:E||!B,className:_,children:E?n(`uiLibrary.privacyMaskSettings.saving`,`Saving…`):n(`uiLibrary.privacyMaskSettings.save`,`Save`)})]}),V>0?(0,h.jsx)(`div`,{className:`flex flex-col gap-1`,children:S.regions.map(e=>{let t=A===e.id,r=e.shape.kind===`polygon`?ae:ee;return(0,h.jsxs)(`div`,{className:`flex items-center gap-2 rounded-md border px-2 py-1 transition-colors ${t?`border-primary/50 bg-primary/10`:`border-border bg-surface`}`,children:[(0,h.jsxs)(`button`,{type:`button`,onClick:()=>he(e.id),disabled:E,className:`flex flex-1 items-center gap-2 text-left text-[11px] font-medium text-foreground-subtle hover:text-foreground disabled:opacity-40 transition-colors`,children:[(0,h.jsx)(r,{className:`h-3.5 w-3.5 shrink-0`}),(0,h.jsx)(`span`,{children:n(`uiLibrary.privacyMaskSettings.zoneN`,`Zone {{id}}`,{id:e.id})}),(0,h.jsx)(`span`,{className:`text-foreground-faint capitalize`,children:e.shape.kind})]}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>ge(e.id),disabled:E,"aria-label":n(`uiLibrary.privacyMaskSettings.deleteZoneN`,`Delete zone {{id}}`,{id:e.id}),title:n(`uiLibrary.privacyMaskSettings.deleteZone`,`Delete zone`),className:`inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-surface text-foreground-subtle hover:border-red-400/40 hover:bg-red-500/10 hover:text-red-400 disabled:opacity-40 transition-colors`,children:(0,h.jsx)(ne,{className:`h-3.5 w-3.5`})})]},e.id)})}):null]}):(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.privacyMaskSettings.loading`,`Loading the camera's privacy mask…`)}),Z.supported&&(0,h.jsxs)(`div`,{className:`flex items-start gap-3 rounded-md border border-border bg-surface px-2 py-2`,children:[(0,h.jsx)(`button`,{type:`button`,role:`switch`,"aria-label":Z.label,"aria-checked":Z.on===!0,disabled:!Z.available||F!==null,onClick:()=>void ve(),title:Z.on===null?n(`uiLibrary.privacyMaskSettings.micTitleUnknown`,`Microphone — state unknown; the camera did not answer.`):Z.on?n(`uiLibrary.privacyMaskSettings.micTitleOn`,`The camera is capturing sound. Turning it off: {{cost}}`,{cost:Z.costWhenOff}):n(`uiLibrary.privacyMaskSettings.micTitleOff`,`The camera is silent. {{cost}}`,{cost:Z.costWhenOff}),className:Z.on===!1||Z.on===null?g:_,children:(0,h.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[Z.on===!1?(0,h.jsx)(oe,{className:`h-3.5 w-3.5`}):(0,h.jsx)(d,{className:`h-3.5 w-3.5`}),Z.on===null?n(`uiLibrary.privacyMaskSettings.micUnknown`,`Microphone unknown`):Z.on?n(`uiLibrary.privacyMaskSettings.micOn`,`Microphone on`):n(`uiLibrary.privacyMaskSettings.micOff`,`Microphone off`)]})}),(0,h.jsx)(`p`,{className:`text-[10px] text-foreground-subtle flex-1 leading-relaxed`,children:L===null?Z.on===null?n(`uiLibrary.privacyMaskSettings.micNotReported`,`The camera did not report its microphone, so this state is unknown.`):Z.costWhenOff:n(`uiLibrary.privacyMaskSettings.writeFailed`,`Write failed: {{reason}}`,{reason:L})})]})]})}):null}export{y as PrivacyMaskSettings};
|
|
1
|
+
import{a as e,i as t,l as n,n as r,o as i}from"./scheduler-0XZJE03d.js";import{C as a,_ as ee,c as o,d as te,g as ne,h as s,l as c,p as re,t as l,x as u,y as d}from"./index-_DGBR6-x.js";import{MaskShapeCanvas as ie}from"./MaskShapeCanvas-BTvl6Rin.js";var ae=a(`hexagon`,[[`path`,{d:`M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z`,key:`yt0hxn`}]]),oe=a(`mic-off`,[[`path`,{d:`M12 19v3`,key:`npa21l`}],[`path`,{d:`M15 9.34V5a3 3 0 0 0-5.68-1.33`,key:`1gzdoj`}],[`path`,{d:`M16.95 16.95A7 7 0 0 1 5 12v-2`,key:`cqa7eg`}],[`path`,{d:`M18.89 13.23A7 7 0 0 0 19 12v-2`,key:`16hl24`}],[`path`,{d:`m2 2 20 20`,key:`1ooewy`}],[`path`,{d:`M9 9v3a3 3 0 0 0 5.12 2.12`,key:`r2i35w`}]]),f=n(i(),1),p=`Microphone`,m=`The camera encodes no audio at all — live view, recordings, exports and the audio analyzer are all silent.`;function se(e){let t=e.supportsAudioMute===!0,n=t?e.audioEnabled:null,r=e.pendingOn??null;return{label:p,supported:t,on:n===null?null:r??n,available:t&&n!==null,costWhenOff:m}}function ce(e){return!e.available||e.on===null?null:{enabled:!e.on}}var h=n(e(),1),le=120,ue=`privacy-mask`,g=`rounded-md border border-border bg-surface px-2 py-1 text-[11px] font-medium text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors`,_=`rounded-md border border-primary/50 bg-primary/15 px-2.5 py-1 text-[11px] font-medium text-primary hover:bg-primary/25 disabled:opacity-40 transition-colors`;function v(e){return e.kind===`rect`||e.kind===`polygon`?e:null}function de(e){let t=new Set(e.map(e=>e.id)),n=0;for(;t.has(n);)n+=1;return n}function fe(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1)if(JSON.stringify(e[n])!==JSON.stringify(t[n]))return!1;return!0}function y({deviceId:e}){let n=t(),i=te(s().trpcClient,e),[a,p]=(0,f.useState)(null),[m,y]=(0,f.useState)(!1),[b,x]=(0,f.useState)(!1),[S,C]=(0,f.useState)(null),[w,T]=(0,f.useState)(null),[E,D]=(0,f.useState)(!1),[O,k]=(0,f.useState)(!1),[A,j]=(0,f.useState)(null),[M,N]=(0,f.useState)(null),[pe,P]=(0,f.useState)(null),[F,I]=(0,f.useState)(null),[L,R]=(0,f.useState)(null),z=(0,f.useRef)(!1);(0,f.useEffect)(()=>{if(!i)return;let e=!1;return z.current=!1,p(null),y(!1),x(!1),C(null),T(null),k(!1),j(null),N(null),P(null),I(null),R(null),(async()=>{try{let t=await i.privacyMask?.getOptions({});if(e)return;if(!t)throw Error(`device proxy not ready`);if(p(t),z.current)return;let n=await i.privacyMask?.getStatus({});if(e)return;if(!n)throw Error(`device proxy not ready`);if(n.regions===null){x(!0),P(n.audioEnabled);return}z.current=!0;let r={enabled:n.enabled,regions:n.regions};T(r),C(r),P(n.audioEnabled)}catch(t){if(e)return;c(t)?y(!0):console.error(`Privacy Mask load failed`,t)}})(),()=>{e=!0}},[i]);let B=(0,f.useMemo)(()=>S!==null&&w!==null&&(S.enabled!==w.enabled||!fe(S.regions,w.regions)),[S,w]),V=S?S.regions.length:0,H=a?a.maxRegions:0,U=(0,f.useRef)(0);(0,f.useEffect)(()=>{U.current=H},[H]);let W=H>0&&V>=H,me=(0,f.useCallback)(()=>{C(e=>e&&{...e,enabled:!e.enabled})},[]),G=(0,f.useCallback)(e=>{j(typeof e==`number`?e:null)},[]),K=(0,f.useMemo)(()=>S?S.regions.map(e=>({id:e.id,shape:e.shape,enabled:e.enabled,label:n(`uiLibrary.privacyMaskSettings.zoneN`,`Zone {{id}}`,{id:e.id})})):[],[S,n]),q=(0,f.useCallback)((e,t)=>{let n=v(t);n&&C(t=>t&&{...t,regions:t.regions.map(t=>t.id===e?{...t,shape:n}:t)})},[]),J=(0,f.useCallback)(e=>{let t=v(e);t&&(N(null),C(e=>{if(!e)return e;let n=U.current;if(n>0&&e.regions.length>=n)return e;let r=de(e.regions),i={id:r,enabled:!0,shape:t};return j(r),{...e,regions:[...e.regions,i]}}))},[]),Y=(0,f.useCallback)(e=>{k(!0),j(null),N(e)},[]),he=(0,f.useCallback)(e=>{k(!0),N(null),j(e)},[]),ge=(0,f.useCallback)(e=>{j(t=>t===e?null:t),C(t=>t&&{...t,regions:t.regions.filter(t=>t.id!==e)})},[]),_e=(0,f.useCallback)(()=>{N(null),j(null),w&&C({enabled:w.enabled,regions:w.regions})},[w]),X=(0,f.useCallback)(async()=>{if(!(!i||!S)){D(!0);try{await i.privacyMask?.setMask({patch:{enabled:S.enabled,regions:[...S.regions]}});let e=await i.privacyMask?.getStatus({});if(e&&e.regions!==null){let t={enabled:e.enabled,regions:e.regions};T(t),C(t)}}catch(e){console.error(`Privacy Mask save failed`,e)}finally{D(!1)}}},[i,S]),Z=se({supportsAudioMute:a===null?null:a.supportsAudioMute,audioEnabled:pe,pendingOn:F}),ve=(0,f.useCallback)(async()=>{let e=ce(Z);if(!(!i||e===null)){I(e.enabled),R(null);try{await i.privacyMask?.setAudioEnabled(e);let t=await i.privacyMask?.getStatus({});t&&P(t.audioEnabled)}catch(e){console.error(`Privacy microphone write failed — reverting`,e),R(e instanceof Error?e.message:String(e))}finally{I(null)}}},[i,Z]),ye=(0,f.useCallback)(()=>{k(e=>(e&&(N(null),j(null)),!e))},[]),Q=a?.supportedShapes??[];l((0,f.useMemo)(()=>O&&!m&&a&&S?{id:ue,order:le,node:(0,h.jsx)(ie,{transparent:!0,items:K,supportedShapes:Q,polygonVertices:a.polygonVertices,selectedId:A,onSelect:G,onShapeChange:q,onDrawComplete:J,drawingKind:M})}:null,[O,m,a,S,K,Q,A,G,q,J,M]));let be=a?.supportedShapes.includes(`rect`)??!1,xe=a?.supportedShapes.includes(`polygon`)??!1,$=a!==null&&(a.maxRegions<=0||a.supportedShapes.length===0),Se=!m&&!$&&!b&&a!==null&&S!==null;return i?(0,h.jsx)(re,{title:n(`uiLibrary.privacyMaskSettings.title`,`Privacy Mask`),icon:(0,h.jsx)(u,{className:`h-3.5 w-3.5 text-foreground-subtle`}),children:(0,h.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[m||$?(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.privacyMaskSettings.unsupported`,`This camera doesn't support an on-board privacy mask.`)}):b?(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.privacyMaskSettings.unreadable`,`This camera hasn't answered, so what it currently masks is unknown — the editor stays closed rather than showing an empty frame you could save over. A battery camera answers once it wakes; otherwise check that it is reachable.`)}):Se?(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:(0,h.jsx)(r,{uiKey:`uiLibrary.privacyMaskSettings.help`,fallback:`Toggle <0>Edit mask</0> to draw blanked-out zones on the live frame, then <1>Save</1> to push them to the camera. Drag a rectangle to move, its corner to resize; drag polygon vertices, click an edge midpoint to add one, or right-click a vertex to remove it.`,components:[(0,h.jsx)(`strong`,{className:`text-foreground`},`edit`),(0,h.jsx)(`strong`,{className:`text-foreground`},`save`)]})}),(0,h.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,h.jsx)(`button`,{type:`button`,onClick:ye,disabled:E,"aria-pressed":O,className:O?_:g,children:O?n(`uiLibrary.privacyMaskSettings.doneEditing`,`Done editing`):n(`uiLibrary.privacyMaskSettings.editMask`,`Edit mask`)}),(0,h.jsx)(`button`,{type:`button`,onClick:me,disabled:E,"aria-pressed":S.enabled,className:S.enabled?_:g,children:S.enabled?n(`uiLibrary.privacyMaskSettings.maskOn`,`Mask on`):n(`uiLibrary.privacyMaskSettings.maskOff`,`Mask off`)}),be&&(0,h.jsx)(`button`,{type:`button`,onClick:()=>Y(`rect`),disabled:E||W,"aria-pressed":M===`rect`,className:M===`rect`?_:g,title:W?n(`uiLibrary.privacyMaskSettings.maxZones`,`Maximum zones reached`):n(`uiLibrary.privacyMaskSettings.addRect`,`Add a rectangle zone`),children:n(`uiLibrary.privacyMaskSettings.rectButton`,`+ Rect`)}),xe&&(0,h.jsx)(`button`,{type:`button`,onClick:()=>Y(`polygon`),disabled:E||W,"aria-pressed":M===`polygon`,className:M===`polygon`?_:g,title:W?n(`uiLibrary.privacyMaskSettings.maxZones`,`Maximum zones reached`):n(`uiLibrary.privacyMaskSettings.addPolygon`,`Add a polygon zone`),children:n(`uiLibrary.privacyMaskSettings.polygonButton`,`+ Polygon`)}),(0,h.jsx)(`span`,{className:`${o} ml-1 tabular-nums`,children:n(`uiLibrary.privacyMaskSettings.zoneCount`,`{{active}} / {{max}} zones`,{active:V,max:H})}),(0,h.jsx)(`span`,{className:`flex-1`}),(0,h.jsx)(`button`,{type:`button`,onClick:_e,disabled:E||!B,className:`rounded-md border border-border bg-surface px-2 py-1 text-[11px] text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors`,children:n(`uiLibrary.privacyMaskSettings.revert`,`Revert`)}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>void X(),disabled:E||!B,className:_,children:E?n(`uiLibrary.privacyMaskSettings.saving`,`Saving…`):n(`uiLibrary.privacyMaskSettings.save`,`Save`)})]}),V>0?(0,h.jsx)(`div`,{className:`flex flex-col gap-1`,children:S.regions.map(e=>{let t=A===e.id,r=e.shape.kind===`polygon`?ae:ee;return(0,h.jsxs)(`div`,{className:`flex items-center gap-2 rounded-md border px-2 py-1 transition-colors ${t?`border-primary/50 bg-primary/10`:`border-border bg-surface`}`,children:[(0,h.jsxs)(`button`,{type:`button`,onClick:()=>he(e.id),disabled:E,className:`flex flex-1 items-center gap-2 text-left text-[11px] font-medium text-foreground-subtle hover:text-foreground disabled:opacity-40 transition-colors`,children:[(0,h.jsx)(r,{className:`h-3.5 w-3.5 shrink-0`}),(0,h.jsx)(`span`,{children:n(`uiLibrary.privacyMaskSettings.zoneN`,`Zone {{id}}`,{id:e.id})}),(0,h.jsx)(`span`,{className:`text-foreground-faint capitalize`,children:e.shape.kind})]}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>ge(e.id),disabled:E,"aria-label":n(`uiLibrary.privacyMaskSettings.deleteZoneN`,`Delete zone {{id}}`,{id:e.id}),title:n(`uiLibrary.privacyMaskSettings.deleteZone`,`Delete zone`),className:`inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-surface text-foreground-subtle hover:border-red-400/40 hover:bg-red-500/10 hover:text-red-400 disabled:opacity-40 transition-colors`,children:(0,h.jsx)(ne,{className:`h-3.5 w-3.5`})})]},e.id)})}):null]}):(0,h.jsx)(`p`,{className:`${o} leading-relaxed`,children:n(`uiLibrary.privacyMaskSettings.loading`,`Loading the camera's privacy mask…`)}),Z.supported&&(0,h.jsxs)(`div`,{className:`flex items-start gap-3 rounded-md border border-border bg-surface px-2 py-2`,children:[(0,h.jsx)(`button`,{type:`button`,role:`switch`,"aria-label":Z.label,"aria-checked":Z.on===!0,disabled:!Z.available||F!==null,onClick:()=>void ve(),title:Z.on===null?n(`uiLibrary.privacyMaskSettings.micTitleUnknown`,`Microphone — state unknown; the camera did not answer.`):Z.on?n(`uiLibrary.privacyMaskSettings.micTitleOn`,`The camera is capturing sound. Turning it off: {{cost}}`,{cost:Z.costWhenOff}):n(`uiLibrary.privacyMaskSettings.micTitleOff`,`The camera is silent. {{cost}}`,{cost:Z.costWhenOff}),className:Z.on===!1||Z.on===null?g:_,children:(0,h.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[Z.on===!1?(0,h.jsx)(oe,{className:`h-3.5 w-3.5`}):(0,h.jsx)(d,{className:`h-3.5 w-3.5`}),Z.on===null?n(`uiLibrary.privacyMaskSettings.micUnknown`,`Microphone unknown`):Z.on?n(`uiLibrary.privacyMaskSettings.micOn`,`Microphone on`):n(`uiLibrary.privacyMaskSettings.micOff`,`Microphone off`)]})}),(0,h.jsx)(`p`,{className:`text-[10px] text-foreground-subtle flex-1 leading-relaxed`,children:L===null?Z.on===null?n(`uiLibrary.privacyMaskSettings.micNotReported`,`The camera did not report its microphone, so this state is unknown.`):Z.costWhenOff:n(`uiLibrary.privacyMaskSettings.writeFailed`,`Write failed: {{reason}}`,{reason:L})})]})]})}):null}export{y as PrivacyMaskSettings};
|