@camstack/addon-admin-ui 1.2.267 → 1.2.269

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.
Files changed (84) hide show
  1. package/dist/assets/{AddonCollectionPage-Dh-LfpqC.js → AddonCollectionPage-D-gYSGkW.js} +1 -1
  2. package/dist/assets/{Addons-DKGmO7Vl.js → Addons-C-vPILkP.js} +1 -1
  3. package/dist/assets/AdminTabs-BTGn6tEG.js +1 -0
  4. package/dist/assets/{AiProfiles-BJuMQ6wD.js → AiProfiles-B0A4baBM.js} +1 -1
  5. package/dist/assets/{BrokerForm-C2s68cIi.js → BrokerForm-CqAQZoqg.js} +1 -1
  6. package/dist/assets/{Build-BVFIc0Jj.js → Build-DIvLgeZ-.js} +3 -3
  7. package/dist/assets/{Capabilities-B9uMfM8F.js → Capabilities-KIQ63MO9.js} +1 -1
  8. package/dist/assets/{CapabilityBadges-Ct0inpgH.js → CapabilityBadges-DKrha3CG.js} +1 -1
  9. package/dist/assets/{Cluster-Bb9DzB1J.js → Cluster-j8EXDQDu.js} +1 -1
  10. package/dist/assets/{Data-CaQYutBe.js → Data-CGONwfXu.js} +1 -1
  11. package/dist/assets/{DetectionIntelligence-BzJRcjAx.js → DetectionIntelligence-Djo1KwDz.js} +1 -1
  12. package/dist/assets/{DeviceAggregateSection-Cb9122jc.js → DeviceAggregateSection-FVXPGL0L.js} +1 -1
  13. package/dist/assets/{DeviceDetail-R6hSrRFn.js → DeviceDetail-CmgubXA9.js} +2 -2
  14. package/dist/assets/{Devices-DX2V2Hql.js → Devices-5De1IznW.js} +1 -1
  15. package/dist/assets/{EmbedPlayerPage-CSI6tdlW.js → EmbedPlayerPage-ByhGpbVT.js} +1 -1
  16. package/dist/assets/{Events-5d_CgskZ.js → Events-Y3OVukWQ.js} +1 -1
  17. package/dist/assets/{FormBuilder-UFHjWUf9.js → FormBuilder-DiXV8BUC.js} +1 -1
  18. package/dist/assets/{Identity-C24JJMCy.js → Identity-DhZoFy8Y.js} +1 -1
  19. package/dist/assets/{IntegrationDetail-HyrgKwN2.js → IntegrationDetail-2hO9NnB4.js} +1 -1
  20. package/dist/assets/{Integrations-B8UJIzje.js → Integrations-BMRoaJBZ.js} +1 -1
  21. package/dist/assets/{Integrations-BCl9C1In.js → Integrations-CrpwkBzs.js} +1 -1
  22. package/dist/assets/{Locations-E9MNQtAR.js → Locations-Dyu_MjDb.js} +2 -2
  23. package/dist/assets/{Logs-D63ITz9A.js → Logs-BYY68bWg.js} +1 -1
  24. package/dist/assets/{MotionZonesSettings-E1rpEAhz.js → MotionZonesSettings-B7R3uaIs.js} +1 -1
  25. package/dist/assets/{MyAccess-H0JabXJO.js → MyAccess-DA6TCKFM.js} +1 -1
  26. package/dist/assets/{Network-D3Zcqg9s.js → Network-DnWSXtE1.js} +1 -1
  27. package/dist/assets/{NodeAddonsSettingsPanel-DsZ2vgKd.js → NodeAddonsSettingsPanel-BoybMDMM.js} +1 -1
  28. package/dist/assets/{NodeInferenceDevices-C1sPl_zK.js → NodeInferenceDevices-D_I4AO6e.js} +1 -1
  29. package/dist/assets/Notifications-j8rMhe2B.js +1 -0
  30. package/dist/assets/{Pipeline-RvagGKJX.js → Pipeline-CN75uSQb.js} +1 -1
  31. package/dist/assets/{Plates-CtlTpcml.js → Plates-DagiGO4b.js} +1 -1
  32. package/dist/assets/{PrivacyMaskSettings-Di4BC6vd.js → PrivacyMaskSettings-CQYzmC99.js} +1 -1
  33. package/dist/assets/{ProviderIcon-DarxxQmF.js → ProviderIcon-XK7JkRiz.js} +1 -1
  34. package/dist/assets/{Recordings-DF3Exx_Q.js → Recordings-DeSrQvVu.js} +1 -1
  35. package/dist/assets/{ScanNetworkModal-CM_xHHJx.js → ScanNetworkModal-B7BPfyqQ.js} +1 -1
  36. package/dist/assets/{SceneMonitorEditor-oyJ6wM8D.js → SceneMonitorEditor-CFRbMsj-.js} +1 -1
  37. package/dist/assets/{Scenes-DSR74x1f.js → Scenes-jEozoC5J.js} +1 -1
  38. package/dist/assets/{Settings-GcdrheF3.js → Settings-C4vFCpZg.js} +1 -1
  39. package/dist/assets/{Showroom-A5hppkEk.js → Showroom-CdFOYXww.js} +1 -1
  40. package/dist/assets/{StorageLocationsPanel-vIIkNOEf.js → StorageLocationsPanel-DP9rO7W9.js} +1 -1
  41. package/dist/assets/{Terminal-4muMQSI4.js → Terminal-SmHRVcI9.js} +1 -1
  42. package/dist/assets/{Viewer-DGC4t6RF.js → Viewer-9xIHwCzN.js} +1 -1
  43. package/dist/assets/{_virtual_mf-localSharedImportMap___mfe_internal__admin_ui_host-D_KUeTsd.js → _virtual_mf-localSharedImportMap___mfe_internal__admin_ui_host-aBHmNPgW.js} +1 -1
  44. package/dist/assets/{archive-qAgd4cmZ.js → archive-Dsj5Yn7T.js} +1 -1
  45. package/dist/assets/{authed-media-CT8Ntkf6.js → authed-media-7apZd91b.js} +1 -1
  46. package/dist/assets/{boxes-B76KDVc3.js → boxes-Bo8Eo7Eo.js} +1 -1
  47. package/dist/assets/circle-slash-DjTa1Zvs.js +1 -0
  48. package/dist/assets/{debounced-invalidate-D_2NBRHb.js → debounced-invalidate-CzLxXRyZ.js} +1 -1
  49. package/dist/assets/dist-BnI34jwy.js +1 -0
  50. package/dist/assets/dist-s-m3gvQn.js +349 -0
  51. package/dist/assets/{face-bbox-sQNCcpBD.js → face-bbox-CQAHU2sS.js} +1 -1
  52. package/dist/assets/{hard-drive-download-QwRO-K79.js → hard-drive-download-DfDGbPXo.js} +1 -1
  53. package/dist/assets/{hostInit-GlPGaf9F.js → hostInit-gW89JebF.js} +1 -1
  54. package/dist/assets/{index-BFsDCSWR.css → index-B-0u4ZEx.css} +1 -1
  55. package/dist/assets/{index-DZmZt8Pw.js → index-CHPT-81A.js} +3 -3
  56. package/dist/assets/{layers-DpGMZn67.js → layers-C9A4C8lf.js} +1 -1
  57. package/dist/assets/{location-owned-usage-M2Ke8WDZ.js → location-owned-usage-Da_UJwfV.js} +1 -1
  58. package/dist/assets/{mf-entry-bootstrap-0-3f655ace.js → mf-entry-bootstrap-0-5a995df0.js} +2 -2
  59. package/dist/assets/{player-overlays-DBeLKlvr.js → player-overlays--BOkL6mz.js} +1 -1
  60. package/dist/assets/remoteEntry-BrwpwqGC.js +1 -0
  61. package/dist/assets/{send-Dj20pEAB.js → send-DZKRTbf_.js} +1 -1
  62. package/dist/assets/{settings-2-DFFRVeal.js → settings-2--5_3LkW6.js} +1 -1
  63. package/dist/assets/{square-check-big-CrYM6cIR.js → square-check-big-B5AtTb7Y.js} +1 -1
  64. package/dist/assets/src-BoFa7hhW.js +67 -0
  65. package/dist/assets/src-Di313rQf.js +349 -0
  66. package/dist/assets/{use-scenes-feed-BnJkVAGn.js → use-scenes-feed-CZhAv0u4.js} +1 -1
  67. package/dist/assets/{use-stationary-objects-EvgA5taz.js → use-stationary-objects-Cdir5Pea.js} +1 -1
  68. package/dist/assets/useEventInvalidation-C0Ht3Sui.js +1 -0
  69. package/dist/assets/{useNodeUrlSelection-DEKxRLjy.js → useNodeUrlSelection-CbkBS3rA.js} +1 -1
  70. package/dist/assets/user-round-C6L5OyWq.js +1 -0
  71. package/dist/assets/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__admin_ui_host__remoteEntry-_hash_-CZO6_ULN.js → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__admin_ui_host__remoteEntry-_hash_-CTdJOO8z.js} +2 -2
  72. package/dist/index.html +6 -6
  73. package/dist/server/addon.js +223 -8
  74. package/package.json +1 -1
  75. package/dist/assets/AdminTabs-DhkAbSbM.js +0 -1
  76. package/dist/assets/Notifications-1wByVqt4.js +0 -1
  77. package/dist/assets/circle-slash-DqKy2VT5.js +0 -1
  78. package/dist/assets/dist-BZGaQ7Y7.js +0 -1
  79. package/dist/assets/dist-C2bPequg.js +0 -349
  80. package/dist/assets/remoteEntry-Blr1kesh.js +0 -1
  81. package/dist/assets/src-B2UA4y-L.js +0 -349
  82. package/dist/assets/src-Cr7Ldmwc.js +0 -67
  83. package/dist/assets/useEventInvalidation-B6eXiCUA.js +0 -1
  84. package/dist/assets/user-round-Cs8qBz0D.js +0 -1
@@ -5361,7 +5361,7 @@ var ZodIssueCode = {
5361
5361
  var ZodFirstPartyTypeKind;
5362
5362
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5363
5363
  //#endregion
5364
- //#region ../types/dist/sleep-D_4W7xuQ.mjs
5364
+ //#region ../types/dist/sleep-DU7mu4wb.mjs
5365
5365
  /**
5366
5366
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5367
5367
  * window to float samples (D455).
@@ -16998,6 +16998,9 @@ var NcSystemEventKindSchema = _enum([
16998
16998
  "device-battery-normal",
16999
16999
  "device-consumable-low",
17000
17000
  "device-consumable-normal",
17001
+ "device-tank-low",
17002
+ "device-tank-full",
17003
+ "device-tank-normal",
17001
17004
  "stream-online",
17002
17005
  "stream-offline",
17003
17006
  "node-online",
@@ -17068,7 +17071,22 @@ var NcSystemEventConditionSchema = object({
17068
17071
  */
17069
17072
  excludeDeviceIds: array(number().int()).min(1).optional(),
17070
17073
  nodeIds: array(string().min(1)).min(1).optional(),
17071
- packageNames: array(string().min(1)).min(1).optional()
17074
+ packageNames: array(string().min(1)).min(1).optional(),
17075
+ /**
17076
+ * At or below this remaining-life %, a consumable is LOW for THIS rule
17077
+ * (D642). Absent = {@link NC_CONSUMABLE_LOW_PERCENT_DEFAULT}; at most
17078
+ * {@link NC_CONSUMABLE_LOW_PERCENT_MAX}, so every episode can recover. Scoped to the
17079
+ * consumable kinds (`systemEventFilterApplies`) and to the device-events
17080
+ * family; ignored on every other kind.
17081
+ *
17082
+ * It is a property of the RULE because the operator decided so: a rule at
17083
+ * 25 must be told about a filter at 20 %, a rule at 10 must not. The hub
17084
+ * keeps one episode per (threshold, device, item) — its own hysteresis, its
17085
+ * own reminder — and a rule hears only the episode judged at ITS threshold,
17086
+ * exactly as an occupancy rule hears only the edge of its own count. A
17087
+ * provider's own `replace` verdict is low at every threshold.
17088
+ */
17089
+ consumableLowPercent: number().int().min(1).max(95).optional()
17072
17090
  });
17073
17091
  /** Hard ceiling on a window (24h). A snooze that could not expire would be an
17074
17092
  * outage the operator asked for once and forgot. */
@@ -17211,6 +17229,16 @@ var NcCrossingSchema = _enum([
17211
17229
  "exit",
17212
17230
  "any"
17213
17231
  ]);
17232
+ /**
17233
+ * Which edge of a BOOLEAN sensor fires a device-event rule (D640).
17234
+ * - `raised` — the sensor went high: water detected, smoke, open, tampered.
17235
+ * - `cleared` — it went back: dry, clear, closed.
17236
+ * - absent — both edges, which is what every rule authored before this did.
17237
+ *
17238
+ * There is no third member for "both": absence already says it, and a value
17239
+ * that means the same as absence is a second way to write one rule.
17240
+ */
17241
+ var NcSensorTransitionSchema = _enum(["raised", "cleared"]);
17214
17242
  /** Admin-zone membership condition (zone IDs as stamped by the ZoneEngine). */
17215
17243
  var NcZoneConditionSchema = object({
17216
17244
  ids: array(string().min(1)).min(1),
@@ -17400,6 +17428,20 @@ var NcConditionsSchema = object({
17400
17428
  scene: NcSceneConditionSchema.optional(),
17401
17429
  /** Device scope — absent = all devices. */
17402
17430
  devices: array(number()).optional(),
17431
+ /**
17432
+ * Device EXCLUSION (D641) — "every device except these". Judged on the SAME
17433
+ * subject ids {@link devices} is judged on (the camera, the sensor that
17434
+ * fired, a linked set's sensor and row cameras), so a sensor fanned out per
17435
+ * linked camera is excluded exactly where an include would have tested it.
17436
+ * `min(1)`: an empty exclusion excludes nothing and is written as absent.
17437
+ *
17438
+ * Not for `system-event` rules — those carry their own
17439
+ * `systemEvent.excludeDeviceIds` (D636), and the hub refuses this key there.
17440
+ * Editors present the two lists as ONE field (All | Only these | All except
17441
+ * these); the engine evaluates each independently, so a legacy rule
17442
+ * carrying both still means "these, minus those".
17443
+ */
17444
+ devicesExclude: array(number()).min(1).optional(),
17403
17445
  /** Detector class names (any overlap with the record's class set). */
17404
17446
  classes: array(string().min(1)).optional(),
17405
17447
  /** Veto classes — any overlap fails the rule. */
@@ -17533,6 +17575,16 @@ var NcConditionsSchema = object({
17533
17575
  */
17534
17576
  sensorKinds: array(string().min(1)).optional(),
17535
17577
  /**
17578
+ * DEVICE-EVENT only (D640). Fire on one edge of a boolean sensor —
17579
+ * {@link NcSensorTransitionSchema}. Which field of the slice means "raised"
17580
+ * is `@camstack/types` → `notification/sensor-raised.ts`. A reading the
17581
+ * engine cannot place (a kind with no raise, an unreadable slice) PASSES:
17582
+ * the condition fails open towards notifying, never towards silence. Editors
17583
+ * offer it only when every chosen {@link sensorKinds} member has a raise
17584
+ * (`sensorTransitionOffered`), and the hub refuses it on any other delivery.
17585
+ */
17586
+ sensorTransition: NcSensorTransitionSchema.optional(),
17587
+ /**
17536
17588
  * PACKAGE-EVENT only. Which package phase fires the rule — `delivered`
17537
17589
  * (a parked parcel appeared), `picked-up` (it departed), or `both`. Fails
17538
17590
  * when the subject's phase does not match (a subject always carries a phase
@@ -18151,6 +18203,7 @@ var NcConditionDescriptorSchema = object({
18151
18203
  /** Editor widget the UI renders — never hardcode per-condition forms. */
18152
18204
  valueType: _enum([
18153
18205
  "deviceIdList",
18206
+ "deviceIdExcludeList",
18154
18207
  "stringList",
18155
18208
  "number01",
18156
18209
  "number",
@@ -18161,6 +18214,7 @@ var NcConditionDescriptorSchema = object({
18161
18214
  "plateMatcher",
18162
18215
  "packagePhase",
18163
18216
  "crossingSelect",
18217
+ "sensorTransition",
18164
18218
  "polygonDraw",
18165
18219
  "occupancy",
18166
18220
  "audio",
@@ -18311,6 +18365,28 @@ var NcHistoryFilterSchema = object({
18311
18365
  limit: number().int().min(1).max(500).default(100)
18312
18366
  });
18313
18367
  /**
18368
+ * Every rule's last run, in one answer.
18369
+ *
18370
+ * A rule ABSENT from `runs` produced no delivery inside `horizonMs` — how far
18371
+ * back this answer looked, in ms before the hub's now. It is the outbox prune
18372
+ * window (7 days by default, operator-configurable), NARROWED when the read hit
18373
+ * its row bound: the answer never claims a window it did not read. `null` means
18374
+ * the operator keeps the outbox forever AND the read reached its end, so absent
18375
+ * means "never on record". A UI derives its "not in the last N days" from this
18376
+ * value, never from a constant — and only when the call ANSWERED (D315).
18377
+ */
18378
+ var NcRuleLastRunsSchema = object({
18379
+ runs: array(object({
18380
+ ruleId: string(),
18381
+ /** Fire time of the newest row (`createdAt`, epoch ms). */
18382
+ lastAt: number(),
18383
+ status: NcHistoryStatusSchema,
18384
+ /** The camera/device of that row (a digest row files under its first camera). */
18385
+ deviceId: number()
18386
+ })),
18387
+ horizonMs: number().nonnegative().nullable()
18388
+ });
18389
+ /**
18314
18390
  * What a snooze covers. Broader scopes win when several overlap, so one window
18315
18391
  * leaves ONE digest rather than a rule snooze and a whole-feed snooze both
18316
18392
  * summarising the same silence.
@@ -18491,6 +18567,14 @@ var NcAlarmModeCoverageSchema = object({
18491
18567
  /** Ids named by the covering rules. A SUBSET when `allDevices` is true. */
18492
18568
  deviceIds: array(number().int()),
18493
18569
  /**
18570
+ * D641: the ids NOT covered although `allDevices` is true — every unscoped
18571
+ * covering rule EXCLUDES them (`conditions.devicesExclude`) and no named rule
18572
+ * covers them. Always `[]` when `allDevices` is false. Excluded by the rules,
18573
+ * which is not the same as skipped by a switch: never in `skippedDevices`.
18574
+ * Defaulted so an answer computed before this field parses as "none".
18575
+ */
18576
+ allDevicesExcept: array(number().int()).default([]),
18577
+ /**
18494
18578
  * Devices this mode NAMES but cannot actually arm, each with the switch that
18495
18579
  * excludes it.
18496
18580
  *
@@ -18626,7 +18710,7 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
18626
18710
  })), method(object({}), object({ vars: array(NcTemplateVarDescriptorSchema) })), method(NcTemplatePreviewInputSchema, NcTemplatePreviewSchema, {
18627
18711
  kind: "mutation",
18628
18712
  access: "view"
18629
- }), method(object({ filter: NcHistoryFilterSchema.default({ limit: 100 }) }), object({ entries: array(NcHistoryEntrySchema) }), { auth: "admin" }), method(object({ artifactId: string().min(1) }), object({ url: string().nullable() }), { auth: "admin" }), method(object({}), object({ snoozes: array(NcSnoozeSchema) }), { caller: "required" }), method(object({ snooze: NcSnoozeInputSchema }), object({ snooze: NcSnoozeSchema }), {
18713
+ }), method(object({ filter: NcHistoryFilterSchema.default({ limit: 100 }) }), object({ entries: array(NcHistoryEntrySchema) }), { auth: "admin" }), method(object({}), NcRuleLastRunsSchema, { auth: "admin" }), method(object({ artifactId: string().min(1) }), object({ url: string().nullable() }), { auth: "admin" }), method(object({}), object({ snoozes: array(NcSnoozeSchema) }), { caller: "required" }), method(object({ snooze: NcSnoozeInputSchema }), object({ snooze: NcSnoozeSchema }), {
18630
18714
  kind: "mutation",
18631
18715
  caller: "required"
18632
18716
  }), method(object({ snoozeId: string() }), object({ success: literal(true) }), {
@@ -23072,7 +23156,11 @@ function buildDescriptor(capName, kind) {
23072
23156
  icon: legacyIcon(t.iconId)
23073
23157
  };
23074
23158
  }
23075
- Object.freeze(Object.fromEntries(Object.entries(CAP_TO_KIND).map(([capName, kind]) => [capName, buildDescriptor(capName, kind)])));
23159
+ /**
23160
+ * Sensor / control cap name → static event-kind descriptor. A linked device
23161
+ * contributes one entry per bound cap present in this map.
23162
+ */
23163
+ var EVENT_KIND_BY_CAP = Object.freeze(Object.fromEntries(Object.entries(CAP_TO_KIND).map(([capName, kind]) => [capName, buildDescriptor(capName, kind)])));
23076
23164
  /**
23077
23165
  * server-management — per-NODE singleton capability for a node's ROOT
23078
23166
  * package lifecycle (runtime-updatable node packages).
@@ -33632,6 +33720,42 @@ DeviceType.Camera, method(object({
33632
33720
  package: array(ZoneRuleSchema).readonly()
33633
33721
  });
33634
33722
  /**
33723
+ * LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
33724
+ * valutatore puro del suo FRONTE.
33725
+ *
33726
+ * Viveva dentro il builtin virtual-doorbell
33727
+ * (`@camstack/system` — `builtins/doorbell/trigger-engine.ts`) e i suoi
33728
+ * predicati erano privati al modulo. Il recorder ne ha bisogno per il trigger
33729
+ * `RecordingTriggers.sensorDeviceIds`: copiarla avrebbe creato la SECONDA
33730
+ * tabella, che diverge alla prima cap aggiunta e il cui sintomo — "il sensore
33731
+ * fa suonare il campanello ma non registra" — è esattamente D62. Quindi si
33732
+ * SPOSTA qui e il doorbell la ri-esporta.
33733
+ *
33734
+ * ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
33735
+ * due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
33736
+ * regola" (e include `presence`, `cover`, `alarm-panel`), questa a "qual è il
33737
+ * booleano il cui FRONTE conta". Vocabolari deliberatamente diversi.
33738
+ */
33739
+ /**
33740
+ * Known binary / switch source caps → the boolean slice field whose
33741
+ * false→true rise counts as ACTIVE. Every entry is "fire on active".
33742
+ * Sensors whose "active" reading is not a plain boolean (presence's string
33743
+ * state, connectivity's connected flag) are deliberately excluded — a
33744
+ * reconnect is not a doorbell press, and it is not a recording either.
33745
+ */
33746
+ var SOURCE_CAP_ACTIVE_FIELD = {
33747
+ contact: "entryOpen",
33748
+ binary: "on",
33749
+ switch: "on",
33750
+ motion: "detected",
33751
+ flood: "flooded",
33752
+ gas: "detected",
33753
+ smoke: "detected",
33754
+ "carbon-monoxide": "detected",
33755
+ vibration: "detected",
33756
+ tamper: "tampered"
33757
+ };
33758
+ /**
33635
33759
  * Accessory device helpers — shared across drivers.
33636
33760
  *
33637
33761
  * Many vendor-specific drivers register accessory child devices on
@@ -38537,6 +38661,12 @@ Object.freeze({
38537
38661
  addonId: null,
38538
38662
  access: "view"
38539
38663
  },
38664
+ "notificationRules.getRuleLastRuns": {
38665
+ capName: "notification-rules",
38666
+ capScope: "system",
38667
+ addonId: null,
38668
+ access: "view"
38669
+ },
38540
38670
  "notificationRules.getTemplateCatalog": {
38541
38671
  capName: "notification-rules",
38542
38672
  capScope: "system",
@@ -44133,12 +44263,55 @@ var NC_AUDIO_DEFAULTS = {
44133
44263
  samplingSeconds: 10
44134
44264
  };
44135
44265
  new Set(["devices", "classes"]);
44136
- /** Every filter, for the callers that must cover all four (guards, tests). */
44266
+ /**
44267
+ * WHICH narrowing filter speaks about WHICH system-event kind — one predicate,
44268
+ * consumed by the rule ENGINE and by every rule EDITOR.
44269
+ *
44270
+ * ── The failure this file exists for ───────────────────────────────────────
44271
+ * `NcSystemEventConditionSchema` carries four optional narrowing lists
44272
+ * (`deviceIds`, `deviceTypes`, `nodeIds`, `packageNames`) beside a required
44273
+ * `kinds` gate. They are not four filters over one vocabulary: each belongs to
44274
+ * a FAMILY of kinds and is meaningless outside it. A node going away has no
44275
+ * device type; a completed export has no package; `stream-offline` deliberately
44276
+ * carries no device type at all (a stream belongs to a camera by construction).
44277
+ *
44278
+ * The engine applied all four to every kind, so a filter from one family failed
44279
+ * a kind from another family CLOSED. The operator's live rule "Eventi di
44280
+ * sistema" selected eleven kinds and set `deviceTypes: ['camera']` — the only
44281
+ * way to say "only my cameras" about the two liveness kinds — and NINE of the
44282
+ * eleven silently stopped being deliverable. Four days of history contained
44283
+ * `device-online` and `device-offline` and nothing else, across a window in
44284
+ * which agents were restarted and addons were updated.
44285
+ *
44286
+ * Both editors already computed this scoping, to decide which filter boxes to
44287
+ * render; the cap's own docblock already promised it ("Narrow a `device-*` kind
44288
+ * to these device TYPES"). Only the engine disagreed, and it disagreed in the
44289
+ * destructive direction. So the rule is stated ONCE, here, and the engine and
44290
+ * the editors are readers of it rather than three independent authors.
44291
+ *
44292
+ * ── The direction ─────────────────────────────────────────────────────────
44293
+ * Out of family ⇒ the filter is IGNORED, never fail-closed. An editor that
44294
+ * hides a box has already told the operator this filter does not speak about
44295
+ * these kinds, so honouring it as an exclusion contradicts the only
44296
+ * explanation the operator was ever given. Inside its family the filter still
44297
+ * narrows, and still fails CLOSED on a subject that cannot produce the identity
44298
+ * it tests (a device the mirror cannot name is not evidence of a camera).
44299
+ */
44300
+ /**
44301
+ * Every filter, for the callers that must cover all of them (guards, tests).
44302
+ *
44303
+ * `consumableLowPercent` (D642) is not a list but it is a filter in exactly
44304
+ * this sense: it belongs to a family of kinds (the consumable pair) and the
44305
+ * engine consults it only there. It differs in one way the readers must know —
44306
+ * its ABSENCE is not "no narrowing" but the default threshold, because a
44307
+ * consumable episode is always judged at SOME threshold.
44308
+ */
44137
44309
  var NC_SYSTEM_EVENT_FILTER_KEYS = [
44138
44310
  "deviceIds",
44139
44311
  "deviceTypes",
44140
44312
  "nodeIds",
44141
- "packageNames"
44313
+ "packageNames",
44314
+ "consumableLowPercent"
44142
44315
  ];
44143
44316
  new Map(Object.entries({
44144
44317
  "device-online": "device-events",
@@ -44149,6 +44322,9 @@ new Map(Object.entries({
44149
44322
  "device-battery-normal": "device-events",
44150
44323
  "device-consumable-low": "device-events",
44151
44324
  "device-consumable-normal": "device-events",
44325
+ "device-tank-low": "device-events",
44326
+ "device-tank-full": "device-events",
44327
+ "device-tank-normal": "device-events",
44152
44328
  "stream-online": "device-events",
44153
44329
  "stream-offline": "device-events",
44154
44330
  "detection-blind": "device-events",
@@ -44179,10 +44355,48 @@ new Map(Object.entries({
44179
44355
  }));
44180
44356
  [...NC_SYSTEM_EVENT_FILTER_KEYS];
44181
44357
  NC_AUDIO_DEFAULTS.hitPercent, NC_AUDIO_DEFAULTS.samplingSeconds;
44358
+ /**
44359
+ * WHICH WAY A BOOLEAN SENSOR MOVED — read off the one slice a sensor event
44360
+ * persists (D640 "a sensor rule fires on the raise, the clear, or both").
44361
+ *
44362
+ * A device-event rule over a flood sensor notified on BOTH edges: water
44363
+ * detected, and back to dry. `NcConditions.sensorTransition` lets the rule
44364
+ * name one edge; this file answers, for one `SensorEvent`, which edge it is.
44365
+ *
44366
+ * NOT A SECOND TABLE. The "which boolean of this cap counts as HIGH" question
44367
+ * already has one answer, `SOURCE_CAP_ACTIVE_FIELD`
44368
+ * (`catalogs/sensor-active-state.ts`, the doorbell's and the recorder's edge
44369
+ * table), and a sensor event names its kind, not its cap. So the table here is
44370
+ * DERIVED: event kind → cap (`EVENT_KIND_BY_CAP`) → that cap's active field.
44371
+ * Only kinds whose taxonomy category is `sensor` take part — a switch has an
44372
+ * `on` boolean too, but "it triggers / it clears" is not a sentence about a
44373
+ * light, and offering it there would be a knob with a misleading label.
44374
+ * `presence` is a WORD (`home` / `not_home` / a zone), not a boolean, and is
44375
+ * absent from the source table, so it is absent here.
44376
+ *
44377
+ * `undefined` = never guessed: a kind with no raise (a doorbell press, a
44378
+ * button, a cover), or a slice whose field is missing or not a boolean. The
44379
+ * engine then does NOT filter — a flood alert must not go silent because one
44380
+ * read came back unreadable (the same stance as the alarm's `sensorEdgeOf`).
44381
+ *
44382
+ * Pure, RN-safe: the viewer imports the support rule from here.
44383
+ */
44384
+ /** Event kind → the boolean field of its cap slice that means "raised". */
44385
+ var NC_SENSOR_RAISED_FIELD_BY_KIND = Object.freeze(Object.fromEntries(Object.entries(EVENT_KIND_BY_CAP).flatMap(([capName, descriptor]) => {
44386
+ const field = SOURCE_CAP_ACTIVE_FIELD[capName];
44387
+ if (field === void 0 || descriptor.category !== "sensor") return [];
44388
+ return [[descriptor.kind, field]];
44389
+ })));
44390
+ Object.freeze(Object.keys(NC_SENSOR_RAISED_FIELD_BY_KIND));
44182
44391
  var RULE_BODY_ONLY = ["body"];
44183
44392
  var RULE_TEXT = ["title", "body"];
44184
44393
  var BATTERY = ["device-battery-low", "device-battery-normal"];
44185
44394
  var CONSUMABLE = ["device-consumable-low", "device-consumable-normal"];
44395
+ var TANK = [
44396
+ "device-tank-low",
44397
+ "device-tank-full",
44398
+ "device-tank-normal"
44399
+ ];
44186
44400
  var UPDATES = [
44187
44401
  "addon-update-available",
44188
44402
  "server-update-available",
@@ -44208,12 +44422,13 @@ var DEVICE_EVENTS = [
44208
44422
  "device-enabled",
44209
44423
  ...BATTERY,
44210
44424
  ...CONSUMABLE,
44425
+ ...TANK,
44211
44426
  "stream-online",
44212
44427
  "stream-offline",
44213
44428
  "detection-blind",
44214
44429
  ...ALARM
44215
44430
  ];
44216
- [...DEVICE_EVENTS], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...PACKAGE_UPDATES], [...RULE_TEXT], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_BODY_ONLY], [...RULE_TEXT], [...RULE_TEXT], [...DEVICE_EVENTS], [...RULE_TEXT], [...DEVICE_EVENTS], [...RULE_TEXT], [...BATTERY, ...CONSUMABLE], [...RULE_TEXT], [...CONSUMABLE], [...RULE_TEXT], [...RULE_TEXT], [...UPDATES], [...RULE_TEXT], [...UPDATES], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...UPDATES], [...RULE_TEXT], [...PACKAGE_UPDATES], [...RULE_TEXT], [...PACKAGE_UPDATES], [...RULE_TEXT], [...UPDATES], [...RULE_TEXT], [...UPDATES], [...RULE_TEXT], [...PACKAGE_UPDATES], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT];
44431
+ [...DEVICE_EVENTS], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...PACKAGE_UPDATES], [...RULE_TEXT], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...COMBINED_ALARM], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_BODY_ONLY], [...RULE_TEXT], [...RULE_TEXT], [...DEVICE_EVENTS], [...RULE_TEXT], [...DEVICE_EVENTS], [...RULE_TEXT], [...BATTERY, ...CONSUMABLE], [...RULE_TEXT], [...CONSUMABLE], [...RULE_TEXT], [...TANK], [...RULE_TEXT], [...RULE_TEXT], [...UPDATES], [...RULE_TEXT], [...UPDATES], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...UPDATES], [...RULE_TEXT], [...PACKAGE_UPDATES], [...RULE_TEXT], [...PACKAGE_UPDATES], [...RULE_TEXT], [...UPDATES], [...RULE_TEXT], [...UPDATES], [...RULE_TEXT], [...PACKAGE_UPDATES], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT], [...RULE_TEXT];
44217
44432
  /**
44218
44433
  * TimelapseRule — the STANDALONE scheduled timelapse producer's rule model.
44219
44434
  *
@@ -44708,7 +44923,7 @@ var AdminUIAddon = class extends BaseAddon {
44708
44923
  capability: adminUiCapability,
44709
44924
  provider: {
44710
44925
  getStaticDir: async () => ({ staticDir: resolveAdminUiDistDir() }),
44711
- getVersion: async () => ({ version: "1.2.267" })
44926
+ getVersion: async () => ({ version: "1.2.269" })
44712
44927
  }
44713
44928
  }];
44714
44929
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-admin-ui",
3
- "version": "1.2.267",
3
+ "version": "1.2.269",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Admin UI — Vite frontend build and server-side addon",
@@ -1 +0,0 @@
1
- import{S as e,x as t}from"./_virtual_mf___mfe_internal__admin_ui_host__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-DhP-Lgiq.js";import{s as n}from"./index-DZmZt8Pw.js";import{t as r}from"./StableTabPanel-Dc954AQl.js";function i({tabs:i,defaultTab:a}){let[o,s]=n(),c=o.get(`tab`),l=a??i[0]?.id??``,u=i.some(e=>e.id===c)?c:l,d=i.find(e=>e.id===u)??i[0],f=e=>{let t=new URLSearchParams(o);t.set(`tab`,e),s(t,{replace:!0})};return e(`div`,{className:`space-y-3`,children:[t(`div`,{className:`flex border-b border-border overflow-x-auto`,children:i.map(n=>{let r=n.icon;return e(`button`,{onClick:()=>f(n.id),className:`flex shrink-0 items-center gap-1.5 whitespace-nowrap px-3 py-2 text-xs font-medium border-b-2 transition-colors ${n.id===u?`border-primary text-primary`:`border-transparent text-foreground-subtle hover:text-foreground`}`,children:[r&&t(r,{className:`h-3.5 w-3.5`}),n.label]},n.id)})}),t(r,{tabKey:u,children:d?.content})]})}export{i as t};