@camstack/addon-agent-ui 1.2.316 → 1.2.317

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/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.2.317] - 2026-11-02
11
+
12
+ ### Changed
13
+
14
+ - Rebuilt against updated dependencies.
15
+
10
16
  ## [1.2.316] - 2026-11-02
11
17
 
12
18
  ### Changed
@@ -362,13 +362,13 @@
362
362
  "server/server/packages/addon-agent-ui/src/updates-panel.tsx": "ec6b5b3701322bbb68dbe581703409cd373418cf9227ce829ea0945e70e60d54",
363
363
  "server/server/packages/addon-agent-ui/src/use-pairing-status.ts": "46193a1e83a64250dfff75d417448d74ba0159465e710861b996e903b03e427a",
364
364
  "server/server/packages/sdk/dist/index.js": "89409bfb9632c46ed63ee4882c70b7994c1ff90c67d27a5d4b86b0990c41a131",
365
- "server/server/packages/types/dist/client.mjs": "2a0c6aa3c936a99dca6bc907fdb2fdc02ce769b8922275c9629cc8f9cf7e8bb2",
365
+ "server/server/packages/types/dist/client.mjs": "66a9ee78c3809d41d4dd02d78c14689c5f982b293c14a6ca83855026ff522b3b",
366
366
  "server/server/packages/types/dist/composition-Dh3RfMx5.mjs": "3bd5440c77222424fd992b3c3c5c68953abfccce331a639c311c36dd9d523e26",
367
367
  "server/server/packages/types/dist/device-type-CfHw_quR.mjs": "a925875f57dabf69331e51c8d28fbade95a6a0ba92ab5bfe362f49c212290846",
368
368
  "server/server/packages/types/dist/event-category-BmPm98n0.mjs": "3617fc3941b34f1dcc8ebd3c1360e8c302747400d43e3ab694388496c2bb568d",
369
- "server/server/packages/types/dist/index.mjs": "0972856a8c716655043783d76bf65b8820cc150c908a7e4972466a2ac85f7b97",
369
+ "server/server/packages/types/dist/index.mjs": "4acece64e7484dcb45f2bb4e30951ddd77e4d6e81db2c41695860dbf91005444",
370
370
  "server/server/packages/types/dist/node-color.mjs": "942e663074f0a4ed2f8643848ec139eba4b5fd16d0d01c8a23e08a4819a8843b",
371
- "server/server/packages/types/dist/sleep-QsoHs66J.mjs": "dd8a98c45a8cd12e44f1bd0ffba0c461c8d3c4e471225acdd8647926843668dd",
371
+ "server/server/packages/types/dist/sleep-hmSP-eJt.mjs": "306ed83461a4dd117d4bbc43b207cdd686c872e969bb15d9d6d893aaaffe9181",
372
372
  "server/server/packages/ui-library/src/composites/adaptive-downlink.ts": "6e9698e97721461b72a3750f930dd7214d049be865491bfb5a64b87c032b0e22",
373
373
  "server/server/packages/ui-library/src/composites/camera-stream-player.tsx": "c04809229b4e091fed09e2bcfe643d6b36cb3a39e294229b49f8a095e4e6ebd3",
374
374
  "server/server/packages/ui-library/src/composites/cap-settings/CameraGridLayoutEditor.tsx": "bfe36ccad931ef0981fe24fa315f136d35dbc3164df221346806173447178324",
@@ -418,7 +418,7 @@
418
418
  "server/server/packages/ui-library/src/composites/device-controls/media-player-panel.tsx": "8c2a9628faef628dfad76292df4e5b3cb3dbfbef762305cc3039cda155eb7a2e",
419
419
  "server/server/packages/ui-library/src/composites/device-controls/panel-controls.tsx": "adefb5bcae34bf27f2858221cfaf2be6f86a84c1bf5776e5ab61987cd069116d",
420
420
  "server/server/packages/ui-library/src/composites/device-controls/pet-feeder-panel.tsx": "5d521ed27b5145cd23e36cde522457c19c5babccc00f0faa0b9b5899cc18106a",
421
- "server/server/packages/ui-library/src/composites/device-controls/pet-fountain-panel.tsx": "a44a3dacfc964e17f087fde0c3477d9de9c95c07e6059b304b3cdb8a59629b7f",
421
+ "server/server/packages/ui-library/src/composites/device-controls/pet-fountain-panel.tsx": "b8ab7862853c2003f974780ac01abc6d8ed43b9fd08a222f215333578adaca40",
422
422
  "server/server/packages/ui-library/src/composites/device-controls/radial-gauge.tsx": "c44860eb09a4a891fd734ba000cbaea3fbd62e36b97d9176b718aa33693d4702",
423
423
  "server/server/packages/ui-library/src/composites/device-controls/script-automation-controls.tsx": "d1733db6a99ba7105587548f39a351225a85b245391f30658d5a5cc1f04086bc",
424
424
  "server/server/packages/ui-library/src/composites/device-controls/sensor-hero-card.tsx": "ce0f346176c1a70f183eed9169a814a67d39f79efbc086b8e981e5ec9c57330c",
@@ -479,7 +479,7 @@
479
479
  "server/server/packages/ui-library/src/contexts/vod-playback.tsx": "c07bc3ecc786182ef2f27d13bec3f520288e0b47367edd7ddf1c2e7b4a2bbaee",
480
480
  "server/server/packages/ui-library/src/contexts/widget-registry.tsx": "71a2815c645abe96821a9e9e5668e321187527d569414f5ca197d615856cc17a",
481
481
  "server/server/packages/ui-library/src/contexts/zone-editing.tsx": "275f680304ab09dd747fd9e859dc5aa0535df33eb2d33eb669a6de66bdd848d0",
482
- "server/server/packages/ui-library/src/generated/system-hooks.ts": "4d6469255cb91a0656ea905e2cea621559c79d6dcb399d8e317c2125df4e5403",
482
+ "server/server/packages/ui-library/src/generated/system-hooks.ts": "5fd6bc7b142eeacac8c2bf789505e134c16db40f12a5b393d7b0764223b71fdb",
483
483
  "server/server/packages/ui-library/src/hooks/turn-server-cache.ts": "fab22f069c3761e0d268449e056d9c499b6ea63b879684a40023735b34bad061",
484
484
  "server/server/packages/ui-library/src/hooks/use-device-capability.ts": "b74ede60be8039c45f6c712a407ee838ab208610435870ddabaa8598cb7cd7f3",
485
485
  "server/server/packages/ui-library/src/hooks/use-device-detections.ts": "61cc54cf2e7f53864e5aa533c05679e4c204c4004a0296f63ab169b003888611",
package/dist/addon.js CHANGED
@@ -5843,7 +5843,7 @@ var ZodIssueCode = {
5843
5843
  var ZodFirstPartyTypeKind;
5844
5844
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5845
5845
  //#endregion
5846
- //#region ../types/dist/sleep-QsoHs66J.mjs
5846
+ //#region ../types/dist/sleep-hmSP-eJt.mjs
5847
5847
  /**
5848
5848
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5849
5849
  * window to float samples (D455).
@@ -9282,6 +9282,7 @@ var CAP_NAMES = Object.freeze([
9282
9282
  "backup",
9283
9283
  "battery",
9284
9284
  "binary",
9285
+ "board-key-source",
9285
9286
  "brightness",
9286
9287
  "broker",
9287
9288
  "button",
@@ -9403,6 +9404,7 @@ var CAP_NAMES = Object.freeze([
9403
9404
  "privacy-mask",
9404
9405
  "ptz",
9405
9406
  "ptz-autotrack",
9407
+ "pump-cycle",
9406
9408
  "reboot",
9407
9409
  "record-entries",
9408
9410
  "recording",
@@ -10695,18 +10697,6 @@ Object.freeze({
10695
10697
  "path": "pumpRunning",
10696
10698
  "valueType": "boolean"
10697
10699
  },
10698
- {
10699
- "path": "pumpIntervalEnabled",
10700
- "valueType": "boolean"
10701
- },
10702
- {
10703
- "path": "pumpOnTime",
10704
- "valueType": "number"
10705
- },
10706
- {
10707
- "path": "pumpOffTime",
10708
- "valueType": "number"
10709
- },
10710
10700
  {
10711
10701
  "path": "lastDrink",
10712
10702
  "valueType": "number"
@@ -10830,6 +10820,20 @@ Object.freeze({
10830
10820
  "valueType": "number"
10831
10821
  }
10832
10822
  ],
10823
+ "pump-cycle": [
10824
+ {
10825
+ "path": "enabled",
10826
+ "valueType": "boolean"
10827
+ },
10828
+ {
10829
+ "path": "onTime",
10830
+ "valueType": "number"
10831
+ },
10832
+ {
10833
+ "path": "offTime",
10834
+ "valueType": "number"
10835
+ }
10836
+ ],
10833
10837
  "recording-archive": [
10834
10838
  {
10835
10839
  "path": "deviceId",
@@ -18832,24 +18836,52 @@ var APPLIANCE_CAP_VOCABULARY = {
18832
18836
  args: { on: false }
18833
18837
  },
18834
18838
  {
18835
- id: "petFountain.intervalOn",
18836
- method: "setPumpInterval",
18839
+ id: "petFountain.resetDailyConsumption",
18840
+ method: "resetDailyConsumption",
18841
+ label: t("Clear daily consumption", "Azzera il consumo giornaliero"),
18842
+ phrase: t("Clear the daily water consumption of {device}", "Azzera il consumo giornaliero di acqua di {device}"),
18843
+ icon: "rotate-ccw"
18844
+ }
18845
+ ],
18846
+ state: [{
18847
+ kind: "boolean",
18848
+ field: "empty",
18849
+ label: t("Tank empty", "Serbatoio vuoto"),
18850
+ whenTrue: t("When the tank of {device} is empty", "Quando il serbatoio di {device} è vuoto"),
18851
+ whenFalse: t("When the tank of {device} is refilled", "Quando il serbatoio di {device} viene riempito"),
18852
+ icon: "droplet"
18853
+ }, {
18854
+ kind: "numeric",
18855
+ field: "waterLevel",
18856
+ quantity: t("the water level", "il livello dell’acqua"),
18857
+ label: t("Water level", "Livello dell’acqua"),
18858
+ unit: "%",
18859
+ icon: "droplets"
18860
+ }]
18861
+ },
18862
+ "pump-cycle": {
18863
+ scope: "device",
18864
+ noun: t("Pump cycle", "Ciclo della pompa"),
18865
+ actions: [
18866
+ {
18867
+ id: "pumpCycle.on",
18868
+ method: "setEnabled",
18837
18869
  label: t("Pump cycle on", "Ciclo pompa attivo"),
18838
18870
  phrase: t("Run the pump of {device} on its on/off cycle", "Fai lavorare la pompa di {device} a ciclo acceso/spento"),
18839
18871
  icon: "timer",
18840
18872
  args: { on: true }
18841
18873
  },
18842
18874
  {
18843
- id: "petFountain.intervalOff",
18844
- method: "setPumpInterval",
18875
+ id: "pumpCycle.off",
18876
+ method: "setEnabled",
18845
18877
  label: t("Pump cycle off", "Ciclo pompa spento"),
18846
18878
  phrase: t("Run the pump of {device} continuously", "Fai lavorare la pompa di {device} in continuo"),
18847
18879
  icon: "timer-off",
18848
18880
  args: { on: false }
18849
18881
  },
18850
18882
  {
18851
- id: "petFountain.pumpOnMinutes",
18852
- method: "setPumpOnMinutes",
18883
+ id: "pumpCycle.onMinutes",
18884
+ method: "setOnMinutes",
18853
18885
  label: t("Set pump run time", "Imposta il tempo di lavoro della pompa"),
18854
18886
  phrase: t("Set the pump of {device} to run {minutes} minutes per cycle", "Imposta la pompa di {device} a lavorare {minutes} minuti per ciclo"),
18855
18887
  icon: "timer",
@@ -18865,8 +18897,8 @@ var APPLIANCE_CAP_VOCABULARY = {
18865
18897
  }]
18866
18898
  },
18867
18899
  {
18868
- id: "petFountain.pumpOffMinutes",
18869
- method: "setPumpOffMinutes",
18900
+ id: "pumpCycle.offMinutes",
18901
+ method: "setOffMinutes",
18870
18902
  label: t("Set pump rest time", "Imposta il tempo di riposo della pompa"),
18871
18903
  phrase: t("Set the pump of {device} to rest {minutes} minutes per cycle", "Imposta la pompa di {device} a riposare {minutes} minuti per ciclo"),
18872
18904
  icon: "timer-off",
@@ -18880,29 +18912,15 @@ var APPLIANCE_CAP_VOCABULARY = {
18880
18912
  unit: "min"
18881
18913
  }
18882
18914
  }]
18883
- },
18884
- {
18885
- id: "petFountain.resetDailyConsumption",
18886
- method: "resetDailyConsumption",
18887
- label: t("Clear daily consumption", "Azzera il consumo giornaliero"),
18888
- phrase: t("Clear the daily water consumption of {device}", "Azzera il consumo giornaliero di acqua di {device}"),
18889
- icon: "rotate-ccw"
18890
18915
  }
18891
18916
  ],
18892
18917
  state: [{
18893
18918
  kind: "boolean",
18894
- field: "empty",
18895
- label: t("Tank empty", "Serbatoio vuoto"),
18896
- whenTrue: t("When the tank of {device} is empty", "Quando il serbatoio di {device} è vuoto"),
18897
- whenFalse: t("When the tank of {device} is refilled", "Quando il serbatoio di {device} viene riempito"),
18898
- icon: "droplet"
18899
- }, {
18900
- kind: "numeric",
18901
- field: "waterLevel",
18902
- quantity: t("the water level", "il livello dell’acqua"),
18903
- label: t("Water level", "Livello dell’acqua"),
18904
- unit: "%",
18905
- icon: "droplets"
18919
+ field: "enabled",
18920
+ label: t("Pump cycle", "Ciclo pompa"),
18921
+ whenTrue: t("When {device} starts running its pump on a cycle", "Quando {device} inizia a far lavorare la pompa a ciclo"),
18922
+ whenFalse: t("When {device} runs its pump continuously", "Quando {device} fa lavorare la pompa in continuo"),
18923
+ icon: "timer"
18906
18924
  }]
18907
18925
  },
18908
18926
  "media-player": {
@@ -20795,6 +20813,7 @@ var SYSTEM_CAP_VOCABULARY = {
20795
20813
  "audio-analyzer": system(PIPELINE),
20796
20814
  "audio-codec": system(INTERNAL),
20797
20815
  "auth-provider": system(IDENTITY),
20816
+ "board-key-source": system(INTERNAL),
20798
20817
  backup: system("system backups — run and restored from the Backups page"),
20799
20818
  broker: system("message-broker connections — configured, not actuated"),
20800
20819
  "calendar-source": system(INTERNAL),
@@ -45238,6 +45257,49 @@ object({
45238
45257
  lastChangedAt: number()
45239
45258
  });
45240
45259
  DeviceType.Sensor;
45260
+ /**
45261
+ * Why a board key could not be read. Typed so a caller reports the cause and
45262
+ * never treats "could not read" as "has no key" (D49).
45263
+ */
45264
+ var BoardKeyFailureReasonSchema = _enum([
45265
+ "unknown-source",
45266
+ "not-admin",
45267
+ "no-builder",
45268
+ "no-ingress-url",
45269
+ "unreachable",
45270
+ "unknown-board",
45271
+ "no-encryption-key",
45272
+ "unreadable-config"
45273
+ ]);
45274
+ var BoardKeySourceSchema = object({
45275
+ sourceId: string(),
45276
+ name: string()
45277
+ });
45278
+ var BoardKeyBoardSchema = object({
45279
+ /** The builder's file name, e.g. `kitchen.yaml`: the handle `getBoardKey` takes. */
45280
+ configuration: string(),
45281
+ /** The node name the builder gives the board. */
45282
+ name: string(),
45283
+ /** The address the builder knows the board by, when it has one. */
45284
+ address: string().nullable()
45285
+ });
45286
+ var BoardKeyFailureSchema = object({
45287
+ ok: literal(false),
45288
+ reason: BoardKeyFailureReasonSchema,
45289
+ detail: string().optional()
45290
+ });
45291
+ var ListBoardsResultSchema = discriminatedUnion("ok", [object({
45292
+ ok: literal(true),
45293
+ boards: array(BoardKeyBoardSchema).readonly()
45294
+ }), BoardKeyFailureSchema]);
45295
+ var GetBoardKeyResultSchema = discriminatedUnion("ok", [object({
45296
+ ok: literal(true),
45297
+ key: string()
45298
+ }), BoardKeyFailureSchema]);
45299
+ method(_void(), array(BoardKeySourceSchema).readonly(), { auth: "admin" }), method(object({ sourceId: string().min(1) }), ListBoardsResultSchema, { auth: "admin" }), method(object({
45300
+ sourceId: string().min(1),
45301
+ configuration: string().min(1)
45302
+ }), GetBoardKeyResultSchema, { auth: "admin" });
45241
45303
  object({
45242
45304
  /** Current level as 0..100 inclusive. Firmware-reported. */
45243
45305
  level: number().min(0).max(100).meta(readingMeta("percentage")),
@@ -50900,7 +50962,7 @@ object({
50900
50962
  /** Ms epoch of the last value received from the appliance; 0 = never. */
50901
50963
  lastFetchedAt: number()
50902
50964
  });
50903
- var DeviceIdSchema$1 = number().int().nonnegative();
50965
+ var DeviceIdSchema$2 = number().int().nonnegative();
50904
50966
  /** A value a program option or setting can take. */
50905
50967
  var DishwasherValueSchema = union([
50906
50968
  boolean(),
@@ -50964,77 +51026,77 @@ var DishwasherOptionsSchema = object({
50964
51026
  options: array(DishwasherOptionDescriptorSchema)
50965
51027
  });
50966
51028
  DeviceType.Dishwasher, method(object({
50967
- deviceId: DeviceIdSchema$1,
51029
+ deviceId: DeviceIdSchema$2,
50968
51030
  program: string().min(1).optional(),
50969
51031
  options: record(string(), DishwasherValueSchema).optional()
50970
51032
  }), _void(), {
50971
51033
  kind: "mutation",
50972
51034
  auth: "protected"
50973
- }), method(object({ deviceId: DeviceIdSchema$1 }), _void(), {
51035
+ }), method(object({ deviceId: DeviceIdSchema$2 }), _void(), {
50974
51036
  kind: "mutation",
50975
51037
  auth: "protected"
50976
- }), method(object({ deviceId: DeviceIdSchema$1 }), _void(), {
51038
+ }), method(object({ deviceId: DeviceIdSchema$2 }), _void(), {
50977
51039
  kind: "mutation",
50978
51040
  auth: "protected"
50979
- }), method(object({ deviceId: DeviceIdSchema$1 }), _void(), {
51041
+ }), method(object({ deviceId: DeviceIdSchema$2 }), _void(), {
50980
51042
  kind: "mutation",
50981
51043
  auth: "protected"
50982
51044
  }), method(object({
50983
- deviceId: DeviceIdSchema$1,
51045
+ deviceId: DeviceIdSchema$2,
50984
51046
  program: string().min(1)
50985
51047
  }), _void(), {
50986
51048
  kind: "mutation",
50987
51049
  auth: "protected"
50988
51050
  }), method(object({
50989
- deviceId: DeviceIdSchema$1,
51051
+ deviceId: DeviceIdSchema$2,
50990
51052
  on: boolean()
50991
51053
  }), _void(), {
50992
51054
  kind: "mutation",
50993
51055
  auth: "protected"
50994
51056
  }), method(object({
50995
- deviceId: DeviceIdSchema$1,
51057
+ deviceId: DeviceIdSchema$2,
50996
51058
  on: boolean()
50997
51059
  }), _void(), {
50998
51060
  kind: "mutation",
50999
51061
  auth: "protected"
51000
51062
  }), method(object({
51001
- deviceId: DeviceIdSchema$1,
51063
+ deviceId: DeviceIdSchema$2,
51002
51064
  on: boolean()
51003
51065
  }), _void(), {
51004
51066
  kind: "mutation",
51005
51067
  auth: "protected"
51006
51068
  }), method(object({
51007
- deviceId: DeviceIdSchema$1,
51069
+ deviceId: DeviceIdSchema$2,
51008
51070
  on: boolean()
51009
51071
  }), _void(), {
51010
51072
  kind: "mutation",
51011
51073
  auth: "protected"
51012
51074
  }), method(object({
51013
- deviceId: DeviceIdSchema$1,
51075
+ deviceId: DeviceIdSchema$2,
51014
51076
  on: boolean()
51015
51077
  }), _void(), {
51016
51078
  kind: "mutation",
51017
51079
  auth: "protected"
51018
51080
  }), method(object({
51019
- deviceId: DeviceIdSchema$1,
51081
+ deviceId: DeviceIdSchema$2,
51020
51082
  on: boolean()
51021
51083
  }), _void(), {
51022
51084
  kind: "mutation",
51023
51085
  auth: "protected"
51024
51086
  }), method(object({
51025
- deviceId: DeviceIdSchema$1,
51087
+ deviceId: DeviceIdSchema$2,
51026
51088
  on: boolean()
51027
51089
  }), _void(), {
51028
51090
  kind: "mutation",
51029
51091
  auth: "protected"
51030
51092
  }), method(object({
51031
- deviceId: DeviceIdSchema$1,
51093
+ deviceId: DeviceIdSchema$2,
51032
51094
  key: string().min(1),
51033
51095
  value: DishwasherValueSchema
51034
51096
  }), _void(), {
51035
51097
  kind: "mutation",
51036
51098
  auth: "protected"
51037
- }), method(object({ deviceId: DeviceIdSchema$1 }), DishwasherOptionsSchema, { auth: "protected" });
51099
+ }), method(object({ deviceId: DeviceIdSchema$2 }), DishwasherOptionsSchema, { auth: "protected" });
51038
51100
  /**
51039
51101
  * Palette entry ids (D939). Audio is the one gradient; `audio-*` leaves are
51040
51102
  * not entries. `heatmapScrub` is a mark, not an event kind.
@@ -64850,52 +64912,27 @@ object({
64850
64912
  empty: boolean().nullable(),
64851
64913
  /** True while the pump is running. Null while unknown. */
64852
64914
  pumpRunning: boolean().nullable(),
64853
- /** True when the pump works on an on/off duty cycle rather than continuously. */
64854
- pumpIntervalEnabled: boolean().nullable(),
64855
- /** How long the pump runs per cycle, in seconds. */
64856
- pumpOnTime: number().min(0).nullable().meta(readingMeta("duration")),
64857
- /** How long the pump rests per cycle, in seconds. */
64858
- pumpOffTime: number().min(0).nullable().meta(readingMeta("duration")),
64859
64915
  /** Water drunk in the last drink, in litres. */
64860
64916
  lastDrink: number().min(0).nullable().meta(readingMeta("volume")),
64861
64917
  /** Water drunk in the current hour, in litres. */
64862
64918
  currentHourDrink: number().min(0).nullable().meta(readingMeta("volume")),
64863
64919
  /** Water drunk over the last 24 hours (rolling), in litres. */
64864
64920
  last24hDrink: number().min(0).nullable().meta(readingMeta("volume")),
64865
- /** Water drunk since local midnight, in litres. */
64921
+ /** Water drunk since local midnight, in litres. Null when the fountain has no such sensor. */
64866
64922
  todayDrink: number().min(0).nullable().meta(readingMeta("volume")),
64867
64923
  /** Decoded fault message. Null means healthy; a non-null string is an active fault. */
64868
64924
  error: string().nullable(),
64869
64925
  /** Ms epoch when the slice was last refreshed. */
64870
64926
  lastFetchedAt: number()
64871
64927
  });
64872
- var DeviceIdSchema = number().int().nonnegative();
64873
- var MinutesSchema = number().int().min(0);
64928
+ var DeviceIdSchema$1 = number().int().nonnegative();
64874
64929
  DeviceType.PetFountain, method(object({
64875
- deviceId: DeviceIdSchema,
64876
- on: boolean()
64877
- }), _void(), {
64878
- kind: "mutation",
64879
- auth: "protected"
64880
- }), method(object({
64881
- deviceId: DeviceIdSchema,
64930
+ deviceId: DeviceIdSchema$1,
64882
64931
  on: boolean()
64883
64932
  }), _void(), {
64884
64933
  kind: "mutation",
64885
64934
  auth: "protected"
64886
- }), method(object({
64887
- deviceId: DeviceIdSchema,
64888
- minutes: MinutesSchema
64889
- }), _void(), {
64890
- kind: "mutation",
64891
- auth: "protected"
64892
- }), method(object({
64893
- deviceId: DeviceIdSchema,
64894
- minutes: MinutesSchema
64895
- }), _void(), {
64896
- kind: "mutation",
64897
- auth: "protected"
64898
- }), method(object({ deviceId: DeviceIdSchema }), _void(), {
64935
+ }), method(object({ deviceId: DeviceIdSchema$1 }), _void(), {
64899
64936
  kind: "mutation",
64900
64937
  auth: "protected"
64901
64938
  });
@@ -66855,6 +66892,37 @@ DeviceType.Camera, method(object({ deviceId: number() }), PtzAutotrackStatusSche
66855
66892
  deviceId: number(),
66856
66893
  status: PtzAutotrackStatusSchema
66857
66894
  });
66895
+ object({
66896
+ /** True when the pump works on the on/off cycle, false when it runs continuously. Null while unknown. */
66897
+ enabled: boolean().nullable(),
66898
+ /** How long the pump runs per cycle, in seconds. Null while unknown. */
66899
+ onTime: number().min(0).nullable().meta(readingMeta("duration")),
66900
+ /** How long the pump rests per cycle, in seconds. Null while unknown. */
66901
+ offTime: number().min(0).nullable().meta(readingMeta("duration")),
66902
+ /** Ms epoch when the slice was last refreshed. */
66903
+ lastFetchedAt: number()
66904
+ });
66905
+ var DeviceIdSchema = number().int().nonnegative();
66906
+ var MinutesSchema = number().int().min(0);
66907
+ DeviceType.PetFountain, method(object({
66908
+ deviceId: DeviceIdSchema,
66909
+ on: boolean()
66910
+ }), _void(), {
66911
+ kind: "mutation",
66912
+ auth: "protected"
66913
+ }), method(object({
66914
+ deviceId: DeviceIdSchema,
66915
+ minutes: MinutesSchema
66916
+ }), _void(), {
66917
+ kind: "mutation",
66918
+ auth: "protected"
66919
+ }), method(object({
66920
+ deviceId: DeviceIdSchema,
66921
+ minutes: MinutesSchema
66922
+ }), _void(), {
66923
+ kind: "mutation",
66924
+ auth: "protected"
66925
+ });
66858
66926
  DeviceType.Camera, DeviceType.Sensor, DeviceType.Switch, DeviceType.Gateway, method(object({ deviceId: number().int().nonnegative() }), object({ success: literal(true) }), {
66859
66927
  kind: "mutation",
66860
66928
  auth: "admin"
@@ -75548,6 +75616,27 @@ Object.freeze({
75548
75616
  access: "view",
75549
75617
  role: "viewer"
75550
75618
  },
75619
+ "boardKeySource.getBoardKey": {
75620
+ capName: "board-key-source",
75621
+ capScope: "system",
75622
+ addonId: null,
75623
+ access: "view",
75624
+ role: "admin"
75625
+ },
75626
+ "boardKeySource.listBoards": {
75627
+ capName: "board-key-source",
75628
+ capScope: "system",
75629
+ addonId: null,
75630
+ access: "view",
75631
+ role: "admin"
75632
+ },
75633
+ "boardKeySource.listSources": {
75634
+ capName: "board-key-source",
75635
+ capScope: "system",
75636
+ addonId: null,
75637
+ access: "view",
75638
+ role: "admin"
75639
+ },
75551
75640
  "brightness.getStatus": {
75552
75641
  capName: "brightness",
75553
75642
  capScope: "device",
@@ -80371,27 +80460,6 @@ Object.freeze({
80371
80460
  access: "create",
80372
80461
  role: "viewer"
80373
80462
  },
80374
- "petFountain.setPumpInterval": {
80375
- capName: "pet-fountain",
80376
- capScope: "device",
80377
- addonId: null,
80378
- access: "create",
80379
- role: "viewer"
80380
- },
80381
- "petFountain.setPumpOffMinutes": {
80382
- capName: "pet-fountain",
80383
- capScope: "device",
80384
- addonId: null,
80385
- access: "create",
80386
- role: "viewer"
80387
- },
80388
- "petFountain.setPumpOnMinutes": {
80389
- capName: "pet-fountain",
80390
- capScope: "device",
80391
- addonId: null,
80392
- access: "create",
80393
- role: "viewer"
80394
- },
80395
80463
  "pipelineAnalytics.addRetrainFrameFromRecording": {
80396
80464
  capName: "pipeline-analytics",
80397
80465
  capScope: "device",
@@ -82170,6 +82238,34 @@ Object.freeze({
82170
82238
  access: "create",
82171
82239
  role: "admin"
82172
82240
  },
82241
+ "pumpCycle.getStatus": {
82242
+ capName: "pump-cycle",
82243
+ capScope: "device",
82244
+ addonId: null,
82245
+ access: "view",
82246
+ role: "viewer"
82247
+ },
82248
+ "pumpCycle.setEnabled": {
82249
+ capName: "pump-cycle",
82250
+ capScope: "device",
82251
+ addonId: null,
82252
+ access: "create",
82253
+ role: "viewer"
82254
+ },
82255
+ "pumpCycle.setOffMinutes": {
82256
+ capName: "pump-cycle",
82257
+ capScope: "device",
82258
+ addonId: null,
82259
+ access: "create",
82260
+ role: "viewer"
82261
+ },
82262
+ "pumpCycle.setOnMinutes": {
82263
+ capName: "pump-cycle",
82264
+ capScope: "device",
82265
+ addonId: null,
82266
+ access: "create",
82267
+ role: "viewer"
82268
+ },
82173
82269
  "reboot.reboot": {
82174
82270
  capName: "reboot",
82175
82271
  capScope: "device",
@@ -86714,21 +86810,6 @@ Object.freeze({
86714
86810
  form: "single",
86715
86811
  optional: false
86716
86812
  }],
86717
- "petFountain.setPumpInterval": [{
86718
- name: "deviceId",
86719
- form: "single",
86720
- optional: false
86721
- }],
86722
- "petFountain.setPumpOffMinutes": [{
86723
- name: "deviceId",
86724
- form: "single",
86725
- optional: false
86726
- }],
86727
- "petFountain.setPumpOnMinutes": [{
86728
- name: "deviceId",
86729
- form: "single",
86730
- optional: false
86731
- }],
86732
86813
  "pipelineAnalytics.addRetrainFrameFromRecording": [{
86733
86814
  name: "deviceId",
86734
86815
  form: "single",
@@ -87364,6 +87445,26 @@ Object.freeze({
87364
87445
  form: "single",
87365
87446
  optional: false
87366
87447
  }],
87448
+ "pumpCycle.getStatus": [{
87449
+ name: "deviceId",
87450
+ form: "single",
87451
+ optional: false
87452
+ }],
87453
+ "pumpCycle.setEnabled": [{
87454
+ name: "deviceId",
87455
+ form: "single",
87456
+ optional: false
87457
+ }],
87458
+ "pumpCycle.setOffMinutes": [{
87459
+ name: "deviceId",
87460
+ form: "single",
87461
+ optional: false
87462
+ }],
87463
+ "pumpCycle.setOnMinutes": [{
87464
+ name: "deviceId",
87465
+ form: "single",
87466
+ optional: false
87467
+ }],
87367
87468
  "reboot.reboot": [{
87368
87469
  name: "deviceId",
87369
87470
  form: "single",
@@ -89555,7 +89656,7 @@ var AgentUIAddon = class extends BaseAddon {
89555
89656
  capability: adminUiCapability,
89556
89657
  provider: {
89557
89658
  getStaticDir: async () => ({ staticDir: path.resolve(__dirname) }),
89558
- getVersion: async () => ({ version: "1.2.316" })
89659
+ getVersion: async () => ({ version: "1.2.317" })
89559
89660
  }
89560
89661
  }];
89561
89662
  }
@@ -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,d as o,g as s,l as c,p as l,t as u,w as d}from"./index-DO3az6fG.js";import{MaskShapeCanvas as f}from"./MaskShapeCanvas-BTvl6Rin.js";var p=d(`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`}]]),m=n(i(),1),h=n(e(),1),g=110,_=`motion-zones`,v=0,y=[1,2,3],b=1,x=`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`,S=`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 C(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 w(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 T(e,t){return Math.ceil(e/t)}function E(e,t,n){return Math.min(n-1,Math.floor((e+.5)/t*n))}function D(e,t,n,r){let i=T(t,r),a=T(n,r),o=Array.from({length:i*a},()=>!1);for(let r=0;r<n;r+=1){let s=E(r,n,a);for(let n=0;n<t;n+=1)e[r*t+n]===!0&&(o[s*i+E(n,t,i)]=!0)}return o}function O(e,t,n,r){let i=T(t,r),a=T(n,r),o=Array.from({length:t*n},()=>!1);for(let r=0;r<n;r+=1){let s=E(r,n,a);for(let n=0;n<t;n+=1)o[r*t+n]=e[s*i+E(n,t,i)]===!0}return o}function k({deviceId:e}){let n=t(),i=o(s().trpcClient,e),[d,E]=(0,m.useState)(null),[k,A]=(0,m.useState)(!1),[j,M]=(0,m.useState)(null),[N,P]=(0,m.useState)(null),[F,I]=(0,m.useState)(b),[L,R]=(0,m.useState)(!1),[z,B]=(0,m.useState)(!1),V=(0,m.useRef)(!1);(0,m.useEffect)(()=>{if(!i)return;let e=!1;return V.current=!1,E(null),A(!1),M(null),P(null),I(b),B(!1),(async()=>{try{let t=await i.motionZones?.getOptions({});if(e)return;if(!t)throw Error(`device proxy not ready`);if(E(t),V.current)return;let n=await i.motionZones?.getStatus({});if(e)return;if(!n)throw Error(`device proxy not ready`);V.current=!0;let r=n.regions.find(e=>e.shape.kind===`grid`),a=C(r?r.shape.cells:[],t.grid.width,t.grid.height);P(a),M(D(a,t.grid.width,t.grid.height,b))}catch(t){if(e)return;c(t)?A(!0):console.error(`Motion Zones load failed`,t)}})(),()=>{e=!0}},[i]);let H=d?d.grid.width:0,U=d?d.grid.height:0,W=T(H,F),G=T(U,F),K=(0,m.useMemo)(()=>j&&d?O(j,H,U,F):null,[j,d,H,U,F]),q=(0,m.useMemo)(()=>K!==null&&N!==null&&!w(K,N),[K,N]),J=(0,m.useMemo)(()=>K?K.reduce((e,t)=>t?e+1:e,0):0,[K]),Y=H*U,X=W*G,Z=(0,m.useCallback)(e=>{X>0&&M(Array.from({length:X},()=>e))},[X]),ee=(0,m.useCallback)(()=>{M(e=>e&&e.map(e=>!e))},[]),te=(0,m.useCallback)(()=>{N&&d&&M(D(N,H,U,F))},[N,d,H,U,F]),ne=(0,m.useCallback)(e=>{e===F||!d||M(t=>{if(!t)return I(e),t;let n=D(O(t,H,U,F),H,U,e);return I(e),n})},[F,d,H,U]),Q=(0,m.useMemo)(()=>d&&j?[{id:v,shape:{kind:`grid`,gridWidth:W,gridHeight:G,cells:[...j]}}]:[],[d,j,W,G]),$=(0,m.useCallback)((e,t)=>{t.kind===`grid`&&M(t.cells)},[]),re=(0,m.useCallback)(async()=>{if(!(!i||!j||!d)){R(!0);try{let e=O(j,d.grid.width,d.grid.height,F),t={kind:`grid`,gridWidth:d.grid.width,gridHeight:d.grid.height,cells:e};await i.motionZones?.setZone({patch:{regions:[{id:v,enabled:!0,shape:t}]}});let n=await i.motionZones?.getStatus({});if(n){let e=n.regions.find(e=>e.shape.kind===`grid`),t=C(e?e.shape.cells:[],d.grid.width,d.grid.height);P(t),M(D(t,d.grid.width,d.grid.height,F))}}catch(e){console.error(`Motion Zones save failed`,e)}finally{R(!1)}}},[i,j,d,F]);u((0,m.useMemo)(()=>z&&!k&&d&&j?{id:_,order:g,node:(0,h.jsx)(f,{transparent:!0,items:Q,supportedShapes:[`grid`],grid:{width:W,height:G},selectedId:v,onSelect:()=>{},onShapeChange:$,onDrawComplete:()=>{},drawingKind:null})}:null,[z,k,d,j,Q,$,W,G]));let ie=!k&&d!==null&&j!==null;return i?(0,h.jsx)(l,{title:n(`uiLibrary.motionZones.title`,`Motion Zones`),icon:(0,h.jsx)(p,{className:`h-3.5 w-3.5 text-foreground-subtle`}),children:(0,h.jsx)(`div`,{className:`flex flex-col gap-3`,children:k?(0,h.jsx)(`p`,{className:`${a} leading-relaxed`,children:n(`uiLibrary.motionZones.unsupported`,`This camera doesn't expose an on-board motion zones grid.`)}):ie?(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`p`,{className:`${a} leading-relaxed`,children:(0,h.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,h.jsx)(`strong`,{className:`text-foreground`},`e`),(0,h.jsx)(`strong`,{className:`text-foreground`},`s`),(0,h.jsx)(`strong`,{className:`text-foreground`},`c`)],values:{width:d.grid.width,height:d.grid.height}})}),(0,h.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,h.jsx)(`button`,{type:`button`,onClick:()=>B(e=>!e),disabled:L,"aria-pressed":z,className:z?S:x,children:z?n(`uiLibrary.motionZones.doneEditing`,`Done editing`):n(`uiLibrary.motionZones.editGrid`,`Edit grid`)}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>Z(!0),disabled:L,className:x,children:n(`uiLibrary.motionZones.allOn`,`All on`)}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>Z(!1),disabled:L,className:x,children:n(`uiLibrary.motionZones.allOff`,`All off`)}),(0,h.jsx)(`button`,{type:`button`,onClick:ee,disabled:L,className:x,children:n(`uiLibrary.motionZones.invert`,`Invert`)}),(0,h.jsxs)(`div`,{className:`flex items-center gap-1 ml-1`,role:`group`,"aria-label":n(`uiLibrary.motionZones.cellSize`,`Cell size`),children:[(0,h.jsx)(`span`,{className:`${a} mr-0.5`,children:n(`uiLibrary.motionZones.cellSize`,`Cell size`)}),y.map(e=>(0,h.jsxs)(`button`,{type:`button`,onClick:()=>ne(e),disabled:L,"aria-pressed":F===e,title:e===1?n(`uiLibrary.motionZones.cameraGrid`,`Camera grid {{width}}×{{height}} (finest)`,{width:H,height:U}):n(`uiLibrary.motionZones.paintingGrid`,`{{width}}×{{height}} painting grid · cells ×{{factor}} bigger`,{width:T(H,e),height:T(U,e),factor:e}),className:F===e?S:x,children:[`×`,e]},e))]}),(0,h.jsxs)(`span`,{className:`${a} ml-1 tabular-nums`,children:[n(`uiLibrary.motionZones.cells`,`{{active}} / {{total}} cells · {{width}}×{{height}}`,{active:J,total:Y,width:d.grid.width,height:d.grid.height}),F===1?``:n(`uiLibrary.motionZones.paintSuffix`,` · paint {{width}}×{{height}}`,{width:W,height:G})]}),(0,h.jsx)(`span`,{className:`flex-1`}),(0,h.jsx)(`button`,{type:`button`,onClick:te,disabled:L||!q,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,h.jsx)(`button`,{type:`button`,onClick:()=>void re(),disabled:L||!q,className:S,children:L?n(`uiLibrary.motionZones.saving`,`Saving…`):n(`uiLibrary.motionZones.save`,`Save`)})]})]}):(0,h.jsx)(`p`,{className:`${a} leading-relaxed`,children:n(`uiLibrary.motionZones.loading`,`Loading the camera's grid…`)})})}):null}export{k as MotionZonesSettings};
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,d as o,g as s,l as c,p as l,t as u,w as d}from"./index-DMz4jMip.js";import{MaskShapeCanvas as f}from"./MaskShapeCanvas-BTvl6Rin.js";var p=d(`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`}]]),m=n(i(),1),h=n(e(),1),g=110,_=`motion-zones`,v=0,y=[1,2,3],b=1,x=`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`,S=`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 C(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 w(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 T(e,t){return Math.ceil(e/t)}function E(e,t,n){return Math.min(n-1,Math.floor((e+.5)/t*n))}function D(e,t,n,r){let i=T(t,r),a=T(n,r),o=Array.from({length:i*a},()=>!1);for(let r=0;r<n;r+=1){let s=E(r,n,a);for(let n=0;n<t;n+=1)e[r*t+n]===!0&&(o[s*i+E(n,t,i)]=!0)}return o}function O(e,t,n,r){let i=T(t,r),a=T(n,r),o=Array.from({length:t*n},()=>!1);for(let r=0;r<n;r+=1){let s=E(r,n,a);for(let n=0;n<t;n+=1)o[r*t+n]=e[s*i+E(n,t,i)]===!0}return o}function k({deviceId:e}){let n=t(),i=o(s().trpcClient,e),[d,E]=(0,m.useState)(null),[k,A]=(0,m.useState)(!1),[j,M]=(0,m.useState)(null),[N,P]=(0,m.useState)(null),[F,I]=(0,m.useState)(b),[L,R]=(0,m.useState)(!1),[z,B]=(0,m.useState)(!1),V=(0,m.useRef)(!1);(0,m.useEffect)(()=>{if(!i)return;let e=!1;return V.current=!1,E(null),A(!1),M(null),P(null),I(b),B(!1),(async()=>{try{let t=await i.motionZones?.getOptions({});if(e)return;if(!t)throw Error(`device proxy not ready`);if(E(t),V.current)return;let n=await i.motionZones?.getStatus({});if(e)return;if(!n)throw Error(`device proxy not ready`);V.current=!0;let r=n.regions.find(e=>e.shape.kind===`grid`),a=C(r?r.shape.cells:[],t.grid.width,t.grid.height);P(a),M(D(a,t.grid.width,t.grid.height,b))}catch(t){if(e)return;c(t)?A(!0):console.error(`Motion Zones load failed`,t)}})(),()=>{e=!0}},[i]);let H=d?d.grid.width:0,U=d?d.grid.height:0,W=T(H,F),G=T(U,F),K=(0,m.useMemo)(()=>j&&d?O(j,H,U,F):null,[j,d,H,U,F]),q=(0,m.useMemo)(()=>K!==null&&N!==null&&!w(K,N),[K,N]),J=(0,m.useMemo)(()=>K?K.reduce((e,t)=>t?e+1:e,0):0,[K]),Y=H*U,X=W*G,Z=(0,m.useCallback)(e=>{X>0&&M(Array.from({length:X},()=>e))},[X]),ee=(0,m.useCallback)(()=>{M(e=>e&&e.map(e=>!e))},[]),te=(0,m.useCallback)(()=>{N&&d&&M(D(N,H,U,F))},[N,d,H,U,F]),ne=(0,m.useCallback)(e=>{e===F||!d||M(t=>{if(!t)return I(e),t;let n=D(O(t,H,U,F),H,U,e);return I(e),n})},[F,d,H,U]),Q=(0,m.useMemo)(()=>d&&j?[{id:v,shape:{kind:`grid`,gridWidth:W,gridHeight:G,cells:[...j]}}]:[],[d,j,W,G]),$=(0,m.useCallback)((e,t)=>{t.kind===`grid`&&M(t.cells)},[]),re=(0,m.useCallback)(async()=>{if(!(!i||!j||!d)){R(!0);try{let e=O(j,d.grid.width,d.grid.height,F),t={kind:`grid`,gridWidth:d.grid.width,gridHeight:d.grid.height,cells:e};await i.motionZones?.setZone({patch:{regions:[{id:v,enabled:!0,shape:t}]}});let n=await i.motionZones?.getStatus({});if(n){let e=n.regions.find(e=>e.shape.kind===`grid`),t=C(e?e.shape.cells:[],d.grid.width,d.grid.height);P(t),M(D(t,d.grid.width,d.grid.height,F))}}catch(e){console.error(`Motion Zones save failed`,e)}finally{R(!1)}}},[i,j,d,F]);u((0,m.useMemo)(()=>z&&!k&&d&&j?{id:_,order:g,node:(0,h.jsx)(f,{transparent:!0,items:Q,supportedShapes:[`grid`],grid:{width:W,height:G},selectedId:v,onSelect:()=>{},onShapeChange:$,onDrawComplete:()=>{},drawingKind:null})}:null,[z,k,d,j,Q,$,W,G]));let ie=!k&&d!==null&&j!==null;return i?(0,h.jsx)(l,{title:n(`uiLibrary.motionZones.title`,`Motion Zones`),icon:(0,h.jsx)(p,{className:`h-3.5 w-3.5 text-foreground-subtle`}),children:(0,h.jsx)(`div`,{className:`flex flex-col gap-3`,children:k?(0,h.jsx)(`p`,{className:`${a} leading-relaxed`,children:n(`uiLibrary.motionZones.unsupported`,`This camera doesn't expose an on-board motion zones grid.`)}):ie?(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`p`,{className:`${a} leading-relaxed`,children:(0,h.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,h.jsx)(`strong`,{className:`text-foreground`},`e`),(0,h.jsx)(`strong`,{className:`text-foreground`},`s`),(0,h.jsx)(`strong`,{className:`text-foreground`},`c`)],values:{width:d.grid.width,height:d.grid.height}})}),(0,h.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,h.jsx)(`button`,{type:`button`,onClick:()=>B(e=>!e),disabled:L,"aria-pressed":z,className:z?S:x,children:z?n(`uiLibrary.motionZones.doneEditing`,`Done editing`):n(`uiLibrary.motionZones.editGrid`,`Edit grid`)}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>Z(!0),disabled:L,className:x,children:n(`uiLibrary.motionZones.allOn`,`All on`)}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>Z(!1),disabled:L,className:x,children:n(`uiLibrary.motionZones.allOff`,`All off`)}),(0,h.jsx)(`button`,{type:`button`,onClick:ee,disabled:L,className:x,children:n(`uiLibrary.motionZones.invert`,`Invert`)}),(0,h.jsxs)(`div`,{className:`flex items-center gap-1 ml-1`,role:`group`,"aria-label":n(`uiLibrary.motionZones.cellSize`,`Cell size`),children:[(0,h.jsx)(`span`,{className:`${a} mr-0.5`,children:n(`uiLibrary.motionZones.cellSize`,`Cell size`)}),y.map(e=>(0,h.jsxs)(`button`,{type:`button`,onClick:()=>ne(e),disabled:L,"aria-pressed":F===e,title:e===1?n(`uiLibrary.motionZones.cameraGrid`,`Camera grid {{width}}×{{height}} (finest)`,{width:H,height:U}):n(`uiLibrary.motionZones.paintingGrid`,`{{width}}×{{height}} painting grid · cells ×{{factor}} bigger`,{width:T(H,e),height:T(U,e),factor:e}),className:F===e?S:x,children:[`×`,e]},e))]}),(0,h.jsxs)(`span`,{className:`${a} ml-1 tabular-nums`,children:[n(`uiLibrary.motionZones.cells`,`{{active}} / {{total}} cells · {{width}}×{{height}}`,{active:J,total:Y,width:d.grid.width,height:d.grid.height}),F===1?``:n(`uiLibrary.motionZones.paintSuffix`,` · paint {{width}}×{{height}}`,{width:W,height:G})]}),(0,h.jsx)(`span`,{className:`flex-1`}),(0,h.jsx)(`button`,{type:`button`,onClick:te,disabled:L||!q,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,h.jsx)(`button`,{type:`button`,onClick:()=>void re(),disabled:L||!q,className:S,children:L?n(`uiLibrary.motionZones.saving`,`Saving…`):n(`uiLibrary.motionZones.save`,`Save`)})]})]}):(0,h.jsx)(`p`,{className:`${a} leading-relaxed`,children:n(`uiLibrary.motionZones.loading`,`Loading the camera's grid…`)})})}):null}export{k as MotionZonesSettings};