@camstack/addon-agent-ui 1.2.245 → 1.2.246
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 +252 -45
- package/dist/assets/{MotionZonesSettings-CADIMKXy.js → MotionZonesSettings-C8oVEnMF.js} +1 -1
- package/dist/assets/{PrivacyMaskSettings-jyCsS2fM.js → PrivacyMaskSettings-D6x2O9OH.js} +1 -1
- package/dist/assets/{SceneMonitorEditor-BLjncILr.js → SceneMonitorEditor-D-GizqmN.js} +1 -1
- package/dist/assets/index-CR-n-9UK.js +112 -0
- package/dist/index.html +1 -1
- package/package.json +1 -1
- package/dist/assets/index-Bk_nU6ve.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-DOl51-Ij.mjs
|
|
4
4
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
5
5
|
EventCategory["SystemBoot"] = "system.boot";
|
|
6
6
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -79,9 +79,18 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
79
79
|
/**
|
|
80
80
|
* The node's one-shot runner boot check (D877): planned runners against the
|
|
81
81
|
* process service, `degraded` when any is failed, refused or missing. The
|
|
82
|
-
* alert centre turns it into one
|
|
82
|
+
* alert centre turns it into one critical alert.
|
|
83
83
|
*/
|
|
84
84
|
EventCategory["SystemRunnerCheck"] = "system.runner-check";
|
|
85
|
+
/**
|
|
86
|
+
* An alert EPISODE opened or closed, emitted by the alert centre for alerts
|
|
87
|
+
* of severity `critical` or `error` (`AlertEpisodePayload`). The alert
|
|
88
|
+
* centre sends no notification of its own: Notification Center turns this
|
|
89
|
+
* into the `alert-critical` / `alert-error` / `alert-critical-resolved`
|
|
90
|
+
* system-event kinds, and reconciles from the alerts store because a bus
|
|
91
|
+
* event may be dropped (D8, D11).
|
|
92
|
+
*/
|
|
93
|
+
EventCategory["AlertEpisode"] = "alert.episode";
|
|
85
94
|
EventCategory["AddonError"] = "addon.error";
|
|
86
95
|
EventCategory["AddonPageReady"] = "addon.page-ready";
|
|
87
96
|
EventCategory["AddonWidgetReady"] = "addon.widget-ready";
|
|
@@ -5406,7 +5415,7 @@ var ZodIssueCode = {
|
|
|
5406
5415
|
var ZodFirstPartyTypeKind;
|
|
5407
5416
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5408
5417
|
//#endregion
|
|
5409
|
-
//#region ../types/dist/sleep-
|
|
5418
|
+
//#region ../types/dist/sleep-BxjU_fJM.mjs
|
|
5410
5419
|
/**
|
|
5411
5420
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5412
5421
|
* window to float samples (D455).
|
|
@@ -13106,7 +13115,14 @@ var AlertSeveritySchema = _enum([
|
|
|
13106
13115
|
]);
|
|
13107
13116
|
var AlertActionSchema = object({
|
|
13108
13117
|
label: string(),
|
|
13109
|
-
href: string().optional()
|
|
13118
|
+
href: string().optional(),
|
|
13119
|
+
/**
|
|
13120
|
+
* How `href` is followed. Absent / `app`: an admin-ui route (client-side).
|
|
13121
|
+
* `server`: a route the HUB serves (an addon HTTP route such as an OAuth
|
|
13122
|
+
* start) — the browser must leave the SPA with a full navigation, because
|
|
13123
|
+
* the SPA has no such route and would bounce to the home page.
|
|
13124
|
+
*/
|
|
13125
|
+
navigation: _enum(["app", "server"]).optional()
|
|
13110
13126
|
});
|
|
13111
13127
|
var AlertStatusSchema = _enum([
|
|
13112
13128
|
"active",
|
|
@@ -41482,6 +41498,9 @@ var NcSystemEventKindSchema = _enum([
|
|
|
41482
41498
|
"server-updated",
|
|
41483
41499
|
"export-completed",
|
|
41484
41500
|
"backup-completed",
|
|
41501
|
+
"alert-critical",
|
|
41502
|
+
"alert-error",
|
|
41503
|
+
"alert-critical-resolved",
|
|
41485
41504
|
"camera-online",
|
|
41486
41505
|
"camera-offline",
|
|
41487
41506
|
"camera-disabled",
|
|
@@ -50514,7 +50533,10 @@ method(StorageMigrationInputSchema, StorageMigrationPlanSchema, { auth: "admin"
|
|
|
50514
50533
|
}), method(object({ jobId: string().optional() }), StorageMigrationJobSchema.nullable(), { auth: "admin" }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
|
|
50515
50534
|
kind: "mutation",
|
|
50516
50535
|
auth: "admin"
|
|
50517
|
-
}), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({
|
|
50536
|
+
}), method(object({}), array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }), method(object({ locationIds: array(string()).readonly() }), object({
|
|
50537
|
+
clear: boolean(),
|
|
50538
|
+
repointLocationId: string().optional()
|
|
50539
|
+
}), { auth: "admin" }), method(object({}), array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }), method(StorageMigrationDrainInputSchema, object({ jobId: string() }), {
|
|
50518
50540
|
kind: "mutation",
|
|
50519
50541
|
auth: "admin"
|
|
50520
50542
|
}), method(StorageCleanupInputSchema, object({ jobId: string() }), {
|
|
@@ -53949,6 +53971,11 @@ object({
|
|
|
53949
53971
|
*
|
|
53950
53972
|
* `kind: 'poll'` — cloud REST APIs typically have no push channel; the
|
|
53951
53973
|
* provider refreshes the slice on an interval and eagerly after commands.
|
|
53974
|
+
*
|
|
53975
|
+
* UNKNOWN IS NOT OFF. Every field the appliance reports separately is
|
|
53976
|
+
* nullable: `null` means "not known right now" (the appliance has not said,
|
|
53977
|
+
* the link is down, or the description does not carry it) and is never
|
|
53978
|
+
* rendered or exported as `false` / `0`. `availability` says why.
|
|
53952
53979
|
*/
|
|
53953
53980
|
var DishwasherStateSchema = _enum([
|
|
53954
53981
|
"idle",
|
|
@@ -53958,112 +53985,227 @@ var DishwasherStateSchema = _enum([
|
|
|
53958
53985
|
"error",
|
|
53959
53986
|
"unavailable"
|
|
53960
53987
|
]);
|
|
53988
|
+
/**
|
|
53989
|
+
* The appliance's own operation state, uncollapsed. `state` above is the coarse
|
|
53990
|
+
* view for compact surfaces; this is what the appliance said.
|
|
53991
|
+
*/
|
|
53992
|
+
var DishwasherOperationStateSchema = _enum([
|
|
53993
|
+
"Inactive",
|
|
53994
|
+
"Ready",
|
|
53995
|
+
"DelayedStart",
|
|
53996
|
+
"Run",
|
|
53997
|
+
"Pause",
|
|
53998
|
+
"ActionRequired",
|
|
53999
|
+
"Finished",
|
|
54000
|
+
"Error",
|
|
54001
|
+
"Aborting"
|
|
54002
|
+
]);
|
|
54003
|
+
/**
|
|
54004
|
+
* Why fields may be `null`:
|
|
54005
|
+
* - `available` — the link is up and the description is loaded;
|
|
54006
|
+
* - `offline` — the local link is down (values are unknown, not last-known);
|
|
54007
|
+
* - `description-missing` — the link is up but the appliance's description could not
|
|
54008
|
+
* be loaded, so its values cannot be decoded.
|
|
54009
|
+
*/
|
|
54010
|
+
var DishwasherAvailabilitySchema = _enum([
|
|
54011
|
+
"available",
|
|
54012
|
+
"offline",
|
|
54013
|
+
"description-missing"
|
|
54014
|
+
]);
|
|
53961
54015
|
var DishwasherConsumableLevelSchema = _enum([
|
|
53962
54016
|
"ok",
|
|
53963
54017
|
"low",
|
|
53964
54018
|
"empty"
|
|
53965
54019
|
]);
|
|
53966
54020
|
object({
|
|
54021
|
+
availability: DishwasherAvailabilitySchema,
|
|
54022
|
+
/** Coarse state for compact surfaces; `unavailable` whenever the appliance state is not known. */
|
|
53967
54023
|
state: DishwasherStateSchema,
|
|
53968
|
-
/**
|
|
54024
|
+
/** The appliance's operation state as reported; null when not known. */
|
|
54025
|
+
operationState: DishwasherOperationStateSchema.nullable(),
|
|
54026
|
+
/** Feature key of the ACTIVE (running) program, or null when none runs / not known. */
|
|
53969
54027
|
program: string().nullable(),
|
|
53970
|
-
/**
|
|
54028
|
+
/** Feature key of the SELECTED program (what Start would run), or null when none / not known. */
|
|
54029
|
+
selectedProgram: string().nullable(),
|
|
54030
|
+
/** Feature keys of the programs the appliance currently offers — drives the UI selector. */
|
|
53971
54031
|
availablePrograms: array(string()),
|
|
53972
|
-
/**
|
|
53973
|
-
|
|
54032
|
+
/** Seconds remaining on the active cycle, or null when not running / not known. */
|
|
54033
|
+
remainingSeconds: number().int().nonnegative().nullable(),
|
|
54034
|
+
/** Seconds the delayed start is set to (time until the cycle starts), or null. */
|
|
54035
|
+
delayedStartSeconds: number().int().nonnegative().nullable(),
|
|
53974
54036
|
/** Cycle completion 0..100, or null when not applicable. */
|
|
53975
54037
|
progressPercent: number().min(0).max(100).nullable(),
|
|
53976
|
-
/** True when the door is reported open. */
|
|
53977
|
-
doorOpen: boolean(),
|
|
53978
|
-
/** True when
|
|
53979
|
-
|
|
53980
|
-
/**
|
|
53981
|
-
|
|
54038
|
+
/** True when the door is reported open; null when the door state is not known. */
|
|
54039
|
+
doorOpen: boolean().nullable(),
|
|
54040
|
+
/** True when the door is latched (locked) during a cycle; null when not reported. */
|
|
54041
|
+
doorLocked: boolean().nullable(),
|
|
54042
|
+
/** True when remote start is allowed (door closed, power on, etc.); null when not known. */
|
|
54043
|
+
remoteStartAllowed: boolean().nullable(),
|
|
54044
|
+
/** True when the appliance accepts remote control now; null when not known. */
|
|
54045
|
+
remoteControlActive: boolean().nullable(),
|
|
54046
|
+
/** True while somebody operates the appliance at its panel; null when not reported. */
|
|
54047
|
+
localControlActive: boolean().nullable(),
|
|
54048
|
+
/** Main power / switched-on state; null when not known. */
|
|
54049
|
+
powerOn: boolean().nullable(),
|
|
54050
|
+
/** The raw power state (`On`, `Off`, `Standby`, …); null when not known. */
|
|
54051
|
+
powerState: string().nullable(),
|
|
53982
54052
|
saltLevel: DishwasherConsumableLevelSchema.nullable(),
|
|
53983
54053
|
rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
|
|
53984
|
-
|
|
53985
|
-
|
|
54054
|
+
/** Option states: null when the appliance does not expose the option or has not said. */
|
|
54055
|
+
halfLoad: boolean().nullable(),
|
|
54056
|
+
hygienePlus: boolean().nullable(),
|
|
53986
54057
|
/** Extra dry option when the appliance exposes it. */
|
|
53987
|
-
extraDry: boolean(),
|
|
54058
|
+
extraDry: boolean().nullable(),
|
|
53988
54059
|
/** Intensive zone (lower basket) when the appliance exposes it. */
|
|
53989
|
-
intensiveZone: boolean(),
|
|
54060
|
+
intensiveZone: boolean().nullable(),
|
|
53990
54061
|
/** VarioSpeed / VarioSpeed+ when the appliance exposes it. */
|
|
53991
|
-
varioSpeedPlus: boolean(),
|
|
53992
|
-
/** Child lock (controls disabled on the appliance). */
|
|
53993
|
-
childLock: boolean(),
|
|
54062
|
+
varioSpeedPlus: boolean().nullable(),
|
|
54063
|
+
/** Child lock (controls disabled on the appliance); null when not known. */
|
|
54064
|
+
childLock: boolean().nullable(),
|
|
54065
|
+
/** Feature keys of the events currently raised (salt low, rinse aid low, program finished, …). */
|
|
54066
|
+
activeEvents: array(string()),
|
|
54067
|
+
/** Numeric error code when the appliance reports one; null otherwise. */
|
|
53994
54068
|
errorCode: number().nullable(),
|
|
54069
|
+
/** Name of the raised alert-level event while the appliance is in error; null otherwise. */
|
|
53995
54070
|
errorLabel: string().nullable(),
|
|
54071
|
+
/** Ms epoch of the last value received from the appliance; 0 = never. */
|
|
53996
54072
|
lastFetchedAt: number()
|
|
53997
54073
|
});
|
|
53998
|
-
|
|
54074
|
+
var DeviceIdSchema = number().int().nonnegative();
|
|
54075
|
+
/** A value a program option or setting can take. */
|
|
54076
|
+
var DishwasherValueSchema = union([
|
|
54077
|
+
boolean(),
|
|
54078
|
+
string(),
|
|
54079
|
+
number()
|
|
54080
|
+
]);
|
|
54081
|
+
var DishwasherAccessSchema = _enum([
|
|
54082
|
+
"none",
|
|
54083
|
+
"read",
|
|
54084
|
+
"readWrite",
|
|
54085
|
+
"writeOnly",
|
|
54086
|
+
"readStatic"
|
|
54087
|
+
]);
|
|
54088
|
+
/**
|
|
54089
|
+
* One option or setting the appliance declares, with the constraints its description
|
|
54090
|
+
* gives. A `readWrite` descriptor that is `available` is what `setOption` accepts.
|
|
54091
|
+
*/
|
|
54092
|
+
var DishwasherOptionDescriptorSchema = object({
|
|
54093
|
+
/** Feature key (`Dishcare.Dishwasher.Option.ExtraDry`). */
|
|
54094
|
+
key: string(),
|
|
54095
|
+
/** Last segment of the key, for display. */
|
|
54096
|
+
name: string(),
|
|
54097
|
+
type: _enum([
|
|
54098
|
+
"boolean",
|
|
54099
|
+
"number",
|
|
54100
|
+
"enum",
|
|
54101
|
+
"string"
|
|
54102
|
+
]),
|
|
54103
|
+
access: DishwasherAccessSchema,
|
|
54104
|
+
/** The appliance reports this entity as currently available. */
|
|
54105
|
+
available: boolean(),
|
|
54106
|
+
/** Unit the description declares for a number; null when it declares none. */
|
|
54107
|
+
unit: string().nullable(),
|
|
54108
|
+
min: number().nullable(),
|
|
54109
|
+
max: number().nullable(),
|
|
54110
|
+
step: number().nullable(),
|
|
54111
|
+
/** Allowed members of an enum; null for other types. */
|
|
54112
|
+
enumValues: array(string()).nullable(),
|
|
54113
|
+
defaultValue: DishwasherValueSchema.nullable()
|
|
54114
|
+
});
|
|
54115
|
+
var DishwasherProgramSchema = object({
|
|
54116
|
+
/** Feature key (`Dishcare.Dishwasher.Program.Eco50`) — what `setProgram` / `start` take. */
|
|
54117
|
+
key: string(),
|
|
54118
|
+
name: string(),
|
|
54119
|
+
/** The appliance currently offers this program. */
|
|
54120
|
+
available: boolean(),
|
|
54121
|
+
/** The options this program lists, with the program-level access / availability / default. */
|
|
54122
|
+
options: array(DishwasherOptionDescriptorSchema)
|
|
54123
|
+
});
|
|
54124
|
+
var DishwasherOptionsSchema = object({
|
|
54125
|
+
availability: DishwasherAvailabilitySchema,
|
|
54126
|
+
/** What the appliance can be told to do, from the commands its description declares. */
|
|
54127
|
+
supportsStart: boolean(),
|
|
54128
|
+
supportsPause: boolean(),
|
|
54129
|
+
supportsResume: boolean(),
|
|
54130
|
+
supportsStop: boolean(),
|
|
54131
|
+
supportsPower: boolean(),
|
|
54132
|
+
/** Every program the description lists, with its options. */
|
|
54133
|
+
programs: array(DishwasherProgramSchema),
|
|
54134
|
+
/** Every option and setting entity the description lists (programs reference these by key). */
|
|
54135
|
+
options: array(DishwasherOptionDescriptorSchema)
|
|
54136
|
+
});
|
|
54137
|
+
DeviceType.Dishwasher, method(object({
|
|
54138
|
+
deviceId: DeviceIdSchema,
|
|
54139
|
+
program: string().min(1).optional(),
|
|
54140
|
+
options: record(string(), DishwasherValueSchema).optional()
|
|
54141
|
+
}), _void(), {
|
|
53999
54142
|
kind: "mutation",
|
|
54000
54143
|
auth: "protected"
|
|
54001
|
-
}), method(object({ deviceId:
|
|
54144
|
+
}), method(object({ deviceId: DeviceIdSchema }), _void(), {
|
|
54002
54145
|
kind: "mutation",
|
|
54003
54146
|
auth: "protected"
|
|
54004
|
-
}), method(object({ deviceId:
|
|
54147
|
+
}), method(object({ deviceId: DeviceIdSchema }), _void(), {
|
|
54148
|
+
kind: "mutation",
|
|
54149
|
+
auth: "protected"
|
|
54150
|
+
}), method(object({ deviceId: DeviceIdSchema }), _void(), {
|
|
54005
54151
|
kind: "mutation",
|
|
54006
54152
|
auth: "protected"
|
|
54007
54153
|
}), method(object({
|
|
54008
|
-
deviceId:
|
|
54154
|
+
deviceId: DeviceIdSchema,
|
|
54009
54155
|
program: string().min(1)
|
|
54010
54156
|
}), _void(), {
|
|
54011
54157
|
kind: "mutation",
|
|
54012
54158
|
auth: "protected"
|
|
54013
54159
|
}), method(object({
|
|
54014
|
-
deviceId:
|
|
54160
|
+
deviceId: DeviceIdSchema,
|
|
54015
54161
|
on: boolean()
|
|
54016
54162
|
}), _void(), {
|
|
54017
54163
|
kind: "mutation",
|
|
54018
54164
|
auth: "protected"
|
|
54019
54165
|
}), method(object({
|
|
54020
|
-
deviceId:
|
|
54166
|
+
deviceId: DeviceIdSchema,
|
|
54021
54167
|
on: boolean()
|
|
54022
54168
|
}), _void(), {
|
|
54023
54169
|
kind: "mutation",
|
|
54024
54170
|
auth: "protected"
|
|
54025
54171
|
}), method(object({
|
|
54026
|
-
deviceId:
|
|
54172
|
+
deviceId: DeviceIdSchema,
|
|
54027
54173
|
on: boolean()
|
|
54028
54174
|
}), _void(), {
|
|
54029
54175
|
kind: "mutation",
|
|
54030
54176
|
auth: "protected"
|
|
54031
54177
|
}), method(object({
|
|
54032
|
-
deviceId:
|
|
54178
|
+
deviceId: DeviceIdSchema,
|
|
54033
54179
|
on: boolean()
|
|
54034
54180
|
}), _void(), {
|
|
54035
54181
|
kind: "mutation",
|
|
54036
54182
|
auth: "protected"
|
|
54037
54183
|
}), method(object({
|
|
54038
|
-
deviceId:
|
|
54184
|
+
deviceId: DeviceIdSchema,
|
|
54039
54185
|
on: boolean()
|
|
54040
54186
|
}), _void(), {
|
|
54041
54187
|
kind: "mutation",
|
|
54042
54188
|
auth: "protected"
|
|
54043
54189
|
}), method(object({
|
|
54044
|
-
deviceId:
|
|
54190
|
+
deviceId: DeviceIdSchema,
|
|
54045
54191
|
on: boolean()
|
|
54046
54192
|
}), _void(), {
|
|
54047
54193
|
kind: "mutation",
|
|
54048
54194
|
auth: "protected"
|
|
54049
54195
|
}), method(object({
|
|
54050
|
-
deviceId:
|
|
54196
|
+
deviceId: DeviceIdSchema,
|
|
54051
54197
|
on: boolean()
|
|
54052
54198
|
}), _void(), {
|
|
54053
54199
|
kind: "mutation",
|
|
54054
54200
|
auth: "protected"
|
|
54055
54201
|
}), method(object({
|
|
54056
|
-
deviceId:
|
|
54202
|
+
deviceId: DeviceIdSchema,
|
|
54057
54203
|
key: string().min(1),
|
|
54058
|
-
value:
|
|
54059
|
-
boolean(),
|
|
54060
|
-
string(),
|
|
54061
|
-
number()
|
|
54062
|
-
])
|
|
54204
|
+
value: DishwasherValueSchema
|
|
54063
54205
|
}), _void(), {
|
|
54064
54206
|
kind: "mutation",
|
|
54065
54207
|
auth: "protected"
|
|
54066
|
-
});
|
|
54208
|
+
}), method(object({ deviceId: DeviceIdSchema }), DishwasherOptionsSchema, { auth: "protected" });
|
|
54067
54209
|
object({
|
|
54068
54210
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
54069
54211
|
lastPressedAt: number().nullable(),
|
|
@@ -64123,6 +64265,12 @@ Object.freeze({
|
|
|
64123
64265
|
addonId: null,
|
|
64124
64266
|
access: "view"
|
|
64125
64267
|
},
|
|
64268
|
+
"dishwasher.getOptions": {
|
|
64269
|
+
capName: "dishwasher",
|
|
64270
|
+
capScope: "device",
|
|
64271
|
+
addonId: null,
|
|
64272
|
+
access: "view"
|
|
64273
|
+
},
|
|
64126
64274
|
"dishwasher.getStatus": {
|
|
64127
64275
|
capName: "dishwasher",
|
|
64128
64276
|
capScope: "device",
|
|
@@ -64135,6 +64283,12 @@ Object.freeze({
|
|
|
64135
64283
|
addonId: null,
|
|
64136
64284
|
access: "create"
|
|
64137
64285
|
},
|
|
64286
|
+
"dishwasher.resume": {
|
|
64287
|
+
capName: "dishwasher",
|
|
64288
|
+
capScope: "device",
|
|
64289
|
+
addonId: null,
|
|
64290
|
+
access: "create"
|
|
64291
|
+
},
|
|
64138
64292
|
"dishwasher.setChildLock": {
|
|
64139
64293
|
capName: "dishwasher",
|
|
64140
64294
|
capScope: "device",
|
|
@@ -68635,6 +68789,12 @@ Object.freeze({
|
|
|
68635
68789
|
addonId: null,
|
|
68636
68790
|
access: "view"
|
|
68637
68791
|
},
|
|
68792
|
+
"storageMigration.moverClearance": {
|
|
68793
|
+
capName: "storage-migration",
|
|
68794
|
+
capScope: "system",
|
|
68795
|
+
addonId: null,
|
|
68796
|
+
access: "view"
|
|
68797
|
+
},
|
|
68638
68798
|
"storageMigration.movers": {
|
|
68639
68799
|
capName: "storage-migration",
|
|
68640
68800
|
capScope: "system",
|
|
@@ -70828,6 +70988,11 @@ Object.freeze({
|
|
|
70828
70988
|
form: "single",
|
|
70829
70989
|
optional: false
|
|
70830
70990
|
}],
|
|
70991
|
+
"dishwasher.getOptions": [{
|
|
70992
|
+
name: "deviceId",
|
|
70993
|
+
form: "single",
|
|
70994
|
+
optional: false
|
|
70995
|
+
}],
|
|
70831
70996
|
"dishwasher.getStatus": [{
|
|
70832
70997
|
name: "deviceId",
|
|
70833
70998
|
form: "single",
|
|
@@ -70838,6 +71003,11 @@ Object.freeze({
|
|
|
70838
71003
|
form: "single",
|
|
70839
71004
|
optional: false
|
|
70840
71005
|
}],
|
|
71006
|
+
"dishwasher.resume": [{
|
|
71007
|
+
name: "deviceId",
|
|
71008
|
+
form: "single",
|
|
71009
|
+
optional: false
|
|
71010
|
+
}],
|
|
70841
71011
|
"dishwasher.setChildLock": [{
|
|
70842
71012
|
name: "deviceId",
|
|
70843
71013
|
form: "single",
|
|
@@ -72924,6 +73094,9 @@ new Map(Object.entries({
|
|
|
72924
73094
|
"wrapper-update-available": "system",
|
|
72925
73095
|
"backup-completed": "system",
|
|
72926
73096
|
"export-completed": "system",
|
|
73097
|
+
"alert-critical": "system",
|
|
73098
|
+
"alert-error": "system",
|
|
73099
|
+
"alert-critical-resolved": "system",
|
|
72927
73100
|
"storage-location-low": "system",
|
|
72928
73101
|
"storage-location-critical": "system",
|
|
72929
73102
|
"storage-location-ok": "system",
|
|
@@ -73048,6 +73221,16 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
73048
73221
|
"storage-location-ok"
|
|
73049
73222
|
]
|
|
73050
73223
|
},
|
|
73224
|
+
{
|
|
73225
|
+
id: "alerts",
|
|
73226
|
+
family: "system",
|
|
73227
|
+
label: "Alerts",
|
|
73228
|
+
kinds: [
|
|
73229
|
+
"alert-critical",
|
|
73230
|
+
"alert-error",
|
|
73231
|
+
"alert-critical-resolved"
|
|
73232
|
+
]
|
|
73233
|
+
},
|
|
73051
73234
|
{
|
|
73052
73235
|
id: "alarm",
|
|
73053
73236
|
family: "alarm",
|
|
@@ -73092,6 +73275,21 @@ var NC_SENSOR_RAISED_FIELD_BY_KIND = Object.freeze(Object.fromEntries(Object.ent
|
|
|
73092
73275
|
return [[descriptor.kind, field]];
|
|
73093
73276
|
})));
|
|
73094
73277
|
Object.freeze(Object.keys(NC_SENSOR_RAISED_FIELD_BY_KIND));
|
|
73278
|
+
object({
|
|
73279
|
+
phase: _enum(["raised", "resolved"]),
|
|
73280
|
+
episodeId: string().min(1),
|
|
73281
|
+
alertId: string().min(1),
|
|
73282
|
+
severity: AlertSeveritySchema,
|
|
73283
|
+
category: string(),
|
|
73284
|
+
title: string(),
|
|
73285
|
+
message: string(),
|
|
73286
|
+
sourceType: string().optional(),
|
|
73287
|
+
sourceId: string().optional(),
|
|
73288
|
+
nodeId: string().optional(),
|
|
73289
|
+
/** The alert's own action link (where the operator acts on it), when it has one. */
|
|
73290
|
+
actionUrl: string().optional(),
|
|
73291
|
+
at: number()
|
|
73292
|
+
});
|
|
73095
73293
|
var RULE_BODY_ONLY = ["body"];
|
|
73096
73294
|
var RULE_TEXT = ["title", "body"];
|
|
73097
73295
|
var BATTERY = ["device-battery-low", "device-battery-normal"];
|
|
@@ -73101,6 +73299,11 @@ var TANK = [
|
|
|
73101
73299
|
"device-tank-full",
|
|
73102
73300
|
"device-tank-normal"
|
|
73103
73301
|
];
|
|
73302
|
+
var ALERT_EPISODE = [
|
|
73303
|
+
"alert-critical",
|
|
73304
|
+
"alert-error",
|
|
73305
|
+
"alert-critical-resolved"
|
|
73306
|
+
];
|
|
73104
73307
|
var UPDATES = [
|
|
73105
73308
|
"addon-update-available",
|
|
73106
73309
|
"server-update-available",
|
|
@@ -73293,14 +73496,14 @@ var STATE_SUMMARY_VARS = [
|
|
|
73293
73496
|
([...RULE_TEXT], [...CONSUMABLE]),
|
|
73294
73497
|
([...RULE_TEXT], [...TANK]),
|
|
73295
73498
|
[...RULE_TEXT],
|
|
73296
|
-
([...RULE_TEXT], [...UPDATES]),
|
|
73297
|
-
([...RULE_TEXT], [...UPDATES]),
|
|
73298
|
-
[...RULE_TEXT],
|
|
73499
|
+
([...RULE_TEXT], [...UPDATES, ...ALERT_EPISODE]),
|
|
73500
|
+
([...RULE_TEXT], [...UPDATES, ...ALERT_EPISODE]),
|
|
73299
73501
|
[...RULE_TEXT],
|
|
73300
73502
|
[...RULE_TEXT],
|
|
73301
73503
|
[...RULE_TEXT],
|
|
73302
73504
|
[...RULE_TEXT],
|
|
73303
73505
|
[...RULE_TEXT],
|
|
73506
|
+
([...RULE_TEXT], [...ALERT_EPISODE]),
|
|
73304
73507
|
[...RULE_TEXT],
|
|
73305
73508
|
[...RULE_TEXT],
|
|
73306
73509
|
[...RULE_TEXT],
|
|
@@ -73318,7 +73521,11 @@ var STATE_SUMMARY_VARS = [
|
|
|
73318
73521
|
[...RULE_TEXT],
|
|
73319
73522
|
[...RULE_TEXT],
|
|
73320
73523
|
[...RULE_TEXT],
|
|
73321
|
-
[...RULE_TEXT],
|
|
73524
|
+
([...RULE_TEXT], [...ALERT_EPISODE]),
|
|
73525
|
+
([...RULE_TEXT], [...ALERT_EPISODE]),
|
|
73526
|
+
([...RULE_TEXT], [...ALERT_EPISODE]),
|
|
73527
|
+
([...RULE_TEXT], [...ALERT_EPISODE]),
|
|
73528
|
+
([...RULE_TEXT], [...ALERT_EPISODE]),
|
|
73322
73529
|
[...RULE_TEXT],
|
|
73323
73530
|
[...RULE_TEXT],
|
|
73324
73531
|
[...RULE_TEXT],
|
|
@@ -73879,7 +74086,7 @@ var AgentUIAddon = class extends BaseAddon {
|
|
|
73879
74086
|
capability: adminUiCapability,
|
|
73880
74087
|
provider: {
|
|
73881
74088
|
getStaticDir: async () => ({ staticDir: path.resolve(__dirname) }),
|
|
73882
|
-
getVersion: async () => ({ version: "1.2.
|
|
74089
|
+
getVersion: async () => ({ version: "1.2.246" })
|
|
73883
74090
|
}
|
|
73884
74091
|
}];
|
|
73885
74092
|
}
|
|
@@ -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-CR-n-9UK.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-Bk_nU6ve.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-CR-n-9UK.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};
|