@camstack/addon-waste-collections 0.1.27 → 0.1.29

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