@camstack/addon-waste-collections 0.1.27 → 0.1.28

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.
@@ -2,7 +2,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { dirname, join } from "node:path";
3
3
  import { spawn } from "node:child_process";
4
4
  import { fileURLToPath } from "node:url";
5
- //#region ../types/dist/event-category-fDPduoeC.mjs
5
+ //#region ../types/dist/event-category-DHXxB8t9.mjs
6
6
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
7
7
  EventCategory["SystemBoot"] = "system.boot";
8
8
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -298,7 +298,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
298
298
  * TRANSITION into that state (never per dispatch), and the node is dropped
299
299
  * from the placement candidate set for as long as it holds.
300
300
  *
301
- * This exists because the state was previously invisible: little-unraid
301
+ * This exists because the state was previously invisible: agent-a
302
302
  * absorbed 283k inference errors in a day while still being handed cameras,
303
303
  * and nothing in the system said so.
304
304
  *
@@ -474,6 +474,10 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
474
474
  * on the device detail page.
475
475
  */
476
476
  EventCategory["DoorbellOnPressed"] = "doorbell.onPressed";
477
+ /** Mirrors `runningStateCapability.events.onStarted`. */
478
+ EventCategory["RunningStarted"] = "running.started";
479
+ /** Mirrors `runningStateCapability.events.onFinished`. */
480
+ EventCategory["RunningFinished"] = "running.finished";
477
481
  /**
478
482
  * Cap event fired by every device that registers the `event-emitter`
479
483
  * capability. Mirrors `eventEmitterCapability.events.onEvent`. Carries
@@ -5566,7 +5570,7 @@ var ZodIssueCode = {
5566
5570
  var ZodFirstPartyTypeKind;
5567
5571
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5568
5572
  //#endregion
5569
- //#region ../types/dist/sleep-CHIEEJkY.mjs
5573
+ //#region ../types/dist/sleep-BErAxhul.mjs
5570
5574
  /**
5571
5575
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5572
5576
  * window to float samples (D455).
@@ -5915,7 +5919,7 @@ Object.fromEntries([
5915
5919
  * `hydrateSchema` to skip the `value` injection for structural-only fields.
5916
5920
  */
5917
5921
  function isValuelessField(field) {
5918
- return field.type === "separator" || field.type === "info" || field.type === "qr-code" || field.type === "button" || field.type === "object-array" || field.type === "widget" || field.type === "addon-action-button" || field.type === "device-action-button";
5922
+ return field.type === "separator" || field.type === "info" || field.type === "qr-code" || field.type === "button" || field.type === "object-array" || field.type === "widget" || field.type === "addon-action-button" || field.type === "device-action-button" || field.type === "account-sign-in" || field.type === "secret-presence";
5919
5923
  }
5920
5924
  function hydrateSchema(schema, values, options = {}) {
5921
5925
  return {
@@ -8805,6 +8809,1980 @@ method(object({ deviceId: number() }), array(StreamSourceEntrySchema)), method(o
8805
8809
  kind: "mutation",
8806
8810
  auth: "admin"
8807
8811
  }), method(object({ deviceId: number() }), unknown().nullable()), method(object({ deviceId: number() }), RawStateResultSchema.nullable(), { auth: "protected" });
8812
+ Object.freeze({ "doorbell": "lastPressedAt" });
8813
+ /** Every capability name, so addon code can check a name without the schema graph. */
8814
+ var CAP_NAMES = Object.freeze([
8815
+ "accessories",
8816
+ "addon-pages",
8817
+ "addon-pages-source",
8818
+ "addon-routes",
8819
+ "addon-settings",
8820
+ "addon-widgets",
8821
+ "addon-widgets-source",
8822
+ "addons",
8823
+ "admin-ui",
8824
+ "air-quality-sensor",
8825
+ "alarm-panel",
8826
+ "alerts",
8827
+ "ambient-light-sensor",
8828
+ "audio-analysis",
8829
+ "audio-analyzer",
8830
+ "audio-codec",
8831
+ "audio-metrics",
8832
+ "auth-provider",
8833
+ "automation-control",
8834
+ "backup",
8835
+ "battery",
8836
+ "binary",
8837
+ "brightness",
8838
+ "broker",
8839
+ "button",
8840
+ "calendar-source",
8841
+ "calendars",
8842
+ "camera-credentials",
8843
+ "camera-grid-layout",
8844
+ "camera-pipeline-config",
8845
+ "camera-streams",
8846
+ "carbon-monoxide",
8847
+ "climate-control",
8848
+ "color",
8849
+ "composer",
8850
+ "connection-test",
8851
+ "connectivity",
8852
+ "consumables",
8853
+ "contact",
8854
+ "control",
8855
+ "core-blocks",
8856
+ "cover",
8857
+ "custom-model-registry",
8858
+ "data-store-provider",
8859
+ "database-snapshot",
8860
+ "day-night",
8861
+ "decoder",
8862
+ "detection-pipeline",
8863
+ "device-admin-link",
8864
+ "device-adoption",
8865
+ "device-credentials",
8866
+ "device-discovery",
8867
+ "device-export",
8868
+ "device-extension",
8869
+ "device-history",
8870
+ "device-manager",
8871
+ "device-ops",
8872
+ "device-provider",
8873
+ "device-removal-hook",
8874
+ "device-state",
8875
+ "device-status",
8876
+ "dishwasher",
8877
+ "display-palette",
8878
+ "doorbell",
8879
+ "embedding-encoder",
8880
+ "enum-sensor",
8881
+ "event-emitter",
8882
+ "face-gallery",
8883
+ "failure-contribution",
8884
+ "fan-control",
8885
+ "feature-probe",
8886
+ "filesystem-browse",
8887
+ "flood",
8888
+ "gas",
8889
+ "heating-valve",
8890
+ "humidifier",
8891
+ "humidity-sensor",
8892
+ "image",
8893
+ "image-settings",
8894
+ "integrations",
8895
+ "intercom",
8896
+ "keychain",
8897
+ "keychain-admin",
8898
+ "lawn-mower-control",
8899
+ "llm",
8900
+ "llm-runtime",
8901
+ "load-contribution",
8902
+ "local-network",
8903
+ "lock-control",
8904
+ "log-channels",
8905
+ "log-destination",
8906
+ "login-method",
8907
+ "media-player",
8908
+ "mesh-network",
8909
+ "metrics-provider",
8910
+ "model-convert",
8911
+ "model-distributor",
8912
+ "motion",
8913
+ "motion-detection",
8914
+ "motion-trigger",
8915
+ "motion-zones",
8916
+ "mqtt-broker",
8917
+ "native-object-detection",
8918
+ "navigation",
8919
+ "network-access",
8920
+ "network-link",
8921
+ "network-quality",
8922
+ "node-certificates",
8923
+ "nodes",
8924
+ "notification-output",
8925
+ "notification-rules",
8926
+ "notifier",
8927
+ "numeric-sensor",
8928
+ "oauth-integration",
8929
+ "oidc-connections",
8930
+ "osd",
8931
+ "osd-manager",
8932
+ "pet-feeder",
8933
+ "pipeline-analytics",
8934
+ "pipeline-executor",
8935
+ "pipeline-orchestrator",
8936
+ "pipeline-runner",
8937
+ "plate-gallery",
8938
+ "platform-probe",
8939
+ "power-meter",
8940
+ "presence",
8941
+ "pressure-sensor",
8942
+ "privacy-mask",
8943
+ "ptz",
8944
+ "ptz-autotrack",
8945
+ "reboot",
8946
+ "record-entries",
8947
+ "recording",
8948
+ "recording-archive",
8949
+ "recording-export",
8950
+ "recording-onboard",
8951
+ "recording-signal",
8952
+ "records",
8953
+ "running-state",
8954
+ "scene-monitor",
8955
+ "script-runner",
8956
+ "server-management",
8957
+ "settings-store",
8958
+ "smoke",
8959
+ "smtp-provider",
8960
+ "snapshot",
8961
+ "sso-bridge",
8962
+ "storage",
8963
+ "storage-admin",
8964
+ "storage-evictable",
8965
+ "storage-migration",
8966
+ "storage-occupancy",
8967
+ "storage-provider",
8968
+ "stream-broker",
8969
+ "stream-catalog",
8970
+ "stream-params",
8971
+ "stream-signals",
8972
+ "switch",
8973
+ "system",
8974
+ "tamper",
8975
+ "temperature-sensor",
8976
+ "terminal-session",
8977
+ "toast",
8978
+ "training",
8979
+ "training-provider",
8980
+ "turn-provider",
8981
+ "update",
8982
+ "user-management",
8983
+ "user-passkeys",
8984
+ "vacuum-control",
8985
+ "valve",
8986
+ "vector-store",
8987
+ "vibration",
8988
+ "videoclips",
8989
+ "viewer-ui",
8990
+ "water-heater",
8991
+ "weather",
8992
+ "webrtc-session",
8993
+ "zone-analytics",
8994
+ "zone-rules",
8995
+ "zones"
8996
+ ]);
8997
+ Object.freeze({
8998
+ "air-quality-sensor": [
8999
+ {
9000
+ "path": "co2Ppm",
9001
+ "valueType": "number"
9002
+ },
9003
+ {
9004
+ "path": "vocPpb",
9005
+ "valueType": "number"
9006
+ },
9007
+ {
9008
+ "path": "pm25",
9009
+ "valueType": "number"
9010
+ },
9011
+ {
9012
+ "path": "pm10",
9013
+ "valueType": "number"
9014
+ },
9015
+ {
9016
+ "path": "aqi",
9017
+ "valueType": "number"
9018
+ },
9019
+ {
9020
+ "path": "unit",
9021
+ "valueType": "string"
9022
+ },
9023
+ {
9024
+ "path": "precision",
9025
+ "valueType": "number"
9026
+ }
9027
+ ],
9028
+ "alarm-panel": [
9029
+ {
9030
+ "path": "state",
9031
+ "valueType": "enum",
9032
+ "enumValues": [
9033
+ "disarmed",
9034
+ "armed_home",
9035
+ "armed_away",
9036
+ "armed_night",
9037
+ "armed_vacation",
9038
+ "armed_custom_bypass",
9039
+ "arming",
9040
+ "disarming",
9041
+ "pending",
9042
+ "triggered"
9043
+ ]
9044
+ },
9045
+ {
9046
+ "path": "targetMode",
9047
+ "valueType": "enum",
9048
+ "enumValues": [
9049
+ "home",
9050
+ "away",
9051
+ "night",
9052
+ "vacation",
9053
+ "custom_bypass"
9054
+ ]
9055
+ },
9056
+ {
9057
+ "path": "requiresCode",
9058
+ "valueType": "boolean"
9059
+ }
9060
+ ],
9061
+ "ambient-light-sensor": [
9062
+ {
9063
+ "path": "lux",
9064
+ "valueType": "number"
9065
+ },
9066
+ {
9067
+ "path": "unit",
9068
+ "valueType": "string"
9069
+ },
9070
+ {
9071
+ "path": "precision",
9072
+ "valueType": "number"
9073
+ }
9074
+ ],
9075
+ "audio-metrics": [
9076
+ {
9077
+ "path": "ts",
9078
+ "valueType": "number"
9079
+ },
9080
+ {
9081
+ "path": "windowSec",
9082
+ "valueType": "number"
9083
+ },
9084
+ {
9085
+ "path": "level.rms",
9086
+ "valueType": "number"
9087
+ },
9088
+ {
9089
+ "path": "level.dbfs",
9090
+ "valueType": "number"
9091
+ },
9092
+ {
9093
+ "path": "peakDbfs",
9094
+ "valueType": "number"
9095
+ },
9096
+ {
9097
+ "path": "avgDbfs",
9098
+ "valueType": "number"
9099
+ },
9100
+ {
9101
+ "path": "current.className",
9102
+ "valueType": "string"
9103
+ },
9104
+ {
9105
+ "path": "current.score",
9106
+ "valueType": "number"
9107
+ },
9108
+ {
9109
+ "path": "current.timestamp",
9110
+ "valueType": "number"
9111
+ }
9112
+ ],
9113
+ "automation-control": [
9114
+ {
9115
+ "path": "enabled",
9116
+ "valueType": "boolean"
9117
+ },
9118
+ {
9119
+ "path": "isRunning",
9120
+ "valueType": "boolean"
9121
+ },
9122
+ {
9123
+ "path": "lastTriggeredAt",
9124
+ "valueType": "number"
9125
+ },
9126
+ {
9127
+ "path": "lastError",
9128
+ "valueType": "string"
9129
+ }
9130
+ ],
9131
+ "battery": [
9132
+ {
9133
+ "path": "percentage",
9134
+ "valueType": "number"
9135
+ },
9136
+ {
9137
+ "path": "charging",
9138
+ "valueType": "enum",
9139
+ "enumValues": [
9140
+ "dc",
9141
+ "solar",
9142
+ "none",
9143
+ "unknown"
9144
+ ]
9145
+ },
9146
+ {
9147
+ "path": "sleeping",
9148
+ "valueType": "boolean"
9149
+ },
9150
+ {
9151
+ "path": "lastUpdated",
9152
+ "valueType": "number"
9153
+ },
9154
+ {
9155
+ "path": "lastContactAt",
9156
+ "valueType": "number"
9157
+ },
9158
+ {
9159
+ "path": "lastFullRefreshAt",
9160
+ "valueType": "number"
9161
+ },
9162
+ {
9163
+ "path": "binary",
9164
+ "valueType": "boolean"
9165
+ }
9166
+ ],
9167
+ "binary": [{
9168
+ "path": "on",
9169
+ "valueType": "boolean"
9170
+ }],
9171
+ "brightness": [{
9172
+ "path": "percentage",
9173
+ "valueType": "number"
9174
+ }],
9175
+ "broker": [{
9176
+ "path": "brokerCount",
9177
+ "valueType": "number"
9178
+ }, {
9179
+ "path": "connectedCount",
9180
+ "valueType": "number"
9181
+ }],
9182
+ "camera-credentials": [
9183
+ {
9184
+ "path": "host",
9185
+ "valueType": "string"
9186
+ },
9187
+ {
9188
+ "path": "port",
9189
+ "valueType": "number"
9190
+ },
9191
+ {
9192
+ "path": "onvifPort",
9193
+ "valueType": "number"
9194
+ },
9195
+ {
9196
+ "path": "rtspPort",
9197
+ "valueType": "number"
9198
+ },
9199
+ {
9200
+ "path": "https",
9201
+ "valueType": "boolean"
9202
+ },
9203
+ {
9204
+ "path": "hasUsername",
9205
+ "valueType": "boolean"
9206
+ },
9207
+ {
9208
+ "path": "hasPassword",
9209
+ "valueType": "boolean"
9210
+ },
9211
+ {
9212
+ "path": "onvifProfile",
9213
+ "valueType": "string"
9214
+ }
9215
+ ],
9216
+ "camera-streams": [
9217
+ {
9218
+ "path": "online",
9219
+ "valueType": "boolean"
9220
+ },
9221
+ {
9222
+ "path": "slotStatuses.high",
9223
+ "valueType": "enum",
9224
+ "enumValues": [
9225
+ "unassigned",
9226
+ "idle",
9227
+ "connecting",
9228
+ "streaming",
9229
+ "error"
9230
+ ]
9231
+ },
9232
+ {
9233
+ "path": "slotStatuses.mid",
9234
+ "valueType": "enum",
9235
+ "enumValues": [
9236
+ "unassigned",
9237
+ "idle",
9238
+ "connecting",
9239
+ "streaming",
9240
+ "error"
9241
+ ]
9242
+ },
9243
+ {
9244
+ "path": "slotStatuses.low",
9245
+ "valueType": "enum",
9246
+ "enumValues": [
9247
+ "unassigned",
9248
+ "idle",
9249
+ "connecting",
9250
+ "streaming",
9251
+ "error"
9252
+ ]
9253
+ },
9254
+ {
9255
+ "path": "slotErrors.high",
9256
+ "valueType": "string"
9257
+ },
9258
+ {
9259
+ "path": "slotErrors.mid",
9260
+ "valueType": "string"
9261
+ },
9262
+ {
9263
+ "path": "slotErrors.low",
9264
+ "valueType": "string"
9265
+ }
9266
+ ],
9267
+ "carbon-monoxide": [{
9268
+ "path": "detected",
9269
+ "valueType": "boolean"
9270
+ }],
9271
+ "climate-control": [
9272
+ {
9273
+ "path": "mode",
9274
+ "valueType": "enum",
9275
+ "enumValues": [
9276
+ "off",
9277
+ "heat",
9278
+ "cool",
9279
+ "auto",
9280
+ "heat_cool",
9281
+ "fan_only",
9282
+ "dry"
9283
+ ]
9284
+ },
9285
+ {
9286
+ "path": "fanMode",
9287
+ "valueType": "string"
9288
+ },
9289
+ {
9290
+ "path": "preset",
9291
+ "valueType": "string"
9292
+ },
9293
+ {
9294
+ "path": "target",
9295
+ "valueType": "number"
9296
+ },
9297
+ {
9298
+ "path": "targetHigh",
9299
+ "valueType": "number"
9300
+ },
9301
+ {
9302
+ "path": "targetLow",
9303
+ "valueType": "number"
9304
+ },
9305
+ {
9306
+ "path": "targetHumidity",
9307
+ "valueType": "number"
9308
+ },
9309
+ {
9310
+ "path": "currentTemp",
9311
+ "valueType": "number"
9312
+ },
9313
+ {
9314
+ "path": "currentHumidity",
9315
+ "valueType": "number"
9316
+ },
9317
+ {
9318
+ "path": "swingVertical",
9319
+ "valueType": "boolean"
9320
+ },
9321
+ {
9322
+ "path": "swingHorizontal",
9323
+ "valueType": "boolean"
9324
+ },
9325
+ {
9326
+ "path": "minTemp",
9327
+ "valueType": "number"
9328
+ },
9329
+ {
9330
+ "path": "maxTemp",
9331
+ "valueType": "number"
9332
+ },
9333
+ {
9334
+ "path": "tempStep",
9335
+ "valueType": "number"
9336
+ }
9337
+ ],
9338
+ "color": [
9339
+ {
9340
+ "path": "mode",
9341
+ "valueType": "enum",
9342
+ "enumValues": [
9343
+ "rgb",
9344
+ "hsv",
9345
+ "mired"
9346
+ ]
9347
+ },
9348
+ {
9349
+ "path": "rgb.r",
9350
+ "valueType": "number"
9351
+ },
9352
+ {
9353
+ "path": "rgb.g",
9354
+ "valueType": "number"
9355
+ },
9356
+ {
9357
+ "path": "rgb.b",
9358
+ "valueType": "number"
9359
+ },
9360
+ {
9361
+ "path": "hsv.h",
9362
+ "valueType": "number"
9363
+ },
9364
+ {
9365
+ "path": "hsv.s",
9366
+ "valueType": "number"
9367
+ },
9368
+ {
9369
+ "path": "hsv.v",
9370
+ "valueType": "number"
9371
+ },
9372
+ {
9373
+ "path": "mireds",
9374
+ "valueType": "number"
9375
+ }
9376
+ ],
9377
+ "connectivity": [{
9378
+ "path": "connected",
9379
+ "valueType": "boolean"
9380
+ }],
9381
+ "contact": [{
9382
+ "path": "entryOpen",
9383
+ "valueType": "boolean"
9384
+ }],
9385
+ "control": [
9386
+ {
9387
+ "path": "kind",
9388
+ "valueType": "enum",
9389
+ "enumValues": [
9390
+ "numeric",
9391
+ "select",
9392
+ "text",
9393
+ "datetime"
9394
+ ]
9395
+ },
9396
+ {
9397
+ "path": "unit",
9398
+ "valueType": "string"
9399
+ },
9400
+ {
9401
+ "path": "min",
9402
+ "valueType": "number"
9403
+ },
9404
+ {
9405
+ "path": "max",
9406
+ "valueType": "number"
9407
+ },
9408
+ {
9409
+ "path": "step",
9410
+ "valueType": "number"
9411
+ },
9412
+ {
9413
+ "path": "precision",
9414
+ "valueType": "number"
9415
+ },
9416
+ {
9417
+ "path": "format",
9418
+ "valueType": "enum",
9419
+ "enumValues": [
9420
+ "date",
9421
+ "time",
9422
+ "datetime"
9423
+ ]
9424
+ }
9425
+ ],
9426
+ "cover": [
9427
+ {
9428
+ "path": "state",
9429
+ "valueType": "enum",
9430
+ "enumValues": [
9431
+ "open",
9432
+ "opening",
9433
+ "closing",
9434
+ "closed",
9435
+ "stopped"
9436
+ ]
9437
+ },
9438
+ {
9439
+ "path": "position",
9440
+ "valueType": "number"
9441
+ },
9442
+ {
9443
+ "path": "tiltPosition",
9444
+ "valueType": "number"
9445
+ }
9446
+ ],
9447
+ "day-night": [
9448
+ {
9449
+ "path": "mode",
9450
+ "valueType": "enum",
9451
+ "enumValues": [
9452
+ "auto",
9453
+ "day",
9454
+ "night",
9455
+ "schedule"
9456
+ ]
9457
+ },
9458
+ {
9459
+ "path": "sensitivity",
9460
+ "valueType": "number"
9461
+ },
9462
+ {
9463
+ "path": "switchDelaySec",
9464
+ "valueType": "number"
9465
+ }
9466
+ ],
9467
+ "device-adoption": [
9468
+ {
9469
+ "path": "lastDiscoveryAt",
9470
+ "valueType": "number"
9471
+ },
9472
+ {
9473
+ "path": "candidateCount",
9474
+ "valueType": "number"
9475
+ },
9476
+ {
9477
+ "path": "adoptedCount",
9478
+ "valueType": "number"
9479
+ },
9480
+ {
9481
+ "path": "lastError",
9482
+ "valueType": "string"
9483
+ }
9484
+ ],
9485
+ "device-discovery": [{
9486
+ "path": "lastDiscoveryAt",
9487
+ "valueType": "number"
9488
+ }, {
9489
+ "path": "lastError",
9490
+ "valueType": "string"
9491
+ }],
9492
+ "device-export": [
9493
+ {
9494
+ "path": "linkState",
9495
+ "valueType": "enum",
9496
+ "enumValues": [
9497
+ "unlinked",
9498
+ "linked",
9499
+ "error"
9500
+ ]
9501
+ },
9502
+ {
9503
+ "path": "exposedDeviceCount",
9504
+ "valueType": "number"
9505
+ },
9506
+ {
9507
+ "path": "error",
9508
+ "valueType": "string"
9509
+ },
9510
+ {
9511
+ "path": "setup.qr",
9512
+ "valueType": "string"
9513
+ },
9514
+ {
9515
+ "path": "setup.note",
9516
+ "valueType": "string"
9517
+ }
9518
+ ],
9519
+ "device-status": [{
9520
+ "path": "online",
9521
+ "valueType": "boolean"
9522
+ }],
9523
+ "dishwasher": [
9524
+ {
9525
+ "path": "availability",
9526
+ "valueType": "enum",
9527
+ "enumValues": [
9528
+ "available",
9529
+ "offline",
9530
+ "description-missing"
9531
+ ]
9532
+ },
9533
+ {
9534
+ "path": "state",
9535
+ "valueType": "enum",
9536
+ "enumValues": [
9537
+ "idle",
9538
+ "running",
9539
+ "paused",
9540
+ "finished",
9541
+ "error",
9542
+ "unavailable"
9543
+ ]
9544
+ },
9545
+ {
9546
+ "path": "operationState",
9547
+ "valueType": "enum",
9548
+ "enumValues": [
9549
+ "Inactive",
9550
+ "Ready",
9551
+ "DelayedStart",
9552
+ "Run",
9553
+ "Pause",
9554
+ "ActionRequired",
9555
+ "Finished",
9556
+ "Error",
9557
+ "Aborting"
9558
+ ]
9559
+ },
9560
+ {
9561
+ "path": "program",
9562
+ "valueType": "string"
9563
+ },
9564
+ {
9565
+ "path": "selectedProgram",
9566
+ "valueType": "string"
9567
+ },
9568
+ {
9569
+ "path": "remainingSeconds",
9570
+ "valueType": "number"
9571
+ },
9572
+ {
9573
+ "path": "delayedStartSeconds",
9574
+ "valueType": "number"
9575
+ },
9576
+ {
9577
+ "path": "progressPercent",
9578
+ "valueType": "number"
9579
+ },
9580
+ {
9581
+ "path": "doorOpen",
9582
+ "valueType": "boolean"
9583
+ },
9584
+ {
9585
+ "path": "doorLocked",
9586
+ "valueType": "boolean"
9587
+ },
9588
+ {
9589
+ "path": "remoteStartAllowed",
9590
+ "valueType": "boolean"
9591
+ },
9592
+ {
9593
+ "path": "remoteControlActive",
9594
+ "valueType": "boolean"
9595
+ },
9596
+ {
9597
+ "path": "localControlActive",
9598
+ "valueType": "boolean"
9599
+ },
9600
+ {
9601
+ "path": "powerOn",
9602
+ "valueType": "boolean"
9603
+ },
9604
+ {
9605
+ "path": "powerState",
9606
+ "valueType": "string"
9607
+ },
9608
+ {
9609
+ "path": "filterCleaningDue",
9610
+ "valueType": "boolean"
9611
+ },
9612
+ {
9613
+ "path": "machineCareDue",
9614
+ "valueType": "boolean"
9615
+ },
9616
+ {
9617
+ "path": "machineCareRemainingRuns",
9618
+ "valueType": "number"
9619
+ },
9620
+ {
9621
+ "path": "halfLoad",
9622
+ "valueType": "boolean"
9623
+ },
9624
+ {
9625
+ "path": "hygienePlus",
9626
+ "valueType": "boolean"
9627
+ },
9628
+ {
9629
+ "path": "extraDry",
9630
+ "valueType": "boolean"
9631
+ },
9632
+ {
9633
+ "path": "intensiveZone",
9634
+ "valueType": "boolean"
9635
+ },
9636
+ {
9637
+ "path": "varioSpeedPlus",
9638
+ "valueType": "boolean"
9639
+ },
9640
+ {
9641
+ "path": "childLock",
9642
+ "valueType": "boolean"
9643
+ },
9644
+ {
9645
+ "path": "errorCode",
9646
+ "valueType": "number"
9647
+ },
9648
+ {
9649
+ "path": "errorLabel",
9650
+ "valueType": "string"
9651
+ }
9652
+ ],
9653
+ "doorbell": [{
9654
+ "path": "lastPressedAt",
9655
+ "valueType": "number"
9656
+ }, {
9657
+ "path": "pressCountSinceStart",
9658
+ "valueType": "number"
9659
+ }],
9660
+ "enum-sensor": [{
9661
+ "path": "value",
9662
+ "valueType": "string"
9663
+ }, {
9664
+ "path": "format",
9665
+ "valueType": "enum",
9666
+ "enumValues": [
9667
+ "date",
9668
+ "time",
9669
+ "datetime"
9670
+ ]
9671
+ }],
9672
+ "event-emitter": [
9673
+ {
9674
+ "path": "lastEvent.deviceId",
9675
+ "valueType": "number"
9676
+ },
9677
+ {
9678
+ "path": "lastEvent.eventType",
9679
+ "valueType": "string"
9680
+ },
9681
+ {
9682
+ "path": "lastEvent.timestamp",
9683
+ "valueType": "number"
9684
+ },
9685
+ {
9686
+ "path": "lastEvent.seq",
9687
+ "valueType": "number"
9688
+ },
9689
+ {
9690
+ "path": "eventCountSinceStart",
9691
+ "valueType": "number"
9692
+ }
9693
+ ],
9694
+ "fan-control": [
9695
+ {
9696
+ "path": "percentage",
9697
+ "valueType": "number"
9698
+ },
9699
+ {
9700
+ "path": "percentageStep",
9701
+ "valueType": "number"
9702
+ },
9703
+ {
9704
+ "path": "preset",
9705
+ "valueType": "string"
9706
+ },
9707
+ {
9708
+ "path": "direction",
9709
+ "valueType": "enum",
9710
+ "enumValues": ["forward", "reverse"]
9711
+ },
9712
+ {
9713
+ "path": "oscillating",
9714
+ "valueType": "boolean"
9715
+ }
9716
+ ],
9717
+ "feature-probe": [
9718
+ {
9719
+ "path": "deviceType",
9720
+ "valueType": "string"
9721
+ },
9722
+ {
9723
+ "path": "model",
9724
+ "valueType": "string"
9725
+ },
9726
+ {
9727
+ "path": "channelCount",
9728
+ "valueType": "number"
9729
+ },
9730
+ {
9731
+ "path": "lastProbedAt",
9732
+ "valueType": "number"
9733
+ }
9734
+ ],
9735
+ "flood": [{
9736
+ "path": "flooded",
9737
+ "valueType": "boolean"
9738
+ }],
9739
+ "gas": [{
9740
+ "path": "detected",
9741
+ "valueType": "boolean"
9742
+ }],
9743
+ "heating-valve": [{
9744
+ "path": "position",
9745
+ "valueType": "number"
9746
+ }],
9747
+ "humidifier": [
9748
+ {
9749
+ "path": "on",
9750
+ "valueType": "boolean"
9751
+ },
9752
+ {
9753
+ "path": "currentHumidity",
9754
+ "valueType": "number"
9755
+ },
9756
+ {
9757
+ "path": "targetHumidity",
9758
+ "valueType": "number"
9759
+ },
9760
+ {
9761
+ "path": "mode",
9762
+ "valueType": "string"
9763
+ },
9764
+ {
9765
+ "path": "action",
9766
+ "valueType": "string"
9767
+ },
9768
+ {
9769
+ "path": "minHumidity",
9770
+ "valueType": "number"
9771
+ },
9772
+ {
9773
+ "path": "maxHumidity",
9774
+ "valueType": "number"
9775
+ }
9776
+ ],
9777
+ "humidity-sensor": [
9778
+ {
9779
+ "path": "percent",
9780
+ "valueType": "number"
9781
+ },
9782
+ {
9783
+ "path": "unit",
9784
+ "valueType": "string"
9785
+ },
9786
+ {
9787
+ "path": "precision",
9788
+ "valueType": "number"
9789
+ }
9790
+ ],
9791
+ "image": [{
9792
+ "path": "url",
9793
+ "valueType": "string"
9794
+ }, {
9795
+ "path": "lastUpdated",
9796
+ "valueType": "number"
9797
+ }],
9798
+ "image-settings": [
9799
+ {
9800
+ "path": "brightness",
9801
+ "valueType": "number"
9802
+ },
9803
+ {
9804
+ "path": "contrast",
9805
+ "valueType": "number"
9806
+ },
9807
+ {
9808
+ "path": "saturation",
9809
+ "valueType": "number"
9810
+ },
9811
+ {
9812
+ "path": "sharpness",
9813
+ "valueType": "number"
9814
+ },
9815
+ {
9816
+ "path": "mirror",
9817
+ "valueType": "boolean"
9818
+ },
9819
+ {
9820
+ "path": "flip",
9821
+ "valueType": "boolean"
9822
+ },
9823
+ {
9824
+ "path": "rotate",
9825
+ "valueType": "enum",
9826
+ "enumValues": [
9827
+ "0",
9828
+ "90",
9829
+ "180",
9830
+ "270"
9831
+ ]
9832
+ },
9833
+ {
9834
+ "path": "whiteBalance",
9835
+ "valueType": "enum",
9836
+ "enumValues": ["auto", "manual"]
9837
+ },
9838
+ {
9839
+ "path": "warmth",
9840
+ "valueType": "number"
9841
+ },
9842
+ {
9843
+ "path": "exposureMode",
9844
+ "valueType": "enum",
9845
+ "enumValues": ["auto", "manual"]
9846
+ },
9847
+ {
9848
+ "path": "backlightMode",
9849
+ "valueType": "enum",
9850
+ "enumValues": [
9851
+ "off",
9852
+ "blc",
9853
+ "wdr",
9854
+ "hlc"
9855
+ ]
9856
+ }
9857
+ ],
9858
+ "intercom": [
9859
+ {
9860
+ "path": "talking",
9861
+ "valueType": "boolean"
9862
+ },
9863
+ {
9864
+ "path": "lastSessionAt",
9865
+ "valueType": "number"
9866
+ },
9867
+ {
9868
+ "path": "ability.sampleRate",
9869
+ "valueType": "number"
9870
+ },
9871
+ {
9872
+ "path": "ability.duplex",
9873
+ "valueType": "enum",
9874
+ "enumValues": ["half", "full"]
9875
+ },
9876
+ {
9877
+ "path": "ability.maxBacklogMs",
9878
+ "valueType": "number"
9879
+ }
9880
+ ],
9881
+ "lawn-mower-control": [
9882
+ {
9883
+ "path": "activity",
9884
+ "valueType": "enum",
9885
+ "enumValues": [
9886
+ "idle",
9887
+ "mowing",
9888
+ "paused",
9889
+ "docked",
9890
+ "error"
9891
+ ]
9892
+ },
9893
+ {
9894
+ "path": "batteryLevel",
9895
+ "valueType": "number"
9896
+ },
9897
+ {
9898
+ "path": "progressPercent",
9899
+ "valueType": "number"
9900
+ },
9901
+ {
9902
+ "path": "currentCode",
9903
+ "valueType": "number"
9904
+ },
9905
+ {
9906
+ "path": "currentCodeLabel",
9907
+ "valueType": "string"
9908
+ },
9909
+ {
9910
+ "path": "severity",
9911
+ "valueType": "enum",
9912
+ "enumValues": [
9913
+ "info",
9914
+ "warning",
9915
+ "error"
9916
+ ]
9917
+ }
9918
+ ],
9919
+ "lock-control": [{
9920
+ "path": "state",
9921
+ "valueType": "enum",
9922
+ "enumValues": [
9923
+ "locked",
9924
+ "unlocked",
9925
+ "locking",
9926
+ "unlocking",
9927
+ "jammed"
9928
+ ]
9929
+ }],
9930
+ "media-player": [
9931
+ {
9932
+ "path": "state",
9933
+ "valueType": "enum",
9934
+ "enumValues": [
9935
+ "off",
9936
+ "on",
9937
+ "idle",
9938
+ "playing",
9939
+ "paused",
9940
+ "buffering",
9941
+ "standby"
9942
+ ]
9943
+ },
9944
+ {
9945
+ "path": "volumeLevel",
9946
+ "valueType": "number"
9947
+ },
9948
+ {
9949
+ "path": "isMuted",
9950
+ "valueType": "boolean"
9951
+ },
9952
+ {
9953
+ "path": "source",
9954
+ "valueType": "string"
9955
+ },
9956
+ {
9957
+ "path": "currentMedia.type",
9958
+ "valueType": "string"
9959
+ },
9960
+ {
9961
+ "path": "currentMedia.title",
9962
+ "valueType": "string"
9963
+ },
9964
+ {
9965
+ "path": "currentMedia.artist",
9966
+ "valueType": "string"
9967
+ },
9968
+ {
9969
+ "path": "currentMedia.album",
9970
+ "valueType": "string"
9971
+ },
9972
+ {
9973
+ "path": "currentMedia.imageUrl",
9974
+ "valueType": "string"
9975
+ },
9976
+ {
9977
+ "path": "positionMs",
9978
+ "valueType": "number"
9979
+ },
9980
+ {
9981
+ "path": "durationMs",
9982
+ "valueType": "number"
9983
+ },
9984
+ {
9985
+ "path": "shuffle",
9986
+ "valueType": "boolean"
9987
+ },
9988
+ {
9989
+ "path": "repeat",
9990
+ "valueType": "enum",
9991
+ "enumValues": [
9992
+ "off",
9993
+ "all",
9994
+ "one"
9995
+ ]
9996
+ }
9997
+ ],
9998
+ "motion": [
9999
+ {
10000
+ "path": "detected",
10001
+ "valueType": "boolean"
10002
+ },
10003
+ {
10004
+ "path": "lastDetectedAt",
10005
+ "valueType": "number"
10006
+ },
10007
+ {
10008
+ "path": "autoClearAfterMs",
10009
+ "valueType": "number"
10010
+ }
10011
+ ],
10012
+ "motion-trigger": [{
10013
+ "path": "enabled",
10014
+ "valueType": "boolean"
10015
+ }],
10016
+ "motion-zones": [{
10017
+ "path": "enabled",
10018
+ "valueType": "boolean"
10019
+ }, {
10020
+ "path": "sensitivity",
10021
+ "valueType": "number"
10022
+ }],
10023
+ "mqtt-broker": [{
10024
+ "path": "brokerCount",
10025
+ "valueType": "number"
10026
+ }, {
10027
+ "path": "embeddedRunning",
10028
+ "valueType": "boolean"
10029
+ }],
10030
+ "native-object-detection": [{
10031
+ "path": "enabled",
10032
+ "valueType": "boolean"
10033
+ }],
10034
+ "navigation": [
10035
+ {
10036
+ "path": "mode",
10037
+ "valueType": "enum",
10038
+ "enumValues": [
10039
+ "idle",
10040
+ "cleaning",
10041
+ "spot",
10042
+ "following",
10043
+ "goto",
10044
+ "returning",
10045
+ "paused",
10046
+ "unknown"
10047
+ ]
10048
+ },
10049
+ {
10050
+ "path": "following",
10051
+ "valueType": "boolean"
10052
+ },
10053
+ {
10054
+ "path": "flash",
10055
+ "valueType": "boolean"
10056
+ },
10057
+ {
10058
+ "path": "lightMode",
10059
+ "valueType": "enum",
10060
+ "enumValues": ["auto", "manual"]
10061
+ },
10062
+ {
10063
+ "path": "lightLevel",
10064
+ "valueType": "number"
10065
+ }
10066
+ ],
10067
+ "network-link": [
10068
+ {
10069
+ "path": "type",
10070
+ "valueType": "enum",
10071
+ "enumValues": [
10072
+ "wifi",
10073
+ "ethernet",
10074
+ "cellular",
10075
+ "unknown"
10076
+ ]
10077
+ },
10078
+ {
10079
+ "path": "signalPercent",
10080
+ "valueType": "number"
10081
+ },
10082
+ {
10083
+ "path": "rssiDbm",
10084
+ "valueType": "number"
10085
+ },
10086
+ {
10087
+ "path": "ssid",
10088
+ "valueType": "string"
10089
+ },
10090
+ {
10091
+ "path": "lastUpdated",
10092
+ "valueType": "number"
10093
+ }
10094
+ ],
10095
+ "notifier": [
10096
+ {
10097
+ "path": "lastSentAt",
10098
+ "valueType": "number"
10099
+ },
10100
+ {
10101
+ "path": "lastError",
10102
+ "valueType": "string"
10103
+ },
10104
+ {
10105
+ "path": "queueDepth",
10106
+ "valueType": "number"
10107
+ },
10108
+ {
10109
+ "path": "supports.image",
10110
+ "valueType": "boolean"
10111
+ },
10112
+ {
10113
+ "path": "supports.priority",
10114
+ "valueType": "boolean"
10115
+ },
10116
+ {
10117
+ "path": "supports.data",
10118
+ "valueType": "boolean"
10119
+ },
10120
+ {
10121
+ "path": "supports.actions",
10122
+ "valueType": "boolean"
10123
+ },
10124
+ {
10125
+ "path": "supports.recipients",
10126
+ "valueType": "boolean"
10127
+ }
10128
+ ],
10129
+ "numeric-sensor": [
10130
+ {
10131
+ "path": "value",
10132
+ "valueType": "number"
10133
+ },
10134
+ {
10135
+ "path": "unit",
10136
+ "valueType": "string"
10137
+ },
10138
+ {
10139
+ "path": "precision",
10140
+ "valueType": "number"
10141
+ }
10142
+ ],
10143
+ "pet-feeder": [
10144
+ {
10145
+ "path": "foodLevel",
10146
+ "valueType": "number"
10147
+ },
10148
+ {
10149
+ "path": "food1",
10150
+ "valueType": "number"
10151
+ },
10152
+ {
10153
+ "path": "food2",
10154
+ "valueType": "number"
10155
+ },
10156
+ {
10157
+ "path": "lowFood",
10158
+ "valueType": "boolean"
10159
+ },
10160
+ {
10161
+ "path": "batteryPower",
10162
+ "valueType": "number"
10163
+ },
10164
+ {
10165
+ "path": "desiccantLeftDays",
10166
+ "valueType": "number"
10167
+ },
10168
+ {
10169
+ "path": "feeding",
10170
+ "valueType": "boolean"
10171
+ },
10172
+ {
10173
+ "path": "status",
10174
+ "valueType": "enum",
10175
+ "enumValues": [
10176
+ "normal",
10177
+ "offline",
10178
+ "on_batteries"
10179
+ ]
10180
+ },
10181
+ {
10182
+ "path": "error",
10183
+ "valueType": "string"
10184
+ },
10185
+ {
10186
+ "path": "errorCode",
10187
+ "valueType": "number"
10188
+ },
10189
+ {
10190
+ "path": "isDualHopper",
10191
+ "valueType": "boolean"
10192
+ },
10193
+ {
10194
+ "path": "childLock",
10195
+ "valueType": "boolean"
10196
+ },
10197
+ {
10198
+ "path": "indicatorLight",
10199
+ "valueType": "boolean"
10200
+ },
10201
+ {
10202
+ "path": "feedSound",
10203
+ "valueType": "boolean"
10204
+ },
10205
+ {
10206
+ "path": "volume",
10207
+ "valueType": "number"
10208
+ }
10209
+ ],
10210
+ "power-meter": [
10211
+ {
10212
+ "path": "watts",
10213
+ "valueType": "number"
10214
+ },
10215
+ {
10216
+ "path": "kwhTotal",
10217
+ "valueType": "number"
10218
+ },
10219
+ {
10220
+ "path": "volts",
10221
+ "valueType": "number"
10222
+ },
10223
+ {
10224
+ "path": "amps",
10225
+ "valueType": "number"
10226
+ },
10227
+ {
10228
+ "path": "va",
10229
+ "valueType": "number"
10230
+ },
10231
+ {
10232
+ "path": "powerFactor",
10233
+ "valueType": "number"
10234
+ },
10235
+ {
10236
+ "path": "unit",
10237
+ "valueType": "string"
10238
+ },
10239
+ {
10240
+ "path": "precision",
10241
+ "valueType": "number"
10242
+ }
10243
+ ],
10244
+ "presence": [
10245
+ {
10246
+ "path": "state",
10247
+ "valueType": "string"
10248
+ },
10249
+ {
10250
+ "path": "location",
10251
+ "valueType": "string"
10252
+ },
10253
+ {
10254
+ "path": "gps.latitude",
10255
+ "valueType": "number"
10256
+ },
10257
+ {
10258
+ "path": "gps.longitude",
10259
+ "valueType": "number"
10260
+ },
10261
+ {
10262
+ "path": "gps.accuracyMeters",
10263
+ "valueType": "number"
10264
+ },
10265
+ {
10266
+ "path": "batteryPercent",
10267
+ "valueType": "number"
10268
+ }
10269
+ ],
10270
+ "pressure-sensor": [
10271
+ {
10272
+ "path": "hpa",
10273
+ "valueType": "number"
10274
+ },
10275
+ {
10276
+ "path": "unit",
10277
+ "valueType": "string"
10278
+ },
10279
+ {
10280
+ "path": "precision",
10281
+ "valueType": "number"
10282
+ }
10283
+ ],
10284
+ "privacy-mask": [{
10285
+ "path": "enabled",
10286
+ "valueType": "boolean"
10287
+ }, {
10288
+ "path": "audioEnabled",
10289
+ "valueType": "boolean"
10290
+ }],
10291
+ "ptz": [
10292
+ {
10293
+ "path": "pan",
10294
+ "valueType": "number"
10295
+ },
10296
+ {
10297
+ "path": "tilt",
10298
+ "valueType": "number"
10299
+ },
10300
+ {
10301
+ "path": "zoom",
10302
+ "valueType": "number"
10303
+ },
10304
+ {
10305
+ "path": "autofocus",
10306
+ "valueType": "boolean"
10307
+ }
10308
+ ],
10309
+ "ptz-autotrack": [
10310
+ {
10311
+ "path": "enabled",
10312
+ "valueType": "boolean"
10313
+ },
10314
+ {
10315
+ "path": "currentSettings.targetType",
10316
+ "valueType": "string"
10317
+ },
10318
+ {
10319
+ "path": "currentSettings.stopDelaySeconds",
10320
+ "valueType": "number"
10321
+ },
10322
+ {
10323
+ "path": "currentSettings.disappearDelaySeconds",
10324
+ "valueType": "number"
10325
+ }
10326
+ ],
10327
+ "recording-archive": [
10328
+ {
10329
+ "path": "deviceId",
10330
+ "valueType": "number"
10331
+ },
10332
+ {
10333
+ "path": "enabled",
10334
+ "valueType": "boolean"
10335
+ },
10336
+ {
10337
+ "path": "activeMode",
10338
+ "valueType": "enum",
10339
+ "enumValues": [
10340
+ "off",
10341
+ "events",
10342
+ "continuous",
10343
+ "on-device-decision"
10344
+ ]
10345
+ },
10346
+ {
10347
+ "path": "nodeId",
10348
+ "valueType": "string"
10349
+ },
10350
+ {
10351
+ "path": "storageBytes",
10352
+ "valueType": "number"
10353
+ }
10354
+ ],
10355
+ "recording-onboard": [
10356
+ {
10357
+ "path": "primaryTrackId",
10358
+ "valueType": "string"
10359
+ },
10360
+ {
10361
+ "path": "enabled",
10362
+ "valueType": "boolean"
10363
+ },
10364
+ {
10365
+ "path": "overwriteWhenFull",
10366
+ "valueType": "boolean"
10367
+ },
10368
+ {
10369
+ "path": "preRecordSec",
10370
+ "valueType": "number"
10371
+ },
10372
+ {
10373
+ "path": "postRecordSec",
10374
+ "valueType": "number"
10375
+ },
10376
+ {
10377
+ "path": "segmentMinutes",
10378
+ "valueType": "number"
10379
+ },
10380
+ {
10381
+ "path": "unreadableWindows",
10382
+ "valueType": "number"
10383
+ },
10384
+ {
10385
+ "path": "recordingToNowhere",
10386
+ "valueType": "boolean"
10387
+ }
10388
+ ],
10389
+ "recording-signal": [{
10390
+ "path": "active",
10391
+ "valueType": "boolean"
10392
+ }, {
10393
+ "path": "reason",
10394
+ "valueType": "string"
10395
+ }],
10396
+ "running-state": [
10397
+ {
10398
+ "path": "running",
10399
+ "valueType": "boolean"
10400
+ },
10401
+ {
10402
+ "path": "since",
10403
+ "valueType": "number"
10404
+ },
10405
+ {
10406
+ "path": "source",
10407
+ "valueType": "enum",
10408
+ "enumValues": ["native", "assigned"]
10409
+ },
10410
+ {
10411
+ "path": "phase",
10412
+ "valueType": "string"
10413
+ }
10414
+ ],
10415
+ "script-runner": [
10416
+ {
10417
+ "path": "isRunning",
10418
+ "valueType": "boolean"
10419
+ },
10420
+ {
10421
+ "path": "lastRunAt",
10422
+ "valueType": "number"
10423
+ },
10424
+ {
10425
+ "path": "lastRunSuccess",
10426
+ "valueType": "boolean"
10427
+ },
10428
+ {
10429
+ "path": "lastError",
10430
+ "valueType": "string"
10431
+ }
10432
+ ],
10433
+ "smoke": [{
10434
+ "path": "detected",
10435
+ "valueType": "boolean"
10436
+ }],
10437
+ "snapshot": [
10438
+ {
10439
+ "path": "lastCapturedAt",
10440
+ "valueType": "number"
10441
+ },
10442
+ {
10443
+ "path": "cacheAgeMs",
10444
+ "valueType": "number"
10445
+ },
10446
+ {
10447
+ "path": "lastBytes",
10448
+ "valueType": "number"
10449
+ },
10450
+ {
10451
+ "path": "lastStreamId",
10452
+ "valueType": "string"
10453
+ }
10454
+ ],
10455
+ "stream-params": [
10456
+ {
10457
+ "path": "main.width",
10458
+ "valueType": "number"
10459
+ },
10460
+ {
10461
+ "path": "main.height",
10462
+ "valueType": "number"
10463
+ },
10464
+ {
10465
+ "path": "main.codec",
10466
+ "valueType": "enum",
10467
+ "enumValues": ["h264", "h265"]
10468
+ },
10469
+ {
10470
+ "path": "main.framerate",
10471
+ "valueType": "number"
10472
+ },
10473
+ {
10474
+ "path": "main.bitrate",
10475
+ "valueType": "number"
10476
+ },
10477
+ {
10478
+ "path": "main.bitrateMode",
10479
+ "valueType": "enum",
10480
+ "enumValues": ["vbr", "cbr"]
10481
+ },
10482
+ {
10483
+ "path": "main.encoderProfile",
10484
+ "valueType": "enum",
10485
+ "enumValues": [
10486
+ "high",
10487
+ "main",
10488
+ "baseline"
10489
+ ]
10490
+ },
10491
+ {
10492
+ "path": "main.gop",
10493
+ "valueType": "number"
10494
+ },
10495
+ {
10496
+ "path": "main.audio",
10497
+ "valueType": "boolean"
10498
+ },
10499
+ {
10500
+ "path": "sub.width",
10501
+ "valueType": "number"
10502
+ },
10503
+ {
10504
+ "path": "sub.height",
10505
+ "valueType": "number"
10506
+ },
10507
+ {
10508
+ "path": "sub.codec",
10509
+ "valueType": "enum",
10510
+ "enumValues": ["h264", "h265"]
10511
+ },
10512
+ {
10513
+ "path": "sub.framerate",
10514
+ "valueType": "number"
10515
+ },
10516
+ {
10517
+ "path": "sub.bitrate",
10518
+ "valueType": "number"
10519
+ },
10520
+ {
10521
+ "path": "sub.bitrateMode",
10522
+ "valueType": "enum",
10523
+ "enumValues": ["vbr", "cbr"]
10524
+ },
10525
+ {
10526
+ "path": "sub.encoderProfile",
10527
+ "valueType": "enum",
10528
+ "enumValues": [
10529
+ "high",
10530
+ "main",
10531
+ "baseline"
10532
+ ]
10533
+ },
10534
+ {
10535
+ "path": "sub.gop",
10536
+ "valueType": "number"
10537
+ },
10538
+ {
10539
+ "path": "sub.audio",
10540
+ "valueType": "boolean"
10541
+ },
10542
+ {
10543
+ "path": "ext.width",
10544
+ "valueType": "number"
10545
+ },
10546
+ {
10547
+ "path": "ext.height",
10548
+ "valueType": "number"
10549
+ },
10550
+ {
10551
+ "path": "ext.codec",
10552
+ "valueType": "enum",
10553
+ "enumValues": ["h264", "h265"]
10554
+ },
10555
+ {
10556
+ "path": "ext.framerate",
10557
+ "valueType": "number"
10558
+ },
10559
+ {
10560
+ "path": "ext.bitrate",
10561
+ "valueType": "number"
10562
+ },
10563
+ {
10564
+ "path": "ext.bitrateMode",
10565
+ "valueType": "enum",
10566
+ "enumValues": ["vbr", "cbr"]
10567
+ },
10568
+ {
10569
+ "path": "ext.encoderProfile",
10570
+ "valueType": "enum",
10571
+ "enumValues": [
10572
+ "high",
10573
+ "main",
10574
+ "baseline"
10575
+ ]
10576
+ },
10577
+ {
10578
+ "path": "ext.gop",
10579
+ "valueType": "number"
10580
+ },
10581
+ {
10582
+ "path": "ext.audio",
10583
+ "valueType": "boolean"
10584
+ }
10585
+ ],
10586
+ "switch": [{
10587
+ "path": "on",
10588
+ "valueType": "boolean"
10589
+ }],
10590
+ "tamper": [{
10591
+ "path": "tampered",
10592
+ "valueType": "boolean"
10593
+ }],
10594
+ "temperature-sensor": [
10595
+ {
10596
+ "path": "celsius",
10597
+ "valueType": "number"
10598
+ },
10599
+ {
10600
+ "path": "unit",
10601
+ "valueType": "string"
10602
+ },
10603
+ {
10604
+ "path": "precision",
10605
+ "valueType": "number"
10606
+ }
10607
+ ],
10608
+ "update": [
10609
+ {
10610
+ "path": "currentVersion",
10611
+ "valueType": "string"
10612
+ },
10613
+ {
10614
+ "path": "availableVersion",
10615
+ "valueType": "string"
10616
+ },
10617
+ {
10618
+ "path": "updatable",
10619
+ "valueType": "boolean"
10620
+ },
10621
+ {
10622
+ "path": "state",
10623
+ "valueType": "string"
10624
+ },
10625
+ {
10626
+ "path": "inProgress",
10627
+ "valueType": "boolean"
10628
+ }
10629
+ ],
10630
+ "vacuum-control": [
10631
+ {
10632
+ "path": "state",
10633
+ "valueType": "enum",
10634
+ "enumValues": [
10635
+ "idle",
10636
+ "cleaning",
10637
+ "paused",
10638
+ "returning",
10639
+ "docked",
10640
+ "drying",
10641
+ "error"
10642
+ ]
10643
+ },
10644
+ {
10645
+ "path": "batteryLevel",
10646
+ "valueType": "number"
10647
+ },
10648
+ {
10649
+ "path": "fanSpeed",
10650
+ "valueType": "string"
10651
+ },
10652
+ {
10653
+ "path": "progressPercent",
10654
+ "valueType": "number"
10655
+ },
10656
+ {
10657
+ "path": "errorCode",
10658
+ "valueType": "number"
10659
+ },
10660
+ {
10661
+ "path": "errorLabel",
10662
+ "valueType": "string"
10663
+ }
10664
+ ],
10665
+ "valve": [{
10666
+ "path": "state",
10667
+ "valueType": "enum",
10668
+ "enumValues": [
10669
+ "open",
10670
+ "opening",
10671
+ "closing",
10672
+ "closed",
10673
+ "stopped"
10674
+ ]
10675
+ }, {
10676
+ "path": "position",
10677
+ "valueType": "number"
10678
+ }],
10679
+ "vibration": [{
10680
+ "path": "detected",
10681
+ "valueType": "boolean"
10682
+ }],
10683
+ "water-heater": [
10684
+ {
10685
+ "path": "currentTemp",
10686
+ "valueType": "number"
10687
+ },
10688
+ {
10689
+ "path": "targetTemp",
10690
+ "valueType": "number"
10691
+ },
10692
+ {
10693
+ "path": "operationMode",
10694
+ "valueType": "string"
10695
+ },
10696
+ {
10697
+ "path": "away",
10698
+ "valueType": "boolean"
10699
+ },
10700
+ {
10701
+ "path": "minTemp",
10702
+ "valueType": "number"
10703
+ },
10704
+ {
10705
+ "path": "maxTemp",
10706
+ "valueType": "number"
10707
+ }
10708
+ ],
10709
+ "weather": [
10710
+ {
10711
+ "path": "condition",
10712
+ "valueType": "string"
10713
+ },
10714
+ {
10715
+ "path": "temperature",
10716
+ "valueType": "number"
10717
+ },
10718
+ {
10719
+ "path": "temperatureUnit",
10720
+ "valueType": "string"
10721
+ },
10722
+ {
10723
+ "path": "humidity",
10724
+ "valueType": "number"
10725
+ },
10726
+ {
10727
+ "path": "pressure",
10728
+ "valueType": "number"
10729
+ },
10730
+ {
10731
+ "path": "pressureUnit",
10732
+ "valueType": "string"
10733
+ },
10734
+ {
10735
+ "path": "windSpeed",
10736
+ "valueType": "number"
10737
+ },
10738
+ {
10739
+ "path": "windSpeedUnit",
10740
+ "valueType": "string"
10741
+ },
10742
+ {
10743
+ "path": "windBearing",
10744
+ "valueType": "number"
10745
+ }
10746
+ ],
10747
+ "zone-analytics": [
10748
+ {
10749
+ "path": "ts",
10750
+ "valueType": "number"
10751
+ },
10752
+ {
10753
+ "path": "frameWidth",
10754
+ "valueType": "number"
10755
+ },
10756
+ {
10757
+ "path": "frameHeight",
10758
+ "valueType": "number"
10759
+ },
10760
+ {
10761
+ "path": "frame.totalObjects",
10762
+ "valueType": "number"
10763
+ },
10764
+ {
10765
+ "path": "frame.standingObjects",
10766
+ "valueType": "number"
10767
+ },
10768
+ {
10769
+ "path": "frame.transientObjects",
10770
+ "valueType": "number"
10771
+ },
10772
+ {
10773
+ "path": "unzoned.totalObjects",
10774
+ "valueType": "number"
10775
+ },
10776
+ {
10777
+ "path": "unzoned.standingObjects",
10778
+ "valueType": "number"
10779
+ },
10780
+ {
10781
+ "path": "unzoned.transientObjects",
10782
+ "valueType": "number"
10783
+ }
10784
+ ]
10785
+ });
8808
10786
  object({
8809
10787
  code: string().regex(/^[a-z][a-z0-9-]*(\.[a-z0-9-]+)+$/),
8810
10788
  params: record(string(), union([string(), number()])).optional()
@@ -9153,7 +11131,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
9153
11131
  return DeviceRole;
9154
11132
  }({});
9155
11133
  //#endregion
9156
- //#region ../types/dist/composition-CB6PMT9p.mjs
11134
+ //#region ../types/dist/composition-kEl9mevu.mjs
9157
11135
  /**
9158
11136
  * The ffmpeg build every CamStack node downloads, per platform and arch.
9159
11137
  *
@@ -9213,7 +11191,7 @@ portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac
9213
11191
  * ONE table for everyone who asks "is this device HIGH?": the
9214
11192
  * recorder's `RecordingTriggers.sensorDeviceIds` trigger, the post-analysis
9215
11193
  * sensor markers, the orchestrator's camera-sensors bridge and
9216
- * the sources of a composite doorbell (`doorbellFeatureSources`, D671).
11194
+ * the sources of a pulse (`compilePulseOverride`, D936).
9217
11195
  * A second copy would diverge at the first cap added, and the symptom — "the
9218
11196
  * sensor rings the doorbell but does not record" — is exactly D62.
9219
11197
  *
@@ -9454,6 +11432,20 @@ var table = {
9454
11432
  apply: () => {
9455
11433
  throw new ExpressionEvalError("count: stateful evaluation context is required");
9456
11434
  }
11435
+ },
11436
+ dwell: {
11437
+ minArgs: 3,
11438
+ maxArgs: 3,
11439
+ apply: () => {
11440
+ throw new ExpressionEvalError("dwell: stateful evaluation context is required");
11441
+ }
11442
+ },
11443
+ latchedAt: {
11444
+ minArgs: 1,
11445
+ maxArgs: 1,
11446
+ apply: () => {
11447
+ throw new ExpressionEvalError("latchedAt: stateful evaluation context is required");
11448
+ }
9457
11449
  }
9458
11450
  };
9459
11451
  Object.freeze(Object.assign(Object.create(null), table));
@@ -12354,7 +14346,7 @@ var LogChannelDescriptorSchema = object({
12354
14346
  * `true` is a PROMISE with two halves, and both must hold: the gate is
12355
14347
  * consulted with the numeric device id, AND every line the channel admits
12356
14348
  * carries `tags: { deviceId }` with that same numeric id. The second half is
12357
- * what makes `| json | deviceId="617"` work in Loki — `loki-payload.ts`
14349
+ * what makes `| json | deviceId="102"` work in Loki — `loki-payload.ts`
12358
14350
  * keeps `deviceId` out of the stream labels for cardinality, so the tag in
12359
14351
  * the body is the only way to filter.
12360
14352
  *
@@ -12542,7 +14534,7 @@ var ModelVariantGroupSchema = object({
12542
14534
  precision: _enum(["fp32", "int8"]).optional(),
12543
14535
  /**
12544
14536
  * Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
12545
- * an alternate training of the same family (Scrypted `relu_test`); chip
14537
+ * an alternate training of the same family (plugin catalog `relu_test`); chip
12546
14538
  * label is "Test".
12547
14539
  */
12548
14540
  optimization: _enum(["standard", "test"]).optional(),
@@ -12794,8 +14786,8 @@ var ModelCatalogEntrySchema = object({
12794
14786
  provider: ModelProviderIdSchema.optional(),
12795
14787
  /**
12796
14788
  * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
12797
- * applies (Frigate / COCO public catalog). Set on a custom model whose raw
12798
- * labels already ARE the CamStack macros (Scrypted identity map).
14789
+ * applies (plus catalog / COCO public catalog). Set on a custom model whose raw
14790
+ * labels already ARE the CamStack macros (plugin catalog identity map).
12799
14791
  */
12800
14792
  classMap: DetectionCatalogClassMapSchema.optional(),
12801
14793
  /**
@@ -15764,7 +17756,7 @@ method(object({
15764
17756
  * `1` is real time and is the ONLY value that allows the copy branch —
15765
17757
  * anything else forces `libx264` over the window. That was priced
15766
17758
  * before it was chosen: a per-event burst measured at 0.23 s and 254 KB
15767
- * on a real 615 720p cut, against 922 KB for the copy it replaces. A
17759
+ * on a real 101 720p cut, against 922 KB for the copy it replaces. A
15768
17760
  * re-encode is capped at 720p (`EVENT_CLIP_ENCODE_MAX_WIDTH`), because
15769
17761
  * once the decode is forced the width stops being free.
15770
17762
  */
@@ -16184,6 +18176,7 @@ var CompositionRunStatusSchema = _enum([
16184
18176
  "starting",
16185
18177
  "running",
16186
18178
  "degraded",
18179
+ "incomplete",
16187
18180
  "failed"
16188
18181
  ]);
16189
18182
  var CompositionFieldStateKindSchema = _enum([
@@ -16233,6 +18226,13 @@ var ComposerUnreadableBlockSchema = object({
16233
18226
  /** The parse error, in the operator's words. */
16234
18227
  error: string()
16235
18228
  });
18229
+ /** A confirmed release the hub did not accept. `deviceId` is the claim's device. */
18230
+ var UnreleasedClaimSchema = object({
18231
+ deviceId: number().int(),
18232
+ capName: string(),
18233
+ owner: string(),
18234
+ error: string()
18235
+ });
16236
18236
  method(object({
16237
18237
  /** The shared Blocks integration; null until `core-blocks` has reconciled it. */
16238
18238
  integrationId: string().nullable(),
@@ -16242,7 +18242,13 @@ method(object({
16242
18242
  /** Operator restarts: rebuild these runtimes and re-resolve their sources. Stores nothing (D62). */
16243
18243
  restartBlockIds: array(string()),
16244
18244
  /** Composition rows that exist but do not parse: held, never withdrawn, reported failed. */
16245
- unreadableBlocks: array(ComposerUnreadableBlockSchema)
18245
+ unreadableBlocks: array(ComposerUnreadableBlockSchema),
18246
+ /**
18247
+ * Operator-confirmed deletions. Their claims are released on this apply,
18248
+ * before any replacement block claims. A block that merely vanished from the
18249
+ * snapshot is not listed here and still waits for two applies (D49).
18250
+ */
18251
+ retiredBlockIds: array(string()).optional()
16246
18252
  }), object({
16247
18253
  blocks: array(object({
16248
18254
  blockId: string(),
@@ -16254,7 +18260,13 @@ method(object({
16254
18260
  * integration unknown, its own rows unread or read empty once). An empty
16255
18261
  * apply the caller owes is paid off only by one the composer acted on (D49).
16256
18262
  */
16257
- acted: boolean()
18263
+ acted: boolean(),
18264
+ /**
18265
+ * Confirmed releases this apply tried and the hub did not accept. Empty when
18266
+ * every one landed (or there was nothing to hand back). Absent on a result
18267
+ * that never got that far.
18268
+ */
18269
+ unreleasedClaims: array(UnreleasedClaimSchema).optional()
16258
18270
  }), {
16259
18271
  kind: "mutation",
16260
18272
  auth: "admin"
@@ -16297,7 +18309,15 @@ Object.freeze({
16297
18309
  kind: "fixed",
16298
18310
  result: ["number", "null"]
16299
18311
  },
16300
- count: NUMBER
18312
+ count: NUMBER,
18313
+ dwell: {
18314
+ kind: "fixed",
18315
+ result: ["boolean", "null"]
18316
+ },
18317
+ latchedAt: {
18318
+ kind: "fixed",
18319
+ result: ["number", "null"]
18320
+ }
16301
18321
  });
16302
18322
  `${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
16303
18323
  /**
@@ -16370,6 +18390,7 @@ var CoreBlockStatusSchema = _enum([
16370
18390
  "starting",
16371
18391
  "running",
16372
18392
  "degraded",
18393
+ "incomplete",
16373
18394
  "failed"
16374
18395
  ]);
16375
18396
  /** path → TypeScript source for a multi-file block. */
@@ -38293,7 +40314,7 @@ var PRIMARY_CATEGORIES = new Set(ENTRIES.map((e) => e.primaryCategory));
38293
40314
  * `locationKey` is ALWAYS {@link locationIconKey} of the label — never the
38294
40315
  * operator's casing. The registry matches labels trimmed + case-insensitively
38295
40316
  * everywhere (`addLocation`, `removeLocation`, `renameLocation`), and a
38296
- * case-only rename (`cucina` → `Cucina`) is a real edit this repo supports; a
40317
+ * case-only rename (`kitchen` → `Kitchen`) is a real edit this repo supports; a
38297
40318
  * map keyed on the displayed casing would orphan its entry on exactly that
38298
40319
  * edit. Consumers join by keying their own label through `locationIconKey`.
38299
40320
  */
@@ -38318,7 +40339,7 @@ var LocationDescriptionAssignmentSchema = object({
38318
40339
  /**
38319
40340
  * A SITE ZONE — a named part of the property that several locations belong to.
38320
40341
  *
38321
- * "Zona notte" holds every bedroom; "Zona giorno" the living room and the
40342
+ * "Night zone" holds every bedroom; "Zona giorno" the living room and the
38322
40343
  * kitchen. A camera belongs to exactly one location, and a location to at most
38323
40344
  * one zone, so a camera's zone is derived and never stored on the device: the
38324
40345
  * whole point of this entity is that grouping rooms touches no device row.
@@ -38347,7 +40368,7 @@ var LocationDescriptionAssignmentSchema = object({
38347
40368
  * the locations inside it.
38348
40369
  *
38349
40370
  * The LABEL is carried alongside the key because the key is lossy on purpose —
38350
- * a surface must show "Zona notte", not "zona notte". Locations are carried
40371
+ * a surface must show "Night zone", not "night zone". Locations are carried
38351
40372
  * here, rather than left to a second call, because every consumer wants both
38352
40373
  * at once and a viewer that asked twice could render a zone whose membership
38353
40374
  * it has not fetched yet.
@@ -40460,8 +42481,8 @@ var LoadContributionSchema = object({
40460
42481
  "unattributable"
40461
42482
  ]),
40462
42483
  /**
40463
- * What ONE entry is, in the contributor's own words — `615/high`,
40464
- * `617/native`, `cuda:0 shared pool`. Free text because the unit differs per
42484
+ * What ONE entry is, in the contributor's own words — `101/high`,
42485
+ * `102/native`, `cuda:0 shared pool`. Free text because the unit differs per
40465
42486
  * family and inventing a common one would lose the only information that
40466
42487
  * makes two entries for the same camera distinguishable.
40467
42488
  */
@@ -42109,6 +44130,381 @@ var _macroLookup = /* @__PURE__ */ new Map();
42109
44130
  for (const [k, v] of Object.entries(YAMNET_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
42110
44131
  for (const [k, v] of Object.entries(APPLE_SA_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
42111
44132
  /**
44133
+ * Palette entry ids (D939). Audio is the one gradient; `audio-*` leaves are
44134
+ * not entries. `heatmapScrub` is a mark, not an event kind.
44135
+ */
44136
+ var PALETTE_ENTRY_IDS = [
44137
+ "motion",
44138
+ "audio",
44139
+ "recording",
44140
+ "live",
44141
+ "heatmapScrub",
44142
+ "person",
44143
+ "vehicle",
44144
+ "animal",
44145
+ "package",
44146
+ "sensor",
44147
+ "control",
44148
+ "face",
44149
+ "plate",
44150
+ "car",
44151
+ "truck",
44152
+ "bus",
44153
+ "motorcycle",
44154
+ "bicycle",
44155
+ "airplane",
44156
+ "boat",
44157
+ "train",
44158
+ "bird",
44159
+ "dog",
44160
+ "cat",
44161
+ "horse",
44162
+ "sheep",
44163
+ "cow",
44164
+ "elephant",
44165
+ "bear",
44166
+ "zebra",
44167
+ "giraffe",
44168
+ "package-delivered",
44169
+ "package-picked-up",
44170
+ "suitcase",
44171
+ "backpack",
44172
+ "handbag",
44173
+ "contact",
44174
+ "motion-sensor",
44175
+ "smoke",
44176
+ "flood",
44177
+ "gas",
44178
+ "carbon-monoxide",
44179
+ "vibration",
44180
+ "tamper",
44181
+ "presence",
44182
+ "enum-sensor",
44183
+ "device-event",
44184
+ "lock",
44185
+ "cover",
44186
+ "switch",
44187
+ "siren",
44188
+ "button",
44189
+ "doorbell"
44190
+ ];
44191
+ var AUDIO_ENTRY_ID = "audio";
44192
+ /** Six rungs, quiet → loud. The opaque end is the entry's hex. */
44193
+ var AUDIO_GRADIENT_ALPHAS = [
44194
+ .3,
44195
+ .42,
44196
+ .55,
44197
+ .7,
44198
+ .85,
44199
+ 1
44200
+ ];
44201
+ var PALETTE_PRESET_IDS = [
44202
+ "camstack",
44203
+ "high-contrast",
44204
+ "okabe-ito"
44205
+ ];
44206
+ /** Frozen palette tables (D939). The spec refuses a table that breaks the rule. */
44207
+ var CAMSTACK_HEX = {
44208
+ motion: "#d946ef",
44209
+ audio: "#059eb8",
44210
+ recording: "#ef4444",
44211
+ live: "#8d7a00",
44212
+ heatmapScrub: "#4b32ff",
44213
+ person: "#11a64c",
44214
+ vehicle: "#3b82f6",
44215
+ animal: "#ea6a09",
44216
+ package: "#924667",
44217
+ sensor: "#624bbc",
44218
+ control: "#944d24",
44219
+ face: "#ed4f8d",
44220
+ plate: "#4b7027",
44221
+ car: "#9684cf",
44222
+ truck: "#0f9b89",
44223
+ bus: "#a734a9",
44224
+ motorcycle: "#c1133a",
44225
+ bicycle: "#0e6a9b",
44226
+ airplane: "#7c9928",
44227
+ boat: "#b17933",
44228
+ train: "#ad6ca3",
44229
+ bird: "#0f7c55",
44230
+ dog: "#c82700",
44231
+ cat: "#7268f2",
44232
+ horse: "#cb795e",
44233
+ sheep: "#b8636b",
44234
+ cow: "#cb2969",
44235
+ elephant: "#1158d2",
44236
+ bear: "#8d5e00",
44237
+ zebra: "#0097d6",
44238
+ giraffe: "#8f61bb",
44239
+ "package-delivered": "#cd3f9b",
44240
+ "package-picked-up": "#388a08",
44241
+ suitcase: "#666800",
44242
+ backpack: "#ec5022",
44243
+ handbag: "#a76ef8",
44244
+ contact: "#ab5a49",
44245
+ "motion-sensor": "#b95d1a",
44246
+ smoke: "#dd3858",
44247
+ flood: "#b31e7d",
44248
+ gas: "#5b70b5",
44249
+ "carbon-monoxide": "#7b4e8e",
44250
+ vibration: "#e65bba",
44251
+ tamper: "#98464b",
44252
+ presence: "#3a9468",
44253
+ "enum-sensor": "#7885f8",
44254
+ "device-event": "#8c43c8",
44255
+ lock: "#649653",
44256
+ cover: "#c67597",
44257
+ switch: "#7a812a",
44258
+ siren: "#ac5d7f",
44259
+ button: "#b276cd",
44260
+ doorbell: "#0087ab"
44261
+ };
44262
+ var CAMSTACK_FALLBACK = [
44263
+ "#b34dc7",
44264
+ "#1d7d34",
44265
+ "#db6b6c",
44266
+ "#a43d29",
44267
+ "#0e6ee6",
44268
+ "#29a10b",
44269
+ "#a98731",
44270
+ "#0181c6"
44271
+ ];
44272
+ var HIGH_CONTRAST_HEX = {
44273
+ motion: "#964360",
44274
+ audio: "#23a132",
44275
+ recording: "#2494ca",
44276
+ live: "#bd7e2b",
44277
+ heatmapScrub: "#ad6eea",
44278
+ person: "#62611e",
44279
+ vehicle: "#f4534c",
44280
+ animal: "#1556cd",
44281
+ package: "#9c4415",
44282
+ sensor: "#066c48",
44283
+ control: "#f2479f",
44284
+ face: "#139d8a",
44285
+ plate: "#909024",
44286
+ car: "#8e35ab",
44287
+ truck: "#bd0b2b",
44288
+ bus: "#7a88ca",
44289
+ motorcycle: "#e26725",
44290
+ bicycle: "#a6679b",
44291
+ airplane: "#7c5720",
44292
+ boat: "#467a1b",
44293
+ train: "#6f65a4",
44294
+ bird: "#cb717f",
44295
+ dog: "#c62490",
44296
+ cat: "#b36850",
44297
+ horse: "#1872ac",
44298
+ sheep: "#927939",
44299
+ cow: "#428a5c",
44300
+ elephant: "#d41160",
44301
+ bear: "#799453",
44302
+ zebra: "#a85455",
44303
+ giraffe: "#746be8",
44304
+ "package-delivered": "#824a80",
44305
+ "package-picked-up": "#614ac1",
44306
+ suitcase: "#2f77f3",
44307
+ backpack: "#fa476d",
44308
+ handbag: "#c14cbe",
44309
+ contact: "#c83921",
44310
+ "motion-sensor": "#a07ebd",
44311
+ smoke: "#a25b13",
44312
+ flood: "#526bab",
44313
+ gas: "#924938",
44314
+ "carbon-monoxide": "#bb7e53",
44315
+ vibration: "#b66182",
44316
+ tamper: "#3c6931",
44317
+ presence: "#6c851d",
44318
+ "enum-sensor": "#ad2d48",
44319
+ "device-event": "#5e9b04",
44320
+ lock: "#00a062",
44321
+ cover: "#ad8624",
44322
+ switch: "#d05259",
44323
+ siren: "#cd67b3",
44324
+ button: "#c9746a",
44325
+ doorbell: "#338eeb"
44326
+ };
44327
+ var HIGH_CONTRAST_FALLBACK = [
44328
+ "#817f3b",
44329
+ "#a0733e",
44330
+ "#8658b2",
44331
+ "#956301",
44332
+ "#bc652d",
44333
+ "#647331",
44334
+ "#a14c9e",
44335
+ "#d14e71"
44336
+ ];
44337
+ var OKABE_ITO_HEX = {
44338
+ motion: "#b88128",
44339
+ audio: "#1096c8",
44340
+ recording: "#009e73",
44341
+ live: "#9c8c22",
44342
+ heatmapScrub: "#0072b2",
44343
+ person: "#d55e00",
44344
+ vehicle: "#c0739f",
44345
+ animal: "#226d18",
44346
+ package: "#91446c",
44347
+ sensor: "#217b56",
44348
+ control: "#648647",
44349
+ face: "#c22998",
44350
+ plate: "#fa4575",
44351
+ car: "#956301",
44352
+ truck: "#2f77f3",
44353
+ bus: "#7a4e86",
44354
+ motorcycle: "#f54597",
44355
+ bicycle: "#bb3e75",
44356
+ airplane: "#e054c0",
44357
+ boat: "#457942",
44358
+ train: "#867afa",
44359
+ bird: "#88914c",
44360
+ dog: "#1556cd",
44361
+ cat: "#71702c",
44362
+ horse: "#9b4fa4",
44363
+ sheep: "#c0559d",
44364
+ cow: "#d14f65",
44365
+ elephant: "#98470f",
44366
+ bear: "#595896",
44367
+ zebra: "#96790e",
44368
+ giraffe: "#cb717b",
44369
+ "package-delivered": "#139d8a",
44370
+ "package-picked-up": "#906ead",
44371
+ suitcase: "#d02939",
44372
+ backpack: "#d41160",
44373
+ handbag: "#f64f54",
44374
+ contact: "#7258d2",
44375
+ "motion-sensor": "#b66182",
44376
+ smoke: "#627abb",
44377
+ flood: "#b86ae4",
44378
+ gas: "#a95261",
44379
+ "carbon-monoxide": "#c65d3c",
44380
+ vibration: "#7a40b7",
44381
+ tamper: "#914b34",
44382
+ presence: "#9481c3",
44383
+ "enum-sensor": "#ac6d47",
44384
+ "device-event": "#7b6fce",
44385
+ lock: "#c67662",
44386
+ cover: "#a6564d",
44387
+ switch: "#ad2c4e",
44388
+ siren: "#348e08",
44389
+ button: "#d27303",
44390
+ doorbell: "#55770f"
44391
+ };
44392
+ var OKABE_ITO_FALLBACK = [
44393
+ "#9a3784",
44394
+ "#a7392c",
44395
+ "#409d50",
44396
+ "#6987e7",
44397
+ "#ee5b3d",
44398
+ "#c0430d",
44399
+ "#af79b3",
44400
+ "#4b6628"
44401
+ ];
44402
+ /**
44403
+ * The display palette (D939). One table of colours, three presets, one
44404
+ * validator. Taxonomy colours and every consumer read this — there is no
44405
+ * second hex table.
44406
+ */
44407
+ var paletteHexSchema = string().regex(/^#[0-9a-f]{6}$/);
44408
+ var paletteSwatchSchema = discriminatedUnion("form", [object({
44409
+ form: literal("solid"),
44410
+ hex: paletteHexSchema
44411
+ }), object({
44412
+ form: literal("gradient"),
44413
+ hex: paletteHexSchema,
44414
+ alphas: array(number().gt(0).lte(1)).length(AUDIO_GRADIENT_ALPHAS.length)
44415
+ })]);
44416
+ var paletteReadySchema = object({
44417
+ status: literal("ready"),
44418
+ presetId: _enum(PALETTE_PRESET_IDS),
44419
+ customized: boolean(),
44420
+ source: _enum(["stored", "unconfigured"]),
44421
+ swatches: record(string(), paletteSwatchSchema),
44422
+ fallbacks: array(paletteHexSchema).length(8)
44423
+ });
44424
+ var paletteResultSchema = discriminatedUnion("status", [paletteReadySchema, object({
44425
+ status: literal("unknown"),
44426
+ reason: string()
44427
+ })]);
44428
+ var setPaletteInputSchema = union([object({ presetId: string() }), object({
44429
+ presetId: string(),
44430
+ overrides: record(string(), paletteSwatchSchema)
44431
+ })]);
44432
+ object({
44433
+ presetId: string(),
44434
+ overrides: record(string(), paletteSwatchSchema)
44435
+ });
44436
+ function solid(hex) {
44437
+ return {
44438
+ form: "solid",
44439
+ hex
44440
+ };
44441
+ }
44442
+ function audioGradient(hex) {
44443
+ return {
44444
+ form: "gradient",
44445
+ hex,
44446
+ alphas: [...AUDIO_GRADIENT_ALPHAS]
44447
+ };
44448
+ }
44449
+ function swatchesFrom(hexes) {
44450
+ const out = {};
44451
+ for (const id of PALETTE_ENTRY_IDS) {
44452
+ const hex = hexes[id];
44453
+ if (hex === void 0) throw new Error(`palette table missing ${id}`);
44454
+ out[id] = id === "audio" ? audioGradient(hex) : solid(hex);
44455
+ }
44456
+ return out;
44457
+ }
44458
+ function preset(id, name, hexes, fallbacks) {
44459
+ return {
44460
+ id,
44461
+ name,
44462
+ swatches: swatchesFrom(hexes),
44463
+ fallbacks
44464
+ };
44465
+ }
44466
+ var DISPLAY_PRESETS = [
44467
+ preset("camstack", "CamStack", CAMSTACK_HEX, CAMSTACK_FALLBACK),
44468
+ preset("high-contrast", "High contrast", HIGH_CONTRAST_HEX, HIGH_CONTRAST_FALLBACK),
44469
+ preset("okabe-ito", "Colour-blind safe", OKABE_ITO_HEX, OKABE_ITO_FALLBACK)
44470
+ ];
44471
+ function presetById(id) {
44472
+ return DISPLAY_PRESETS.find((item) => item.id === id);
44473
+ }
44474
+ function bundledCamstack() {
44475
+ const presetRow = presetById("camstack");
44476
+ if (presetRow === void 0) throw new Error("CamStack preset missing");
44477
+ return readyOf(presetRow, "unconfigured", false);
44478
+ }
44479
+ function readyOf(row, source, customized) {
44480
+ return {
44481
+ status: "ready",
44482
+ presetId: row.id,
44483
+ customized,
44484
+ source,
44485
+ swatches: row.swatches,
44486
+ fallbacks: [...row.fallbacks]
44487
+ };
44488
+ }
44489
+ function hashFallback(kind, fallbacks) {
44490
+ let hash = 0;
44491
+ for (let i = 0; i < kind.length; i++) hash = hash * 31 + (kind.codePointAt(i) ?? 0) >>> 0;
44492
+ const hex = fallbacks[hash % fallbacks.length];
44493
+ if (hex === void 0) throw new Error("display palette has no fallback colour");
44494
+ return hex;
44495
+ }
44496
+ /** Colour a kind paints with. Audio leaves share the audio gradient's hex. */
44497
+ function paintHex(swatches, fallbacks, kind) {
44498
+ const key = kind.trim().toLowerCase();
44499
+ if (key.startsWith("audio-")) {
44500
+ const audio = swatches[AUDIO_ENTRY_ID];
44501
+ return audio !== void 0 ? audio.hex : hashFallback(key, fallbacks);
44502
+ }
44503
+ const direct = swatches[key];
44504
+ if (direct !== void 0) return direct.hex;
44505
+ return hashFallback(key, fallbacks);
44506
+ }
44507
+ /**
42112
44508
  * Unified event-kind taxonomy — THE single source of truth for
42113
44509
  * `kind → { parentKind, category, level, color, iconId, labelKey, label,
42114
44510
  * icon }`.
@@ -42122,109 +44518,88 @@ for (const [k, v] of Object.entries(APPLE_SA_TO_MACRO.mapping)) _macroLookup.set
42122
44518
  * - `addon-post-analysis/shared/frame/box-drawer.ts` (DEFAULT_COLOR)
42123
44519
  * - the COCO / audio class maps (macro ↔ sub relationships)
42124
44520
  *
42125
- * The DATA (serializable — color/iconId/labelKey/parentKind) lives here in
42126
- * `@camstack/types`. The UI-side mapping `iconId → lucide component` and
42127
- * `labelKey → t()` lives in `@camstack/ui-library`. UIs never hardcode a
42128
- * color or an icon: they read this dictionary (server descriptors carry the
42129
- * fields inline; the client resolves color/icon/label from `iconId`/`kind`).
44521
+ * The DATA (serializable — parentKind / iconId / labelKey) lives here in
44522
+ * `@camstack/types`. Colour is NOT a second table: each entry's `color` is
44523
+ * the bundled CamStack display palette (D939). The effective cluster palette
44524
+ * is the `display-palette` capability. The UI-side mapping `iconId → lucide
44525
+ * component` and `labelKey → t()` lives in `@camstack/ui-library`.
42130
44526
  *
42131
44527
  * Two levels only (v1 YAGNI): macro → sub. `person` is a leaf macro.
42132
44528
  */
42133
- var TAXONOMY_COLORS = {
42134
- motion: "#f59e0b",
42135
- audio: "#06b6d4",
42136
- person: "#22c55e",
42137
- vehicle: "#3b82f6",
42138
- animal: "#f97316",
42139
- package: "#a855f7",
42140
- sensor: "#8b5cf6",
42141
- control: "#10b981",
42142
- genericDetection: "#64748b"
42143
- };
42144
- var DETECTION_SUB_COLORS = {
42145
- car: "#f59e0b",
42146
- truck: "#d97706",
42147
- bus: "#b45309",
42148
- motorcycle: "#eab308",
42149
- bicycle: "#ca8a04",
42150
- airplane: "#60a5fa",
42151
- boat: "#2563eb",
42152
- train: "#1d4ed8",
42153
- bird: "#14b8a6",
42154
- dog: "#84cc16",
42155
- cat: "#f97316",
42156
- horse: "#a16207",
42157
- sheep: "#a3a3a3",
42158
- cow: "#78716c",
42159
- elephant: "#6b7280",
42160
- bear: "#7c2d12",
42161
- zebra: "#404040",
42162
- giraffe: "#d4a373"
42163
- };
44529
+ var BUNDLED_PALETTE = bundledCamstack();
44530
+ function kindColor(kind) {
44531
+ return paintHex(BUNDLED_PALETTE.swatches, BUNDLED_PALETTE.fallbacks, kind);
44532
+ }
44533
+ function firstFallback(fallbacks) {
44534
+ const hex = fallbacks[0];
44535
+ if (hex === void 0) throw new Error("display palette has no fallback colour");
44536
+ return hex;
44537
+ }
44538
+ firstFallback(BUNDLED_PALETTE.fallbacks);
42164
44539
  function titleCase(id) {
42165
44540
  return id.split(/[-_ ]/).filter((p) => p.length > 0).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(" ");
42166
44541
  }
42167
44542
  var entries$1 = /* @__PURE__ */ new Map();
42168
- function macro(kind, category, color, iconId, label) {
44543
+ function macro(kind, category, iconId, label) {
42169
44544
  entries$1.set(kind, {
42170
44545
  kind,
42171
44546
  parentKind: null,
42172
44547
  level: "macro",
42173
44548
  category,
42174
- color,
44549
+ color: kindColor(kind),
42175
44550
  iconId,
42176
44551
  labelKey: `eventKind.${kind}`,
42177
44552
  label
42178
44553
  });
42179
44554
  }
42180
- function sub(kind, parentKind, category, color, iconId, label) {
44555
+ function sub(kind, parentKind, category, iconId, label) {
42181
44556
  entries$1.set(kind, {
42182
44557
  kind,
42183
44558
  parentKind,
42184
44559
  level: "sub",
42185
44560
  category,
42186
- color,
44561
+ color: kindColor(kind),
42187
44562
  iconId,
42188
44563
  labelKey: `eventKind.${kind}`,
42189
44564
  label
42190
44565
  });
42191
44566
  }
42192
- macro("motion", "motion", TAXONOMY_COLORS.motion, "motion", "Motion");
42193
- macro("audio", "audio", TAXONOMY_COLORS.audio, "audio", "Audio");
42194
- macro("person", "detection", TAXONOMY_COLORS.person, "person", "Person");
42195
- macro("vehicle", "detection", TAXONOMY_COLORS.vehicle, "vehicle", "Vehicle");
42196
- macro("animal", "detection", TAXONOMY_COLORS.animal, "animal", "Animal");
42197
- macro("package", "package", TAXONOMY_COLORS.package, "package", "Package");
42198
- macro("sensor", "sensor", TAXONOMY_COLORS.sensor, "sensor", "Sensor");
42199
- macro("control", "control", TAXONOMY_COLORS.control, "control", "Control");
44567
+ macro("motion", "motion", "motion", "Motion");
44568
+ macro("audio", "audio", "audio", "Audio");
44569
+ macro("person", "detection", "person", "Person");
44570
+ macro("vehicle", "detection", "vehicle", "Vehicle");
44571
+ macro("animal", "detection", "animal", "Animal");
44572
+ macro("package", "package", "package", "Package");
44573
+ macro("sensor", "sensor", "sensor", "Sensor");
44574
+ macro("control", "control", "control", "Control");
42200
44575
  for (const [cocoClass, macroClass] of Object.entries(COCO_TO_MACRO.mapping)) {
42201
44576
  if (macroClass !== "vehicle" && macroClass !== "animal") continue;
42202
44577
  if (entries$1.has(cocoClass)) continue;
42203
- sub(cocoClass, macroClass, "detection", DETECTION_SUB_COLORS[cocoClass] ?? TAXONOMY_COLORS.genericDetection, cocoClass, titleCase(cocoClass));
44578
+ sub(cocoClass, macroClass, "detection", cocoClass, titleCase(cocoClass));
42204
44579
  }
42205
- sub("package-delivered", "package", "package", TAXONOMY_COLORS.package, "package", "Package delivered");
42206
- sub("package-picked-up", "package", "package", TAXONOMY_COLORS.package, "package", "Package picked up");
42207
- sub("contact", "sensor", "sensor", "#f59e0b", "door", "Contact");
42208
- sub("motion-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "pir", "Motion sensor");
42209
- sub("smoke", "sensor", "sensor", "#ef4444", "smoke", "Smoke");
42210
- sub("flood", "sensor", "sensor", "#3b82f6", "water", "Water leak");
42211
- sub("gas", "sensor", "sensor", "#ef4444", "gas", "Gas");
42212
- sub("carbon-monoxide", "sensor", "sensor", "#dc2626", "smoke", "Carbon monoxide");
42213
- sub("vibration", "sensor", "sensor", "#eab308", "vibration", "Vibration");
42214
- sub("tamper", "sensor", "sensor", "#f97316", "tamper", "Tamper");
42215
- sub("presence", "sensor", "sensor", "#22c55e", "presence", "Presence");
42216
- sub("enum-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "generic", "Sensor state");
42217
- sub("device-event", "sensor", "sensor", "#10b981", "button", "Device event");
42218
- sub("lock", "control", "control", "#0ea5e9", "lock", "Lock");
42219
- sub("cover", "control", "control", "#0ea5e9", "door", "Cover");
42220
- sub("switch", "control", "control", TAXONOMY_COLORS.control, "switch", "Switch");
42221
- sub("siren", "control", "control", "#dc2626", "siren", "Siren");
42222
- sub("button", "control", "control", "#10b981", "button", "Button");
42223
- sub("doorbell", "control", "control", "#a855f7", "doorbell", "Doorbell");
44580
+ sub("package-delivered", "package", "package", "package", "Package delivered");
44581
+ sub("package-picked-up", "package", "package", "package", "Package picked up");
44582
+ sub("contact", "sensor", "sensor", "door", "Contact");
44583
+ sub("motion-sensor", "sensor", "sensor", "pir", "Motion sensor");
44584
+ sub("smoke", "sensor", "sensor", "smoke", "Smoke");
44585
+ sub("flood", "sensor", "sensor", "water", "Water leak");
44586
+ sub("gas", "sensor", "sensor", "gas", "Gas");
44587
+ sub("carbon-monoxide", "sensor", "sensor", "smoke", "Carbon monoxide");
44588
+ sub("vibration", "sensor", "sensor", "vibration", "Vibration");
44589
+ sub("tamper", "sensor", "sensor", "tamper", "Tamper");
44590
+ sub("presence", "sensor", "sensor", "presence", "Presence");
44591
+ sub("enum-sensor", "sensor", "sensor", "generic", "Sensor state");
44592
+ sub("device-event", "sensor", "sensor", "button", "Device event");
44593
+ sub("lock", "control", "control", "lock", "Lock");
44594
+ sub("cover", "control", "control", "door", "Cover");
44595
+ sub("switch", "control", "control", "switch", "Switch");
44596
+ sub("siren", "control", "control", "siren", "Siren");
44597
+ sub("button", "control", "control", "button", "Button");
44598
+ sub("doorbell", "control", "control", "doorbell", "Doorbell");
42224
44599
  for (const l of AUDIO_MACRO_LABELS) {
42225
44600
  const kind = `audio-${l.id}`;
42226
44601
  if (entries$1.has(kind)) continue;
42227
- sub(kind, "audio", "audio", TAXONOMY_COLORS.audio, kind, l.name);
44602
+ sub(kind, "audio", "audio", kind, l.name);
42228
44603
  }
42229
44604
  /** The complete taxonomy dictionary, keyed by kind. */
42230
44605
  var EVENT_TAXONOMY = Object.freeze(Object.fromEntries(entries$1));
@@ -42491,9 +44866,6 @@ var NcSystemEventKindSchema = _enum([
42491
44866
  "device-battery-normal",
42492
44867
  "device-consumable-low",
42493
44868
  "device-consumable-normal",
42494
- "device-tank-low",
42495
- "device-tank-full",
42496
- "device-tank-normal",
42497
44869
  "stream-online",
42498
44870
  "stream-offline",
42499
44871
  "node-online",
@@ -42540,13 +44912,14 @@ var NcSystemEventKindSchema = _enum([
42540
44912
  "camera-enabled"
42541
44913
  ]);
42542
44914
  /** The legacy tail of {@link NcSystemEventKindSchema} — see its docblock. */
42543
- var NC_LEGACY_SYSTEM_EVENT_KINDS = new Set([
44915
+ var NC_LEGACY_SYSTEM_EVENT_KINDS = [
42544
44916
  "camera-online",
42545
44917
  "camera-offline",
42546
44918
  "camera-disabled",
42547
44919
  "camera-enabled"
42548
- ]);
42549
- NcSystemEventKindSchema.options.filter((kind) => !NC_LEGACY_SYSTEM_EVENT_KINDS.has(kind));
44920
+ ];
44921
+ var NC_LEGACY_SYSTEM_EVENT_KIND_SET = new Set(NC_LEGACY_SYSTEM_EVENT_KINDS);
44922
+ NcSystemEventKindSchema.options.filter((kind) => !NC_LEGACY_SYSTEM_EVENT_KIND_SET.has(kind));
42550
44923
  /**
42551
44924
  * The panel's transitions, as ONE list.
42552
44925
  *
@@ -43069,7 +45442,7 @@ var NcConditionsSchema = object({
43069
45442
  * with the list under it is worse than no switch (D62).
43070
45443
  *
43071
45444
  * MEMBERS ARE FACE-GALLERY `Identity.id`s (uuid), not display names. A name is
43072
- * renameable, and a rule authored on "Gianluca" went silently dark the moment
45445
+ * renameable, and a rule authored on "Alice" went silently dark the moment
43073
45446
  * the operator fixed the spelling. The id reaches the record on
43074
45447
  * `LabelAttribution.identityId`; the name is what the editor shows and what
43075
45448
  * `{{label}}` renders.
@@ -43620,7 +45993,7 @@ var NcRulePatchSchema = NcRuleInputSchema.partial().extend({
43620
45993
  * A rule scoped to one camera and one zone silently became a rule that
43621
45994
  * matches EVERY event on EVERY camera, and lost its `media` policy
43622
45995
  * (zoneCrop / gif / clip / frame) and its `priority` at the same time. Seen
43623
- * live on 2026-08-12: a rule scoped to device 617 fired on 590 and 615
45996
+ * live on 2026-08-12: a rule scoped to device 102 fired on 104 and 101
43624
45997
  * within a minute of a two-field patch.
43625
45998
  *
43626
45999
  * So every defaulted field is re-declared here WITHOUT its default. The
@@ -43665,18 +46038,11 @@ var NcRuleSchema = NcRuleInputSchema.extend({
43665
46038
  */
43666
46039
  disabledTargetIds: array(string()).default([])
43667
46040
  });
43668
- /**
43669
- * The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
43670
- * report a still-true state. `addons` is the crash-looped addons only and
43671
- * `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
43672
- * job is not an open state, and the alarm stays instant.
43673
- */
43674
46041
  var NcStateSummarySectionIdSchema = _enum([
43675
46042
  "device-state",
43676
46043
  "streams",
43677
46044
  "battery",
43678
46045
  "consumables",
43679
- "tanks",
43680
46046
  "detection-blind",
43681
46047
  "nodes",
43682
46048
  "addons",
@@ -45440,7 +47806,7 @@ var LabelAttributionSchema = object({
45440
47806
  * `Identity.id` or a plate-gallery `Vehicle.id` (both `randomUUID`).
45441
47807
  *
45442
47808
  * The text alone is a DISPLAY NAME, and a display name is renameable: a
45443
- * notification rule authored on "Gianluca" stopped matching the moment the
47809
+ * notification rule authored on "Alice" stopped matching the moment the
45444
47810
  * operator fixed the spelling in the gallery, and nothing said so. The id is
45445
47811
  * the thing that does not move, so it is what a rule matches on
45446
47812
  * (`NcConditions.identities`) and the text is what a human is shown.
@@ -47979,7 +50345,7 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
47979
50345
  /**
47980
50346
  * Root-supplied detections for the tree's ROOT step (D730). Set by
47981
50347
  * `runDetailSubtree` when the camera's root model supplies a crop-kind
47982
- * step (a Frigate+ `license_plate` for `plate-detection`): the step is
50348
+ * step (a plus catalog `license_plate` for `plate-detection`): the step is
47983
50349
  * NOT inferred, these boxes are its output, and its children (the plate
47984
50350
  * reader) run on them through their own crop policy. Boxes are in the
47985
50351
  * PIXELS of the image this call carries. Absent ⇒ the root step runs.
@@ -49612,7 +51978,7 @@ var RunnerCameraConfigSchema = object({
49612
51978
  * detection session that asks for history. What shipped was a last-moment
49613
51979
  * discard — `FrameSlot`'s throttle compares wall clocks, and ~4 s of media
49614
51980
  * arriving inside a few hundred ms of wall clock looks to it like one frame's
49615
- * worth. Device 617, 2026-09-08: a re-run of the SAME model over the stored
51981
+ * worth. Device 102, 2026-09-08: a re-run of the SAME model over the stored
49616
51982
  * recording scored the subject `vehicle 0.5669` — above the 0.50 floor —
49617
51983
  * 1.68 s BEFORE the live track was born, on a frame that was in the pre-roll,
49618
51984
  * was decoded, and was freed.
@@ -51642,7 +54008,7 @@ method(_void(), ProviderInfoSchema, { auth: "admin" }), method(object({ config:
51642
54008
  * The signals a device can emit to WAKE its own stream.
51643
54009
  *
51644
54010
  * A camera whose stream is built on demand sleeps until something asks for it,
51645
- * and "something" cannot be a consumer that is merely attached — a Frigate-style
54011
+ * and "something" cannot be a consumer that is merely attached — a external-catalog
51646
54012
  * puller holds a session open for ever, and treating that as demand would keep
51647
54013
  * a battery camera awake for ever, which is the whole thing the battery is for
51648
54014
  * (D173). So the wake has to come from the CAMERA: an event it noticed by
@@ -52329,7 +54695,7 @@ var ClipSchema = object({
52329
54695
  * {@link MAX_CLIP_EVENT_IDS}. Empty on footage-only clips.
52330
54696
  *
52331
54697
  * Bounded because it is not a payload the surface pages through: one visit on
52332
- * device 615 carried 2 345 ids, and `eventIds` was 99% of a 153 KB
54698
+ * device 101 carried 2 345 ids, and `eventIds` was 99% of a 153 KB
52333
54699
  * camera-day. Read {@link eventCount} for the true total.
52334
54700
  */
52335
54701
  eventIds: array(string()).optional(),
@@ -52474,7 +54840,7 @@ var ClipPlaybackSchema = object({
52474
54840
  * camera has no recordings", which is the defect this whole line of work is
52475
54841
  * about: a battery camera nobody woke (`sleeping`), a camera that could not be
52476
54842
  * reached at all (`unreachable`, also what a provider that THREW reports), a
52477
- * camera whose SD card is not mounted (`no-storage`, measured on 640 —
54843
+ * camera whose SD card is not mounted (`no-storage`, measured on 106 —
52478
54844
  * `HddInfo mount 0`, honestly nothing to list rather than "no clips"), and a
52479
54845
  * camera whose OWN index disagrees with its OWN calendar (`index-empty`,
52480
54846
  * measured on 618: the calendar marks 3–20 September, days 6–20 list zero
@@ -52739,7 +55105,7 @@ DeviceType.Camera, method(object({
52739
55105
  *
52740
55106
  * It was optional, documented as "absent means the device's BOUND
52741
55107
  * provider, which is CamStack on every camera". No code implemented
52742
- * that. Measured on the live hub 2026-09-20 — device 592, bound to
55108
+ * that. Measured on the live hub 2026-09-20 — device 107, bound to
52743
55109
  * `recorder` AND `provider-reolink` — a bare call with `limit: 3`
52744
55110
  * answered SIX rows, three from each source, merged newest-first:
52745
55111
  * `device-collection-dispatch.ts` simply left the fan-out un-narrowed,
@@ -53817,7 +56183,10 @@ object({
53817
56183
  DeviceType.Sensor;
53818
56184
  object({
53819
56185
  /** Current illuminance in lux (lx). */
53820
- lux: number().min(0),
56186
+ lux: number().min(0).meta({
56187
+ unit: "lx",
56188
+ label: "Illuminance"
56189
+ }),
53821
56190
  /** Ms epoch when the slice was last updated. */
53822
56191
  lastFetchedAt: number(),
53823
56192
  /** Live display unit from the upstream source (e.g. HA
@@ -53973,7 +56342,10 @@ var BatteryStatusSchema = object({
53973
56342
  * Consumers must SKIP a null rather than coerce it — `battery-band` already
53974
56343
  * declines to band a non-finite reading, which is the correct shape.
53975
56344
  */
53976
- percentage: number().min(0).max(100).nullable(),
56345
+ percentage: number().min(0).max(100).nullable().meta({
56346
+ unit: "%",
56347
+ label: "Charge"
56348
+ }),
53977
56349
  /**
53978
56350
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
53979
56351
  * Reolink-specific for the Solar Panel 2 accessory (will become
@@ -53992,13 +56364,13 @@ var BatteryStatusSchema = object({
53992
56364
  "solar",
53993
56365
  "none",
53994
56366
  "unknown"
53995
- ]),
56367
+ ]).meta({ label: "Charging source" }),
53996
56368
  /**
53997
56369
  * True when the camera firmware has gone into low-power mode. Battery
53998
56370
  * providers MUST avoid polling during sleep — reading the battery
53999
56371
  * wakes the camera up and drains charge.
54000
56372
  */
54001
- sleeping: boolean(),
56373
+ sleeping: boolean().meta({ label: "Sleeping" }),
54002
56374
  /** Ms epoch of the last observation. Lets consumers reason about freshness. */
54003
56375
  lastUpdated: number(),
54004
56376
  /**
@@ -54038,9 +56410,10 @@ var BatteryStatusSchema = object({
54038
56410
  * sub-threshold = low). UI MUST render "Normal"/"Low" instead of a
54039
56411
  * misleading exact percentage. Absent/false → genuine 0–100 % reading.
54040
56412
  */
54041
- binary: boolean().optional()
56413
+ binary: boolean().optional().meta({ label: "Binary indicator" })
54042
56414
  });
54043
- DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, method(object({
56415
+ DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat;
56416
+ method(object({
54044
56417
  deviceId: number(),
54045
56418
  /** Bound on the wait. Sensible range 3000–10000ms. */
54046
56419
  timeoutMs: number().int().min(500).max(3e4).default(8e3)
@@ -54052,7 +56425,7 @@ DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, Devi
54052
56425
  status: BatteryStatusSchema
54053
56426
  });
54054
56427
  object({
54055
- on: boolean(),
56428
+ on: boolean().meta({ label: "On" }),
54056
56429
  /** Ms epoch of the last transition. 0 if never observed. */
54057
56430
  lastChangedAt: number()
54058
56431
  });
@@ -54320,7 +56693,7 @@ var GridLayoutCellSchema = object({
54320
56693
  *
54321
56694
  * A grid's `high` composes its sources' `high` and its `low` their `low`, so a
54322
56695
  * profile is on offer only when EVERY source can serve it. The refusal NAMES
54323
- * the sources, because "this grid has no low" is not a finding — "615 has no
56696
+ * the sources, because "this grid has no low" is not a finding — "101 has no
54324
56697
  * low" is, and it is the one an operator can act on.
54325
56698
  */
54326
56699
  var GridProfileOfferSchema = object({
@@ -54759,6 +57132,7 @@ var ConsumablesStatusSchema = object({
54759
57132
  })),
54760
57133
  lastChangedAt: number()
54761
57134
  });
57135
+ Object.values(DeviceType), [...ConsumableRemainingUnitSchema.options], [...ConsumableStatusSchema.options], [...ConsumableKindSchema.options], [...ConsumableFormSchema.options];
54762
57136
  Object.values(DeviceType), method(object({
54763
57137
  deviceId: number().int().nonnegative(),
54764
57138
  key: string().min(1)
@@ -54951,6 +57325,30 @@ DeviceType.Camera, method(object({ deviceId: number() }), DayNightOptionsSchema)
54951
57325
  auth: "admin"
54952
57326
  });
54953
57327
  /**
57328
+ * display-palette — the cluster's one colour table (D939).
57329
+ *
57330
+ * Hub singleton. `getPalette` reports `unknown` when the settings store
57331
+ * cannot be read; it does not pretend the bundled preset was stored.
57332
+ * `setPalette` refuses a palette that fails the ΔE / contrast rule and names
57333
+ * the pairs.
57334
+ */
57335
+ var presetSummarySchema = object({
57336
+ id: string(),
57337
+ name: string(),
57338
+ swatches: record(string(), paletteSwatchSchema),
57339
+ fallbacks: array(string())
57340
+ });
57341
+ method(_void(), paletteResultSchema, {
57342
+ auth: "protected",
57343
+ role: "viewer"
57344
+ }), method(_void(), array(presetSummarySchema).readonly(), {
57345
+ auth: "protected",
57346
+ role: "viewer"
57347
+ }), method(setPaletteInputSchema, paletteReadySchema, {
57348
+ kind: "mutation",
57349
+ auth: "admin"
57350
+ });
57351
+ /**
54954
57352
  * Generic device-level status snapshot. Auto-registered by `BaseDevice`
54955
57353
  * for every device, regardless of provider — the kernel needs a uniform
54956
57354
  * cap-keyed slice for the basic device flags every consumer expects to
@@ -55230,6 +57628,7 @@ DeviceType.Dishwasher, method(object({
55230
57628
  kind: "mutation",
55231
57629
  auth: "protected"
55232
57630
  }), method(object({ deviceId: DeviceIdSchema }), DishwasherOptionsSchema, { auth: "protected" });
57631
+ DeviceType.Camera;
55233
57632
  object({
55234
57633
  /** Ms epoch of the last press. null = never observed since this provider started. */
55235
57634
  lastPressedAt: number().nullable(),
@@ -55845,7 +58244,10 @@ DeviceType.Humidifier, method(object({
55845
58244
  });
55846
58245
  object({
55847
58246
  /** Current relative humidity, 0..100. */
55848
- percent: number().min(0).max(100),
58247
+ percent: number().min(0).max(100).meta({
58248
+ unit: "%",
58249
+ label: "Humidity"
58250
+ }),
55849
58251
  /** Ms epoch when the slice was last updated. */
55850
58252
  lastFetchedAt: number(),
55851
58253
  /** Live display unit from the upstream source (e.g. HA
@@ -57022,6 +59424,7 @@ authKey: string().optional() }), object({
57022
59424
  /** Human-readable error when `ok: false`. */
57023
59425
  error: string().optional()
57024
59426
  }), { kind: "mutation" });
59427
+ DeviceType.Camera;
57025
59428
  object({
57026
59429
  detected: boolean(),
57027
59430
  /** Ms epoch of the last detected-true observation. Null if never detected. */
@@ -58621,9 +61024,15 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
58621
61024
  });
58622
61025
  object({
58623
61026
  /** Instantaneous power draw in watts. */
58624
- watts: number().optional(),
61027
+ watts: number().optional().meta({
61028
+ unit: "W",
61029
+ label: "Power"
61030
+ }),
58625
61031
  /** Cumulative energy in kilowatt-hours since the meter was reset. */
58626
- kwhTotal: number().optional(),
61032
+ kwhTotal: number().optional().meta({
61033
+ unit: "kWh",
61034
+ label: "Energy"
61035
+ }),
58627
61036
  /** Voltage in volts. */
58628
61037
  volts: number().optional(),
58629
61038
  /** Current in amperes. */
@@ -58942,9 +61351,9 @@ var PtzOptionsSchema = object({
58942
61351
  * Reolink preset 0, Hikvision preset '1', Dahua preset 1 -- and on this fleet
58943
61352
  * not one of the three cameras honours its own:
58944
61353
  *
58945
- * 592 Videocamera camera Daniel (reolink) preset 0 holds "stanza"
58946
- * 1438 Videocamera dispensa (hikvision) preset 1 holds "Credenza"
58947
- * 3836 Videocamera studio (amcrest) preset 1 holds "Preset1"
61354
+ * 107 Camera camera Carol (reolink) preset 0 holds "stanza"
61355
+ * 1438 Camera dispensa (hikvision) preset 1 holds "Credenza"
61356
+ * 3836 Camera studio (amcrest) preset 1 holds "Preset1"
58948
61357
  *
58949
61358
  * So `goHome` meant "go wherever the operator happened to save in slot 0 or 1",
58950
61359
  * and two of the three swallowed the failure in a bare `catch`. For autotrack
@@ -59085,6 +61494,24 @@ DeviceType.Camera, method(object({ deviceId: number() }), PtzAutotrackStatusSche
59085
61494
  deviceId: number(),
59086
61495
  status: PtzAutotrackStatusSchema
59087
61496
  });
61497
+ var RunningStateSourceSchema = _enum(["native", "assigned"]);
61498
+ object({
61499
+ /** null = unknown — never coerced to false (D393). */
61500
+ running: boolean().nullable(),
61501
+ /** Epoch ms the current boolean began; null while `running` is null. */
61502
+ since: number().nullable(),
61503
+ source: RunningStateSourceSchema.meta({ label: "Source" }),
61504
+ phase: string().nullable(),
61505
+ /** null until a reading has been published (D393). */
61506
+ lastFetchedAt: number().nullable()
61507
+ });
61508
+ object({
61509
+ deviceId: number(),
61510
+ since: number().nullable(),
61511
+ phase: string().nullable()
61512
+ });
61513
+ Object.values(DeviceType);
61514
+ DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
59088
61515
  DeviceType.Camera, DeviceType.Sensor, DeviceType.Switch, method(object({ deviceId: number().int().nonnegative() }), object({ success: literal(true) }), {
59089
61516
  kind: "mutation",
59090
61517
  auth: "admin"
@@ -59126,7 +61553,7 @@ var RecordingAvailabilitySchema = object({
59126
61553
  * would look identical. But the answer used to say nothing about that, so a
59127
61554
  * caller asking "what can I export?" read the single preferred profile as
59128
61555
  * the only one that exists — on this deployment every camera records `high`
59129
- * AND `low`, the low tree holding 14 GB for camera 615 alone, and the export
61556
+ * AND `low`, the low tree holding 14 GB for camera 101 alone, and the export
59130
61557
  * UI could not see it.
59131
61558
  *
59132
61559
  * Cheap: it is the same shallow directory read the profile CHOICE already
@@ -59225,7 +61652,7 @@ var RecordingSourceOptionsSchema = object({
59225
61652
  * `sparse` = gaps are the absence of one, and must be drawn as such.
59226
61653
  *
59227
61654
  * Not an onboard-only concession: measured 2026-09-24, OUR bar covers 98.8 %
59228
- * of 592's day and 1.2 % of 1436's. It is a fact about a (source, camera)
61655
+ * of 107's day and 1.2 % of 1436's. It is a fact about a (source, camera)
59229
61656
  * pair, and ours answers it per camera from `deriveRecordingMode`. */
59230
61657
  coverage: _enum(["continuous", "sparse"]),
59231
61658
  /** Where the playhead may be put.
@@ -59301,7 +61728,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(RecordingSourceS
59301
61728
  * merely discouraged (D554 amended).
59302
61729
  *
59303
61730
  * It was learned the expensive way on `videoclips.listClips`: measured
59304
- * on the live hub 2026-09-20, device 592 bound to `recorder` AND
61731
+ * on the live hub 2026-09-20, device 107 bound to `recorder` AND
59305
61732
  * `provider-reolink`, a bare call with `limit: 3` answered SIX rows,
59306
61733
  * three from each source, merged — `device-collection-dispatch.ts`
59307
61734
  * leaves an unpinned fan-out un-narrowed, so absence buys the union the
@@ -59902,7 +62329,7 @@ var ExportSpeedSchema = number().min(.25).max(32);
59902
62329
  * on a 10 h window holding 29,393 s of footage every range landed late by the
59903
62330
  * gap accumulated before it — up to 6,607 s, well past EOF. Nothing matched,
59904
62331
  * the video was a uniform timelapse, and the log line reported the five ranges
59905
- * that had been ASKED for (2026-08-13, export `57d14363`, camera 615).
62332
+ * that had been ASKED for (2026-08-13, export `57d14363`, camera 101).
59906
62333
  *
59907
62334
  * Relative and not absolute epoch, because an absolute epoch would make every
59908
62335
  * call site responsible for the same subtraction.
@@ -60536,7 +62963,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), RecordingSignalStatusS
60536
62963
  * which put a "Scenes" tab on one camera's detail page. That is the wrong shape
60537
62964
  * for the thing: a scene is a standing question about the property ("is the bin
60538
62965
  * still out"), and the operator's question is "which of my scenes have tripped",
60539
- * across every camera at once — not "what does camera 617 think". Buried one
62966
+ * across every camera at once — not "what does camera 102 think". Buried one
60540
62967
  * camera deep it also could not be found. The surface is now a top-level admin
60541
62968
  * page (`/scenes`, `pages/Scenes.tsx`) that lists every scene on every camera and
60542
62969
  * picks the camera inside the create flow, the same shape Events and Faces have.
@@ -61119,7 +63546,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), StreamParamsOptionsSch
61119
63546
  auth: "admin"
61120
63547
  }), method(object({ deviceId: number() }), unknown().nullable());
61121
63548
  object({
61122
- on: boolean(),
63549
+ on: boolean().meta({ label: "On" }),
61123
63550
  /** Ms epoch of the last state change. Useful for UI "X minutes ago". */
61124
63551
  lastChangedAt: number()
61125
63552
  });
@@ -61682,7 +64109,10 @@ object({
61682
64109
  DeviceType.Sensor;
61683
64110
  object({
61684
64111
  /** Current temperature in Celsius. */
61685
- celsius: number(),
64112
+ celsius: number().meta({
64113
+ unit: "°C",
64114
+ label: "Temperature"
64115
+ }),
61686
64116
  /** Ms epoch when the slice was last updated (push or poll). */
61687
64117
  lastFetchedAt: number(),
61688
64118
  /** Live display unit from the upstream source (e.g. HA
@@ -62830,6 +65260,10 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
62830
65260
  auth: "admin"
62831
65261
  });
62832
65262
  SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
65263
+ DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Camera, DeviceType.Camera, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
65264
+ String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
65265
+ DeviceRole.BinarySensor, DeviceRole.MotionSensor;
65266
+ new Set(CAP_NAMES);
62833
65267
  Object.freeze({
62834
65268
  person: .5,
62835
65269
  vehicle: .5,
@@ -65829,6 +68263,27 @@ Object.freeze({
65829
68263
  access: "create",
65830
68264
  role: "viewer"
65831
68265
  },
68266
+ "displayPalette.getPalette": {
68267
+ capName: "display-palette",
68268
+ capScope: "system",
68269
+ addonId: null,
68270
+ access: "view",
68271
+ role: "viewer"
68272
+ },
68273
+ "displayPalette.listPresets": {
68274
+ capName: "display-palette",
68275
+ capScope: "system",
68276
+ addonId: null,
68277
+ access: "view",
68278
+ role: "viewer"
68279
+ },
68280
+ "displayPalette.setPalette": {
68281
+ capName: "display-palette",
68282
+ capScope: "system",
68283
+ addonId: null,
68284
+ access: "create",
68285
+ role: "admin"
68286
+ },
65832
68287
  "doorbell.getStatus": {
65833
68288
  capName: "doorbell",
65834
68289
  capScope: "device",
@@ -70379,6 +72834,13 @@ Object.freeze({
70379
72834
  access: "create",
70380
72835
  role: "admin"
70381
72836
  },
72837
+ "runningState.getStatus": {
72838
+ capName: "running-state",
72839
+ capScope: "device",
72840
+ addonId: null,
72841
+ access: "view",
72842
+ role: "viewer"
72843
+ },
70382
72844
  "sceneMonitor.captureReference": {
70383
72845
  capName: "scene-monitor",
70384
72846
  capScope: "device",
@@ -75093,6 +77555,32 @@ var APPLIANCE_CAP_VOCABULARY = {
75093
77555
  }],
75094
77556
  events: { onSent: { notOperatorFacing: "a delivery receipt of a send this system made — not a fact about the world" } }
75095
77557
  },
77558
+ "running-state": {
77559
+ scope: "device",
77560
+ noun: t("Running", "In funzione"),
77561
+ state: [{
77562
+ kind: "boolean",
77563
+ field: "running",
77564
+ label: t("Running", "In funzione"),
77565
+ whenTrue: t("When {device} starts", "Quando {device} inizia"),
77566
+ whenFalse: t("When {device} finishes", "Quando {device} finisce"),
77567
+ icon: "play"
77568
+ }],
77569
+ events: {
77570
+ onStarted: {
77571
+ category: EventCategory.RunningStarted,
77572
+ label: t("Started running", "Ha iniziato a funzionare"),
77573
+ phrase: t("When {device} starts running", "Quando {device} inizia a funzionare"),
77574
+ icon: "play"
77575
+ },
77576
+ onFinished: {
77577
+ category: EventCategory.RunningFinished,
77578
+ label: t("Finished", "Ha finito"),
77579
+ phrase: t("When {device} finishes", "Quando {device} finisce"),
77580
+ icon: "square"
77581
+ }
77582
+ }
77583
+ },
75096
77584
  update: {
75097
77585
  scope: "device",
75098
77586
  noun: t("Firmware update", "Aggiornamento firmware"),
@@ -75713,7 +78201,7 @@ var SENSOR_CAP_VOCABULARY = {
75713
78201
  state: [{
75714
78202
  kind: "boolean",
75715
78203
  field: "on",
75716
- label: t("Active", "Attivo"),
78204
+ label: t("On", "Acceso"),
75717
78205
  whenTrue: t("When {device} turns active", "Quando {device} si attiva"),
75718
78206
  whenFalse: t("When {device} turns inactive", "Quando {device} si disattiva"),
75719
78207
  icon: "toggle-right"
@@ -76252,6 +78740,7 @@ var SYSTEM_CAP_VOCABULARY = {
76252
78740
  "device-provider": system(INTERNAL),
76253
78741
  "device-removal-hook": system(INTERNAL),
76254
78742
  "device-state": system("the runtime-state mirror every trigger already reads through"),
78743
+ "display-palette": system("the cluster display palette — one colour table for every client, not a device action"),
76255
78744
  "embedding-encoder": system(ML),
76256
78745
  "face-gallery": system("the face gallery — curated on its own page"),
76257
78746
  "failure-contribution": system(INTERNAL),
@@ -78633,6 +81122,11 @@ Object.freeze({
78633
81122
  form: "single",
78634
81123
  optional: true
78635
81124
  }],
81125
+ "runningState.getStatus": [{
81126
+ name: "deviceId",
81127
+ form: "single",
81128
+ optional: false
81129
+ }],
78636
81130
  "sceneMonitor.captureReference": [{
78637
81131
  name: "deviceId",
78638
81132
  form: "single",
@@ -79131,6 +81625,94 @@ Object.freeze({
79131
81625
  "smtp-provider": "email"
79132
81626
  });
79133
81627
  DeviceType.Camera;
81628
+ /**
81629
+ * A saved Customize assignment (D936). The schema is the type: callers use
81630
+ * `z.infer`, they do not restate the shape.
81631
+ */
81632
+ var OverrideSourceSchema = object({
81633
+ addonId: string().min(1),
81634
+ stableId: string().min(1),
81635
+ cap: string().min(1),
81636
+ fieldPath: string().min(1)
81637
+ });
81638
+ var CustomizeTransformDraftSchema = discriminatedUnion("kind", [
81639
+ object({ kind: literal("identity") }),
81640
+ object({ kind: literal("invert") }),
81641
+ object({
81642
+ kind: literal("threshold"),
81643
+ comparison: _enum(["gte", "lte"]),
81644
+ threshold: number(),
81645
+ startDwellMs: number().nonnegative(),
81646
+ stopDwellMs: number().nonnegative()
81647
+ }),
81648
+ object({
81649
+ kind: literal("linear"),
81650
+ scale: number(),
81651
+ offset: number(),
81652
+ clampMin: number().optional(),
81653
+ clampMax: number().optional()
81654
+ }),
81655
+ object({
81656
+ kind: literal("enum-map"),
81657
+ mapping: record(string(), string().nullable())
81658
+ }),
81659
+ object({ kind: literal("number") })
81660
+ ]);
81661
+ var ScalarOverrideDraftSchema = object({
81662
+ kind: literal("scalar"),
81663
+ cap: string().min(1),
81664
+ targetId: string().min(1),
81665
+ source: OverrideSourceSchema,
81666
+ transform: CustomizeTransformDraftSchema
81667
+ });
81668
+ var KeyedArrayOverrideDraftSchema = object({
81669
+ kind: literal("keyedArray"),
81670
+ cap: string().min(1),
81671
+ targetId: string().min(1),
81672
+ key: string().min(1),
81673
+ label: string().min(1),
81674
+ fieldPath: string().min(1),
81675
+ source: OverrideSourceSchema,
81676
+ transform: CustomizeTransformDraftSchema
81677
+ });
81678
+ var PulseOverrideDraftSchema = object({
81679
+ kind: literal("pulse"),
81680
+ cap: string().min(1),
81681
+ targetId: string().min(1),
81682
+ enabled: boolean(),
81683
+ debounceMs: number().nonnegative(),
81684
+ sources: array(OverrideSourceSchema).min(1)
81685
+ });
81686
+ var SpanSourceDraftSchema = OverrideSourceSchema.extend({ mode: _enum([
81687
+ "in-addition",
81688
+ "confirm",
81689
+ "replace"
81690
+ ]).optional() });
81691
+ discriminatedUnion("kind", [
81692
+ ScalarOverrideDraftSchema,
81693
+ KeyedArrayOverrideDraftSchema,
81694
+ PulseOverrideDraftSchema,
81695
+ object({
81696
+ kind: literal("span"),
81697
+ cap: string().min(1),
81698
+ targetId: string().min(1),
81699
+ timeoutMs: number().nonnegative(),
81700
+ cooldownMs: number().nonnegative().optional(),
81701
+ sources: array(SpanSourceDraftSchema)
81702
+ })
81703
+ ]);
81704
+ object({
81705
+ targetId: string().min(1),
81706
+ configured: boolean(),
81707
+ source: _enum(["native", "assigned"]),
81708
+ state: _enum([
81709
+ "active",
81710
+ "stale",
81711
+ "released",
81712
+ "unavailable"
81713
+ ]),
81714
+ reason: string().nullable()
81715
+ });
79134
81716
  var G711_SCALE_CORRECTION_DB = {
79135
81717
  PCMU: 20 * Math.log10(4),
79136
81718
  PCMA: 20 * Math.log10(8)
@@ -79183,40 +81765,7 @@ var NC_AUDIO_DEFAULTS = {
79183
81765
  samplingSeconds: 10
79184
81766
  };
79185
81767
  new Set(["devices", "classes"]);
79186
- /**
79187
- * WHICH narrowing filter speaks about WHICH system-event kind — one predicate,
79188
- * consumed by the rule ENGINE and by every rule EDITOR.
79189
- *
79190
- * ── The failure this file exists for ───────────────────────────────────────
79191
- * `NcSystemEventConditionSchema` carries four optional narrowing lists
79192
- * (`deviceIds`, `deviceTypes`, `nodeIds`, `packageNames`) beside a required
79193
- * `kinds` gate. They are not four filters over one vocabulary: each belongs to
79194
- * a FAMILY of kinds and is meaningless outside it. A node going away has no
79195
- * device type; a completed export has no package; `stream-offline` deliberately
79196
- * carries no device type at all (a stream belongs to a camera by construction).
79197
- *
79198
- * The engine applied all four to every kind, so a filter from one family failed
79199
- * a kind from another family CLOSED. The operator's live rule "Eventi di
79200
- * sistema" selected eleven kinds and set `deviceTypes: ['camera']` — the only
79201
- * way to say "only my cameras" about the two liveness kinds — and NINE of the
79202
- * eleven silently stopped being deliverable. Four days of history contained
79203
- * `device-online` and `device-offline` and nothing else, across a window in
79204
- * which agents were restarted and addons were updated.
79205
- *
79206
- * Both editors already computed this scoping, to decide which filter boxes to
79207
- * render; the cap's own docblock already promised it ("Narrow a `device-*` kind
79208
- * to these device TYPES"). Only the engine disagreed, and it disagreed in the
79209
- * destructive direction. So the rule is stated ONCE, here, and the engine and
79210
- * the editors are readers of it rather than three independent authors.
79211
- *
79212
- * ── The direction ─────────────────────────────────────────────────────────
79213
- * Out of family ⇒ the filter is IGNORED, never fail-closed. An editor that
79214
- * hides a box has already told the operator this filter does not speak about
79215
- * these kinds, so honouring it as an exclusion contradicts the only
79216
- * explanation the operator was ever given. Inside its family the filter still
79217
- * narrows, and still fails CLOSED on a subject that cannot produce the identity
79218
- * it tests (a device the mirror cannot name is not evidence of a camera).
79219
- */
81768
+ new Set(NC_LEGACY_SYSTEM_EVENT_KINDS);
79220
81769
  /**
79221
81770
  * Every filter, for the callers that must cover all of them (guards, tests).
79222
81771
  *
@@ -79242,9 +81791,6 @@ new Map(Object.entries({
79242
81791
  "device-battery-normal": "device-events",
79243
81792
  "device-consumable-low": "device-events",
79244
81793
  "device-consumable-normal": "device-events",
79245
- "device-tank-low": "device-events",
79246
- "device-tank-full": "device-events",
79247
- "device-tank-normal": "device-events",
79248
81794
  "stream-online": "device-events",
79249
81795
  "stream-offline": "device-events",
79250
81796
  "detection-blind": "device-events",
@@ -79321,16 +81867,6 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
79321
81867
  label: "Consumables",
79322
81868
  kinds: ["device-consumable-low", "device-consumable-normal"]
79323
81869
  },
79324
- {
79325
- id: "tanks",
79326
- family: "device-events",
79327
- label: "Tanks",
79328
- kinds: [
79329
- "device-tank-low",
79330
- "device-tank-full",
79331
- "device-tank-normal"
79332
- ]
79333
- },
79334
81870
  {
79335
81871
  id: "detection-blind",
79336
81872
  family: "device-events",
@@ -79488,11 +82024,6 @@ var RULE_BODY_ONLY = ["body"];
79488
82024
  var RULE_TEXT = ["title", "body"];
79489
82025
  var BATTERY = ["device-battery-low", "device-battery-normal"];
79490
82026
  var CONSUMABLE = ["device-consumable-low", "device-consumable-normal"];
79491
- var TANK = [
79492
- "device-tank-low",
79493
- "device-tank-full",
79494
- "device-tank-normal"
79495
- ];
79496
82027
  var ALERT_EPISODE = [
79497
82028
  "alert-critical",
79498
82029
  "alert-error",
@@ -79524,7 +82055,6 @@ var DEVICE_EVENTS = [
79524
82055
  "device-enabled",
79525
82056
  ...BATTERY,
79526
82057
  ...CONSUMABLE,
79527
- ...TANK,
79528
82058
  "stream-online",
79529
82059
  "stream-offline",
79530
82060
  "detection-blind",
@@ -79555,7 +82085,7 @@ var STATE_SUMMARY_SECTION_VARS = [
79555
82085
  {
79556
82086
  name: "summaryStreams",
79557
82087
  label: "Summary: streams offline",
79558
- example: "Ingresso (high) — since 06:40",
82088
+ example: "Front door (high) — since 06:40",
79559
82089
  kinds: ["stream-offline", "stream-online"]
79560
82090
  },
79561
82091
  {
@@ -79570,22 +82100,16 @@ var STATE_SUMMARY_SECTION_VARS = [
79570
82100
  example: "Robot — filter 10 %",
79571
82101
  kinds: CONSUMABLE
79572
82102
  },
79573
- {
79574
- name: "summaryTanks",
79575
- label: "Summary: tanks",
79576
- example: "Robot — clean water low",
79577
- kinds: TANK
79578
- },
79579
82103
  {
79580
82104
  name: "summaryDetection",
79581
82105
  label: "Summary: cameras detecting nothing",
79582
- example: "Ingresso — since 05:10",
82106
+ example: "Front door — since 05:10",
79583
82107
  kinds: ["detection-blind"]
79584
82108
  },
79585
82109
  {
79586
82110
  name: "summaryNodes",
79587
82111
  label: "Summary: nodes",
79588
- example: "little-unraid — offline since 03:00",
82112
+ example: "agent-a — offline since 03:00",
79589
82113
  kinds: [
79590
82114
  "node-offline",
79591
82115
  "node-online",
@@ -79691,8 +82215,7 @@ var STATE_SUMMARY_VARS = [
79691
82215
  ([...RULE_TEXT], [...COMBINED_ALARM]),
79692
82216
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
79693
82217
  ([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
79694
- ([...RULE_TEXT], [...CONSUMABLE, ...TANK]),
79695
- ([...RULE_TEXT], [...TANK]),
82218
+ ([...RULE_TEXT], [...CONSUMABLE]),
79696
82219
  [...RULE_TEXT],
79697
82220
  ([...RULE_TEXT], [...UPDATES, ...ALERT_EPISODE]),
79698
82221
  ([...RULE_TEXT], [...UPDATES, ...ALERT_EPISODE]),
@@ -79796,15 +82319,6 @@ new Map([
79796
82319
  snapshotLabel: "Consumables low now",
79797
82320
  snapshotSection: "consumables"
79798
82321
  },
79799
- {
79800
- id: "tanks",
79801
- family: "device-events",
79802
- label: "Tanks (low or full / back to normal)",
79803
- bad: ["device-tank-low", "device-tank-full"],
79804
- recovery: ["device-tank-normal"],
79805
- snapshotLabel: "Tanks low or full now",
79806
- snapshotSection: "tanks"
79807
- },
79808
82322
  {
79809
82323
  id: "motion-noise",
79810
82324
  family: "device-events",
@@ -80794,8 +83308,8 @@ var catalog = object({
80794
83308
  }))
80795
83309
  }))
80796
83310
  }).parse({
80797
- generatedAt: "2026-10-12T16:54:36.612Z",
80798
- sourceHash: "35f2f21decca0a4beae07ec89164a2ae5ea34ff5832c440a046d79d69b5963ea",
83311
+ generatedAt: "2026-10-25T15:27:42.947Z",
83312
+ sourceHash: "08c53dc9dd3522a21dad529895ad1f92c8b0a589206b94d67b8e12fa8db0a738",
80799
83313
  entries: [
80800
83314
  {
80801
83315
  "module": "123abfallkalender_de",
@@ -88518,8 +91032,8 @@ var catalog = object({
88518
91032
  },
88519
91033
  {
88520
91034
  "module": "tower_hamlets_gov_uk",
88521
- "title": "London Borough of Tower Hamlets",
88522
- "description": "Source for London Borough of Tower Hamlets",
91035
+ "title": "London Borough of agent-a Hamlets",
91036
+ "description": "Source for London Borough of agent-a Hamlets",
88523
91037
  "url": "https://www.towerhamlets.gov.uk/",
88524
91038
  "countries": ["United Kingdom"],
88525
91039
  "argHints": { "uprn": "Property UPRN (Unique Property Reference Number)" }
@@ -142547,11 +145061,11 @@ var catalog = object({
142547
145061
  }]
142548
145062
  },
142549
145063
  {
142550
- "id": "junker_app--rocca-di-papa-dm-technology-srl",
145064
+ "id": "junker_app--rocca-di-pat-dm-technology-srl",
142551
145065
  "countryId": "italy",
142552
- "label": "Rocca di Papa - DM Technology Srl",
145066
+ "label": "Rocca di Pat - DM Technology Srl",
142553
145067
  "module": "junker_app",
142554
- "defaultArgs": { "municipality": "Rocca di Papa - DM Technology Srl" },
145068
+ "defaultArgs": { "municipality": "Rocca di Pat - DM Technology Srl" },
142555
145069
  "fields": [{
142556
145070
  "key": "area",
142557
145071
  "label": "area",
@@ -162445,6 +164959,19 @@ var catalog = object({
162445
164959
  }
162446
164960
  ]
162447
164961
  },
164962
+ {
164963
+ "id": "tower_hamlets_gov_uk--london-borough-of-agent-a-hamlets",
164964
+ "countryId": "united-kingdom",
164965
+ "label": "London Borough of agent-a Hamlets",
164966
+ "module": "tower_hamlets_gov_uk",
164967
+ "defaultArgs": {},
164968
+ "fields": [{
164969
+ "key": "uprn",
164970
+ "label": "Property UPRN (Unique Property Reference Number)",
164971
+ "required": false,
164972
+ "kind": "text"
164973
+ }]
164974
+ },
162448
164975
  {
162449
164976
  "id": "lbbd_gov_uk--london-borough-of-barking-and-dagenham",
162450
164977
  "countryId": "united-kingdom",
@@ -162691,19 +165218,6 @@ var catalog = object({
162691
165218
  "kind": "text"
162692
165219
  }]
162693
165220
  },
162694
- {
162695
- "id": "tower_hamlets_gov_uk--london-borough-of-tower-hamlets",
162696
- "countryId": "united-kingdom",
162697
- "label": "London Borough of Tower Hamlets",
162698
- "module": "tower_hamlets_gov_uk",
162699
- "defaultArgs": {},
162700
- "fields": [{
162701
- "key": "uprn",
162702
- "label": "Property UPRN (Unique Property Reference Number)",
162703
- "required": false,
162704
- "kind": "text"
162705
- }]
162706
- },
162707
165221
  {
162708
165222
  "id": "apps_imactivate_com--luton",
162709
165223
  "countryId": "united-kingdom",