@camstack/types 1.2.405 → 1.2.407
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/addon.js +21 -2
- package/dist/addon.mjs +21 -2
- package/dist/capabilities/battery.cap.d.ts +46 -0
- package/dist/capabilities/capability-definition.d.ts +8 -0
- package/dist/capabilities/consumables.cap.d.ts +110 -0
- package/dist/capabilities/customize-catalog.d.ts +72 -0
- package/dist/capabilities/customize-spec.d.ts +202 -0
- package/dist/capabilities/doorbell.cap.d.ts +39 -0
- package/dist/capabilities/index.d.ts +6 -4
- package/dist/capabilities/motion.cap.d.ts +39 -0
- package/dist/capabilities/notification-rules.cap.d.ts +3 -78
- package/dist/capabilities/osd-manager.cap.d.ts +0 -18
- package/dist/capabilities/running-state.cap.d.ts +140 -0
- package/dist/catalogs/sensor-active-state.d.ts +1 -1
- package/dist/client.js +11 -63
- package/dist/client.mjs +11 -63
- package/dist/composition/customize/__fixtures__/refs.d.ts +27 -0
- package/dist/composition/customize/__fixtures__/stored-cases.d.ts +13 -0
- package/dist/composition/customize/event-compile.d.ts +20 -0
- package/dist/composition/customize/event-decode.d.ts +19 -0
- package/dist/composition/customize/event-eval.d.ts +35 -0
- package/dist/composition/customize/event-status.d.ts +49 -0
- package/dist/composition/customize/field-source.d.ts +5 -0
- package/dist/composition/customize/keyed-array-compile.d.ts +26 -0
- package/dist/composition/customize/keyed-array-decode.d.ts +20 -0
- package/dist/composition/customize/keyed-array-expr.d.ts +10 -0
- package/dist/composition/customize/keyed-array-status.d.ts +22 -0
- package/dist/composition/customize/normalize.d.ts +4 -0
- package/dist/composition/customize/override-draft.d.ts +311 -0
- package/dist/composition/customize/scalar-compile.d.ts +13 -0
- package/dist/composition/customize/scalar-decode.d.ts +17 -0
- package/dist/composition/customize/scalar-expr.d.ts +33 -0
- package/dist/composition/customize/scalar-status.d.ts +31 -0
- package/dist/composition/customize/stored.d.ts +15 -0
- package/dist/composition/index.d.ts +0 -1
- package/dist/{composition-CB6PMT9p.mjs → composition-BJ8iAZb3.mjs} +87 -3
- package/dist/{composition-eoYYVfOp.js → composition-CSLSFGTO.js} +87 -3
- package/dist/device/cap-vocabulary/entries/appliances.d.ts +1 -1
- package/dist/enums/event-category.d.ts +4 -0
- package/dist/enums.js +1 -1
- package/dist/enums.mjs +1 -1
- package/dist/{event-category-fDPduoeC.mjs → event-category-Ceif8n-v.mjs} +4 -0
- package/dist/{event-category-CXrwjC3e.js → event-category-DG6Vir8Z.js} +4 -0
- package/dist/expression/builtins.d.ts +7 -18
- package/dist/expression/expression-source.d.ts +14 -2
- package/dist/generated/addon-api.d.ts +14 -0
- package/dist/generated/addon-cap-facts.d.ts +1 -1
- package/dist/generated/cap-status-types.d.ts +3 -1
- package/dist/generated/capability-router-map.d.ts +5 -2
- package/dist/generated/customize-catalog.d.ts +229 -0
- package/dist/generated/device-local-state.d.ts +3 -0
- package/dist/generated/device-proxy.d.ts +3 -0
- package/dist/generated/device-scoped-caps.d.ts +1 -1
- package/dist/generated/history-catalog.d.ts +1 -1
- package/dist/generated/method-access-map.d.ts +1 -1
- package/dist/generated/method-device-selectors.d.ts +1 -1
- package/dist/generated/runtime-state-durability.d.ts +1 -1
- package/dist/index.d.ts +16 -0
- package/dist/index.js +2385 -173
- package/dist/index.mjs +2351 -171
- package/dist/interfaces/config-ui.d.ts +69 -2
- package/dist/node.js +1 -1
- package/dist/node.mjs +1 -1
- package/dist/running-state/defaults.d.ts +6 -0
- package/dist/running-state/from-operation.d.ts +14 -0
- package/dist/{sleep-CHIEEJkY.mjs → sleep-CYfIZzGv.mjs} +7 -3
- package/dist/{sleep-BKS4OPMo.js → sleep-UP964hNP.js} +7 -3
- package/package.json +1 -1
- package/dist/composition/presets/doorbell-feature.d.ts +0 -20
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_sleep = require("./sleep-
|
|
3
|
-
const require_event_category = require("./event-category-
|
|
4
|
-
const require_composition = require("./composition-
|
|
2
|
+
const require_sleep = require("./sleep-UP964hNP.js");
|
|
3
|
+
const require_event_category = require("./event-category-DG6Vir8Z.js");
|
|
4
|
+
const require_composition = require("./composition-CSLSFGTO.js");
|
|
5
5
|
const require_node_color = require("./node-color.js");
|
|
6
6
|
const require_err_msg = require("./err-msg-BhVbr0NX.js");
|
|
7
7
|
const require_enums = require("./enums.js");
|
|
@@ -12871,7 +12871,15 @@ var BUILTIN_RESULT_KINDS = Object.freeze({
|
|
|
12871
12871
|
kind: "fixed",
|
|
12872
12872
|
result: ["number", "null"]
|
|
12873
12873
|
},
|
|
12874
|
-
count: NUMBER
|
|
12874
|
+
count: NUMBER,
|
|
12875
|
+
dwell: {
|
|
12876
|
+
kind: "fixed",
|
|
12877
|
+
result: ["boolean", "null"]
|
|
12878
|
+
},
|
|
12879
|
+
latchedAt: {
|
|
12880
|
+
kind: "fixed",
|
|
12881
|
+
result: ["number", "null"]
|
|
12882
|
+
}
|
|
12875
12883
|
});
|
|
12876
12884
|
var KindInferenceError = class extends Error {};
|
|
12877
12885
|
function kindOfValue(value) {
|
|
@@ -43726,9 +43734,6 @@ var NcSystemEventKindSchema = zod.z.enum([
|
|
|
43726
43734
|
"device-battery-normal",
|
|
43727
43735
|
"device-consumable-low",
|
|
43728
43736
|
"device-consumable-normal",
|
|
43729
|
-
"device-tank-low",
|
|
43730
|
-
"device-tank-full",
|
|
43731
|
-
"device-tank-normal",
|
|
43732
43737
|
"stream-online",
|
|
43733
43738
|
"stream-offline",
|
|
43734
43739
|
"node-online",
|
|
@@ -43775,18 +43780,19 @@ var NcSystemEventKindSchema = zod.z.enum([
|
|
|
43775
43780
|
"camera-enabled"
|
|
43776
43781
|
]);
|
|
43777
43782
|
/** The legacy tail of {@link NcSystemEventKindSchema} — see its docblock. */
|
|
43778
|
-
var NC_LEGACY_SYSTEM_EVENT_KINDS =
|
|
43783
|
+
var NC_LEGACY_SYSTEM_EVENT_KINDS = [
|
|
43779
43784
|
"camera-online",
|
|
43780
43785
|
"camera-offline",
|
|
43781
43786
|
"camera-disabled",
|
|
43782
43787
|
"camera-enabled"
|
|
43783
|
-
]
|
|
43788
|
+
];
|
|
43789
|
+
var NC_LEGACY_SYSTEM_EVENT_KIND_SET = new Set(NC_LEGACY_SYSTEM_EVENT_KINDS);
|
|
43784
43790
|
/**
|
|
43785
43791
|
* The kinds a rule may be AUTHORED with — every schema member except the
|
|
43786
43792
|
* legacy tail. Editors render THIS list; the schema still parses the tail so a
|
|
43787
43793
|
* durable row (and an unmigrated rule) survives being read.
|
|
43788
43794
|
*/
|
|
43789
|
-
var NC_AUTHORABLE_SYSTEM_EVENT_KINDS = NcSystemEventKindSchema.options.filter((kind) => !
|
|
43795
|
+
var NC_AUTHORABLE_SYSTEM_EVENT_KINDS = NcSystemEventKindSchema.options.filter((kind) => !NC_LEGACY_SYSTEM_EVENT_KIND_SET.has(kind));
|
|
43790
43796
|
/**
|
|
43791
43797
|
* The panel's transitions, as ONE list.
|
|
43792
43798
|
*
|
|
@@ -43831,12 +43837,6 @@ var NC_BATTERY_CONSUMABLE_SYSTEM_EVENT_KINDS = [
|
|
|
43831
43837
|
* and both editors read it.
|
|
43832
43838
|
*/
|
|
43833
43839
|
var NC_CONSUMABLE_SYSTEM_EVENT_KINDS = ["device-consumable-low", "device-consumable-normal"];
|
|
43834
|
-
/** A vacuum's tank alerts (D642) — raised on the provider's own verdict. */
|
|
43835
|
-
var NC_TANK_SYSTEM_EVENT_KINDS = [
|
|
43836
|
-
"device-tank-low",
|
|
43837
|
-
"device-tank-full",
|
|
43838
|
-
"device-tank-normal"
|
|
43839
|
-
];
|
|
43840
43840
|
/**
|
|
43841
43841
|
* The consumable threshold a rule that does not state one judges at (D642).
|
|
43842
43842
|
* The operator's number ("default 15 %, configurable on the rule"), and the
|
|
@@ -45072,18 +45072,18 @@ var NcRuleSchema = NcRuleInputSchema.extend({
|
|
|
45072
45072
|
* `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
|
|
45073
45073
|
* job is not an open state, and the alarm stays instant.
|
|
45074
45074
|
*/
|
|
45075
|
-
var
|
|
45075
|
+
var NC_STATE_SUMMARY_SECTION_IDS = [
|
|
45076
45076
|
"device-state",
|
|
45077
45077
|
"streams",
|
|
45078
45078
|
"battery",
|
|
45079
45079
|
"consumables",
|
|
45080
|
-
"tanks",
|
|
45081
45080
|
"detection-blind",
|
|
45082
45081
|
"nodes",
|
|
45083
45082
|
"addons",
|
|
45084
45083
|
"addon-updates",
|
|
45085
45084
|
"updates"
|
|
45086
|
-
]
|
|
45085
|
+
];
|
|
45086
|
+
var NcStateSummarySectionIdSchema = zod.z.enum(NC_STATE_SUMMARY_SECTION_IDS);
|
|
45087
45087
|
/** One section of a previewed state summary. `unavailable` = its state could not be read. */
|
|
45088
45088
|
var NcStateSummaryPreviewSectionSchema = zod.z.object({
|
|
45089
45089
|
id: NcStateSummarySectionIdSchema,
|
|
@@ -45460,18 +45460,6 @@ var NC_CONDITION_CATALOG = [
|
|
|
45460
45460
|
value: "device-consumable-normal",
|
|
45461
45461
|
label: "Consumable replaced"
|
|
45462
45462
|
},
|
|
45463
|
-
{
|
|
45464
|
-
value: "device-tank-low",
|
|
45465
|
-
label: "Tank low (water, detergent)"
|
|
45466
|
-
},
|
|
45467
|
-
{
|
|
45468
|
-
value: "device-tank-full",
|
|
45469
|
-
label: "Tank full (dirty water, dust)"
|
|
45470
|
-
},
|
|
45471
|
-
{
|
|
45472
|
-
value: "device-tank-normal",
|
|
45473
|
-
label: "Tank back to normal"
|
|
45474
|
-
},
|
|
45475
45463
|
{
|
|
45476
45464
|
value: "export-completed",
|
|
45477
45465
|
label: "Export completed"
|
|
@@ -60338,20 +60326,68 @@ var BatteryStatusSchema = zod.z.object({
|
|
|
60338
60326
|
*/
|
|
60339
60327
|
binary: zod.z.boolean().optional()
|
|
60340
60328
|
});
|
|
60329
|
+
var BATTERY_DEVICE_TYPES = [
|
|
60330
|
+
require_err_msg.DeviceType.Camera,
|
|
60331
|
+
require_err_msg.DeviceType.Sensor,
|
|
60332
|
+
require_err_msg.DeviceType.Button,
|
|
60333
|
+
require_err_msg.DeviceType.Switch,
|
|
60334
|
+
require_err_msg.DeviceType.PetFeeder,
|
|
60335
|
+
require_err_msg.DeviceType.Container,
|
|
60336
|
+
require_err_msg.DeviceType.Thermostat
|
|
60337
|
+
];
|
|
60338
|
+
/** Generic Customize target for the percentage reading (D936). */
|
|
60339
|
+
var batteryCustomize = {
|
|
60340
|
+
version: 1,
|
|
60341
|
+
targets: [{
|
|
60342
|
+
id: "percentage",
|
|
60343
|
+
cardinality: "scalar",
|
|
60344
|
+
vocabulary: {
|
|
60345
|
+
cap: "battery",
|
|
60346
|
+
stateField: "percentage"
|
|
60347
|
+
},
|
|
60348
|
+
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
60349
|
+
apply: "add-or-replace",
|
|
60350
|
+
path: "percentage",
|
|
60351
|
+
sources: [{
|
|
60352
|
+
kind: "field",
|
|
60353
|
+
valueKinds: ["number", "string"],
|
|
60354
|
+
transforms: [{ kind: "identity" }, {
|
|
60355
|
+
kind: "linear",
|
|
60356
|
+
defaultScale: 1,
|
|
60357
|
+
defaultOffset: 0,
|
|
60358
|
+
clampMin: 0,
|
|
60359
|
+
clampMax: 100
|
|
60360
|
+
}]
|
|
60361
|
+
}],
|
|
60362
|
+
companions: [
|
|
60363
|
+
{
|
|
60364
|
+
kind: "constant",
|
|
60365
|
+
path: "charging",
|
|
60366
|
+
value: "unknown",
|
|
60367
|
+
when: "add"
|
|
60368
|
+
},
|
|
60369
|
+
{
|
|
60370
|
+
kind: "constant",
|
|
60371
|
+
path: "sleeping",
|
|
60372
|
+
value: false,
|
|
60373
|
+
when: "add"
|
|
60374
|
+
},
|
|
60375
|
+
{
|
|
60376
|
+
kind: "clock",
|
|
60377
|
+
path: "lastUpdated",
|
|
60378
|
+
when: "add"
|
|
60379
|
+
}
|
|
60380
|
+
],
|
|
60381
|
+
sourceReport: { status: "assignment-status" },
|
|
60382
|
+
advancedExpression: true
|
|
60383
|
+
}]
|
|
60384
|
+
};
|
|
60341
60385
|
var batteryCapability = {
|
|
60342
60386
|
name: "battery",
|
|
60343
60387
|
scope: "device",
|
|
60344
60388
|
deviceNative: true,
|
|
60345
60389
|
mode: "singleton",
|
|
60346
|
-
deviceTypes:
|
|
60347
|
-
require_err_msg.DeviceType.Camera,
|
|
60348
|
-
require_err_msg.DeviceType.Sensor,
|
|
60349
|
-
require_err_msg.DeviceType.Button,
|
|
60350
|
-
require_err_msg.DeviceType.Switch,
|
|
60351
|
-
require_err_msg.DeviceType.PetFeeder,
|
|
60352
|
-
require_err_msg.DeviceType.Container,
|
|
60353
|
-
require_err_msg.DeviceType.Thermostat
|
|
60354
|
-
],
|
|
60390
|
+
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
60355
60391
|
methods: {
|
|
60356
60392
|
/**
|
|
60357
60393
|
* Explicitly wake the camera from low-power sleep ahead of a
|
|
@@ -60435,6 +60471,7 @@ onStatusChanged: { data: zod.z.object({
|
|
|
60435
60471
|
kind: "gauge",
|
|
60436
60472
|
unit: "%"
|
|
60437
60473
|
} } },
|
|
60474
|
+
customize: batteryCustomize,
|
|
60438
60475
|
/** Clock fields: written, but excluded from the compare that decides
|
|
60439
60476
|
* whether persisting is worth a SQLite commit. */
|
|
60440
60477
|
volatileStateFields: ["lastUpdated"]
|
|
@@ -61633,6 +61670,106 @@ var ConsumablesStatusSchema = zod.z.object({
|
|
|
61633
61670
|
items: zod.z.array(ConsumableItemSchema),
|
|
61634
61671
|
lastChangedAt: zod.z.number()
|
|
61635
61672
|
});
|
|
61673
|
+
/** Synthesize seed for a link-built status (no native provider).
|
|
61674
|
+
*
|
|
61675
|
+
* ⚠ NO LIVE CALLER since 2026-08-08 (device-links deleted; see
|
|
61676
|
+
* `CapabilityStatusSchema.empty`). The wiring guidance below was written for
|
|
61677
|
+
* exactly the case the operator is asking about again — a Dreame's HA
|
|
61678
|
+
* consumable-life sensors — so it is kept for that conversation, not because
|
|
61679
|
+
* anything reads it today. */
|
|
61680
|
+
var EMPTY_STATUS = {
|
|
61681
|
+
items: [],
|
|
61682
|
+
lastChangedAt: 0
|
|
61683
|
+
};
|
|
61684
|
+
/** Seed for a NEW link-built consumable item. `key`/`label` are overwritten
|
|
61685
|
+
* with the link's `itemKey` (see `status.itemArray`), so the placeholder
|
|
61686
|
+
* empty strings never survive into a validated item. Link-built items are
|
|
61687
|
+
* not resettable — there is no native provider to receive `reset()`.
|
|
61688
|
+
*
|
|
61689
|
+
* Wiring guidance (HA vacuum consumable-life sensors):
|
|
61690
|
+
* - a percent-remaining source (`numeric-sensor`, unit '%') → `level` via
|
|
61691
|
+
* `identity` (or `linear` scale 1 offset 0 clamp [0,100] to be safe);
|
|
61692
|
+
* - an hours-remaining source (e.g. Dreame 'Main Brush Time Left', unit 'h')
|
|
61693
|
+
* → `level` via `linear` with scale = 100 / max-hours for that item
|
|
61694
|
+
* (e.g. main brush 300 h → scale 0.3333) + clamp [0,100];
|
|
61695
|
+
* - a discrete source (`enum-sensor`, e.g. mop pad 'installed') → `status`
|
|
61696
|
+
* via `enum-map` (e.g. { installed: 'ok', missing: 'replace' }).
|
|
61697
|
+
* A numeric→'replace' THRESHOLD (level < 10 → 'replace') is NOT expressible
|
|
61698
|
+
* with the current transform kinds — leave `status` null (valid) until the
|
|
61699
|
+
* expression transform lands. */
|
|
61700
|
+
/** Generic Customize target for one consumable item (D936). Native rows stay read-only. */
|
|
61701
|
+
var consumablesCustomize = {
|
|
61702
|
+
version: 1,
|
|
61703
|
+
targets: [{
|
|
61704
|
+
id: "items",
|
|
61705
|
+
cardinality: "keyedArray",
|
|
61706
|
+
vocabulary: { cap: "consumables" },
|
|
61707
|
+
deviceTypes: Object.values(require_err_msg.DeviceType),
|
|
61708
|
+
apply: "add",
|
|
61709
|
+
path: "items",
|
|
61710
|
+
keyField: "key",
|
|
61711
|
+
labelField: "label",
|
|
61712
|
+
itemSchema: ConsumableItemSchema,
|
|
61713
|
+
nativeItems: "read-only",
|
|
61714
|
+
sourceReport: { status: "assignment-status" },
|
|
61715
|
+
fields: [
|
|
61716
|
+
{
|
|
61717
|
+
path: "level",
|
|
61718
|
+
sources: [{
|
|
61719
|
+
kind: "numeric",
|
|
61720
|
+
transforms: [{ kind: "identity" }, {
|
|
61721
|
+
kind: "linear",
|
|
61722
|
+
defaultScale: 1,
|
|
61723
|
+
defaultOffset: 0,
|
|
61724
|
+
clampMin: 0,
|
|
61725
|
+
clampMax: 100
|
|
61726
|
+
}]
|
|
61727
|
+
}]
|
|
61728
|
+
},
|
|
61729
|
+
{
|
|
61730
|
+
path: "remaining.value",
|
|
61731
|
+
sources: [{
|
|
61732
|
+
kind: "numeric",
|
|
61733
|
+
transforms: [{ kind: "identity" }]
|
|
61734
|
+
}],
|
|
61735
|
+
literals: [{
|
|
61736
|
+
path: "remaining.unit",
|
|
61737
|
+
values: [...ConsumableRemainingUnitSchema.options]
|
|
61738
|
+
}]
|
|
61739
|
+
},
|
|
61740
|
+
{
|
|
61741
|
+
path: "status",
|
|
61742
|
+
sources: [{
|
|
61743
|
+
kind: "enum",
|
|
61744
|
+
transforms: [{
|
|
61745
|
+
kind: "enum-map",
|
|
61746
|
+
outputValues: [...ConsumableStatusSchema.options],
|
|
61747
|
+
unmapped: null
|
|
61748
|
+
}]
|
|
61749
|
+
}]
|
|
61750
|
+
}
|
|
61751
|
+
],
|
|
61752
|
+
traits: [{
|
|
61753
|
+
path: "kind",
|
|
61754
|
+
values: [...ConsumableKindSchema.options],
|
|
61755
|
+
defaultValue: "wear"
|
|
61756
|
+
}, {
|
|
61757
|
+
path: "form",
|
|
61758
|
+
values: [...ConsumableFormSchema.options],
|
|
61759
|
+
defaultValue: "part"
|
|
61760
|
+
}],
|
|
61761
|
+
companions: [{
|
|
61762
|
+
kind: "clock",
|
|
61763
|
+
path: "lastChangedAt",
|
|
61764
|
+
when: "add"
|
|
61765
|
+
}, {
|
|
61766
|
+
kind: "clock",
|
|
61767
|
+
path: "lastFetchedAt",
|
|
61768
|
+
when: "add"
|
|
61769
|
+
}],
|
|
61770
|
+
advancedExpression: true
|
|
61771
|
+
}]
|
|
61772
|
+
};
|
|
61636
61773
|
var consumablesCapability = {
|
|
61637
61774
|
name: "consumables",
|
|
61638
61775
|
scope: "device",
|
|
@@ -61670,10 +61807,7 @@ reset: require_sleep.method(zod.z.object({
|
|
|
61670
61807
|
status: {
|
|
61671
61808
|
schema: ConsumablesStatusSchema,
|
|
61672
61809
|
kind: "push",
|
|
61673
|
-
empty:
|
|
61674
|
-
items: [],
|
|
61675
|
-
lastChangedAt: 0
|
|
61676
|
-
},
|
|
61810
|
+
empty: EMPTY_STATUS,
|
|
61677
61811
|
itemArray: {
|
|
61678
61812
|
path: "items",
|
|
61679
61813
|
keyField: "key",
|
|
@@ -61709,6 +61843,7 @@ reset: require_sleep.method(zod.z.object({
|
|
|
61709
61843
|
* brush's remaining life and a dishwasher's salt are each recorded the moment
|
|
61710
61844
|
* their provider reports them; an item that appears later gets its series.
|
|
61711
61845
|
*/
|
|
61846
|
+
customize: consumablesCustomize,
|
|
61712
61847
|
history: {
|
|
61713
61848
|
fields: {},
|
|
61714
61849
|
items: {
|
|
@@ -62511,6 +62646,38 @@ var dishwasherCapability = {
|
|
|
62511
62646
|
};
|
|
62512
62647
|
//#endregion
|
|
62513
62648
|
//#region src/capabilities/doorbell.cap.ts
|
|
62649
|
+
/** A rise closer than this to the previous one is the same press (D671). */
|
|
62650
|
+
var DOORBELL_RISE_DEBOUNCE_MS = 2e3;
|
|
62651
|
+
/** Pulse override: a rising edge advances `lastPressedAt` and the press count. */
|
|
62652
|
+
var doorbellCustomize = {
|
|
62653
|
+
version: 1,
|
|
62654
|
+
targets: [{
|
|
62655
|
+
id: "pressed",
|
|
62656
|
+
cardinality: "event",
|
|
62657
|
+
shape: "pulse",
|
|
62658
|
+
vocabulary: {
|
|
62659
|
+
cap: "doorbell",
|
|
62660
|
+
eventName: "onPressed"
|
|
62661
|
+
},
|
|
62662
|
+
deviceTypes: [require_err_msg.DeviceType.Camera],
|
|
62663
|
+
apply: "add",
|
|
62664
|
+
applyAuthority: { kind: "composition-claim" },
|
|
62665
|
+
eventName: "onPressed",
|
|
62666
|
+
edges: ["rising"],
|
|
62667
|
+
timestampPath: "lastPressedAt",
|
|
62668
|
+
counterPath: "pressCountSinceStart",
|
|
62669
|
+
highWater: "composer-advance",
|
|
62670
|
+
combine: "any",
|
|
62671
|
+
debounce: {
|
|
62672
|
+
kind: "rising-edge",
|
|
62673
|
+
defaultDebounceMs: DOORBELL_RISE_DEBOUNCE_MS,
|
|
62674
|
+
changedAtRequired: true
|
|
62675
|
+
},
|
|
62676
|
+
sources: [{ kind: "binary" }, { kind: "switch" }],
|
|
62677
|
+
sourceReport: { status: "assignment-status" },
|
|
62678
|
+
advancedExpression: true
|
|
62679
|
+
}]
|
|
62680
|
+
};
|
|
62514
62681
|
var DoorbellStatusSchema = zod.z.object({
|
|
62515
62682
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
62516
62683
|
lastPressedAt: zod.z.number().nullable(),
|
|
@@ -62577,7 +62744,8 @@ onPressed: {
|
|
|
62577
62744
|
/**
|
|
62578
62745
|
* History (D850): none — `pressCountSinceStart` resets with the addon, so it is not a monotonic meter; presses live in the events ledger.
|
|
62579
62746
|
*/
|
|
62580
|
-
history: "none"
|
|
62747
|
+
history: "none",
|
|
62748
|
+
customize: doorbellCustomize
|
|
62581
62749
|
};
|
|
62582
62750
|
//#endregion
|
|
62583
62751
|
//#region src/capabilities/enum-sensor.cap.ts
|
|
@@ -65324,6 +65492,44 @@ authKey: zod.z.string().optional() }), zod.z.object({
|
|
|
65324
65492
|
//#endregion
|
|
65325
65493
|
//#region src/capabilities/motion.cap.ts
|
|
65326
65494
|
/**
|
|
65495
|
+
* Span timeout for a camera's attached sensors. This is the pipeline-runner
|
|
65496
|
+
* `motionCooldownMs` default: the window after which a heartbeat-only edge
|
|
65497
|
+
* no longer counts. The span does not declare a separate cooldown.
|
|
65498
|
+
*/
|
|
65499
|
+
var MOTION_SPAN_TIMEOUT_MS = 3e4;
|
|
65500
|
+
/** Span override: start on a rising edge, end on a fall or this timeout. */
|
|
65501
|
+
var motionCustomize = {
|
|
65502
|
+
version: 1,
|
|
65503
|
+
targets: [{
|
|
65504
|
+
id: "detected",
|
|
65505
|
+
cardinality: "event",
|
|
65506
|
+
shape: "span",
|
|
65507
|
+
vocabulary: {
|
|
65508
|
+
cap: "motion",
|
|
65509
|
+
eventName: "onMotionChanged"
|
|
65510
|
+
},
|
|
65511
|
+
deviceTypes: [require_err_msg.DeviceType.Camera],
|
|
65512
|
+
apply: "replace",
|
|
65513
|
+
applyAuthority: {
|
|
65514
|
+
kind: "camera-sensors",
|
|
65515
|
+
timeoutField: "motionCooldownMs"
|
|
65516
|
+
},
|
|
65517
|
+
eventName: "onMotionChanged",
|
|
65518
|
+
start: "rising-edge",
|
|
65519
|
+
end: "falling-edge-or-timeout",
|
|
65520
|
+
timeoutMs: MOTION_SPAN_TIMEOUT_MS,
|
|
65521
|
+
combine: "any",
|
|
65522
|
+
sourceModes: [
|
|
65523
|
+
"in-addition",
|
|
65524
|
+
"confirm",
|
|
65525
|
+
"replace"
|
|
65526
|
+
],
|
|
65527
|
+
sources: [{ kind: "binary" }, { kind: "switch" }],
|
|
65528
|
+
sourceReport: { status: "assignment-status" },
|
|
65529
|
+
advancedExpression: false
|
|
65530
|
+
}]
|
|
65531
|
+
};
|
|
65532
|
+
/**
|
|
65327
65533
|
* Hardware / firmware motion sensor cap — binary detected state plus
|
|
65328
65534
|
* a timestamp of the last observation. Distinct from
|
|
65329
65535
|
* `motion-detection.cap.ts` which owns the LOCAL ML motion pipeline;
|
|
@@ -65487,7 +65693,8 @@ onMotionChanged: { data: MotionOnMotionChangedDataSchema } },
|
|
|
65487
65693
|
history: { fields: { detected: {
|
|
65488
65694
|
kind: "boolean",
|
|
65489
65695
|
excludeDeviceTypes: [require_err_msg.DeviceType.Camera]
|
|
65490
|
-
} } }
|
|
65696
|
+
} } },
|
|
65697
|
+
customize: motionCustomize
|
|
65491
65698
|
};
|
|
65492
65699
|
//#endregion
|
|
65493
65700
|
//#region src/capabilities/motion-trigger.cap.ts
|
|
@@ -69601,6 +69808,138 @@ var ptzAutotrackCapability = {
|
|
|
69601
69808
|
history: "none"
|
|
69602
69809
|
};
|
|
69603
69810
|
//#endregion
|
|
69811
|
+
//#region src/running-state/defaults.ts
|
|
69812
|
+
var RUNNING_POWER_THRESHOLD_WATTS = 5;
|
|
69813
|
+
var RUNNING_POWER_START_DELAY_MS = 3e4;
|
|
69814
|
+
var RUNNING_POWER_STOP_DELAY_MS = 18e4;
|
|
69815
|
+
/** Before any provider reading — all fields unknown (D933). */
|
|
69816
|
+
var RUNNING_STATE_COLD = {
|
|
69817
|
+
running: null,
|
|
69818
|
+
since: null,
|
|
69819
|
+
source: "native",
|
|
69820
|
+
phase: null,
|
|
69821
|
+
lastFetchedAt: null
|
|
69822
|
+
};
|
|
69823
|
+
//#endregion
|
|
69824
|
+
//#region src/capabilities/running-state.cap.ts
|
|
69825
|
+
var RunningStateSourceSchema = zod.z.enum(["native", "assigned"]);
|
|
69826
|
+
var RunningStateStatusSchema = zod.z.object({
|
|
69827
|
+
/** null = unknown — never coerced to false (D393). */
|
|
69828
|
+
running: zod.z.boolean().nullable(),
|
|
69829
|
+
/** Epoch ms the current boolean began; null while `running` is null. */
|
|
69830
|
+
since: zod.z.number().nullable(),
|
|
69831
|
+
source: RunningStateSourceSchema,
|
|
69832
|
+
phase: zod.z.string().nullable(),
|
|
69833
|
+
/** null until a reading has been published (D393). */
|
|
69834
|
+
lastFetchedAt: zod.z.number().nullable()
|
|
69835
|
+
});
|
|
69836
|
+
var RunningFlipEventDataSchema = zod.z.object({
|
|
69837
|
+
deviceId: zod.z.number(),
|
|
69838
|
+
since: zod.z.number().nullable(),
|
|
69839
|
+
phase: zod.z.string().nullable()
|
|
69840
|
+
});
|
|
69841
|
+
var RUNNING_DEVICE_TYPES = Object.values(require_err_msg.DeviceType);
|
|
69842
|
+
/** Generic Customize target for the running boolean (D936). */
|
|
69843
|
+
var runningCustomize = {
|
|
69844
|
+
version: 1,
|
|
69845
|
+
targets: [{
|
|
69846
|
+
id: "running",
|
|
69847
|
+
cardinality: "scalar",
|
|
69848
|
+
vocabulary: {
|
|
69849
|
+
cap: "running-state",
|
|
69850
|
+
stateField: "running"
|
|
69851
|
+
},
|
|
69852
|
+
deviceTypes: [
|
|
69853
|
+
require_err_msg.DeviceType.Dishwasher,
|
|
69854
|
+
require_err_msg.DeviceType.Vacuum,
|
|
69855
|
+
require_err_msg.DeviceType.LawnMower,
|
|
69856
|
+
require_err_msg.DeviceType.MediaPlayer,
|
|
69857
|
+
require_err_msg.DeviceType.WaterHeater,
|
|
69858
|
+
require_err_msg.DeviceType.Humidifier,
|
|
69859
|
+
require_err_msg.DeviceType.Fan,
|
|
69860
|
+
require_err_msg.DeviceType.Climate,
|
|
69861
|
+
require_err_msg.DeviceType.Thermostat,
|
|
69862
|
+
require_err_msg.DeviceType.PetFeeder
|
|
69863
|
+
],
|
|
69864
|
+
apply: "add-or-replace",
|
|
69865
|
+
path: "running",
|
|
69866
|
+
sources: [
|
|
69867
|
+
{
|
|
69868
|
+
kind: "switch",
|
|
69869
|
+
transforms: [{ kind: "identity" }]
|
|
69870
|
+
},
|
|
69871
|
+
{
|
|
69872
|
+
kind: "binary",
|
|
69873
|
+
transforms: [{ kind: "identity" }, { kind: "invert" }]
|
|
69874
|
+
},
|
|
69875
|
+
{
|
|
69876
|
+
kind: "numeric",
|
|
69877
|
+
requiredUnit: "W",
|
|
69878
|
+
transforms: [{
|
|
69879
|
+
kind: "threshold",
|
|
69880
|
+
comparison: "gte",
|
|
69881
|
+
defaultThreshold: 5,
|
|
69882
|
+
defaultStartDwellMs: RUNNING_POWER_START_DELAY_MS,
|
|
69883
|
+
defaultStopDwellMs: RUNNING_POWER_STOP_DELAY_MS,
|
|
69884
|
+
thresholdUnit: "W"
|
|
69885
|
+
}]
|
|
69886
|
+
}
|
|
69887
|
+
],
|
|
69888
|
+
companions: [
|
|
69889
|
+
{
|
|
69890
|
+
kind: "constant",
|
|
69891
|
+
path: "source",
|
|
69892
|
+
value: "assigned",
|
|
69893
|
+
when: "always"
|
|
69894
|
+
},
|
|
69895
|
+
{
|
|
69896
|
+
kind: "constant",
|
|
69897
|
+
path: "phase",
|
|
69898
|
+
value: null,
|
|
69899
|
+
when: "always"
|
|
69900
|
+
},
|
|
69901
|
+
{
|
|
69902
|
+
kind: "clock",
|
|
69903
|
+
path: "lastFetchedAt",
|
|
69904
|
+
when: "always"
|
|
69905
|
+
},
|
|
69906
|
+
{
|
|
69907
|
+
kind: "transition-time",
|
|
69908
|
+
path: "since",
|
|
69909
|
+
sourceChangedAt: "prefer"
|
|
69910
|
+
}
|
|
69911
|
+
],
|
|
69912
|
+
sourceReport: {
|
|
69913
|
+
status: "assignment-status",
|
|
69914
|
+
runtimeField: "source",
|
|
69915
|
+
nativeValue: "native",
|
|
69916
|
+
assignedValue: "assigned"
|
|
69917
|
+
},
|
|
69918
|
+
advancedExpression: true
|
|
69919
|
+
}]
|
|
69920
|
+
};
|
|
69921
|
+
var runningStateCapability = {
|
|
69922
|
+
name: "running-state",
|
|
69923
|
+
scope: "device",
|
|
69924
|
+
deviceNative: true,
|
|
69925
|
+
mode: "singleton",
|
|
69926
|
+
deviceTypes: RUNNING_DEVICE_TYPES,
|
|
69927
|
+
methods: {},
|
|
69928
|
+
events: {
|
|
69929
|
+
onStarted: { data: RunningFlipEventDataSchema },
|
|
69930
|
+
onFinished: { data: RunningFlipEventDataSchema }
|
|
69931
|
+
},
|
|
69932
|
+
status: {
|
|
69933
|
+
schema: RunningStateStatusSchema,
|
|
69934
|
+
kind: "push"
|
|
69935
|
+
},
|
|
69936
|
+
runtimeState: RunningStateStatusSchema,
|
|
69937
|
+
durability: "restored",
|
|
69938
|
+
history: { fields: { running: { kind: "boolean" } } },
|
|
69939
|
+
volatileStateFields: ["lastFetchedAt"],
|
|
69940
|
+
customize: runningCustomize
|
|
69941
|
+
};
|
|
69942
|
+
//#endregion
|
|
69604
69943
|
//#region src/capabilities/reboot.cap.ts
|
|
69605
69944
|
/**
|
|
69606
69945
|
* reboot — device-scoped capability for "soft" device reboots (firmware
|
|
@@ -75827,6 +76166,60 @@ var PIPELINE_OWNER_CAPABILITY_NAMES = [
|
|
|
75827
76166
|
"pipeline-runner"
|
|
75828
76167
|
];
|
|
75829
76168
|
//#endregion
|
|
76169
|
+
//#region src/running-state/from-operation.ts
|
|
76170
|
+
function programStartFromRemaining(running, remainingSeconds, fetchedAt) {
|
|
76171
|
+
if (!running || remainingSeconds === null || remainingSeconds === void 0) return null;
|
|
76172
|
+
if (remainingSeconds <= 0) return null;
|
|
76173
|
+
return fetchedAt - remainingSeconds * 1e3;
|
|
76174
|
+
}
|
|
76175
|
+
function resolveSince(running, previous, transitionAtMs, bootstrapSinceMs) {
|
|
76176
|
+
if (running === null) return null;
|
|
76177
|
+
const prevRunning = previous?.running ?? null;
|
|
76178
|
+
if (prevRunning === null) return bootstrapSinceMs;
|
|
76179
|
+
if (prevRunning !== running) return transitionAtMs;
|
|
76180
|
+
return previous?.since ?? null;
|
|
76181
|
+
}
|
|
76182
|
+
function nativeSlice(running, phase, previous, transitionAtMs, fetchedAt, bootstrapSinceMs) {
|
|
76183
|
+
return {
|
|
76184
|
+
running,
|
|
76185
|
+
since: resolveSince(running, previous, transitionAtMs, bootstrapSinceMs),
|
|
76186
|
+
source: "native",
|
|
76187
|
+
phase: running === null ? null : phase,
|
|
76188
|
+
lastFetchedAt: fetchedAt
|
|
76189
|
+
};
|
|
76190
|
+
}
|
|
76191
|
+
function runningFromDishwasherOperation(operation, program, previous, fetchedAt, remainingSeconds, transitionAt) {
|
|
76192
|
+
const transitionAtMs = transitionAt ?? fetchedAt;
|
|
76193
|
+
if (operation === null) return nativeSlice(null, null, previous, transitionAtMs, fetchedAt, null);
|
|
76194
|
+
if (operation === "Run" || operation === "Aborting") {
|
|
76195
|
+
const bootstrap = programStartFromRemaining(true, remainingSeconds, fetchedAt);
|
|
76196
|
+
return nativeSlice(true, program ?? operation, previous, transitionAtMs, fetchedAt, bootstrap);
|
|
76197
|
+
}
|
|
76198
|
+
if (operation === "Pause") return nativeSlice(false, "Pause", previous, transitionAtMs, fetchedAt, null);
|
|
76199
|
+
return nativeSlice(false, operation, previous, transitionAtMs, fetchedAt, null);
|
|
76200
|
+
}
|
|
76201
|
+
function runningFromVacuumState(state, previous, fetchedAt, transitionAt) {
|
|
76202
|
+
const transitionAtMs = transitionAt ?? fetchedAt;
|
|
76203
|
+
if (state === null) return nativeSlice(null, null, previous, transitionAtMs, fetchedAt, null);
|
|
76204
|
+
if (state === "cleaning" || state === "returning" || state === "drying") return nativeSlice(true, state, previous, transitionAtMs, fetchedAt, null);
|
|
76205
|
+
if (state === "paused") return nativeSlice(false, "paused", previous, transitionAtMs, fetchedAt, null);
|
|
76206
|
+
return nativeSlice(false, state, previous, transitionAtMs, fetchedAt, null);
|
|
76207
|
+
}
|
|
76208
|
+
function runningFromLawnMower(activity, previous, fetchedAt, transitionAt) {
|
|
76209
|
+
const transitionAtMs = transitionAt ?? fetchedAt;
|
|
76210
|
+
if (activity === null) return nativeSlice(null, null, previous, transitionAtMs, fetchedAt, null);
|
|
76211
|
+
if (activity === "mowing") return nativeSlice(true, activity, previous, transitionAtMs, fetchedAt, null);
|
|
76212
|
+
if (activity === "paused") return nativeSlice(false, "paused", previous, transitionAtMs, fetchedAt, null);
|
|
76213
|
+
return nativeSlice(false, activity, previous, transitionAtMs, fetchedAt, null);
|
|
76214
|
+
}
|
|
76215
|
+
function runningFromMediaPlayer(state, previous, fetchedAt, transitionAt) {
|
|
76216
|
+
const transitionAtMs = transitionAt ?? fetchedAt;
|
|
76217
|
+
if (state === null) return nativeSlice(null, null, previous, transitionAtMs, fetchedAt, null);
|
|
76218
|
+
if (state === "playing" || state === "buffering") return nativeSlice(true, state, previous, transitionAtMs, fetchedAt, null);
|
|
76219
|
+
if (state === "paused") return nativeSlice(false, "paused", previous, transitionAtMs, fetchedAt, null);
|
|
76220
|
+
return nativeSlice(false, state, previous, transitionAtMs, fetchedAt, null);
|
|
76221
|
+
}
|
|
76222
|
+
//#endregion
|
|
75830
76223
|
//#region src/clips/clip-event-labels.ts
|
|
75831
76224
|
/**
|
|
75832
76225
|
* Which of OUR object detections a clip window holds — the ONE overlap rule
|
|
@@ -76470,11 +76863,12 @@ function expressionOutcome(source, read, now, stateful) {
|
|
|
76470
76863
|
return unavailable;
|
|
76471
76864
|
}
|
|
76472
76865
|
const deadlines = [];
|
|
76866
|
+
const hooks = {
|
|
76867
|
+
noteDeadline: (at) => deadlines.push(at),
|
|
76868
|
+
convert: (value, from, to) => tryConvertUnit(value, normalizeUnit(from) ?? from, normalizeUnit(to) ?? to) ?? null
|
|
76869
|
+
};
|
|
76473
76870
|
const result = require_composition.evaluateExpressionSource(source.expr, values, now, {
|
|
76474
|
-
hooks
|
|
76475
|
-
noteDeadline: (at) => deadlines.push(at),
|
|
76476
|
-
convert: (value, from, to) => tryConvertUnit(value, normalizeUnit(from) ?? from, normalizeUnit(to) ?? to) ?? null
|
|
76477
|
-
},
|
|
76871
|
+
hooks,
|
|
76478
76872
|
...stateful === void 0 ? {} : { invokeStateful: (invocation) => require_composition.evaluateStatefulExpressionCall(stateful.callPathPrefix === void 0 ? invocation : {
|
|
76479
76873
|
...invocation,
|
|
76480
76874
|
path: `${stateful.callPathPrefix}@${invocation.path}`
|
|
@@ -76482,7 +76876,7 @@ function expressionOutcome(source, read, now, stateful) {
|
|
|
76482
76876
|
currentOutput: stateful.currentOutput,
|
|
76483
76877
|
startedAtMs: stateful.startedAtMs,
|
|
76484
76878
|
nowMs: now
|
|
76485
|
-
}) }
|
|
76879
|
+
}, hooks) }
|
|
76486
76880
|
});
|
|
76487
76881
|
if (!result.ok) return {
|
|
76488
76882
|
state: "unavailable",
|
|
@@ -76715,74 +77109,6 @@ function feederCustomizationExample(sources) {
|
|
|
76715
77109
|
});
|
|
76716
77110
|
}
|
|
76717
77111
|
//#endregion
|
|
76718
|
-
//#region src/composition/presets/doorbell-feature.ts
|
|
76719
|
-
/**
|
|
76720
|
-
* The doorbell of a camera as a customization (D671). ONE builder: the admin
|
|
76721
|
-
* UI's Customize → Doorbell card writes every doorbell feature through it, and
|
|
76722
|
-
* edits one only when it is exactly what this builds (`isDoorbellPresetFeature`)
|
|
76723
|
-
* — a composed doorbell has one canonical shape.
|
|
76724
|
-
*/
|
|
76725
|
-
/** A rise closer than this to the previous one is the same press (D671). */
|
|
76726
|
-
var DOORBELL_RISE_DEBOUNCE_MS = 2e3;
|
|
76727
|
-
/** Every source cap of `source` that `SOURCE_CAP_ACTIVE_FIELD` knows AND the device has bound. */
|
|
76728
|
-
function doorbellFeatureSources(source, boundCaps) {
|
|
76729
|
-
return Object.keys(require_composition.SOURCE_CAP_ACTIVE_FIELD).filter((cap) => Object.hasOwn(require_composition.SOURCE_CAP_CHANGED_AT_FIELD, cap) && boundCaps.includes(cap)).toSorted().flatMap((cap) => {
|
|
76730
|
-
const activeField = require_composition.SOURCE_CAP_ACTIVE_FIELD[cap];
|
|
76731
|
-
const changedAtField = require_composition.SOURCE_CAP_CHANGED_AT_FIELD[cap];
|
|
76732
|
-
return activeField === void 0 || changedAtField === void 0 ? [] : [{
|
|
76733
|
-
source,
|
|
76734
|
-
cap,
|
|
76735
|
-
activeField,
|
|
76736
|
-
changedAtField
|
|
76737
|
-
}];
|
|
76738
|
-
});
|
|
76739
|
-
}
|
|
76740
|
-
/** The canonical D671 doorbell feature. Throws on zero sources. */
|
|
76741
|
-
function buildDoorbellCompositionFeature(input) {
|
|
76742
|
-
const sources = [...input.sources].toSorted((a, b) => `${a.source.addonId}/${a.source.stableId}#${a.cap}`.localeCompare(`${b.source.addonId}/${b.source.stableId}#${b.cap}`));
|
|
76743
|
-
if (sources.length === 0) throw new Error("doorbell composition needs at least one source");
|
|
76744
|
-
const edgeBindings = {};
|
|
76745
|
-
sources.forEach((entry, index) => {
|
|
76746
|
-
edgeBindings[`active${index}`] = {
|
|
76747
|
-
kind: "from",
|
|
76748
|
-
source: entry.source,
|
|
76749
|
-
cap: entry.cap,
|
|
76750
|
-
fieldPath: entry.activeField
|
|
76751
|
-
};
|
|
76752
|
-
edgeBindings[`changed${index}`] = {
|
|
76753
|
-
kind: "from",
|
|
76754
|
-
source: entry.source,
|
|
76755
|
-
cap: entry.cap,
|
|
76756
|
-
fieldPath: entry.changedAtField
|
|
76757
|
-
};
|
|
76758
|
-
});
|
|
76759
|
-
return {
|
|
76760
|
-
kind: "fields",
|
|
76761
|
-
cap: "doorbell",
|
|
76762
|
-
enabled: input.enabled,
|
|
76763
|
-
fields: {
|
|
76764
|
-
lastPressedAt: {
|
|
76765
|
-
kind: "expression",
|
|
76766
|
-
expr: `latest(${sources.map((_, index) => `rose(active${index}, changed${index}, ${DOORBELL_RISE_DEBOUNCE_MS})`).join(", ")})`,
|
|
76767
|
-
bindings: edgeBindings
|
|
76768
|
-
},
|
|
76769
|
-
pressCountSinceStart: {
|
|
76770
|
-
kind: "expression",
|
|
76771
|
-
expr: "count(lastPressedAt)",
|
|
76772
|
-
bindings: { lastPressedAt: {
|
|
76773
|
-
kind: "from",
|
|
76774
|
-
source: {
|
|
76775
|
-
addonId: input.camera.addonId,
|
|
76776
|
-
stableId: input.camera.stableId
|
|
76777
|
-
},
|
|
76778
|
-
cap: "doorbell",
|
|
76779
|
-
fieldPath: "lastPressedAt"
|
|
76780
|
-
} }
|
|
76781
|
-
}
|
|
76782
|
-
}
|
|
76783
|
-
};
|
|
76784
|
-
}
|
|
76785
|
-
//#endregion
|
|
76786
77112
|
//#region src/composition/presets/numeric-transforms.ts
|
|
76787
77113
|
/**
|
|
76788
77114
|
* Self-only invert / unit-convert composition features (D663). The Numeric
|
|
@@ -77434,6 +77760,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
77434
77760
|
ptzAutotrack: ptzAutotrackCapability,
|
|
77435
77761
|
recordingOnboard: recordingOnboardCapability,
|
|
77436
77762
|
recordingSignal: recordingSignalCapability,
|
|
77763
|
+
runningState: runningStateCapability,
|
|
77437
77764
|
sceneMonitor: sceneMonitorCapability,
|
|
77438
77765
|
scriptRunner: scriptRunnerCapability,
|
|
77439
77766
|
smoke: smokeCapability,
|
|
@@ -87017,6 +87344,13 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
87017
87344
|
access: "create",
|
|
87018
87345
|
role: "admin"
|
|
87019
87346
|
},
|
|
87347
|
+
"runningState.getStatus": {
|
|
87348
|
+
capName: "running-state",
|
|
87349
|
+
capScope: "device",
|
|
87350
|
+
addonId: null,
|
|
87351
|
+
access: "view",
|
|
87352
|
+
role: "viewer"
|
|
87353
|
+
},
|
|
87020
87354
|
"sceneMonitor.captureReference": {
|
|
87021
87355
|
capName: "scene-monitor",
|
|
87022
87356
|
capScope: "device",
|
|
@@ -89306,6 +89640,7 @@ var KNOWN_CAP_NAMES = [
|
|
|
89306
89640
|
"recording-onboard",
|
|
89307
89641
|
"recording-signal",
|
|
89308
89642
|
"records",
|
|
89643
|
+
"running-state",
|
|
89309
89644
|
"scene-monitor",
|
|
89310
89645
|
"script-runner",
|
|
89311
89646
|
"server-management",
|
|
@@ -89420,6 +89755,7 @@ var DEVICE_CAP_NAMES = [
|
|
|
89420
89755
|
"recording",
|
|
89421
89756
|
"recording-onboard",
|
|
89422
89757
|
"recording-signal",
|
|
89758
|
+
"running-state",
|
|
89423
89759
|
"scene-monitor",
|
|
89424
89760
|
"script-runner",
|
|
89425
89761
|
"smoke",
|
|
@@ -92104,6 +92440,32 @@ var APPLIANCE_CAP_VOCABULARY = {
|
|
|
92104
92440
|
}],
|
|
92105
92441
|
events: { onSent: { notOperatorFacing: "a delivery receipt of a send this system made — not a fact about the world" } }
|
|
92106
92442
|
},
|
|
92443
|
+
"running-state": {
|
|
92444
|
+
scope: "device",
|
|
92445
|
+
noun: t("Running", "In funzione"),
|
|
92446
|
+
state: [{
|
|
92447
|
+
kind: "boolean",
|
|
92448
|
+
field: "running",
|
|
92449
|
+
label: t("Running", "In funzione"),
|
|
92450
|
+
whenTrue: t("When {device} starts", "Quando {device} inizia"),
|
|
92451
|
+
whenFalse: t("When {device} finishes", "Quando {device} finisce"),
|
|
92452
|
+
icon: "play"
|
|
92453
|
+
}],
|
|
92454
|
+
events: {
|
|
92455
|
+
onStarted: {
|
|
92456
|
+
category: require_event_category.EventCategory.RunningStarted,
|
|
92457
|
+
label: t("Started running", "Ha iniziato a funzionare"),
|
|
92458
|
+
phrase: t("When {device} starts running", "Quando {device} inizia a funzionare"),
|
|
92459
|
+
icon: "play"
|
|
92460
|
+
},
|
|
92461
|
+
onFinished: {
|
|
92462
|
+
category: require_event_category.EventCategory.RunningFinished,
|
|
92463
|
+
label: t("Finished", "Ha finito"),
|
|
92464
|
+
phrase: t("When {device} finishes", "Quando {device} finisce"),
|
|
92465
|
+
icon: "square"
|
|
92466
|
+
}
|
|
92467
|
+
}
|
|
92468
|
+
},
|
|
92107
92469
|
update: {
|
|
92108
92470
|
scope: "device",
|
|
92109
92471
|
noun: t("Firmware update", "Aggiornamento firmware"),
|
|
@@ -95044,6 +95406,7 @@ var CAP_NAMES_WITH_STATUS = [
|
|
|
95044
95406
|
"recording-archive",
|
|
95045
95407
|
"recording-onboard",
|
|
95046
95408
|
"recording-signal",
|
|
95409
|
+
"running-state",
|
|
95047
95410
|
"scene-monitor",
|
|
95048
95411
|
"script-runner",
|
|
95049
95412
|
"smoke",
|
|
@@ -95199,6 +95562,7 @@ var CAPABILITY_NAMES = {
|
|
|
95199
95562
|
recordingOnboard: "recording-onboard",
|
|
95200
95563
|
recordingSignal: "recording-signal",
|
|
95201
95564
|
records: "records",
|
|
95565
|
+
runningState: "running-state",
|
|
95202
95566
|
sceneMonitor: "scene-monitor",
|
|
95203
95567
|
scriptRunner: "script-runner",
|
|
95204
95568
|
serverManagement: "server-management",
|
|
@@ -95792,6 +96156,10 @@ var CAPABILITY_ROUTER_KEYS = [
|
|
|
95792
96156
|
key: "records",
|
|
95793
96157
|
name: "records"
|
|
95794
96158
|
},
|
|
96159
|
+
{
|
|
96160
|
+
key: "runningState",
|
|
96161
|
+
name: "running-state"
|
|
96162
|
+
},
|
|
95795
96163
|
{
|
|
95796
96164
|
key: "sceneMonitor",
|
|
95797
96165
|
name: "scene-monitor"
|
|
@@ -96108,6 +96476,7 @@ var ALL_CAPABILITY_DEFINITIONS = [
|
|
|
96108
96476
|
recordingOnboardCapability,
|
|
96109
96477
|
recordingSignalCapability,
|
|
96110
96478
|
recordsCapability,
|
|
96479
|
+
runningStateCapability,
|
|
96111
96480
|
sceneMonitorCapability,
|
|
96112
96481
|
scriptRunnerCapability,
|
|
96113
96482
|
serverManagementCapability,
|
|
@@ -98424,6 +98793,11 @@ var METHOD_DEVICE_SELECTORS = Object.freeze({
|
|
|
98424
98793
|
form: "single",
|
|
98425
98794
|
optional: true
|
|
98426
98795
|
}],
|
|
98796
|
+
"runningState.getStatus": [{
|
|
98797
|
+
name: "deviceId",
|
|
98798
|
+
form: "single",
|
|
98799
|
+
optional: false
|
|
98800
|
+
}],
|
|
98427
98801
|
"sceneMonitor.captureReference": [{
|
|
98428
98802
|
name: "deviceId",
|
|
98429
98803
|
form: "single",
|
|
@@ -99125,7 +99499,7 @@ function getCapsByProviderKind(kind) {
|
|
|
99125
99499
|
//#region src/generated/runtime-state-durability.ts
|
|
99126
99500
|
/**
|
|
99127
99501
|
* Per-cap runtime-state policy, projected from every `*.cap.ts` that declares
|
|
99128
|
-
* `runtimeState`.
|
|
99502
|
+
* `runtimeState`. 72 caps: 38 `restored`, 34 `session`.
|
|
99129
99503
|
*
|
|
99130
99504
|
* A cap absent from this map has no runtime-state slice at all. A cap PRESENT
|
|
99131
99505
|
* with `durability: 'session'` has one and has decided not to keep it.
|
|
@@ -99343,6 +99717,10 @@ var RUNTIME_STATE_POLICY = {
|
|
|
99343
99717
|
durability: "session",
|
|
99344
99718
|
volatileFields: []
|
|
99345
99719
|
},
|
|
99720
|
+
"running-state": {
|
|
99721
|
+
durability: "restored",
|
|
99722
|
+
volatileFields: ["lastFetchedAt"]
|
|
99723
|
+
},
|
|
99346
99724
|
"scene-monitor": {
|
|
99347
99725
|
durability: "session",
|
|
99348
99726
|
volatileFields: []
|
|
@@ -99465,6 +99843,7 @@ var RESTORED_CAP_NAMES = [
|
|
|
99465
99843
|
"pressure-sensor",
|
|
99466
99844
|
"privacy-mask",
|
|
99467
99845
|
"recording-onboard",
|
|
99846
|
+
"running-state",
|
|
99468
99847
|
"smoke",
|
|
99469
99848
|
"stream-catalog",
|
|
99470
99849
|
"stream-params",
|
|
@@ -99580,7 +99959,7 @@ var BucketAccumulator = class {
|
|
|
99580
99959
|
//#region src/generated/history-catalog.ts
|
|
99581
99960
|
/**
|
|
99582
99961
|
* Cap history catalog, projected from every `*.cap.ts` `history` block.
|
|
99583
|
-
*
|
|
99962
|
+
* 41 caps with series (74 series), 30 caps answered `'none'`.
|
|
99584
99963
|
* Field keys are `runtimeState` paths (`a.b` into fixed objects only).
|
|
99585
99964
|
*/
|
|
99586
99965
|
var HISTORY_CATALOG = {
|
|
@@ -99857,6 +100236,7 @@ var HISTORY_CATALOG = {
|
|
|
99857
100236
|
unit: "hPa",
|
|
99858
100237
|
deadband: .1
|
|
99859
100238
|
} },
|
|
100239
|
+
"running-state": { "running": { kind: "boolean" } },
|
|
99860
100240
|
"smoke": { "detected": { kind: "boolean" } },
|
|
99861
100241
|
"stream-params": {
|
|
99862
100242
|
"main.bitrate": {
|
|
@@ -100002,6 +100382,1852 @@ function historyFieldsFor(capName) {
|
|
|
100002
100382
|
return HISTORY_CATALOG[capName] ?? {};
|
|
100003
100383
|
}
|
|
100004
100384
|
//#endregion
|
|
100385
|
+
//#region src/generated/customize-catalog.ts
|
|
100386
|
+
/**
|
|
100387
|
+
* Customize catalog, projected from every `*.cap.ts` `customize` block.
|
|
100388
|
+
* 5 caps. Field keys are `runtimeState` paths. No Zod.
|
|
100389
|
+
*/
|
|
100390
|
+
var CAP_CUSTOMIZE_CATALOG = {
|
|
100391
|
+
"battery": {
|
|
100392
|
+
version: 1,
|
|
100393
|
+
targets: [{
|
|
100394
|
+
id: "percentage",
|
|
100395
|
+
cardinality: "scalar",
|
|
100396
|
+
deviceTypes: [
|
|
100397
|
+
require_err_msg.DeviceType.Camera,
|
|
100398
|
+
require_err_msg.DeviceType.Sensor,
|
|
100399
|
+
require_err_msg.DeviceType.Button,
|
|
100400
|
+
require_err_msg.DeviceType.Switch,
|
|
100401
|
+
require_err_msg.DeviceType.PetFeeder,
|
|
100402
|
+
require_err_msg.DeviceType.Container,
|
|
100403
|
+
require_err_msg.DeviceType.Thermostat
|
|
100404
|
+
],
|
|
100405
|
+
apply: "add-or-replace",
|
|
100406
|
+
vocabularyCap: "battery",
|
|
100407
|
+
vocabularyStateField: "percentage",
|
|
100408
|
+
sources: [{
|
|
100409
|
+
kind: "field",
|
|
100410
|
+
valueKinds: ["number", "string"],
|
|
100411
|
+
transformKinds: ["identity", "linear"]
|
|
100412
|
+
}],
|
|
100413
|
+
sourceReport: { status: "assignment-status" },
|
|
100414
|
+
advancedExpression: true,
|
|
100415
|
+
path: "percentage",
|
|
100416
|
+
valueKind: "number",
|
|
100417
|
+
nullable: true,
|
|
100418
|
+
companions: [
|
|
100419
|
+
{
|
|
100420
|
+
kind: "constant",
|
|
100421
|
+
path: "charging",
|
|
100422
|
+
value: "unknown",
|
|
100423
|
+
when: "add"
|
|
100424
|
+
},
|
|
100425
|
+
{
|
|
100426
|
+
kind: "constant",
|
|
100427
|
+
path: "sleeping",
|
|
100428
|
+
value: false,
|
|
100429
|
+
when: "add"
|
|
100430
|
+
},
|
|
100431
|
+
{
|
|
100432
|
+
kind: "clock",
|
|
100433
|
+
path: "lastUpdated",
|
|
100434
|
+
when: "add"
|
|
100435
|
+
}
|
|
100436
|
+
]
|
|
100437
|
+
}]
|
|
100438
|
+
},
|
|
100439
|
+
"consumables": {
|
|
100440
|
+
version: 1,
|
|
100441
|
+
targets: [{
|
|
100442
|
+
id: "items",
|
|
100443
|
+
cardinality: "keyedArray",
|
|
100444
|
+
deviceTypes: [
|
|
100445
|
+
require_err_msg.DeviceType.Camera,
|
|
100446
|
+
require_err_msg.DeviceType.Hub,
|
|
100447
|
+
require_err_msg.DeviceType.Light,
|
|
100448
|
+
require_err_msg.DeviceType.Siren,
|
|
100449
|
+
require_err_msg.DeviceType.Switch,
|
|
100450
|
+
require_err_msg.DeviceType.Sensor,
|
|
100451
|
+
require_err_msg.DeviceType.Thermostat,
|
|
100452
|
+
require_err_msg.DeviceType.Climate,
|
|
100453
|
+
require_err_msg.DeviceType.Button,
|
|
100454
|
+
require_err_msg.DeviceType.EventEmitter,
|
|
100455
|
+
require_err_msg.DeviceType.Update,
|
|
100456
|
+
require_err_msg.DeviceType.Generic,
|
|
100457
|
+
require_err_msg.DeviceType.Notifier,
|
|
100458
|
+
require_err_msg.DeviceType.Script,
|
|
100459
|
+
require_err_msg.DeviceType.Automation,
|
|
100460
|
+
require_err_msg.DeviceType.Lock,
|
|
100461
|
+
require_err_msg.DeviceType.Cover,
|
|
100462
|
+
require_err_msg.DeviceType.Valve,
|
|
100463
|
+
require_err_msg.DeviceType.Humidifier,
|
|
100464
|
+
require_err_msg.DeviceType.WaterHeater,
|
|
100465
|
+
require_err_msg.DeviceType.Fan,
|
|
100466
|
+
require_err_msg.DeviceType.MediaPlayer,
|
|
100467
|
+
require_err_msg.DeviceType.AlarmPanel,
|
|
100468
|
+
require_err_msg.DeviceType.Control,
|
|
100469
|
+
require_err_msg.DeviceType.Presence,
|
|
100470
|
+
require_err_msg.DeviceType.Weather,
|
|
100471
|
+
require_err_msg.DeviceType.Vacuum,
|
|
100472
|
+
require_err_msg.DeviceType.LawnMower,
|
|
100473
|
+
require_err_msg.DeviceType.Container,
|
|
100474
|
+
require_err_msg.DeviceType.Image,
|
|
100475
|
+
require_err_msg.DeviceType.PetFeeder,
|
|
100476
|
+
require_err_msg.DeviceType.Dishwasher
|
|
100477
|
+
],
|
|
100478
|
+
apply: "add",
|
|
100479
|
+
vocabularyCap: "consumables",
|
|
100480
|
+
sources: [],
|
|
100481
|
+
sourceReport: { status: "assignment-status" },
|
|
100482
|
+
advancedExpression: true,
|
|
100483
|
+
path: "items",
|
|
100484
|
+
keyField: "key",
|
|
100485
|
+
labelField: "label",
|
|
100486
|
+
nativeItems: "read-only",
|
|
100487
|
+
fields: [
|
|
100488
|
+
{
|
|
100489
|
+
path: "level",
|
|
100490
|
+
valueKind: "number",
|
|
100491
|
+
nullable: true,
|
|
100492
|
+
sources: [{
|
|
100493
|
+
kind: "numeric",
|
|
100494
|
+
transformKinds: ["identity", "linear"]
|
|
100495
|
+
}]
|
|
100496
|
+
},
|
|
100497
|
+
{
|
|
100498
|
+
path: "remaining.value",
|
|
100499
|
+
valueKind: "number",
|
|
100500
|
+
nullable: true,
|
|
100501
|
+
sources: [{
|
|
100502
|
+
kind: "numeric",
|
|
100503
|
+
transformKinds: ["identity"]
|
|
100504
|
+
}],
|
|
100505
|
+
literals: [{
|
|
100506
|
+
path: "remaining.unit",
|
|
100507
|
+
values: [
|
|
100508
|
+
"days",
|
|
100509
|
+
"hours",
|
|
100510
|
+
"cycles"
|
|
100511
|
+
]
|
|
100512
|
+
}]
|
|
100513
|
+
},
|
|
100514
|
+
{
|
|
100515
|
+
path: "status",
|
|
100516
|
+
valueKind: "enum",
|
|
100517
|
+
nullable: true,
|
|
100518
|
+
enumValues: [
|
|
100519
|
+
"ok",
|
|
100520
|
+
"low",
|
|
100521
|
+
"empty",
|
|
100522
|
+
"full",
|
|
100523
|
+
"replace"
|
|
100524
|
+
],
|
|
100525
|
+
sources: [{
|
|
100526
|
+
kind: "enum",
|
|
100527
|
+
transformKinds: ["enum-map"]
|
|
100528
|
+
}]
|
|
100529
|
+
}
|
|
100530
|
+
],
|
|
100531
|
+
traits: [{
|
|
100532
|
+
path: "kind",
|
|
100533
|
+
values: [
|
|
100534
|
+
"wear",
|
|
100535
|
+
"supply",
|
|
100536
|
+
"waste"
|
|
100537
|
+
],
|
|
100538
|
+
defaultValue: "wear"
|
|
100539
|
+
}, {
|
|
100540
|
+
path: "form",
|
|
100541
|
+
values: [
|
|
100542
|
+
"part",
|
|
100543
|
+
"tank",
|
|
100544
|
+
"product",
|
|
100545
|
+
"bin"
|
|
100546
|
+
],
|
|
100547
|
+
defaultValue: "part"
|
|
100548
|
+
}],
|
|
100549
|
+
companions: [{
|
|
100550
|
+
kind: "clock",
|
|
100551
|
+
path: "lastChangedAt",
|
|
100552
|
+
when: "add"
|
|
100553
|
+
}, {
|
|
100554
|
+
kind: "clock",
|
|
100555
|
+
path: "lastFetchedAt",
|
|
100556
|
+
when: "add"
|
|
100557
|
+
}]
|
|
100558
|
+
}]
|
|
100559
|
+
},
|
|
100560
|
+
"doorbell": {
|
|
100561
|
+
version: 1,
|
|
100562
|
+
targets: [{
|
|
100563
|
+
id: "pressed",
|
|
100564
|
+
cardinality: "event",
|
|
100565
|
+
deviceTypes: [require_err_msg.DeviceType.Camera],
|
|
100566
|
+
apply: "add",
|
|
100567
|
+
vocabularyCap: "doorbell",
|
|
100568
|
+
vocabularyEvent: "onPressed",
|
|
100569
|
+
sources: [{
|
|
100570
|
+
kind: "binary",
|
|
100571
|
+
transformKinds: []
|
|
100572
|
+
}, {
|
|
100573
|
+
kind: "switch",
|
|
100574
|
+
transformKinds: []
|
|
100575
|
+
}],
|
|
100576
|
+
sourceReport: { status: "assignment-status" },
|
|
100577
|
+
advancedExpression: true,
|
|
100578
|
+
shape: "pulse",
|
|
100579
|
+
applyAuthority: { kind: "composition-claim" },
|
|
100580
|
+
eventName: "onPressed",
|
|
100581
|
+
combine: "any",
|
|
100582
|
+
edges: ["rising"],
|
|
100583
|
+
timestampPath: "lastPressedAt",
|
|
100584
|
+
counterPath: "pressCountSinceStart",
|
|
100585
|
+
highWater: "composer-advance",
|
|
100586
|
+
debounceMs: 2e3
|
|
100587
|
+
}]
|
|
100588
|
+
},
|
|
100589
|
+
"motion": {
|
|
100590
|
+
version: 1,
|
|
100591
|
+
targets: [{
|
|
100592
|
+
id: "detected",
|
|
100593
|
+
cardinality: "event",
|
|
100594
|
+
deviceTypes: [require_err_msg.DeviceType.Camera],
|
|
100595
|
+
apply: "replace",
|
|
100596
|
+
vocabularyCap: "motion",
|
|
100597
|
+
vocabularyEvent: "onMotionChanged",
|
|
100598
|
+
sources: [{
|
|
100599
|
+
kind: "binary",
|
|
100600
|
+
transformKinds: []
|
|
100601
|
+
}, {
|
|
100602
|
+
kind: "switch",
|
|
100603
|
+
transformKinds: []
|
|
100604
|
+
}],
|
|
100605
|
+
sourceReport: { status: "assignment-status" },
|
|
100606
|
+
advancedExpression: false,
|
|
100607
|
+
shape: "span",
|
|
100608
|
+
applyAuthority: {
|
|
100609
|
+
kind: "camera-sensors",
|
|
100610
|
+
timeoutField: "motionCooldownMs"
|
|
100611
|
+
},
|
|
100612
|
+
eventName: "onMotionChanged",
|
|
100613
|
+
combine: "any",
|
|
100614
|
+
start: "rising-edge",
|
|
100615
|
+
end: "falling-edge-or-timeout",
|
|
100616
|
+
timeoutMs: 3e4,
|
|
100617
|
+
sourceModes: [
|
|
100618
|
+
"in-addition",
|
|
100619
|
+
"confirm",
|
|
100620
|
+
"replace"
|
|
100621
|
+
]
|
|
100622
|
+
}]
|
|
100623
|
+
},
|
|
100624
|
+
"running-state": {
|
|
100625
|
+
version: 1,
|
|
100626
|
+
targets: [{
|
|
100627
|
+
id: "running",
|
|
100628
|
+
cardinality: "scalar",
|
|
100629
|
+
deviceTypes: [
|
|
100630
|
+
require_err_msg.DeviceType.Dishwasher,
|
|
100631
|
+
require_err_msg.DeviceType.Vacuum,
|
|
100632
|
+
require_err_msg.DeviceType.LawnMower,
|
|
100633
|
+
require_err_msg.DeviceType.MediaPlayer,
|
|
100634
|
+
require_err_msg.DeviceType.WaterHeater,
|
|
100635
|
+
require_err_msg.DeviceType.Humidifier,
|
|
100636
|
+
require_err_msg.DeviceType.Fan,
|
|
100637
|
+
require_err_msg.DeviceType.Climate,
|
|
100638
|
+
require_err_msg.DeviceType.Thermostat,
|
|
100639
|
+
require_err_msg.DeviceType.PetFeeder
|
|
100640
|
+
],
|
|
100641
|
+
apply: "add-or-replace",
|
|
100642
|
+
vocabularyCap: "running-state",
|
|
100643
|
+
vocabularyStateField: "running",
|
|
100644
|
+
sources: [
|
|
100645
|
+
{
|
|
100646
|
+
kind: "switch",
|
|
100647
|
+
transformKinds: ["identity"]
|
|
100648
|
+
},
|
|
100649
|
+
{
|
|
100650
|
+
kind: "binary",
|
|
100651
|
+
transformKinds: ["identity", "invert"]
|
|
100652
|
+
},
|
|
100653
|
+
{
|
|
100654
|
+
kind: "numeric",
|
|
100655
|
+
requiredUnit: "W",
|
|
100656
|
+
transformKinds: ["threshold"]
|
|
100657
|
+
}
|
|
100658
|
+
],
|
|
100659
|
+
sourceReport: {
|
|
100660
|
+
status: "assignment-status",
|
|
100661
|
+
runtimeField: "source",
|
|
100662
|
+
nativeValue: "native",
|
|
100663
|
+
assignedValue: "assigned"
|
|
100664
|
+
},
|
|
100665
|
+
advancedExpression: true,
|
|
100666
|
+
path: "running",
|
|
100667
|
+
valueKind: "boolean",
|
|
100668
|
+
nullable: true,
|
|
100669
|
+
companions: [
|
|
100670
|
+
{
|
|
100671
|
+
kind: "constant",
|
|
100672
|
+
path: "source",
|
|
100673
|
+
value: "assigned",
|
|
100674
|
+
when: "always"
|
|
100675
|
+
},
|
|
100676
|
+
{
|
|
100677
|
+
kind: "constant",
|
|
100678
|
+
path: "phase",
|
|
100679
|
+
value: null,
|
|
100680
|
+
when: "always"
|
|
100681
|
+
},
|
|
100682
|
+
{
|
|
100683
|
+
kind: "clock",
|
|
100684
|
+
path: "lastFetchedAt",
|
|
100685
|
+
when: "always"
|
|
100686
|
+
},
|
|
100687
|
+
{
|
|
100688
|
+
kind: "transition-time",
|
|
100689
|
+
path: "since",
|
|
100690
|
+
sourceChangedAt: "prefer"
|
|
100691
|
+
}
|
|
100692
|
+
]
|
|
100693
|
+
}]
|
|
100694
|
+
}
|
|
100695
|
+
};
|
|
100696
|
+
//#endregion
|
|
100697
|
+
//#region src/composition/customize/override-draft.ts
|
|
100698
|
+
/**
|
|
100699
|
+
* A saved Customize assignment (D936). The schema is the type: callers use
|
|
100700
|
+
* `z.infer`, they do not restate the shape.
|
|
100701
|
+
*/
|
|
100702
|
+
var OverrideSourceSchema = zod.z.object({
|
|
100703
|
+
addonId: zod.z.string().min(1),
|
|
100704
|
+
stableId: zod.z.string().min(1),
|
|
100705
|
+
cap: zod.z.string().min(1),
|
|
100706
|
+
fieldPath: zod.z.string().min(1)
|
|
100707
|
+
});
|
|
100708
|
+
var IdentityTransformDraftSchema = zod.z.object({ kind: zod.z.literal("identity") });
|
|
100709
|
+
var InvertTransformDraftSchema = zod.z.object({ kind: zod.z.literal("invert") });
|
|
100710
|
+
var ThresholdTransformDraftSchema = zod.z.object({
|
|
100711
|
+
kind: zod.z.literal("threshold"),
|
|
100712
|
+
comparison: zod.z.enum(["gte", "lte"]),
|
|
100713
|
+
threshold: zod.z.number(),
|
|
100714
|
+
startDwellMs: zod.z.number().nonnegative(),
|
|
100715
|
+
stopDwellMs: zod.z.number().nonnegative()
|
|
100716
|
+
});
|
|
100717
|
+
var LinearTransformDraftSchema = zod.z.object({
|
|
100718
|
+
kind: zod.z.literal("linear"),
|
|
100719
|
+
scale: zod.z.number(),
|
|
100720
|
+
offset: zod.z.number(),
|
|
100721
|
+
clampMin: zod.z.number().optional(),
|
|
100722
|
+
clampMax: zod.z.number().optional()
|
|
100723
|
+
});
|
|
100724
|
+
var EnumMapTransformDraftSchema = zod.z.object({
|
|
100725
|
+
kind: zod.z.literal("enum-map"),
|
|
100726
|
+
mapping: zod.z.record(zod.z.string(), zod.z.string().nullable())
|
|
100727
|
+
});
|
|
100728
|
+
var NumberBridgeTransformDraftSchema = zod.z.object({ kind: zod.z.literal("number") });
|
|
100729
|
+
var CustomizeTransformDraftSchema = zod.z.discriminatedUnion("kind", [
|
|
100730
|
+
IdentityTransformDraftSchema,
|
|
100731
|
+
InvertTransformDraftSchema,
|
|
100732
|
+
ThresholdTransformDraftSchema,
|
|
100733
|
+
LinearTransformDraftSchema,
|
|
100734
|
+
EnumMapTransformDraftSchema,
|
|
100735
|
+
NumberBridgeTransformDraftSchema
|
|
100736
|
+
]);
|
|
100737
|
+
var ScalarOverrideDraftSchema = zod.z.object({
|
|
100738
|
+
kind: zod.z.literal("scalar"),
|
|
100739
|
+
cap: zod.z.string().min(1),
|
|
100740
|
+
targetId: zod.z.string().min(1),
|
|
100741
|
+
source: OverrideSourceSchema,
|
|
100742
|
+
transform: CustomizeTransformDraftSchema
|
|
100743
|
+
});
|
|
100744
|
+
var KeyedArrayOverrideDraftSchema = zod.z.object({
|
|
100745
|
+
kind: zod.z.literal("keyedArray"),
|
|
100746
|
+
cap: zod.z.string().min(1),
|
|
100747
|
+
targetId: zod.z.string().min(1),
|
|
100748
|
+
key: zod.z.string().min(1),
|
|
100749
|
+
label: zod.z.string().min(1),
|
|
100750
|
+
fieldPath: zod.z.string().min(1),
|
|
100751
|
+
source: OverrideSourceSchema,
|
|
100752
|
+
transform: CustomizeTransformDraftSchema
|
|
100753
|
+
});
|
|
100754
|
+
var PulseOverrideDraftSchema = zod.z.object({
|
|
100755
|
+
kind: zod.z.literal("pulse"),
|
|
100756
|
+
cap: zod.z.string().min(1),
|
|
100757
|
+
targetId: zod.z.string().min(1),
|
|
100758
|
+
enabled: zod.z.boolean(),
|
|
100759
|
+
debounceMs: zod.z.number().nonnegative(),
|
|
100760
|
+
sources: zod.z.array(OverrideSourceSchema).min(1)
|
|
100761
|
+
});
|
|
100762
|
+
var SpanSourceDraftSchema = OverrideSourceSchema.extend({ mode: zod.z.enum([
|
|
100763
|
+
"in-addition",
|
|
100764
|
+
"confirm",
|
|
100765
|
+
"replace"
|
|
100766
|
+
]).optional() });
|
|
100767
|
+
var SpanOverrideDraftSchema = zod.z.object({
|
|
100768
|
+
kind: zod.z.literal("span"),
|
|
100769
|
+
cap: zod.z.string().min(1),
|
|
100770
|
+
targetId: zod.z.string().min(1),
|
|
100771
|
+
timeoutMs: zod.z.number().nonnegative(),
|
|
100772
|
+
cooldownMs: zod.z.number().nonnegative().optional(),
|
|
100773
|
+
sources: zod.z.array(SpanSourceDraftSchema)
|
|
100774
|
+
});
|
|
100775
|
+
var OverrideDraftSchema = zod.z.discriminatedUnion("kind", [
|
|
100776
|
+
ScalarOverrideDraftSchema,
|
|
100777
|
+
KeyedArrayOverrideDraftSchema,
|
|
100778
|
+
PulseOverrideDraftSchema,
|
|
100779
|
+
SpanOverrideDraftSchema
|
|
100780
|
+
]);
|
|
100781
|
+
/** Effective authority for one declared target. Not a second stored switch. */
|
|
100782
|
+
var CustomizeAssignmentStatusSchema = zod.z.object({
|
|
100783
|
+
targetId: zod.z.string().min(1),
|
|
100784
|
+
configured: zod.z.boolean(),
|
|
100785
|
+
source: zod.z.enum(["native", "assigned"]),
|
|
100786
|
+
state: zod.z.enum([
|
|
100787
|
+
"active",
|
|
100788
|
+
"stale",
|
|
100789
|
+
"released",
|
|
100790
|
+
"unavailable"
|
|
100791
|
+
]),
|
|
100792
|
+
reason: zod.z.string().nullable()
|
|
100793
|
+
});
|
|
100794
|
+
//#endregion
|
|
100795
|
+
//#region src/composition/customize/field-source.ts
|
|
100796
|
+
function fromRead(source, cap, fieldPath) {
|
|
100797
|
+
return {
|
|
100798
|
+
kind: "from",
|
|
100799
|
+
source,
|
|
100800
|
+
cap,
|
|
100801
|
+
fieldPath
|
|
100802
|
+
};
|
|
100803
|
+
}
|
|
100804
|
+
function expression(expr, bindings) {
|
|
100805
|
+
return {
|
|
100806
|
+
kind: "expression",
|
|
100807
|
+
expr,
|
|
100808
|
+
bindings
|
|
100809
|
+
};
|
|
100810
|
+
}
|
|
100811
|
+
function literal(expr) {
|
|
100812
|
+
return expression(expr, {});
|
|
100813
|
+
}
|
|
100814
|
+
function isLiteral(source, expr) {
|
|
100815
|
+
return source?.kind === "expression" && source.expr === expr && Object.keys(source.bindings).length === 0;
|
|
100816
|
+
}
|
|
100817
|
+
//#endregion
|
|
100818
|
+
//#region src/composition/customize/scalar-expr.ts
|
|
100819
|
+
var UNSIGNED = /^\d+(?:\.\d+)?$/;
|
|
100820
|
+
var SIGNED = /^-?\d+(?:\.\d+)?$/;
|
|
100821
|
+
var DWELL = /^dwell\(x (>=|<=) (\d+(?:\.\d+)?), (\d+(?:\.\d+)?), (\d+(?:\.\d+)?)\)$/;
|
|
100822
|
+
var LINEAR_CLAMP = /^clamp\((x|number\(x\)) \* (-?\d+(?:\.\d+)?) \+ (-?\d+(?:\.\d+)?), (-?\d+(?:\.\d+)?), (-?\d+(?:\.\d+)?)\)$/;
|
|
100823
|
+
var LINEAR_BARE = /^(x|number\(x\)) \* (-?\d+(?:\.\d+)?) \+ (-?\d+(?:\.\d+)?)$/;
|
|
100824
|
+
var IDENT = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
100825
|
+
function unsignedToken(value) {
|
|
100826
|
+
return token(value, UNSIGNED);
|
|
100827
|
+
}
|
|
100828
|
+
function signedToken(value) {
|
|
100829
|
+
return token(value, SIGNED);
|
|
100830
|
+
}
|
|
100831
|
+
function constantExpr(value) {
|
|
100832
|
+
if (typeof value === "string") return JSON.stringify(value);
|
|
100833
|
+
if (typeof value === "number") return signedToken(value);
|
|
100834
|
+
if (typeof value === "boolean") return value ? "true" : "false";
|
|
100835
|
+
return "null";
|
|
100836
|
+
}
|
|
100837
|
+
function isIdentifier(path) {
|
|
100838
|
+
return IDENT.test(path);
|
|
100839
|
+
}
|
|
100840
|
+
function dwellExpr(comparison, threshold, start, stop) {
|
|
100841
|
+
return `dwell(x ${comparison === "gte" ? ">=" : "<="} ${threshold}, ${start}, ${stop})`;
|
|
100842
|
+
}
|
|
100843
|
+
function linearExpr(inner, scale, offset, clampMin, clampMax) {
|
|
100844
|
+
const arithmetic = `${inner} * ${scale} + ${offset}`;
|
|
100845
|
+
if (clampMin === null || clampMax === null) return arithmetic;
|
|
100846
|
+
return `clamp(${arithmetic}, ${clampMin}, ${clampMax})`;
|
|
100847
|
+
}
|
|
100848
|
+
function parseDwell(expr) {
|
|
100849
|
+
const match = DWELL.exec(expr);
|
|
100850
|
+
if (match === null) return null;
|
|
100851
|
+
const threshold = Number(match[2]);
|
|
100852
|
+
const startDwellMs = Number(match[3]);
|
|
100853
|
+
const stopDwellMs = Number(match[4]);
|
|
100854
|
+
if (!Number.isFinite(threshold) || !Number.isFinite(startDwellMs) || !Number.isFinite(stopDwellMs)) return null;
|
|
100855
|
+
return {
|
|
100856
|
+
comparison: match[1] === "<=" ? "lte" : "gte",
|
|
100857
|
+
threshold,
|
|
100858
|
+
startDwellMs,
|
|
100859
|
+
stopDwellMs
|
|
100860
|
+
};
|
|
100861
|
+
}
|
|
100862
|
+
function parseLinear(expr) {
|
|
100863
|
+
const clamped = LINEAR_CLAMP.exec(expr);
|
|
100864
|
+
if (clamped !== null) return linearFrom(clamped[1], clamped[2], clamped[3], clamped[4], clamped[5]);
|
|
100865
|
+
const bare = LINEAR_BARE.exec(expr);
|
|
100866
|
+
if (bare === null) return null;
|
|
100867
|
+
return linearFrom(bare[1], bare[2], bare[3], void 0, void 0);
|
|
100868
|
+
}
|
|
100869
|
+
function singleFrom(source) {
|
|
100870
|
+
if (source.kind === "from") return {
|
|
100871
|
+
cap: source.cap,
|
|
100872
|
+
fieldPath: source.fieldPath,
|
|
100873
|
+
addonId: source.source.addonId,
|
|
100874
|
+
stableId: source.source.stableId
|
|
100875
|
+
};
|
|
100876
|
+
if (source.kind !== "expression" || Object.keys(source.bindings).length !== 1) return null;
|
|
100877
|
+
const bound = source.bindings["x"];
|
|
100878
|
+
if (bound === void 0 || bound.kind !== "from") return null;
|
|
100879
|
+
return {
|
|
100880
|
+
cap: bound.cap,
|
|
100881
|
+
fieldPath: bound.fieldPath,
|
|
100882
|
+
addonId: bound.source.addonId,
|
|
100883
|
+
stableId: bound.source.stableId
|
|
100884
|
+
};
|
|
100885
|
+
}
|
|
100886
|
+
function token(value, pattern) {
|
|
100887
|
+
if (!Number.isFinite(value)) return null;
|
|
100888
|
+
const text = Object.is(value, -0) ? "0" : String(value);
|
|
100889
|
+
return pattern.test(text) ? text : null;
|
|
100890
|
+
}
|
|
100891
|
+
function linearFrom(inner, scale, offset, clampMin, clampMax) {
|
|
100892
|
+
if (inner !== "x" && inner !== "number(x)") return null;
|
|
100893
|
+
if (scale === void 0 || offset === void 0) return null;
|
|
100894
|
+
const parsedScale = Number(scale);
|
|
100895
|
+
const parsedOffset = Number(offset);
|
|
100896
|
+
if (!Number.isFinite(parsedScale) || !Number.isFinite(parsedOffset)) return null;
|
|
100897
|
+
if (clampMin === void 0 || clampMax === void 0) return {
|
|
100898
|
+
inner,
|
|
100899
|
+
scale: parsedScale,
|
|
100900
|
+
offset: parsedOffset
|
|
100901
|
+
};
|
|
100902
|
+
const parsedMin = Number(clampMin);
|
|
100903
|
+
const parsedMax = Number(clampMax);
|
|
100904
|
+
if (!Number.isFinite(parsedMin) || !Number.isFinite(parsedMax)) return null;
|
|
100905
|
+
return {
|
|
100906
|
+
inner,
|
|
100907
|
+
scale: parsedScale,
|
|
100908
|
+
offset: parsedOffset,
|
|
100909
|
+
clampMin: parsedMin,
|
|
100910
|
+
clampMax: parsedMax
|
|
100911
|
+
};
|
|
100912
|
+
}
|
|
100913
|
+
//#endregion
|
|
100914
|
+
//#region src/composition/customize/scalar-compile.ts
|
|
100915
|
+
var catalog$4 = CAP_CUSTOMIZE_CATALOG;
|
|
100916
|
+
function compileScalarOverride(input) {
|
|
100917
|
+
const target = catalogTarget$4(input.draft.cap, input.draft.targetId);
|
|
100918
|
+
if (target === null || target.cardinality !== "scalar" || target.path === void 0) return fail$2("target");
|
|
100919
|
+
if (input.draft.transform.kind === "enum-map") return fail$2("enum");
|
|
100920
|
+
const source = sourceSpec$1(target, input.sourceValueKind, input.draft.source.cap);
|
|
100921
|
+
if (source === null) return fail$2("source-kind");
|
|
100922
|
+
if (source.requiredUnit !== void 0 && input.sourceUnit !== source.requiredUnit) return fail$2("unit");
|
|
100923
|
+
const allowed = input.draft.transform.kind === "number" ? "identity" : input.draft.transform.kind;
|
|
100924
|
+
if (!source.transformKinds.includes(allowed)) return fail$2("transform");
|
|
100925
|
+
const value = compileValue$1(input);
|
|
100926
|
+
if (!value.ok) return value;
|
|
100927
|
+
const fields = compileCompanions$1(input, target, value.value);
|
|
100928
|
+
if (!fields.ok) return fields;
|
|
100929
|
+
return {
|
|
100930
|
+
ok: true,
|
|
100931
|
+
value: {
|
|
100932
|
+
kind: "fields",
|
|
100933
|
+
cap: input.draft.cap,
|
|
100934
|
+
fields: fields.value
|
|
100935
|
+
}
|
|
100936
|
+
};
|
|
100937
|
+
}
|
|
100938
|
+
function fail$2(reason) {
|
|
100939
|
+
return {
|
|
100940
|
+
ok: false,
|
|
100941
|
+
reason
|
|
100942
|
+
};
|
|
100943
|
+
}
|
|
100944
|
+
function catalogTarget$4(cap, targetId) {
|
|
100945
|
+
const entry = catalog$4[cap];
|
|
100946
|
+
if (entry === void 0) return null;
|
|
100947
|
+
return entry.targets.find((target) => target.id === targetId) ?? null;
|
|
100948
|
+
}
|
|
100949
|
+
function sourceSpec$1(target, valueKind, sourceCap) {
|
|
100950
|
+
if (valueKind === "boolean" && sourceCap === "switch") return target.sources.find((source) => source.kind === "switch") ?? null;
|
|
100951
|
+
if (valueKind === "boolean") return target.sources.find((source) => source.kind === "binary") ?? fieldSource(target, "boolean");
|
|
100952
|
+
if (valueKind === "number") return target.sources.find((source) => source.kind === "numeric") ?? fieldSource(target, "number");
|
|
100953
|
+
return fieldSource(target, "string");
|
|
100954
|
+
}
|
|
100955
|
+
function fieldSource(target, valueKind) {
|
|
100956
|
+
return target.sources.find((source) => source.kind === "field" && (source.valueKinds ?? []).includes(valueKind)) ?? null;
|
|
100957
|
+
}
|
|
100958
|
+
function compileValue$1(input) {
|
|
100959
|
+
const read = fromRead(refOf$1(input.draft), input.draft.source.cap, input.draft.source.fieldPath);
|
|
100960
|
+
const transform = input.draft.transform;
|
|
100961
|
+
if (transform.kind === "identity" || transform.kind === "number") return {
|
|
100962
|
+
ok: true,
|
|
100963
|
+
value: identityValue(read, input.sourceValueKind)
|
|
100964
|
+
};
|
|
100965
|
+
if (transform.kind === "invert") {
|
|
100966
|
+
if (input.sourceValueKind !== "boolean") return fail$2("source-kind");
|
|
100967
|
+
return {
|
|
100968
|
+
ok: true,
|
|
100969
|
+
value: expression("!x", { x: read })
|
|
100970
|
+
};
|
|
100971
|
+
}
|
|
100972
|
+
if (transform.kind === "threshold") return thresholdValue(transform, read);
|
|
100973
|
+
if (transform.kind === "linear") return linearValue$1(transform, read, input.sourceValueKind);
|
|
100974
|
+
return fail$2("transform");
|
|
100975
|
+
}
|
|
100976
|
+
function identityValue(read, valueKind) {
|
|
100977
|
+
if (valueKind === "string") return expression("number(x)", { x: read });
|
|
100978
|
+
return read;
|
|
100979
|
+
}
|
|
100980
|
+
function thresholdValue(transform, read) {
|
|
100981
|
+
const threshold = unsignedToken(transform.threshold);
|
|
100982
|
+
if (threshold === null) return fail$2("threshold");
|
|
100983
|
+
const start = unsignedToken(transform.startDwellMs);
|
|
100984
|
+
const stop = unsignedToken(transform.stopDwellMs);
|
|
100985
|
+
if (start === null || stop === null) return fail$2("dwell");
|
|
100986
|
+
return {
|
|
100987
|
+
ok: true,
|
|
100988
|
+
value: expression(dwellExpr(transform.comparison, threshold, start, stop), { x: read })
|
|
100989
|
+
};
|
|
100990
|
+
}
|
|
100991
|
+
function linearValue$1(transform, read, valueKind) {
|
|
100992
|
+
const scale = signedToken(transform.scale);
|
|
100993
|
+
const offset = signedToken(transform.offset);
|
|
100994
|
+
if (scale === null || offset === null) return fail$2("scale");
|
|
100995
|
+
const clamps = clampTokens$1(transform.clampMin, transform.clampMax);
|
|
100996
|
+
if (!clamps.ok) return clamps;
|
|
100997
|
+
return {
|
|
100998
|
+
ok: true,
|
|
100999
|
+
value: expression(linearExpr(valueKind === "string" ? "number(x)" : "x", scale, offset, clamps.value.min, clamps.value.max), { x: read })
|
|
101000
|
+
};
|
|
101001
|
+
}
|
|
101002
|
+
function clampTokens$1(clampMin, clampMax) {
|
|
101003
|
+
if (clampMin === void 0 && clampMax === void 0) return {
|
|
101004
|
+
ok: true,
|
|
101005
|
+
value: {
|
|
101006
|
+
min: null,
|
|
101007
|
+
max: null
|
|
101008
|
+
}
|
|
101009
|
+
};
|
|
101010
|
+
if (clampMin === void 0 || clampMax === void 0) return fail$2("clamp");
|
|
101011
|
+
const min = signedToken(clampMin);
|
|
101012
|
+
const max = signedToken(clampMax);
|
|
101013
|
+
if (min === null || max === null || clampMin > clampMax) return fail$2("clamp");
|
|
101014
|
+
return {
|
|
101015
|
+
ok: true,
|
|
101016
|
+
value: {
|
|
101017
|
+
min,
|
|
101018
|
+
max
|
|
101019
|
+
}
|
|
101020
|
+
};
|
|
101021
|
+
}
|
|
101022
|
+
function compileCompanions$1(input, target, value) {
|
|
101023
|
+
if (target.path === void 0) return fail$2("target");
|
|
101024
|
+
const path = target.path;
|
|
101025
|
+
return (target.companions ?? []).filter((companion) => companionIncluded$1(companion, input.apply)).reduce((acc, companion) => {
|
|
101026
|
+
if (!acc.ok) return acc;
|
|
101027
|
+
const built = companionField(input, path, companion);
|
|
101028
|
+
if (!built.ok) return {
|
|
101029
|
+
ok: false,
|
|
101030
|
+
reason: built.reason
|
|
101031
|
+
};
|
|
101032
|
+
return {
|
|
101033
|
+
ok: true,
|
|
101034
|
+
value: {
|
|
101035
|
+
...acc.value,
|
|
101036
|
+
[companion.path]: built.value
|
|
101037
|
+
}
|
|
101038
|
+
};
|
|
101039
|
+
}, {
|
|
101040
|
+
ok: true,
|
|
101041
|
+
value: { [path]: value }
|
|
101042
|
+
});
|
|
101043
|
+
}
|
|
101044
|
+
function companionIncluded$1(companion, apply) {
|
|
101045
|
+
if (companion.kind === "transition-time") return true;
|
|
101046
|
+
return companion.when === "always" || apply === "add";
|
|
101047
|
+
}
|
|
101048
|
+
function companionField(input, path, companion) {
|
|
101049
|
+
if (companion.kind === "constant") {
|
|
101050
|
+
const expr = constantExpr(companion.value);
|
|
101051
|
+
if (expr === null) return fail$2("scale");
|
|
101052
|
+
return {
|
|
101053
|
+
ok: true,
|
|
101054
|
+
value: literal(expr)
|
|
101055
|
+
};
|
|
101056
|
+
}
|
|
101057
|
+
if (companion.kind === "clock") return {
|
|
101058
|
+
ok: true,
|
|
101059
|
+
value: literal("now")
|
|
101060
|
+
};
|
|
101061
|
+
return transitionField(input, path, companion.sourceChangedAt);
|
|
101062
|
+
}
|
|
101063
|
+
function transitionField(input, path, sourceChangedAt) {
|
|
101064
|
+
if (sourceChangedAt === "prefer" && input.sourceValueKind === "boolean" && input.changedAtField !== null && isIdentifier(input.changedAtField)) return {
|
|
101065
|
+
ok: true,
|
|
101066
|
+
value: fromRead(refOf$1(input.draft), input.draft.source.cap, input.changedAtField)
|
|
101067
|
+
};
|
|
101068
|
+
if (!isIdentifier(path)) return fail$2("transform");
|
|
101069
|
+
const bindings = { [path]: fromRead(input.device, input.draft.cap, path) };
|
|
101070
|
+
return {
|
|
101071
|
+
ok: true,
|
|
101072
|
+
value: expression(`latchedAt(${path})`, bindings)
|
|
101073
|
+
};
|
|
101074
|
+
}
|
|
101075
|
+
function refOf$1(draft) {
|
|
101076
|
+
return {
|
|
101077
|
+
addonId: draft.source.addonId,
|
|
101078
|
+
stableId: draft.source.stableId
|
|
101079
|
+
};
|
|
101080
|
+
}
|
|
101081
|
+
//#endregion
|
|
101082
|
+
//#region src/composition/customize/normalize.ts
|
|
101083
|
+
function sortKeys(value) {
|
|
101084
|
+
if (Array.isArray(value)) return value.map(sortKeys);
|
|
101085
|
+
if (typeof value !== "object" || value === null) return value;
|
|
101086
|
+
return Object.fromEntries(Object.entries(value).toSorted(([a], [b]) => a.localeCompare(b)).map(([key, inner]) => [key, sortKeys(inner)]));
|
|
101087
|
+
}
|
|
101088
|
+
/** Key order is not part of the stored contract. Array order is. */
|
|
101089
|
+
function normalizeStored(stored) {
|
|
101090
|
+
return sortKeys(stored);
|
|
101091
|
+
}
|
|
101092
|
+
function sameStored(a, b) {
|
|
101093
|
+
return JSON.stringify(normalizeStored(a)) === JSON.stringify(normalizeStored(b));
|
|
101094
|
+
}
|
|
101095
|
+
//#endregion
|
|
101096
|
+
//#region src/composition/customize/scalar-decode.ts
|
|
101097
|
+
var catalog$3 = CAP_CUSTOMIZE_CATALOG;
|
|
101098
|
+
function decodeScalarOverride(input) {
|
|
101099
|
+
const target = catalogTarget$3(input.cap, input.targetId);
|
|
101100
|
+
if (target === null || target.cardinality !== "scalar" || target.path === void 0) return null;
|
|
101101
|
+
if (input.feature.cap !== input.cap || input.feature.kind !== "fields") return null;
|
|
101102
|
+
const outputKind = scalarOutputKind(target.valueKind);
|
|
101103
|
+
if (outputKind === null) return null;
|
|
101104
|
+
const value = input.feature.fields[target.path];
|
|
101105
|
+
const read = readValue(value, outputKind, input.cap, input.targetId);
|
|
101106
|
+
if (read === null) return null;
|
|
101107
|
+
const apply = inferApply$1(target, input.feature.fields);
|
|
101108
|
+
if (apply === null) return null;
|
|
101109
|
+
const changedAtField = inferChangedAt(target, input.feature.fields, read);
|
|
101110
|
+
const sourceUnit = unitFor(target, read.sourceValueKind, read.draft.source.cap);
|
|
101111
|
+
const decoded = {
|
|
101112
|
+
...read,
|
|
101113
|
+
apply,
|
|
101114
|
+
changedAtField,
|
|
101115
|
+
sourceUnit
|
|
101116
|
+
};
|
|
101117
|
+
return reproduces$1(decoded, input.device, input.feature) ? decoded : null;
|
|
101118
|
+
}
|
|
101119
|
+
function catalogTarget$3(cap, targetId) {
|
|
101120
|
+
const entry = catalog$3[cap];
|
|
101121
|
+
if (entry === void 0) return null;
|
|
101122
|
+
return entry.targets.find((target) => target.id === targetId) ?? null;
|
|
101123
|
+
}
|
|
101124
|
+
function scalarOutputKind(valueKind) {
|
|
101125
|
+
if (valueKind === "boolean" || valueKind === "number" || valueKind === "string") return valueKind;
|
|
101126
|
+
return null;
|
|
101127
|
+
}
|
|
101128
|
+
function readValue(field, outputKind, cap, targetId) {
|
|
101129
|
+
if (field === void 0) return null;
|
|
101130
|
+
if (field.kind === "from") return drafted(field, { kind: "identity" }, outputKind, cap, targetId);
|
|
101131
|
+
if (field.kind !== "expression") return null;
|
|
101132
|
+
if (field.expr === "number(x)" && outputKind === "number") return drafted(field, { kind: "identity" }, "string", cap, targetId);
|
|
101133
|
+
if (field.expr === "!x" && outputKind === "boolean") return drafted(field, { kind: "invert" }, "boolean", cap, targetId);
|
|
101134
|
+
const dwell = parseDwell(field.expr);
|
|
101135
|
+
if (dwell !== null) return drafted(field, {
|
|
101136
|
+
kind: "threshold",
|
|
101137
|
+
comparison: dwell.comparison,
|
|
101138
|
+
threshold: dwell.threshold,
|
|
101139
|
+
startDwellMs: dwell.startDwellMs,
|
|
101140
|
+
stopDwellMs: dwell.stopDwellMs
|
|
101141
|
+
}, "number", cap, targetId);
|
|
101142
|
+
const linear = parseLinear(field.expr);
|
|
101143
|
+
if (linear === null || outputKind !== "number") return null;
|
|
101144
|
+
return drafted(field, {
|
|
101145
|
+
kind: "linear",
|
|
101146
|
+
scale: linear.scale,
|
|
101147
|
+
offset: linear.offset,
|
|
101148
|
+
...linear.clampMin === void 0 || linear.clampMax === void 0 ? {} : {
|
|
101149
|
+
clampMin: linear.clampMin,
|
|
101150
|
+
clampMax: linear.clampMax
|
|
101151
|
+
}
|
|
101152
|
+
}, linear.inner === "number(x)" ? "string" : "number", cap, targetId);
|
|
101153
|
+
}
|
|
101154
|
+
function drafted(field, transform, sourceValueKind, cap, targetId) {
|
|
101155
|
+
const bound = singleFrom(field);
|
|
101156
|
+
if (bound === null) return null;
|
|
101157
|
+
return {
|
|
101158
|
+
sourceValueKind,
|
|
101159
|
+
draft: {
|
|
101160
|
+
kind: "scalar",
|
|
101161
|
+
cap,
|
|
101162
|
+
targetId,
|
|
101163
|
+
source: {
|
|
101164
|
+
addonId: bound.addonId,
|
|
101165
|
+
stableId: bound.stableId,
|
|
101166
|
+
cap: bound.cap,
|
|
101167
|
+
fieldPath: bound.fieldPath
|
|
101168
|
+
},
|
|
101169
|
+
transform
|
|
101170
|
+
}
|
|
101171
|
+
};
|
|
101172
|
+
}
|
|
101173
|
+
function inferApply$1(target, fields) {
|
|
101174
|
+
const addPaths = (target.companions ?? []).flatMap((companion) => companion.kind !== "transition-time" && companion.when === "add" ? [companion.path] : []);
|
|
101175
|
+
if (addPaths.length === 0) return "replace";
|
|
101176
|
+
const present = addPaths.filter((path) => fields[path] !== void 0);
|
|
101177
|
+
if (present.length === addPaths.length) return "add";
|
|
101178
|
+
if (present.length === 0) return "replace";
|
|
101179
|
+
return null;
|
|
101180
|
+
}
|
|
101181
|
+
function inferChangedAt(target, fields, read) {
|
|
101182
|
+
if (read.sourceValueKind !== "boolean") return null;
|
|
101183
|
+
const transition = (target.companions ?? []).find((companion) => companion.kind === "transition-time");
|
|
101184
|
+
if (transition === void 0 || transition.sourceChangedAt !== "prefer") return null;
|
|
101185
|
+
const since = fields[transition.path];
|
|
101186
|
+
if (since?.kind !== "from") return null;
|
|
101187
|
+
if (since.cap !== read.draft.source.cap) return null;
|
|
101188
|
+
if (since.source.addonId !== read.draft.source.addonId || since.source.stableId !== read.draft.source.stableId) return null;
|
|
101189
|
+
return since.fieldPath;
|
|
101190
|
+
}
|
|
101191
|
+
function unitFor(target, valueKind, sourceCap) {
|
|
101192
|
+
if (valueKind === "boolean" && sourceCap === "switch") return null;
|
|
101193
|
+
if (valueKind === "number") return target.sources.find((source) => source.kind === "numeric")?.requiredUnit ?? null;
|
|
101194
|
+
return null;
|
|
101195
|
+
}
|
|
101196
|
+
function reproduces$1(decoded, device, stored) {
|
|
101197
|
+
const compiled = compileScalarOverride({
|
|
101198
|
+
draft: decoded.draft,
|
|
101199
|
+
device,
|
|
101200
|
+
apply: decoded.apply,
|
|
101201
|
+
sourceValueKind: decoded.sourceValueKind,
|
|
101202
|
+
changedAtField: decoded.changedAtField,
|
|
101203
|
+
sourceUnit: decoded.sourceUnit
|
|
101204
|
+
});
|
|
101205
|
+
if (!compiled.ok) return false;
|
|
101206
|
+
return sameFeature$2(compiled.value, stored);
|
|
101207
|
+
}
|
|
101208
|
+
function sameFeature$2(compiled, stored) {
|
|
101209
|
+
return sameStored(wrap$1(withoutEnabled(compiled)), wrap$1(withoutEnabled(stored)));
|
|
101210
|
+
}
|
|
101211
|
+
function withoutEnabled(feature) {
|
|
101212
|
+
const { enabled: _enabled, ...rest } = feature;
|
|
101213
|
+
return rest;
|
|
101214
|
+
}
|
|
101215
|
+
function wrap$1(feature) {
|
|
101216
|
+
return {
|
|
101217
|
+
family: "composition",
|
|
101218
|
+
target: {
|
|
101219
|
+
addonId: "t",
|
|
101220
|
+
stableId: "t"
|
|
101221
|
+
},
|
|
101222
|
+
feature
|
|
101223
|
+
};
|
|
101224
|
+
}
|
|
101225
|
+
//#endregion
|
|
101226
|
+
//#region src/composition/customize/scalar-status.ts
|
|
101227
|
+
function projectScalarAssignment(input) {
|
|
101228
|
+
if (input.stored.kind === "pending") return unanswered$1(input.targetId, "pending", null);
|
|
101229
|
+
if (input.stored.kind === "unknown") return unanswered$1(input.targetId, "unknown", input.stored.reason ?? "unknown");
|
|
101230
|
+
if (input.stored.value === null) return native$2(input.targetId);
|
|
101231
|
+
const decoded = decodeScalarOverride({
|
|
101232
|
+
feature: input.stored.value,
|
|
101233
|
+
device: input.device,
|
|
101234
|
+
cap: input.cap,
|
|
101235
|
+
targetId: input.targetId
|
|
101236
|
+
});
|
|
101237
|
+
if (decoded === null) return {
|
|
101238
|
+
text: "unknown",
|
|
101239
|
+
status: status$1(input.targetId, true, "assigned", "unavailable", "not-canonical")
|
|
101240
|
+
};
|
|
101241
|
+
return projectDecoded$1(input, decoded.apply, sourceLabel(decoded.draft.source.cap, decoded.draft.source.fieldPath));
|
|
101242
|
+
}
|
|
101243
|
+
function projectDecoded$1(input, apply, label) {
|
|
101244
|
+
if (input.sourcePresence === "pending") return {
|
|
101245
|
+
text: "pending",
|
|
101246
|
+
status: status$1(input.targetId, true, "assigned", "stale", null)
|
|
101247
|
+
};
|
|
101248
|
+
if (input.sourcePresence === "unknown") return {
|
|
101249
|
+
text: "unknown",
|
|
101250
|
+
status: status$1(input.targetId, true, "assigned", "stale", input.sourceUnknownReason ?? "unknown")
|
|
101251
|
+
};
|
|
101252
|
+
if (input.sourcePresence === "absent" && apply === "replace") return {
|
|
101253
|
+
text: "Native · source missing",
|
|
101254
|
+
status: status$1(input.targetId, true, "native", "released", "source-missing")
|
|
101255
|
+
};
|
|
101256
|
+
if (input.sourcePresence === "absent") return {
|
|
101257
|
+
text: `Assigned · ${label}`,
|
|
101258
|
+
status: status$1(input.targetId, true, "assigned", "unavailable", "source-missing")
|
|
101259
|
+
};
|
|
101260
|
+
return {
|
|
101261
|
+
text: `Assigned · ${label}`,
|
|
101262
|
+
status: status$1(input.targetId, true, "assigned", "active", null)
|
|
101263
|
+
};
|
|
101264
|
+
}
|
|
101265
|
+
function native$2(targetId) {
|
|
101266
|
+
return {
|
|
101267
|
+
text: "Native",
|
|
101268
|
+
status: status$1(targetId, false, "native", "active", null)
|
|
101269
|
+
};
|
|
101270
|
+
}
|
|
101271
|
+
function unanswered$1(targetId, text, reason) {
|
|
101272
|
+
return {
|
|
101273
|
+
text,
|
|
101274
|
+
status: status$1(targetId, false, "native", text === "pending" ? "unavailable" : "stale", reason)
|
|
101275
|
+
};
|
|
101276
|
+
}
|
|
101277
|
+
function sourceLabel(cap, fieldPath) {
|
|
101278
|
+
return `${cap}.${fieldPath}`;
|
|
101279
|
+
}
|
|
101280
|
+
function status$1(targetId, configured, source, state, reason) {
|
|
101281
|
+
return {
|
|
101282
|
+
targetId,
|
|
101283
|
+
configured,
|
|
101284
|
+
source,
|
|
101285
|
+
state,
|
|
101286
|
+
reason
|
|
101287
|
+
};
|
|
101288
|
+
}
|
|
101289
|
+
//#endregion
|
|
101290
|
+
//#region src/composition/customize/event-compile.ts
|
|
101291
|
+
var catalog$2 = CAP_CUSTOMIZE_CATALOG;
|
|
101292
|
+
function compilePulseOverride(input) {
|
|
101293
|
+
const target = catalogTarget$2(input.draft.cap, input.draft.targetId);
|
|
101294
|
+
if (target === null || target.shape !== "pulse") return fail$1("target");
|
|
101295
|
+
const timestampPath = target.timestampPath;
|
|
101296
|
+
const counterPath = target.counterPath;
|
|
101297
|
+
if (timestampPath === void 0 || counterPath === void 0 || !isIdentifier(timestampPath) || !isIdentifier(counterPath)) return fail$1("path");
|
|
101298
|
+
if (!(target.edges ?? []).includes("rising")) return fail$1("edge");
|
|
101299
|
+
const pairs = pairSources(input);
|
|
101300
|
+
if (!pairs.ok) return pairs;
|
|
101301
|
+
if (pairs.value.length === 0) return fail$1("sources");
|
|
101302
|
+
const debounce = unsignedToken(input.draft.debounceMs);
|
|
101303
|
+
if (debounce === null) return fail$1("debounce");
|
|
101304
|
+
const ordered = pairs.value.toSorted((a, b) => pairKey(a).localeCompare(pairKey(b)));
|
|
101305
|
+
return {
|
|
101306
|
+
ok: true,
|
|
101307
|
+
value: {
|
|
101308
|
+
kind: "fields",
|
|
101309
|
+
cap: input.draft.cap,
|
|
101310
|
+
enabled: input.draft.enabled,
|
|
101311
|
+
fields: {
|
|
101312
|
+
[timestampPath]: expression(pulseExpr(ordered.length, debounce), pulseBindings(ordered)),
|
|
101313
|
+
[counterPath]: expression(`count(${timestampPath})`, { [timestampPath]: fromRead(input.device, input.draft.cap, timestampPath) })
|
|
101314
|
+
}
|
|
101315
|
+
}
|
|
101316
|
+
};
|
|
101317
|
+
}
|
|
101318
|
+
function compileSpanOverride(input) {
|
|
101319
|
+
const target = catalogTarget$2(input.draft.cap, input.draft.targetId);
|
|
101320
|
+
if (target === null || target.shape !== "span") return fail$1("target");
|
|
101321
|
+
if (target.applyAuthority?.kind !== "camera-sensors") return fail$1("authority");
|
|
101322
|
+
if (input.draft.timeoutMs < 0 || !Number.isFinite(input.draft.timeoutMs)) return fail$1("timeout");
|
|
101323
|
+
if (target.cooldownMs === void 0 && input.draft.cooldownMs !== void 0) return fail$1("cooldown");
|
|
101324
|
+
if (input.draft.cooldownMs !== void 0 && input.draft.cooldownMs < 0) return fail$1("cooldown");
|
|
101325
|
+
const sensors = sensorEntries(input.draft.sources, input.device, target.sourceModes);
|
|
101326
|
+
if (!sensors.ok) return sensors;
|
|
101327
|
+
if (sensors.value.length === 0) return {
|
|
101328
|
+
ok: true,
|
|
101329
|
+
value: {
|
|
101330
|
+
config: null,
|
|
101331
|
+
timeoutMs: input.draft.timeoutMs,
|
|
101332
|
+
cooldownMs: input.draft.cooldownMs
|
|
101333
|
+
}
|
|
101334
|
+
};
|
|
101335
|
+
const parsed = CameraSensorsConfigSchema.safeParse({ sensors: sensors.value });
|
|
101336
|
+
if (!parsed.success) {
|
|
101337
|
+
const issue = parsed.error.issues[0];
|
|
101338
|
+
return fail$1(issue === void 0 ? "cameraSensors" : issue.message);
|
|
101339
|
+
}
|
|
101340
|
+
return {
|
|
101341
|
+
ok: true,
|
|
101342
|
+
value: {
|
|
101343
|
+
config: parsed.data,
|
|
101344
|
+
timeoutMs: input.draft.timeoutMs,
|
|
101345
|
+
cooldownMs: input.draft.cooldownMs
|
|
101346
|
+
}
|
|
101347
|
+
};
|
|
101348
|
+
}
|
|
101349
|
+
function pairSources(input) {
|
|
101350
|
+
if (input.changedAtFields.length !== input.draft.sources.length) return fail$1("changed-at");
|
|
101351
|
+
const pairs = input.draft.sources.map((source, index) => {
|
|
101352
|
+
return {
|
|
101353
|
+
source,
|
|
101354
|
+
changedAtField: input.changedAtFields[index] ?? ""
|
|
101355
|
+
};
|
|
101356
|
+
});
|
|
101357
|
+
if (pairs.some((pair) => pair.changedAtField.length === 0 || pair.source.fieldPath.length === 0)) return fail$1("changed-at");
|
|
101358
|
+
return {
|
|
101359
|
+
ok: true,
|
|
101360
|
+
value: pairs
|
|
101361
|
+
};
|
|
101362
|
+
}
|
|
101363
|
+
function pairKey(pair) {
|
|
101364
|
+
return `${pair.source.addonId}/${pair.source.stableId}#${pair.source.cap}#${pair.source.fieldPath}`;
|
|
101365
|
+
}
|
|
101366
|
+
function pulseExpr(count, debounce) {
|
|
101367
|
+
const roses = [];
|
|
101368
|
+
for (let index = 0; index < count; index += 1) roses.push(`rose(active${index}, changed${index}, ${debounce})`);
|
|
101369
|
+
return `latest(${roses.join(", ")})`;
|
|
101370
|
+
}
|
|
101371
|
+
function pulseBindings(pairs) {
|
|
101372
|
+
const bindings = {};
|
|
101373
|
+
pairs.forEach((pair, index) => {
|
|
101374
|
+
const ref = {
|
|
101375
|
+
addonId: pair.source.addonId,
|
|
101376
|
+
stableId: pair.source.stableId
|
|
101377
|
+
};
|
|
101378
|
+
bindings[`active${index}`] = fromRead(ref, pair.source.cap, pair.source.fieldPath);
|
|
101379
|
+
bindings[`changed${index}`] = fromRead(ref, pair.source.cap, pair.changedAtField);
|
|
101380
|
+
});
|
|
101381
|
+
return bindings;
|
|
101382
|
+
}
|
|
101383
|
+
function sensorEntries(sources, device, modes) {
|
|
101384
|
+
const entries = [];
|
|
101385
|
+
for (const source of sources) {
|
|
101386
|
+
if (source.addonId === device.addonId && source.stableId === device.stableId) return fail$1("self");
|
|
101387
|
+
const mode = source.mode ?? "in-addition";
|
|
101388
|
+
if (modes !== void 0 && !modes.includes(mode)) return fail$1("mode");
|
|
101389
|
+
if (modes === void 0 && source.mode !== void 0 && source.mode !== "in-addition") return fail$1("mode");
|
|
101390
|
+
entries.push({
|
|
101391
|
+
addonId: source.addonId,
|
|
101392
|
+
stableId: source.stableId,
|
|
101393
|
+
mode
|
|
101394
|
+
});
|
|
101395
|
+
}
|
|
101396
|
+
return {
|
|
101397
|
+
ok: true,
|
|
101398
|
+
value: entries
|
|
101399
|
+
};
|
|
101400
|
+
}
|
|
101401
|
+
function catalogTarget$2(cap, targetId) {
|
|
101402
|
+
const entry = catalog$2[cap];
|
|
101403
|
+
if (entry === void 0) return null;
|
|
101404
|
+
return entry.targets.find((target) => target.id === targetId) ?? null;
|
|
101405
|
+
}
|
|
101406
|
+
function fail$1(reason) {
|
|
101407
|
+
return {
|
|
101408
|
+
ok: false,
|
|
101409
|
+
reason
|
|
101410
|
+
};
|
|
101411
|
+
}
|
|
101412
|
+
//#endregion
|
|
101413
|
+
//#region src/composition/customize/event-decode.ts
|
|
101414
|
+
var ROSE_SOURCE = String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
101415
|
+
function decodePulseOverride(input) {
|
|
101416
|
+
if (input.feature.cap !== input.cap || input.feature.kind !== "fields") return null;
|
|
101417
|
+
if (input.feature.enabled === void 0) return null;
|
|
101418
|
+
const timestamp = input.feature.fields[input.timestampPath];
|
|
101419
|
+
const counter = input.feature.fields[input.counterPath];
|
|
101420
|
+
if (timestamp === void 0 || counter === void 0) return null;
|
|
101421
|
+
if (Object.keys(input.feature.fields).length !== 2) return null;
|
|
101422
|
+
const edges = readEdges(timestamp);
|
|
101423
|
+
if (edges === null) return null;
|
|
101424
|
+
if (readCount(counter, input) === null) return null;
|
|
101425
|
+
const draft = {
|
|
101426
|
+
kind: "pulse",
|
|
101427
|
+
cap: input.cap,
|
|
101428
|
+
targetId: input.targetId,
|
|
101429
|
+
enabled: input.feature.enabled,
|
|
101430
|
+
debounceMs: edges.debounceMs,
|
|
101431
|
+
sources: edges.sources
|
|
101432
|
+
};
|
|
101433
|
+
const decoded = {
|
|
101434
|
+
draft,
|
|
101435
|
+
changedAtFields: edges.changedAtFields
|
|
101436
|
+
};
|
|
101437
|
+
const compiled = compilePulseOverride({
|
|
101438
|
+
draft,
|
|
101439
|
+
device: input.device,
|
|
101440
|
+
changedAtFields: edges.changedAtFields
|
|
101441
|
+
});
|
|
101442
|
+
if (!compiled.ok) return null;
|
|
101443
|
+
return sameFeature$1(compiled.value, input.feature) ? decoded : null;
|
|
101444
|
+
}
|
|
101445
|
+
function readEdges(field) {
|
|
101446
|
+
if (field.kind !== "expression" || !field.expr.startsWith("latest(") || !field.expr.endsWith(")")) return null;
|
|
101447
|
+
const inner = field.expr.slice(7, -1);
|
|
101448
|
+
const found = [...inner.matchAll(new RegExp(ROSE_SOURCE, "g"))];
|
|
101449
|
+
if (found.length === 0 || found.map((match) => match[0]).join(", ") !== inner) return null;
|
|
101450
|
+
if (Object.keys(field.bindings).length !== found.length * 2) return null;
|
|
101451
|
+
const rows = found.map((match, index) => readRose(match, index, field.bindings));
|
|
101452
|
+
if (rows.some((row) => row === null)) return null;
|
|
101453
|
+
const edges = rows.filter((row) => row !== null);
|
|
101454
|
+
const debounceMs = edges[0]?.debounceMs;
|
|
101455
|
+
if (debounceMs === void 0 || edges.some((row) => row.debounceMs !== debounceMs)) return null;
|
|
101456
|
+
return {
|
|
101457
|
+
debounceMs,
|
|
101458
|
+
sources: edges.map((row) => row.source),
|
|
101459
|
+
changedAtFields: edges.map((row) => row.changedAtField)
|
|
101460
|
+
};
|
|
101461
|
+
}
|
|
101462
|
+
function readRose(match, index, bindings) {
|
|
101463
|
+
const activeIndex = Number(match[1]);
|
|
101464
|
+
const changedIndex = Number(match[2]);
|
|
101465
|
+
const debounceMs = Number(match[3]);
|
|
101466
|
+
if (activeIndex !== index || changedIndex !== index || !Number.isFinite(debounceMs)) return null;
|
|
101467
|
+
const active = fromBinding(bindings[`active${index}`]);
|
|
101468
|
+
const changed = fromBinding(bindings[`changed${index}`]);
|
|
101469
|
+
if (active === null || changed === null) return null;
|
|
101470
|
+
if (active.cap !== changed.cap) return null;
|
|
101471
|
+
if (active.source.addonId !== changed.source.addonId) return null;
|
|
101472
|
+
if (active.source.stableId !== changed.source.stableId) return null;
|
|
101473
|
+
return {
|
|
101474
|
+
debounceMs,
|
|
101475
|
+
changedAtField: changed.fieldPath,
|
|
101476
|
+
source: {
|
|
101477
|
+
addonId: active.source.addonId,
|
|
101478
|
+
stableId: active.source.stableId,
|
|
101479
|
+
cap: active.cap,
|
|
101480
|
+
fieldPath: active.fieldPath
|
|
101481
|
+
}
|
|
101482
|
+
};
|
|
101483
|
+
}
|
|
101484
|
+
function fromBinding(value) {
|
|
101485
|
+
if (value === void 0 || value.kind !== "from") return null;
|
|
101486
|
+
return value;
|
|
101487
|
+
}
|
|
101488
|
+
function readCount(field, input) {
|
|
101489
|
+
if (field.kind !== "expression" || field.expr !== `count(${input.timestampPath})`) return null;
|
|
101490
|
+
const binding = fromBinding(field.bindings[input.timestampPath]);
|
|
101491
|
+
if (binding === null) return null;
|
|
101492
|
+
if (Object.keys(field.bindings).length !== 1) return null;
|
|
101493
|
+
if (binding.cap !== input.cap || binding.fieldPath !== input.timestampPath) return null;
|
|
101494
|
+
if (binding.source.addonId !== input.device.addonId) return null;
|
|
101495
|
+
if (binding.source.stableId !== input.device.stableId) return null;
|
|
101496
|
+
return true;
|
|
101497
|
+
}
|
|
101498
|
+
function sameFeature$1(left, right) {
|
|
101499
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
101500
|
+
}
|
|
101501
|
+
//#endregion
|
|
101502
|
+
//#region src/composition/customize/event-eval.ts
|
|
101503
|
+
var INITIAL_PULSE = {
|
|
101504
|
+
priorActive: void 0,
|
|
101505
|
+
lastPressedAt: null,
|
|
101506
|
+
count: 0,
|
|
101507
|
+
acceptedAt: null
|
|
101508
|
+
};
|
|
101509
|
+
var INITIAL_SPAN = {
|
|
101510
|
+
open: false,
|
|
101511
|
+
startedAt: null,
|
|
101512
|
+
endedAt: null,
|
|
101513
|
+
quietUntil: null,
|
|
101514
|
+
priorActive: void 0
|
|
101515
|
+
};
|
|
101516
|
+
function stepPulse(state, sample, debounceMs) {
|
|
101517
|
+
if (sample.kind === "unread" || debounceMs < 0) return state;
|
|
101518
|
+
if (state.priorActive === void 0) return {
|
|
101519
|
+
...state,
|
|
101520
|
+
priorActive: sample.active
|
|
101521
|
+
};
|
|
101522
|
+
if (!sample.active) return {
|
|
101523
|
+
...state,
|
|
101524
|
+
priorActive: false
|
|
101525
|
+
};
|
|
101526
|
+
if (state.priorActive) return state;
|
|
101527
|
+
const at = finite(sample.changedAt);
|
|
101528
|
+
if (at === null) return {
|
|
101529
|
+
...state,
|
|
101530
|
+
priorActive: true
|
|
101531
|
+
};
|
|
101532
|
+
if (state.acceptedAt !== null && at - state.acceptedAt < debounceMs) return {
|
|
101533
|
+
...state,
|
|
101534
|
+
priorActive: true
|
|
101535
|
+
};
|
|
101536
|
+
return {
|
|
101537
|
+
priorActive: true,
|
|
101538
|
+
lastPressedAt: at,
|
|
101539
|
+
count: state.count + 1,
|
|
101540
|
+
acceptedAt: at
|
|
101541
|
+
};
|
|
101542
|
+
}
|
|
101543
|
+
function stepSpan(state, sample, timing) {
|
|
101544
|
+
const timed = expire(state, timing);
|
|
101545
|
+
if (sample.kind === "unread" || timing.timeoutMs < 0 || timing.cooldownMs < 0) return timed;
|
|
101546
|
+
if (timed.priorActive === void 0) return {
|
|
101547
|
+
...timed,
|
|
101548
|
+
priorActive: sample.active
|
|
101549
|
+
};
|
|
101550
|
+
if (timed.open && timed.priorActive && !sample.active) return finish(timed, finite(sample.changedAt) ?? timing.nowMs, timing.cooldownMs, false);
|
|
101551
|
+
if (!sample.active) return {
|
|
101552
|
+
...timed,
|
|
101553
|
+
priorActive: false
|
|
101554
|
+
};
|
|
101555
|
+
if (timed.priorActive || timed.open) return {
|
|
101556
|
+
...timed,
|
|
101557
|
+
priorActive: true
|
|
101558
|
+
};
|
|
101559
|
+
const at = finite(sample.changedAt) ?? timing.nowMs;
|
|
101560
|
+
if (timed.quietUntil !== null && at < timed.quietUntil) return {
|
|
101561
|
+
...timed,
|
|
101562
|
+
priorActive: true
|
|
101563
|
+
};
|
|
101564
|
+
return {
|
|
101565
|
+
open: true,
|
|
101566
|
+
startedAt: at,
|
|
101567
|
+
endedAt: null,
|
|
101568
|
+
quietUntil: null,
|
|
101569
|
+
priorActive: true
|
|
101570
|
+
};
|
|
101571
|
+
}
|
|
101572
|
+
function expire(state, timing) {
|
|
101573
|
+
if (!state.open || state.startedAt === null) return state;
|
|
101574
|
+
const deadline = state.startedAt + timing.timeoutMs;
|
|
101575
|
+
if (timing.nowMs < deadline) return state;
|
|
101576
|
+
return finish(state, deadline, timing.cooldownMs, state.priorActive === true);
|
|
101577
|
+
}
|
|
101578
|
+
function finish(state, endedAt, cooldownMs, priorActive) {
|
|
101579
|
+
return {
|
|
101580
|
+
open: false,
|
|
101581
|
+
startedAt: state.startedAt,
|
|
101582
|
+
endedAt,
|
|
101583
|
+
quietUntil: cooldownMs > 0 ? endedAt + cooldownMs : null,
|
|
101584
|
+
priorActive
|
|
101585
|
+
};
|
|
101586
|
+
}
|
|
101587
|
+
function finite(value) {
|
|
101588
|
+
return value !== null && Number.isFinite(value) ? value : null;
|
|
101589
|
+
}
|
|
101590
|
+
//#endregion
|
|
101591
|
+
//#region src/composition/customize/event-status.ts
|
|
101592
|
+
function projectPulseAssignment(input) {
|
|
101593
|
+
if (input.stored.kind === "pending") return held(input.targetId, "pending", null);
|
|
101594
|
+
if (input.stored.kind === "unknown") return held(input.targetId, "unknown", input.stored.reason ?? "unknown");
|
|
101595
|
+
if (input.stored.value === null) return native$1(input.targetId);
|
|
101596
|
+
const decoded = decodePulseOverride({
|
|
101597
|
+
feature: input.stored.value,
|
|
101598
|
+
device: input.device,
|
|
101599
|
+
cap: input.cap,
|
|
101600
|
+
targetId: input.targetId,
|
|
101601
|
+
timestampPath: input.timestampPath,
|
|
101602
|
+
counterPath: input.counterPath
|
|
101603
|
+
});
|
|
101604
|
+
if (decoded === null) return {
|
|
101605
|
+
text: "unknown",
|
|
101606
|
+
status: row(input.targetId, true, "assigned", "unavailable", "not-canonical")
|
|
101607
|
+
};
|
|
101608
|
+
if (input.sourcePresence === "pending") return {
|
|
101609
|
+
text: "pending",
|
|
101610
|
+
status: row(input.targetId, true, "assigned", "stale", null)
|
|
101611
|
+
};
|
|
101612
|
+
if (input.sourcePresence === "unknown") return {
|
|
101613
|
+
text: "unknown",
|
|
101614
|
+
status: row(input.targetId, true, "assigned", "stale", input.sourceUnknownReason ?? "unknown")
|
|
101615
|
+
};
|
|
101616
|
+
if (input.sourcePresence === "absent" && input.apply === "replace") return {
|
|
101617
|
+
text: "Native · source missing",
|
|
101618
|
+
status: row(input.targetId, true, "native", "released", "source-missing")
|
|
101619
|
+
};
|
|
101620
|
+
if (input.sourcePresence === "absent") return {
|
|
101621
|
+
text: "Assigned · source missing",
|
|
101622
|
+
status: row(input.targetId, true, "assigned", "unavailable", "source-missing")
|
|
101623
|
+
};
|
|
101624
|
+
const source = decoded.draft.sources[0];
|
|
101625
|
+
return {
|
|
101626
|
+
text: `Assigned · ${source === void 0 ? "assigned" : `${source.cap}.${source.fieldPath}`}`,
|
|
101627
|
+
status: row(input.targetId, true, "assigned", "active", null)
|
|
101628
|
+
};
|
|
101629
|
+
}
|
|
101630
|
+
function projectSpanAssignment(targetId, stored) {
|
|
101631
|
+
if (stored.kind === "pending") return {
|
|
101632
|
+
text: "pending",
|
|
101633
|
+
writable: false,
|
|
101634
|
+
rows: [],
|
|
101635
|
+
status: row(targetId, false, "native", "unavailable", null)
|
|
101636
|
+
};
|
|
101637
|
+
if (stored.kind === "unknown") return {
|
|
101638
|
+
text: "unknown",
|
|
101639
|
+
writable: false,
|
|
101640
|
+
rows: [],
|
|
101641
|
+
status: row(targetId, false, "native", "stale", stored.reason ?? "unknown")
|
|
101642
|
+
};
|
|
101643
|
+
if (stored.value.state === "unreadable") return {
|
|
101644
|
+
text: "unreadable",
|
|
101645
|
+
writable: false,
|
|
101646
|
+
rows: [],
|
|
101647
|
+
status: row(targetId, false, "assigned", "unavailable", stored.value.reason)
|
|
101648
|
+
};
|
|
101649
|
+
if (stored.value.state === "not-configured") return {
|
|
101650
|
+
text: "Native",
|
|
101651
|
+
writable: true,
|
|
101652
|
+
rows: [],
|
|
101653
|
+
status: row(targetId, false, "native", "active", null)
|
|
101654
|
+
};
|
|
101655
|
+
const rows = stored.value.sensors.map(sensorRow);
|
|
101656
|
+
const reason = spanReason(stored.value);
|
|
101657
|
+
return {
|
|
101658
|
+
text: rows.length === 0 ? "Native" : "Assigned",
|
|
101659
|
+
writable: true,
|
|
101660
|
+
rows,
|
|
101661
|
+
status: row(targetId, rows.length > 0, "assigned", "active", reason)
|
|
101662
|
+
};
|
|
101663
|
+
}
|
|
101664
|
+
function spanReason(status) {
|
|
101665
|
+
if (status.notForwarded !== void 0) return status.notForwarded;
|
|
101666
|
+
if (status.notEnforced !== void 0) return status.notEnforced;
|
|
101667
|
+
return status.sensors.map(attachmentReason).find((reason) => reason !== null) ?? null;
|
|
101668
|
+
}
|
|
101669
|
+
function sensorRow(sensor) {
|
|
101670
|
+
return {
|
|
101671
|
+
key: `${sensor.addonId}/${sensor.stableId}`,
|
|
101672
|
+
addonId: sensor.addonId,
|
|
101673
|
+
stableId: sensor.stableId,
|
|
101674
|
+
name: sensor.state === "missing" || sensor.state === "unreadable" ? sensor.stableId : sensor.name,
|
|
101675
|
+
mode: sensor.mode,
|
|
101676
|
+
state: sensor.state,
|
|
101677
|
+
reason: attachmentReason(sensor)
|
|
101678
|
+
};
|
|
101679
|
+
}
|
|
101680
|
+
function attachmentReason(sensor) {
|
|
101681
|
+
switch (sensor.state) {
|
|
101682
|
+
case "ready": return null;
|
|
101683
|
+
case "offline":
|
|
101684
|
+
case "missing":
|
|
101685
|
+
case "unsupported":
|
|
101686
|
+
case "unreadable": return sensor.reason;
|
|
101687
|
+
}
|
|
101688
|
+
}
|
|
101689
|
+
function native$1(targetId) {
|
|
101690
|
+
return {
|
|
101691
|
+
text: "Native",
|
|
101692
|
+
status: row(targetId, false, "native", "active", null)
|
|
101693
|
+
};
|
|
101694
|
+
}
|
|
101695
|
+
function held(targetId, text, reason) {
|
|
101696
|
+
return {
|
|
101697
|
+
text,
|
|
101698
|
+
status: row(targetId, false, "native", text === "pending" ? "unavailable" : "stale", reason)
|
|
101699
|
+
};
|
|
101700
|
+
}
|
|
101701
|
+
function row(targetId, configured, source, state, reason) {
|
|
101702
|
+
return {
|
|
101703
|
+
targetId,
|
|
101704
|
+
configured,
|
|
101705
|
+
source,
|
|
101706
|
+
state,
|
|
101707
|
+
reason
|
|
101708
|
+
};
|
|
101709
|
+
}
|
|
101710
|
+
//#endregion
|
|
101711
|
+
//#region src/composition/customize/keyed-array-expr.ts
|
|
101712
|
+
var STEP = /^x == ("(?:\\.|[^"\\])*") \? ("(?:\\.|[^"\\])*"|null) : ([\s\S]+)$/;
|
|
101713
|
+
function enumMapExpr(mapping) {
|
|
101714
|
+
const keys = Object.keys(mapping).toSorted();
|
|
101715
|
+
if (keys.length === 0) return null;
|
|
101716
|
+
return keys.reduceRight((rest, key) => {
|
|
101717
|
+
if (rest === null) return null;
|
|
101718
|
+
const value = mapping[key];
|
|
101719
|
+
if (value === void 0) return null;
|
|
101720
|
+
const rhs = value === null ? "null" : JSON.stringify(value);
|
|
101721
|
+
return `x == ${JSON.stringify(key)} ? ${rhs} : ${rest}`;
|
|
101722
|
+
}, "null");
|
|
101723
|
+
}
|
|
101724
|
+
function parseEnumMap(expr) {
|
|
101725
|
+
const mapping = {};
|
|
101726
|
+
let rest = expr;
|
|
101727
|
+
while (rest !== "null") {
|
|
101728
|
+
const match = STEP.exec(rest);
|
|
101729
|
+
if (match === null || match[1] === void 0 || match[2] === void 0 || match[3] === void 0) return null;
|
|
101730
|
+
const key = jsonString(match[1]);
|
|
101731
|
+
const value = match[2] === "null" ? null : jsonString(match[2]);
|
|
101732
|
+
if (key === null || match[2] !== "null" && value === null) return null;
|
|
101733
|
+
if (Object.prototype.hasOwnProperty.call(mapping, key)) return null;
|
|
101734
|
+
mapping[key] = value;
|
|
101735
|
+
rest = match[3];
|
|
101736
|
+
}
|
|
101737
|
+
return Object.keys(mapping).length === 0 ? null : mapping;
|
|
101738
|
+
}
|
|
101739
|
+
function enumMapDraft(mapping) {
|
|
101740
|
+
return {
|
|
101741
|
+
kind: "enum-map",
|
|
101742
|
+
mapping: { ...mapping }
|
|
101743
|
+
};
|
|
101744
|
+
}
|
|
101745
|
+
function jsonString(token) {
|
|
101746
|
+
try {
|
|
101747
|
+
const parsed = JSON.parse(token);
|
|
101748
|
+
return typeof parsed === "string" ? parsed : null;
|
|
101749
|
+
} catch {
|
|
101750
|
+
return null;
|
|
101751
|
+
}
|
|
101752
|
+
}
|
|
101753
|
+
//#endregion
|
|
101754
|
+
//#region src/composition/customize/keyed-array-compile.ts
|
|
101755
|
+
var catalog$1 = CAP_CUSTOMIZE_CATALOG;
|
|
101756
|
+
function compileKeyedArrayOverride(input) {
|
|
101757
|
+
const target = catalogTarget$1(input.cap, input.targetId);
|
|
101758
|
+
if (target === null || target.cardinality !== "keyedArray") return fail("target");
|
|
101759
|
+
if (input.items.length === 0) return fail("items");
|
|
101760
|
+
if (input.items.some((item) => item.draft.cap !== input.cap || item.draft.targetId !== input.targetId)) return fail("target");
|
|
101761
|
+
const keys = input.items.map((item) => item.draft.key);
|
|
101762
|
+
if (new Set(keys).size !== keys.length) return fail("key");
|
|
101763
|
+
const built = input.items.reduce((acc, item) => {
|
|
101764
|
+
if (!acc.ok) return acc;
|
|
101765
|
+
const entry = compileItem(target, item);
|
|
101766
|
+
if (!entry.ok) return entry;
|
|
101767
|
+
return {
|
|
101768
|
+
ok: true,
|
|
101769
|
+
value: {
|
|
101770
|
+
...acc.value,
|
|
101771
|
+
[item.draft.key]: entry.value
|
|
101772
|
+
}
|
|
101773
|
+
};
|
|
101774
|
+
}, {
|
|
101775
|
+
ok: true,
|
|
101776
|
+
value: {}
|
|
101777
|
+
});
|
|
101778
|
+
if (!built.ok) return built;
|
|
101779
|
+
const fields = compileCompanions(target, input.apply);
|
|
101780
|
+
if (!fields.ok) return fields;
|
|
101781
|
+
return {
|
|
101782
|
+
ok: true,
|
|
101783
|
+
value: {
|
|
101784
|
+
kind: "fields",
|
|
101785
|
+
cap: input.cap,
|
|
101786
|
+
fields: fields.value,
|
|
101787
|
+
items: { ...built.value }
|
|
101788
|
+
}
|
|
101789
|
+
};
|
|
101790
|
+
}
|
|
101791
|
+
/** Put one compiled item into an existing feature. Other items stay as stored. */
|
|
101792
|
+
function mergeKeyedArrayItem(current, compiled, key) {
|
|
101793
|
+
const item = compiled.items?.[key];
|
|
101794
|
+
if (item === void 0) return null;
|
|
101795
|
+
return {
|
|
101796
|
+
kind: "fields",
|
|
101797
|
+
cap: compiled.cap,
|
|
101798
|
+
...current?.enabled === void 0 ? {} : { enabled: current.enabled },
|
|
101799
|
+
fields: current === null ? compiled.fields : current.fields,
|
|
101800
|
+
items: {
|
|
101801
|
+
...current?.items,
|
|
101802
|
+
[key]: item
|
|
101803
|
+
}
|
|
101804
|
+
};
|
|
101805
|
+
}
|
|
101806
|
+
/** The feature without item `key`. Null when that item was the last one. */
|
|
101807
|
+
function withoutKeyedArrayItem(feature, key) {
|
|
101808
|
+
const rest = Object.fromEntries(Object.entries(feature.items ?? {}).filter(([name]) => name !== key));
|
|
101809
|
+
if (Object.keys(rest).length === 0) return null;
|
|
101810
|
+
return {
|
|
101811
|
+
...feature,
|
|
101812
|
+
items: rest
|
|
101813
|
+
};
|
|
101814
|
+
}
|
|
101815
|
+
function fail(reason) {
|
|
101816
|
+
return {
|
|
101817
|
+
ok: false,
|
|
101818
|
+
reason
|
|
101819
|
+
};
|
|
101820
|
+
}
|
|
101821
|
+
function catalogTarget$1(cap, targetId) {
|
|
101822
|
+
const entry = catalog$1[cap];
|
|
101823
|
+
if (entry === void 0) return null;
|
|
101824
|
+
return entry.targets.find((target) => target.id === targetId) ?? null;
|
|
101825
|
+
}
|
|
101826
|
+
function compileItem(target, item) {
|
|
101827
|
+
if (!require_composition.COMPOSITION_ITEM_KEY_RE.test(item.draft.key) || item.draft.label.trim() === "") return fail("key");
|
|
101828
|
+
const field = (target.fields ?? []).find((entry) => entry.path === item.draft.fieldPath);
|
|
101829
|
+
if (field === void 0) return fail("field");
|
|
101830
|
+
const source = sourceSpec(field, item);
|
|
101831
|
+
if (source === null) return fail("source-kind");
|
|
101832
|
+
if (source.requiredUnit !== void 0 && item.sourceUnit !== source.requiredUnit) return fail("unit");
|
|
101833
|
+
const allowed = item.draft.transform.kind;
|
|
101834
|
+
if (!source.transformKinds.includes(allowed)) return fail("transform");
|
|
101835
|
+
const value = compileValue(item, field);
|
|
101836
|
+
if (!value.ok) return value;
|
|
101837
|
+
const fields = compileLiterals(target, field, item, value.value);
|
|
101838
|
+
if (!fields.ok) return fields;
|
|
101839
|
+
return {
|
|
101840
|
+
ok: true,
|
|
101841
|
+
value: {
|
|
101842
|
+
label: item.draft.label.trim(),
|
|
101843
|
+
fields: fields.value
|
|
101844
|
+
}
|
|
101845
|
+
};
|
|
101846
|
+
}
|
|
101847
|
+
function sourceSpec(field, item) {
|
|
101848
|
+
if (item.sourceValueKind === "number") return field.sources.find((source) => source.kind === "numeric") ?? null;
|
|
101849
|
+
if (item.sourceValueKind === "enum" || item.sourceValueKind === "string") return field.sources.find((source) => source.kind === "enum") ?? null;
|
|
101850
|
+
return null;
|
|
101851
|
+
}
|
|
101852
|
+
function compileValue(item, field) {
|
|
101853
|
+
const read = fromRead(refOf(item.draft), item.draft.source.cap, item.draft.source.fieldPath);
|
|
101854
|
+
const transform = item.draft.transform;
|
|
101855
|
+
if (transform.kind === "identity") return {
|
|
101856
|
+
ok: true,
|
|
101857
|
+
value: read
|
|
101858
|
+
};
|
|
101859
|
+
if (transform.kind === "linear") return linearValue(transform, read);
|
|
101860
|
+
if (transform.kind === "enum-map") return enumValue(transform, read, field);
|
|
101861
|
+
return fail("transform");
|
|
101862
|
+
}
|
|
101863
|
+
function linearValue(transform, read) {
|
|
101864
|
+
const scale = signedToken(transform.scale);
|
|
101865
|
+
const offset = signedToken(transform.offset);
|
|
101866
|
+
if (scale === null || offset === null) return fail("scale");
|
|
101867
|
+
const clamps = clampTokens(transform.clampMin, transform.clampMax);
|
|
101868
|
+
if (!clamps.ok) return clamps;
|
|
101869
|
+
return {
|
|
101870
|
+
ok: true,
|
|
101871
|
+
value: expression(linearExpr("x", scale, offset, clamps.value.min, clamps.value.max), { x: read })
|
|
101872
|
+
};
|
|
101873
|
+
}
|
|
101874
|
+
function clampTokens(clampMin, clampMax) {
|
|
101875
|
+
if (clampMin === void 0 && clampMax === void 0) return {
|
|
101876
|
+
ok: true,
|
|
101877
|
+
value: {
|
|
101878
|
+
min: null,
|
|
101879
|
+
max: null
|
|
101880
|
+
}
|
|
101881
|
+
};
|
|
101882
|
+
if (clampMin === void 0 || clampMax === void 0) return fail("clamp");
|
|
101883
|
+
const min = signedToken(clampMin);
|
|
101884
|
+
const max = signedToken(clampMax);
|
|
101885
|
+
if (min === null || max === null || clampMin > clampMax) return fail("clamp");
|
|
101886
|
+
return {
|
|
101887
|
+
ok: true,
|
|
101888
|
+
value: {
|
|
101889
|
+
min,
|
|
101890
|
+
max
|
|
101891
|
+
}
|
|
101892
|
+
};
|
|
101893
|
+
}
|
|
101894
|
+
function enumValue(transform, read, field) {
|
|
101895
|
+
const allowed = new Set(field.enumValues ?? []);
|
|
101896
|
+
const entries = Object.entries(transform.mapping);
|
|
101897
|
+
if (entries.length === 0) return fail("enum");
|
|
101898
|
+
if (entries.some(([key, value]) => key.length === 0 || value !== null && !allowed.has(value))) return fail("enum");
|
|
101899
|
+
const expr = enumMapExpr(transform.mapping);
|
|
101900
|
+
if (expr === null) return fail("enum");
|
|
101901
|
+
return {
|
|
101902
|
+
ok: true,
|
|
101903
|
+
value: expression(expr, { x: read })
|
|
101904
|
+
};
|
|
101905
|
+
}
|
|
101906
|
+
function compileLiterals(target, field, item, value) {
|
|
101907
|
+
const required = new Set((field.literals ?? []).map((literalSpec) => literalSpec.path));
|
|
101908
|
+
const traits = new Map((target.traits ?? []).map((trait) => [trait.path, new Set(trait.values)]));
|
|
101909
|
+
if ([...required].filter((path) => !item.literals.some((literalSpec) => literalSpec.path === path)).length > 0) return fail("literal");
|
|
101910
|
+
return item.literals.reduce((acc, entry) => {
|
|
101911
|
+
if (!acc.ok) return acc;
|
|
101912
|
+
if (entry.path === field.path || acc.value[entry.path] !== void 0) return fail("literal");
|
|
101913
|
+
const allowed = allowedLiteral(field, traits, entry.path);
|
|
101914
|
+
if (allowed === null || !allowed.has(entry.value)) return fail("literal");
|
|
101915
|
+
const expr = constantExpr(entry.value);
|
|
101916
|
+
if (expr === null) return fail("literal");
|
|
101917
|
+
return {
|
|
101918
|
+
ok: true,
|
|
101919
|
+
value: {
|
|
101920
|
+
...acc.value,
|
|
101921
|
+
[entry.path]: literal(expr)
|
|
101922
|
+
}
|
|
101923
|
+
};
|
|
101924
|
+
}, {
|
|
101925
|
+
ok: true,
|
|
101926
|
+
value: { [field.path]: value }
|
|
101927
|
+
});
|
|
101928
|
+
}
|
|
101929
|
+
function allowedLiteral(field, traits, path) {
|
|
101930
|
+
const trait = traits.get(path);
|
|
101931
|
+
if (trait !== void 0) return trait;
|
|
101932
|
+
const required = (field.literals ?? []).find((entry) => entry.path === path);
|
|
101933
|
+
return required === void 0 ? null : new Set(required.values);
|
|
101934
|
+
}
|
|
101935
|
+
function compileCompanions(target, apply) {
|
|
101936
|
+
return (target.companions ?? []).filter((companion) => companionIncluded(companion, apply)).reduce((acc, companion) => {
|
|
101937
|
+
if (!acc.ok) return acc;
|
|
101938
|
+
if (companion.kind !== "clock") return fail("companion");
|
|
101939
|
+
return {
|
|
101940
|
+
ok: true,
|
|
101941
|
+
value: {
|
|
101942
|
+
...acc.value,
|
|
101943
|
+
[companion.path]: literal("now")
|
|
101944
|
+
}
|
|
101945
|
+
};
|
|
101946
|
+
}, {
|
|
101947
|
+
ok: true,
|
|
101948
|
+
value: {}
|
|
101949
|
+
});
|
|
101950
|
+
}
|
|
101951
|
+
function companionIncluded(companion, apply) {
|
|
101952
|
+
if (companion.kind === "transition-time") return false;
|
|
101953
|
+
return companion.when === "always" || apply === "add";
|
|
101954
|
+
}
|
|
101955
|
+
function refOf(draft) {
|
|
101956
|
+
return {
|
|
101957
|
+
addonId: draft.source.addonId,
|
|
101958
|
+
stableId: draft.source.stableId
|
|
101959
|
+
};
|
|
101960
|
+
}
|
|
101961
|
+
//#endregion
|
|
101962
|
+
//#region src/composition/customize/keyed-array-decode.ts
|
|
101963
|
+
var catalog = CAP_CUSTOMIZE_CATALOG;
|
|
101964
|
+
function readKeyedArrayItems(feature, cap, targetId) {
|
|
101965
|
+
const target = catalogTarget(cap, targetId);
|
|
101966
|
+
if (target === null || target.cardinality !== "keyedArray" || feature.cap !== cap) return null;
|
|
101967
|
+
const apply = inferApply(target, feature.fields);
|
|
101968
|
+
const canonical = apply !== null && companionsMatch(target, feature.fields, apply);
|
|
101969
|
+
const items = Object.entries(feature.items ?? {}).map(([key, item]) => viewOf(target, cap, targetId, key, item, canonical));
|
|
101970
|
+
return {
|
|
101971
|
+
canonical,
|
|
101972
|
+
apply: apply ?? "add",
|
|
101973
|
+
items
|
|
101974
|
+
};
|
|
101975
|
+
}
|
|
101976
|
+
function decodeKeyedArrayOverride(input) {
|
|
101977
|
+
const read = readKeyedArrayItems(input.feature, input.cap, input.targetId);
|
|
101978
|
+
if (read === null || !read.canonical) return null;
|
|
101979
|
+
if (read.items.some((item) => item.compile === null)) return null;
|
|
101980
|
+
const compiles = read.items.flatMap((item) => item.compile === null ? [] : [item.compile]);
|
|
101981
|
+
const compiled = compileKeyedArrayOverride({
|
|
101982
|
+
cap: input.cap,
|
|
101983
|
+
targetId: input.targetId,
|
|
101984
|
+
device: input.device,
|
|
101985
|
+
apply: read.apply,
|
|
101986
|
+
items: compiles
|
|
101987
|
+
});
|
|
101988
|
+
if (!compiled.ok) return null;
|
|
101989
|
+
return sameFeature(compiled.value, input.feature) ? read : null;
|
|
101990
|
+
}
|
|
101991
|
+
function viewOf(target, cap, targetId, key, item, canonical) {
|
|
101992
|
+
const blank = {
|
|
101993
|
+
key,
|
|
101994
|
+
label: item.label,
|
|
101995
|
+
recognized: false,
|
|
101996
|
+
compile: null
|
|
101997
|
+
};
|
|
101998
|
+
if (!canonical) return blank;
|
|
101999
|
+
const compile = compileOf(target, cap, targetId, key, item);
|
|
102000
|
+
if (compile === null) return blank;
|
|
102001
|
+
return {
|
|
102002
|
+
key,
|
|
102003
|
+
label: item.label,
|
|
102004
|
+
recognized: true,
|
|
102005
|
+
compile
|
|
102006
|
+
};
|
|
102007
|
+
}
|
|
102008
|
+
function compileOf(target, cap, targetId, key, item) {
|
|
102009
|
+
const assigned = assignedField(target, item);
|
|
102010
|
+
if (assigned === null) return null;
|
|
102011
|
+
const literals = literalFields(target, assigned.field, item, assigned.path);
|
|
102012
|
+
if (literals === null) return null;
|
|
102013
|
+
const draft = draftOf(cap, targetId, key, item.label, assigned);
|
|
102014
|
+
if (draft === null) return null;
|
|
102015
|
+
const compile = {
|
|
102016
|
+
draft,
|
|
102017
|
+
sourceValueKind: assigned.sourceValueKind,
|
|
102018
|
+
sourceUnit: null,
|
|
102019
|
+
literals
|
|
102020
|
+
};
|
|
102021
|
+
return reproduces(cap, targetId, key, compile, item) ? compile : null;
|
|
102022
|
+
}
|
|
102023
|
+
function assignedField(target, item) {
|
|
102024
|
+
const paths = Object.keys(item.fields).filter((path) => !isConstant(item.fields[path]));
|
|
102025
|
+
if (paths.length !== 1) return null;
|
|
102026
|
+
const path = paths[0];
|
|
102027
|
+
if (path === void 0) return null;
|
|
102028
|
+
const field = (target.fields ?? []).find((entry) => entry.path === path);
|
|
102029
|
+
const source = item.fields[path];
|
|
102030
|
+
if (field === void 0 || source === void 0) return null;
|
|
102031
|
+
const read = readTransform(source, field);
|
|
102032
|
+
if (read === null) return null;
|
|
102033
|
+
return {
|
|
102034
|
+
path,
|
|
102035
|
+
field,
|
|
102036
|
+
source,
|
|
102037
|
+
...read
|
|
102038
|
+
};
|
|
102039
|
+
}
|
|
102040
|
+
function readTransform(source, field) {
|
|
102041
|
+
if (source.kind === "from") return field.valueKind === "enum" ? {
|
|
102042
|
+
sourceValueKind: "enum",
|
|
102043
|
+
transform: { kind: "identity" }
|
|
102044
|
+
} : {
|
|
102045
|
+
sourceValueKind: "number",
|
|
102046
|
+
transform: { kind: "identity" }
|
|
102047
|
+
};
|
|
102048
|
+
if (source.kind !== "expression") return null;
|
|
102049
|
+
const mapped = parseEnumMap(source.expr);
|
|
102050
|
+
if (mapped !== null && field.valueKind === "enum") return {
|
|
102051
|
+
sourceValueKind: "enum",
|
|
102052
|
+
transform: enumMapDraft(mapped)
|
|
102053
|
+
};
|
|
102054
|
+
const linear = parseLinear(source.expr);
|
|
102055
|
+
if (linear === null || linear.inner !== "x" || field.valueKind !== "number") return null;
|
|
102056
|
+
return {
|
|
102057
|
+
sourceValueKind: "number",
|
|
102058
|
+
transform: {
|
|
102059
|
+
kind: "linear",
|
|
102060
|
+
scale: linear.scale,
|
|
102061
|
+
offset: linear.offset,
|
|
102062
|
+
...linear.clampMin === void 0 || linear.clampMax === void 0 ? {} : {
|
|
102063
|
+
clampMin: linear.clampMin,
|
|
102064
|
+
clampMax: linear.clampMax
|
|
102065
|
+
}
|
|
102066
|
+
}
|
|
102067
|
+
};
|
|
102068
|
+
}
|
|
102069
|
+
function literalFields(target, field, item, assignedPath) {
|
|
102070
|
+
const required = new Set((field.literals ?? []).map((entry) => entry.path));
|
|
102071
|
+
const traits = new Set((target.traits ?? []).map((trait) => trait.path));
|
|
102072
|
+
const found = Object.keys(item.fields).filter((path) => path !== assignedPath);
|
|
102073
|
+
if (found.some((path) => !required.has(path) && !traits.has(path))) return null;
|
|
102074
|
+
if ([...required].some((path) => !found.includes(path))) return null;
|
|
102075
|
+
const literals = found.map((path) => literalValue(item.fields[path], path));
|
|
102076
|
+
if (literals.some((entry) => entry === null)) return null;
|
|
102077
|
+
return literals.flatMap((entry) => entry === null ? [] : [entry]);
|
|
102078
|
+
}
|
|
102079
|
+
function literalValue(source, path) {
|
|
102080
|
+
if (source?.kind !== "expression" || Object.keys(source.bindings).length !== 0) return null;
|
|
102081
|
+
if (!(source.expr.startsWith("\"") && source.expr.endsWith("\""))) return null;
|
|
102082
|
+
try {
|
|
102083
|
+
const parsed = JSON.parse(source.expr);
|
|
102084
|
+
return typeof parsed === "string" ? {
|
|
102085
|
+
path,
|
|
102086
|
+
value: parsed
|
|
102087
|
+
} : null;
|
|
102088
|
+
} catch {
|
|
102089
|
+
return null;
|
|
102090
|
+
}
|
|
102091
|
+
}
|
|
102092
|
+
function draftOf(cap, targetId, key, label, assigned) {
|
|
102093
|
+
const bound = singleFrom(assigned.source);
|
|
102094
|
+
if (bound === null) return null;
|
|
102095
|
+
return {
|
|
102096
|
+
kind: "keyedArray",
|
|
102097
|
+
cap,
|
|
102098
|
+
targetId,
|
|
102099
|
+
key,
|
|
102100
|
+
label,
|
|
102101
|
+
fieldPath: assigned.path,
|
|
102102
|
+
source: {
|
|
102103
|
+
addonId: bound.addonId,
|
|
102104
|
+
stableId: bound.stableId,
|
|
102105
|
+
cap: bound.cap,
|
|
102106
|
+
fieldPath: bound.fieldPath
|
|
102107
|
+
},
|
|
102108
|
+
transform: assigned.transform
|
|
102109
|
+
};
|
|
102110
|
+
}
|
|
102111
|
+
function reproduces(cap, targetId, key, compile, item) {
|
|
102112
|
+
const compiled = compileKeyedArrayOverride({
|
|
102113
|
+
cap,
|
|
102114
|
+
targetId,
|
|
102115
|
+
device: {
|
|
102116
|
+
addonId: "t",
|
|
102117
|
+
stableId: "t"
|
|
102118
|
+
},
|
|
102119
|
+
apply: "add",
|
|
102120
|
+
items: [compile]
|
|
102121
|
+
});
|
|
102122
|
+
if (!compiled.ok) return false;
|
|
102123
|
+
const written = compiled.value.items?.[key];
|
|
102124
|
+
if (written === void 0) return false;
|
|
102125
|
+
return JSON.stringify(written) === JSON.stringify(item);
|
|
102126
|
+
}
|
|
102127
|
+
function isConstant(source) {
|
|
102128
|
+
return source?.kind === "expression" && Object.keys(source.bindings).length === 0;
|
|
102129
|
+
}
|
|
102130
|
+
function inferApply(target, fields) {
|
|
102131
|
+
const addPaths = (target.companions ?? []).flatMap((companion) => companion.kind !== "transition-time" && companion.when === "add" ? [companion.path] : []);
|
|
102132
|
+
if (addPaths.length === 0) return "replace";
|
|
102133
|
+
const present = addPaths.filter((path) => fields[path] !== void 0);
|
|
102134
|
+
if (present.length === addPaths.length) return "add";
|
|
102135
|
+
if (present.length === 0) return "replace";
|
|
102136
|
+
return null;
|
|
102137
|
+
}
|
|
102138
|
+
function companionsMatch(target, fields, apply) {
|
|
102139
|
+
const expected = (target.companions ?? []).flatMap((companion) => {
|
|
102140
|
+
if (companion.kind === "transition-time") return [];
|
|
102141
|
+
if (companion.when === "always" || apply === "add") return [companion.path];
|
|
102142
|
+
return [];
|
|
102143
|
+
});
|
|
102144
|
+
if (Object.keys(fields).toSorted().join(",") !== [...expected].toSorted().join(",")) return false;
|
|
102145
|
+
return expected.every((path) => isLiteral(fields[path], "now"));
|
|
102146
|
+
}
|
|
102147
|
+
function catalogTarget(cap, targetId) {
|
|
102148
|
+
const entry = catalog[cap];
|
|
102149
|
+
if (entry === void 0) return null;
|
|
102150
|
+
return entry.targets.find((target) => target.id === targetId) ?? null;
|
|
102151
|
+
}
|
|
102152
|
+
function sameFeature(compiled, stored) {
|
|
102153
|
+
return sameStored(wrap(stripEnabled(compiled)), wrap(stripEnabled(stored)));
|
|
102154
|
+
}
|
|
102155
|
+
function stripEnabled(feature) {
|
|
102156
|
+
const { enabled: _enabled, ...rest } = feature;
|
|
102157
|
+
return rest;
|
|
102158
|
+
}
|
|
102159
|
+
function wrap(feature) {
|
|
102160
|
+
return {
|
|
102161
|
+
family: "composition",
|
|
102162
|
+
target: {
|
|
102163
|
+
addonId: "t",
|
|
102164
|
+
stableId: "t"
|
|
102165
|
+
},
|
|
102166
|
+
feature
|
|
102167
|
+
};
|
|
102168
|
+
}
|
|
102169
|
+
//#endregion
|
|
102170
|
+
//#region src/composition/customize/keyed-array-status.ts
|
|
102171
|
+
function projectKeyedArrayAssignment(input) {
|
|
102172
|
+
if (input.stored.kind === "pending") return unanswered(input.targetId, "pending", null);
|
|
102173
|
+
if (input.stored.kind === "unknown") return unanswered(input.targetId, "unknown", input.stored.reason ?? "unknown");
|
|
102174
|
+
if (input.stored.value === null) return native(input.targetId);
|
|
102175
|
+
const read = readKeyedArrayItems(input.stored.value, input.cap, input.targetId);
|
|
102176
|
+
const count = read?.items.filter((item) => item.recognized).length ?? 0;
|
|
102177
|
+
if (read === null || !read.canonical || count === 0) return {
|
|
102178
|
+
text: "unknown",
|
|
102179
|
+
assignedCount: 0,
|
|
102180
|
+
status: status(input.targetId, true, "assigned", "unavailable", "not-canonical")
|
|
102181
|
+
};
|
|
102182
|
+
return projectDecoded(input, count);
|
|
102183
|
+
}
|
|
102184
|
+
function projectDecoded(input, count) {
|
|
102185
|
+
const text = `${count} assigned`;
|
|
102186
|
+
if (input.sourcePresence === "pending") return {
|
|
102187
|
+
text: "pending",
|
|
102188
|
+
assignedCount: count,
|
|
102189
|
+
status: status(input.targetId, true, "assigned", "stale", null)
|
|
102190
|
+
};
|
|
102191
|
+
if (input.sourcePresence === "unknown") return {
|
|
102192
|
+
text: "unknown",
|
|
102193
|
+
assignedCount: count,
|
|
102194
|
+
status: status(input.targetId, true, "assigned", "stale", input.sourceUnknownReason ?? "unknown")
|
|
102195
|
+
};
|
|
102196
|
+
if (input.sourcePresence === "absent") return {
|
|
102197
|
+
text,
|
|
102198
|
+
assignedCount: count,
|
|
102199
|
+
status: status(input.targetId, true, "assigned", "unavailable", "source-missing")
|
|
102200
|
+
};
|
|
102201
|
+
return {
|
|
102202
|
+
text,
|
|
102203
|
+
assignedCount: count,
|
|
102204
|
+
status: status(input.targetId, true, "assigned", "active", null)
|
|
102205
|
+
};
|
|
102206
|
+
}
|
|
102207
|
+
function native(targetId) {
|
|
102208
|
+
return {
|
|
102209
|
+
text: "Native",
|
|
102210
|
+
assignedCount: 0,
|
|
102211
|
+
status: status(targetId, false, "native", "active", null)
|
|
102212
|
+
};
|
|
102213
|
+
}
|
|
102214
|
+
function unanswered(targetId, text, reason) {
|
|
102215
|
+
return {
|
|
102216
|
+
text,
|
|
102217
|
+
assignedCount: 0,
|
|
102218
|
+
status: status(targetId, false, "native", text === "pending" ? "unavailable" : "stale", reason)
|
|
102219
|
+
};
|
|
102220
|
+
}
|
|
102221
|
+
function status(targetId, configured, source, state, reason) {
|
|
102222
|
+
return {
|
|
102223
|
+
targetId,
|
|
102224
|
+
configured,
|
|
102225
|
+
source,
|
|
102226
|
+
state,
|
|
102227
|
+
reason
|
|
102228
|
+
};
|
|
102229
|
+
}
|
|
102230
|
+
//#endregion
|
|
100005
102231
|
//#region src/generated/scope-presets.ts
|
|
100006
102232
|
var SCOPE_PRESETS = [
|
|
100007
102233
|
{
|
|
@@ -101660,6 +103886,7 @@ function prepareNotification(caps, n) {
|
|
|
101660
103886
|
* narrows, and still fails CLOSED on a subject that cannot produce the identity
|
|
101661
103887
|
* it tests (a device the mirror cannot name is not evidence of a camera).
|
|
101662
103888
|
*/
|
|
103889
|
+
var LEGACY_KINDS_WITHOUT_FILTERS = new Set(NC_LEGACY_SYSTEM_EVENT_KINDS);
|
|
101663
103890
|
/**
|
|
101664
103891
|
* Every filter, for the callers that must cover all of them (guards, tests).
|
|
101665
103892
|
*
|
|
@@ -101683,6 +103910,7 @@ var NC_SYSTEM_EVENT_FILTER_KEYS = [
|
|
|
101683
103910
|
* ignores it and an editor hides its input. It never means "excluded".
|
|
101684
103911
|
*/
|
|
101685
103912
|
function systemEventFilterApplies(kind, filter) {
|
|
103913
|
+
if (LEGACY_KINDS_WITHOUT_FILTERS.has(kind)) return false;
|
|
101686
103914
|
switch (filter) {
|
|
101687
103915
|
case "deviceIds": return kind.startsWith("device-") || kind.startsWith("stream-") || kind === "detection-blind" || kind.startsWith("motion-") || kind.startsWith("recording-") || kind === "alarm-triggered";
|
|
101688
103916
|
case "deviceTypes": return kind.startsWith("device-") || kind === "detection-blind" || kind.startsWith("motion-");
|
|
@@ -101737,9 +103965,6 @@ var NC_SYSTEM_EVENT_FAMILY = {
|
|
|
101737
103965
|
"device-battery-normal": "device-events",
|
|
101738
103966
|
"device-consumable-low": "device-events",
|
|
101739
103967
|
"device-consumable-normal": "device-events",
|
|
101740
|
-
"device-tank-low": "device-events",
|
|
101741
|
-
"device-tank-full": "device-events",
|
|
101742
|
-
"device-tank-normal": "device-events",
|
|
101743
103968
|
"stream-online": "device-events",
|
|
101744
103969
|
"stream-offline": "device-events",
|
|
101745
103970
|
"detection-blind": "device-events",
|
|
@@ -101834,16 +104059,6 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
101834
104059
|
label: "Consumables",
|
|
101835
104060
|
kinds: ["device-consumable-low", "device-consumable-normal"]
|
|
101836
104061
|
},
|
|
101837
|
-
{
|
|
101838
|
-
id: "tanks",
|
|
101839
|
-
family: "device-events",
|
|
101840
|
-
label: "Tanks",
|
|
101841
|
-
kinds: [
|
|
101842
|
-
"device-tank-low",
|
|
101843
|
-
"device-tank-full",
|
|
101844
|
-
"device-tank-normal"
|
|
101845
|
-
]
|
|
101846
|
-
},
|
|
101847
104062
|
{
|
|
101848
104063
|
id: "detection-blind",
|
|
101849
104064
|
family: "device-events",
|
|
@@ -103740,11 +105955,6 @@ var RULE_BODY_ONLY = ["body"];
|
|
|
103740
105955
|
var RULE_TEXT = ["title", "body"];
|
|
103741
105956
|
var BATTERY = ["device-battery-low", "device-battery-normal"];
|
|
103742
105957
|
var CONSUMABLE = ["device-consumable-low", "device-consumable-normal"];
|
|
103743
|
-
var TANK = [
|
|
103744
|
-
"device-tank-low",
|
|
103745
|
-
"device-tank-full",
|
|
103746
|
-
"device-tank-normal"
|
|
103747
|
-
];
|
|
103748
105958
|
var ALERT_EPISODE = [
|
|
103749
105959
|
"alert-critical",
|
|
103750
105960
|
"alert-error",
|
|
@@ -103776,7 +105986,6 @@ var DEVICE_EVENTS = [
|
|
|
103776
105986
|
"device-enabled",
|
|
103777
105987
|
...BATTERY,
|
|
103778
105988
|
...CONSUMABLE,
|
|
103779
|
-
...TANK,
|
|
103780
105989
|
"stream-online",
|
|
103781
105990
|
"stream-offline",
|
|
103782
105991
|
"detection-blind",
|
|
@@ -103822,12 +106031,6 @@ var STATE_SUMMARY_SECTION_VARS = [
|
|
|
103822
106031
|
example: "Robot — filter 10 %",
|
|
103823
106032
|
kinds: CONSUMABLE
|
|
103824
106033
|
},
|
|
103825
|
-
{
|
|
103826
|
-
name: "summaryTanks",
|
|
103827
|
-
label: "Summary: tanks",
|
|
103828
|
-
example: "Robot — clean water low",
|
|
103829
|
-
kinds: TANK
|
|
103830
|
-
},
|
|
103831
106034
|
{
|
|
103832
106035
|
name: "summaryDetection",
|
|
103833
106036
|
label: "Summary: cameras detecting nothing",
|
|
@@ -104236,18 +106439,7 @@ var NC_TEMPLATE_VARS = [
|
|
|
104236
106439
|
families: ["rule"],
|
|
104237
106440
|
fields: [...RULE_TEXT],
|
|
104238
106441
|
kinds: ["system"],
|
|
104239
|
-
systemEventKinds: [...CONSUMABLE
|
|
104240
|
-
},
|
|
104241
|
-
{
|
|
104242
|
-
name: "tank",
|
|
104243
|
-
label: "Tank",
|
|
104244
|
-
description: "Which tank, as a stable token: cleanWater, dirtyWater, detergent, dustBin, or the device key of any other supply (salt, rinse aid).",
|
|
104245
|
-
example: "clean water",
|
|
104246
|
-
group: "system",
|
|
104247
|
-
families: ["rule"],
|
|
104248
|
-
fields: [...RULE_TEXT],
|
|
104249
|
-
kinds: ["system"],
|
|
104250
|
-
systemEventKinds: [...TANK]
|
|
106442
|
+
systemEventKinds: [...CONSUMABLE]
|
|
104251
106443
|
},
|
|
104252
106444
|
{
|
|
104253
106445
|
name: "profile",
|
|
@@ -104898,9 +107090,6 @@ var NC_TEMPLATE_VARS = [
|
|
|
104898
107090
|
* delete it from here then, and the served catalog names it again.
|
|
104899
107091
|
*/
|
|
104900
107092
|
var NC_TEMPLATE_HELD_BACK_SYSTEM_EVENT_KINDS = [
|
|
104901
|
-
"device-tank-low",
|
|
104902
|
-
"device-tank-full",
|
|
104903
|
-
"device-tank-normal",
|
|
104904
107093
|
"node-restarting",
|
|
104905
107094
|
"node-updating",
|
|
104906
107095
|
"alert-critical",
|
|
@@ -105062,15 +107251,6 @@ var NC_SYSTEM_EVENT_CLASS_SPECS = [
|
|
|
105062
107251
|
snapshotLabel: "Consumables low now",
|
|
105063
107252
|
snapshotSection: "consumables"
|
|
105064
107253
|
},
|
|
105065
|
-
{
|
|
105066
|
-
id: "tanks",
|
|
105067
|
-
family: "device-events",
|
|
105068
|
-
label: "Tanks (low or full / back to normal)",
|
|
105069
|
-
bad: ["device-tank-low", "device-tank-full"],
|
|
105070
|
-
recovery: ["device-tank-normal"],
|
|
105071
|
-
snapshotLabel: "Tanks low or full now",
|
|
105072
|
-
snapshotSection: "tanks"
|
|
105073
|
-
},
|
|
105074
107254
|
{
|
|
105075
107255
|
id: "motion-noise",
|
|
105076
107256
|
family: "device-events",
|
|
@@ -110783,6 +112963,7 @@ exports.CAMSTACK_EVENT_PREFIX = CAMSTACK_EVENT_PREFIX;
|
|
|
110783
112963
|
exports.CAM_PROFILE_ORDER = require_sleep.CAM_PROFILE_ORDER;
|
|
110784
112964
|
exports.CAPABILITY_NAMES = CAPABILITY_NAMES;
|
|
110785
112965
|
exports.CAPABILITY_ROUTER_KEYS = CAPABILITY_ROUTER_KEYS;
|
|
112966
|
+
exports.CAP_CUSTOMIZE_CATALOG = CAP_CUSTOMIZE_CATALOG;
|
|
110786
112967
|
exports.CAP_NAMES_WITH_STATUS = CAP_NAMES_WITH_STATUS;
|
|
110787
112968
|
exports.CAP_NODE_PIN_CONTEXT_KEY = require_sleep.CAP_NODE_PIN_CONTEXT_KEY;
|
|
110788
112969
|
exports.CAP_PROVIDER_KIND_MAP = CAP_PROVIDER_KIND_MAP;
|
|
@@ -111011,6 +113192,7 @@ exports.CredentialScopeSchema = CredentialScopeSchema;
|
|
|
111011
113192
|
exports.CredentialTokenClaimsSchema = CredentialTokenClaimsSchema;
|
|
111012
113193
|
exports.CustomActionInputSchema = CustomActionInputSchema;
|
|
111013
113194
|
exports.CustomModelDescriptorSchema = CustomModelDescriptorSchema;
|
|
113195
|
+
exports.CustomizeAssignmentStatusSchema = CustomizeAssignmentStatusSchema;
|
|
111014
113196
|
exports.DATABASE_SNAPSHOT_PARTIAL_SUFFIX = DATABASE_SNAPSHOT_PARTIAL_SUFFIX;
|
|
111015
113197
|
exports.DATABASE_SNAPSHOT_SUFFIX = DATABASE_SNAPSHOT_SUFFIX;
|
|
111016
113198
|
exports.DATABASE_SNAPSHOT_TIMEOUT_MS = DATABASE_SNAPSHOT_TIMEOUT_MS;
|
|
@@ -111352,6 +113534,8 @@ exports.ICON_ENTRIES = ICON_ENTRIES;
|
|
|
111352
113534
|
exports.ICON_KEYS = ICON_KEYS;
|
|
111353
113535
|
exports.ICON_VIEWER_MODULES = ICON_VIEWER_MODULES;
|
|
111354
113536
|
exports.INFERENCE_DEVICE_EXCLUSION_REASONS = INFERENCE_DEVICE_EXCLUSION_REASONS;
|
|
113537
|
+
exports.INITIAL_PULSE = INITIAL_PULSE;
|
|
113538
|
+
exports.INITIAL_SPAN = INITIAL_SPAN;
|
|
111355
113539
|
exports.INVERTIBLE_CAPS = INVERTIBLE_CAPS;
|
|
111356
113540
|
exports.IconKeySchema = IconKeySchema;
|
|
111357
113541
|
exports.ImageContractSchema = ImageContractSchema;
|
|
@@ -111533,6 +113717,7 @@ exports.MOTION_CROP_MAX_REGIONS = MOTION_CROP_MAX_REGIONS;
|
|
|
111533
113717
|
exports.MOTION_CROP_MOTION_PAD = MOTION_CROP_MOTION_PAD;
|
|
111534
113718
|
exports.MOTION_CROP_TRACKED_PAD = MOTION_CROP_TRACKED_PAD;
|
|
111535
113719
|
exports.MOTION_SOURCE_LABELS = MOTION_SOURCE_LABELS;
|
|
113720
|
+
exports.MOTION_SPAN_TIMEOUT_MS = MOTION_SPAN_TIMEOUT_MS;
|
|
111536
113721
|
exports.MOTION_TRIGGER_FEATURE = MOTION_TRIGGER_FEATURE;
|
|
111537
113722
|
exports.ManagedModelCatalogEntrySchema = ManagedModelCatalogEntrySchema;
|
|
111538
113723
|
exports.ManagedModelExtraFileSchema = ManagedModelExtraFileSchema;
|
|
@@ -111665,6 +113850,7 @@ exports.NC_GROUPING_MAX_SEC = NC_GROUPING_MAX_SEC;
|
|
|
111665
113850
|
exports.NC_GROUPING_MIN_SEC = NC_GROUPING_MIN_SEC;
|
|
111666
113851
|
exports.NC_HISTORY_LIMIT_DEFAULT = NC_HISTORY_LIMIT_DEFAULT;
|
|
111667
113852
|
exports.NC_HISTORY_LIMIT_MAX = NC_HISTORY_LIMIT_MAX;
|
|
113853
|
+
exports.NC_LEGACY_SYSTEM_EVENT_KINDS = NC_LEGACY_SYSTEM_EVENT_KINDS;
|
|
111668
113854
|
exports.NC_MAX_PER_TRACK_IMMEDIATE = NC_MAX_PER_TRACK_IMMEDIATE;
|
|
111669
113855
|
exports.NC_MEDIA_IMAGE_MODES = NC_MEDIA_IMAGE_MODES;
|
|
111670
113856
|
exports.NC_OCCUPANCY_DEFAULTS = NC_OCCUPANCY_DEFAULTS;
|
|
@@ -111679,6 +113865,7 @@ exports.NC_SENSOR_TRANSITION_NEVER_FIRES_WARNING = NC_SENSOR_TRANSITION_NEVER_FI
|
|
|
111679
113865
|
exports.NC_SENSOR_TRANSITION_UNSUPPORTED_REASON = NC_SENSOR_TRANSITION_UNSUPPORTED_REASON;
|
|
111680
113866
|
exports.NC_SERVER_PACKAGE_NAME = NC_SERVER_PACKAGE_NAME;
|
|
111681
113867
|
exports.NC_SNOOZE_MAX_MINUTES = NC_SNOOZE_MAX_MINUTES;
|
|
113868
|
+
exports.NC_STATE_SUMMARY_SECTION_IDS = NC_STATE_SUMMARY_SECTION_IDS;
|
|
111682
113869
|
exports.NC_SYSTEM_DELIVERY = NC_SYSTEM_DELIVERY;
|
|
111683
113870
|
exports.NC_SYSTEM_EVENT_CLASS_SPECS = NC_SYSTEM_EVENT_CLASS_SPECS;
|
|
111684
113871
|
exports.NC_SYSTEM_EVENT_CONDITION_FILTER_KEYS = NC_SYSTEM_EVENT_CONDITION_FILTER_KEYS;
|
|
@@ -111689,7 +113876,6 @@ exports.NC_SYSTEM_EVENT_FILTER_KEYS = NC_SYSTEM_EVENT_FILTER_KEYS;
|
|
|
111689
113876
|
exports.NC_SYSTEM_EVENT_KIND_GROUP_SPECS = NC_SYSTEM_EVENT_KIND_GROUP_SPECS;
|
|
111690
113877
|
exports.NC_SYSTEM_EVENT_SUMMARY_FAMILIES = NC_SYSTEM_EVENT_SUMMARY_FAMILIES;
|
|
111691
113878
|
exports.NC_SYSTEM_RULE_KINDS = NC_SYSTEM_RULE_KINDS;
|
|
111692
|
-
exports.NC_TANK_SYSTEM_EVENT_KINDS = NC_TANK_SYSTEM_EVENT_KINDS;
|
|
111693
113879
|
exports.NC_TAXONOMY = NC_TAXONOMY;
|
|
111694
113880
|
exports.NC_TEMPLATE_HELD_BACK_SYSTEM_EVENT_KINDS = NC_TEMPLATE_HELD_BACK_SYSTEM_EVENT_KINDS;
|
|
111695
113881
|
exports.NC_TEMPLATE_VARS = NC_TEMPLATE_VARS;
|
|
@@ -111907,6 +114093,7 @@ exports.OsdTemplateBindingSchema = OsdTemplateBindingSchema;
|
|
|
111907
114093
|
exports.OsdTemplateFormatSchema = OsdTemplateFormatSchema;
|
|
111908
114094
|
exports.OsdTemplatePickSchema = OsdTemplatePickSchema;
|
|
111909
114095
|
exports.OsdTemplateTokenKindSchema = OsdTemplateTokenKindSchema;
|
|
114096
|
+
exports.OverrideDraftSchema = OverrideDraftSchema;
|
|
111910
114097
|
exports.PEER_BYTES_CHUNK_BYTES = require_sleep.PEER_BYTES_CHUNK_BYTES;
|
|
111911
114098
|
exports.PEER_BYTES_MAX_OUTSTANDING = require_sleep.PEER_BYTES_MAX_OUTSTANDING;
|
|
111912
114099
|
exports.PEER_BYTES_STALL_MS = require_sleep.PEER_BYTES_STALL_MS;
|
|
@@ -112067,6 +114254,10 @@ exports.ROOT_CHILD_CONTAINMENT_MIN = ROOT_CHILD_CONTAINMENT_MIN;
|
|
|
112067
114254
|
exports.ROOT_FACE_REFINE_INPUT_PX = ROOT_FACE_REFINE_INPUT_PX;
|
|
112068
114255
|
exports.ROOT_FACE_REFINE_SCALE = ROOT_FACE_REFINE_SCALE;
|
|
112069
114256
|
exports.ROOT_SUPPLIABLE_STEP_IDS = ROOT_SUPPLIABLE_STEP_IDS;
|
|
114257
|
+
exports.RUNNING_POWER_START_DELAY_MS = RUNNING_POWER_START_DELAY_MS;
|
|
114258
|
+
exports.RUNNING_POWER_STOP_DELAY_MS = RUNNING_POWER_STOP_DELAY_MS;
|
|
114259
|
+
exports.RUNNING_POWER_THRESHOLD_WATTS = RUNNING_POWER_THRESHOLD_WATTS;
|
|
114260
|
+
exports.RUNNING_STATE_COLD = RUNNING_STATE_COLD;
|
|
112070
114261
|
exports.RUNTIME_DEFAULTS = require_sleep.RUNTIME_DEFAULTS;
|
|
112071
114262
|
exports.RUNTIME_STATE_POLICY = RUNTIME_STATE_POLICY;
|
|
112072
114263
|
exports.RUNTIME_STATE_REFRESH_MISS_COOLDOWN_MS = RUNTIME_STATE_REFRESH_MISS_COOLDOWN_MS;
|
|
@@ -112218,6 +114409,8 @@ exports.RunnerJumpStepProvisioningSchema = RunnerJumpStepProvisioningSchema;
|
|
|
112218
114409
|
exports.RunnerLocalLoadSchema = RunnerLocalLoadSchema;
|
|
112219
114410
|
exports.RunnerLocalMetricsSchema = RunnerLocalMetricsSchema;
|
|
112220
114411
|
exports.RunnerRefusalSchema = RunnerRefusalSchema;
|
|
114412
|
+
exports.RunningStateSourceSchema = RunningStateSourceSchema;
|
|
114413
|
+
exports.RunningStateStatusSchema = RunningStateStatusSchema;
|
|
112221
114414
|
exports.SCENE_CONDITIONS = SCENE_CONDITIONS;
|
|
112222
114415
|
exports.SCENE_CONFIRM_DEFAULT_MAX_IMAGE_PX = SCENE_CONFIRM_DEFAULT_MAX_IMAGE_PX;
|
|
112223
114416
|
exports.SCENE_CONFIRM_DEFAULT_TIMEOUT_MS = SCENE_CONFIRM_DEFAULT_TIMEOUT_MS;
|
|
@@ -112657,7 +114850,6 @@ exports.buildCapabilityLookup = buildCapabilityLookup;
|
|
|
112657
114850
|
exports.buildDeviceAdminUrl = buildDeviceAdminUrl;
|
|
112658
114851
|
exports.buildDeviceEnrollmentLink = buildDeviceEnrollmentLink;
|
|
112659
114852
|
exports.buildDeviceSignatureMessage = buildDeviceSignatureMessage;
|
|
112660
|
-
exports.buildDoorbellCompositionFeature = buildDoorbellCompositionFeature;
|
|
112661
114853
|
exports.buildEventKindDescriptor = buildEventKindDescriptor;
|
|
112662
114854
|
exports.buildFfmpegArgs = require_composition.buildFfmpegArgs;
|
|
112663
114855
|
exports.buildFrigateClassMap = buildFrigateClassMap;
|
|
@@ -112731,6 +114923,10 @@ exports.commitWatchdogRestart = commitWatchdogRestart;
|
|
|
112731
114923
|
exports.compareToTarget = compareToTarget;
|
|
112732
114924
|
exports.compileExpression = require_composition.compileExpression;
|
|
112733
114925
|
exports.compileExpressionSafe = require_composition.compileExpressionSafe;
|
|
114926
|
+
exports.compileKeyedArrayOverride = compileKeyedArrayOverride;
|
|
114927
|
+
exports.compilePulseOverride = compilePulseOverride;
|
|
114928
|
+
exports.compileScalarOverride = compileScalarOverride;
|
|
114929
|
+
exports.compileSpanOverride = compileSpanOverride;
|
|
112734
114930
|
exports.composeSwitchedOff = composeSwitchedOff;
|
|
112735
114931
|
exports.composedDeviceRef = require_composition.composedDeviceRef;
|
|
112736
114932
|
exports.composedDeviceStableId = require_composition.composedDeviceStableId;
|
|
@@ -112795,6 +114991,9 @@ exports.dayOfWeekToIndex = dayOfWeekToIndex;
|
|
|
112795
114991
|
exports.declarationOwnerNodeId = declarationOwnerNodeId;
|
|
112796
114992
|
exports.declarationsOf = require_sleep.declarationsOf;
|
|
112797
114993
|
exports.declareLogChannel = declareLogChannel;
|
|
114994
|
+
exports.decodeKeyedArrayOverride = decodeKeyedArrayOverride;
|
|
114995
|
+
exports.decodePulseOverride = decodePulseOverride;
|
|
114996
|
+
exports.decodeScalarOverride = decodeScalarOverride;
|
|
112798
114997
|
exports.decodeVectorBase64 = decodeVectorBase64;
|
|
112799
114998
|
exports.decoderCapability = decoderCapability;
|
|
112800
114999
|
exports.defaultDeliveryForSection = defaultDeliveryForSection;
|
|
@@ -112853,7 +115052,6 @@ exports.dishwasherCapability = dishwasherCapability;
|
|
|
112853
115052
|
exports.doActionSelectValue = doActionSelectValue;
|
|
112854
115053
|
exports.dominantClipLabels = dominantClipLabels;
|
|
112855
115054
|
exports.doorbellCapability = doorbellCapability;
|
|
112856
|
-
exports.doorbellFeatureSources = doorbellFeatureSources;
|
|
112857
115055
|
exports.droppedConditionsForKind = droppedConditionsForKind;
|
|
112858
115056
|
exports.edgetpuDelegateDevice = edgetpuDelegateDevice;
|
|
112859
115057
|
exports.effectiveStepSettings = effectiveStepSettings;
|
|
@@ -113105,6 +115303,7 @@ exports.measuredDetectorCells = measuredDetectorCells;
|
|
|
113105
115303
|
exports.mediaPlayerCapability = mediaPlayerCapability;
|
|
113106
115304
|
exports.memoizePinnedFfmpeg = memoizePinnedFfmpeg;
|
|
113107
115305
|
exports.mergeClipLabels = mergeClipLabels;
|
|
115306
|
+
exports.mergeKeyedArrayItem = mergeKeyedArrayItem;
|
|
113108
115307
|
exports.mergeSecretStatePaths = require_sleep.mergeSecretStatePaths;
|
|
113109
115308
|
exports.mergeSettingsBags = mergeSettingsBags;
|
|
113110
115309
|
exports.mergeSourceInfo = mergeSourceInfo;
|
|
@@ -113231,6 +115430,10 @@ exports.pressureSensorCapability = pressureSensorCapability;
|
|
|
113231
115430
|
exports.principalMayReachAddon = principalMayReachAddon;
|
|
113232
115431
|
exports.privacyMaskCapability = privacyMaskCapability;
|
|
113233
115432
|
exports.procedureAuthKey = procedureAuthKey;
|
|
115433
|
+
exports.projectKeyedArrayAssignment = projectKeyedArrayAssignment;
|
|
115434
|
+
exports.projectPulseAssignment = projectPulseAssignment;
|
|
115435
|
+
exports.projectScalarAssignment = projectScalarAssignment;
|
|
115436
|
+
exports.projectSpanAssignment = projectSpanAssignment;
|
|
113234
115437
|
exports.projectSubjectPath = projectSubjectPath;
|
|
113235
115438
|
exports.providerMotionEvent = providerMotionEvent;
|
|
113236
115439
|
exports.ptzAutotrackCapability = ptzAutotrackCapability;
|
|
@@ -113246,6 +115449,7 @@ exports.readErrorI18n = require_sleep.readErrorI18n;
|
|
|
113246
115449
|
exports.readFaceRescoreIntervalMinutes = readFaceRescoreIntervalMinutes;
|
|
113247
115450
|
exports.readHubMotionDetected = readHubMotionDetected;
|
|
113248
115451
|
exports.readHubMotionStatus = readHubMotionStatus;
|
|
115452
|
+
exports.readKeyedArrayItems = readKeyedArrayItems;
|
|
113249
115453
|
exports.readMotionTriggeredBy = readMotionTriggeredBy;
|
|
113250
115454
|
exports.readNativeLeaseOverride = readNativeLeaseOverride;
|
|
113251
115455
|
exports.readNodePin = require_sleep.readNodePin;
|
|
@@ -113348,6 +115552,11 @@ exports.ruleSectionOf = ruleSectionOf;
|
|
|
113348
115552
|
exports.ruleSeedForSection = ruleSeedForSection;
|
|
113349
115553
|
exports.ruleTriggerZoneIds = ruleTriggerZoneIds;
|
|
113350
115554
|
exports.runInferenceStep = runInferenceStep;
|
|
115555
|
+
exports.runningFromDishwasherOperation = runningFromDishwasherOperation;
|
|
115556
|
+
exports.runningFromLawnMower = runningFromLawnMower;
|
|
115557
|
+
exports.runningFromMediaPlayer = runningFromMediaPlayer;
|
|
115558
|
+
exports.runningFromVacuumState = runningFromVacuumState;
|
|
115559
|
+
exports.runningStateCapability = runningStateCapability;
|
|
113351
115560
|
exports.runtimeDevices = runtimeDevices;
|
|
113352
115561
|
exports.runtimeStatePolicyFor = runtimeStatePolicyFor;
|
|
113353
115562
|
exports.sameDoFamily = sameDoFamily;
|
|
@@ -113405,7 +115614,9 @@ exports.startReachabilityPoll = startReachabilityPoll;
|
|
|
113405
115614
|
exports.stateLabel = stateLabel;
|
|
113406
115615
|
exports.stateVocabularyFor = stateVocabularyFor;
|
|
113407
115616
|
exports.stepModelRunsOnFormat = stepModelRunsOnFormat;
|
|
115617
|
+
exports.stepPulse = stepPulse;
|
|
113408
115618
|
exports.stepSettingSource = stepSettingSource;
|
|
115619
|
+
exports.stepSpan = stepSpan;
|
|
113409
115620
|
exports.storageAdminCapability = storageAdminCapability;
|
|
113410
115621
|
exports.storageCapability = storageCapability;
|
|
113411
115622
|
exports.storageEvictableCapability = storageEvictableCapability;
|
|
@@ -113523,6 +115734,7 @@ exports.withLocationMode = withLocationMode;
|
|
|
113523
115734
|
exports.withSystemEventClasses = withSystemEventClasses;
|
|
113524
115735
|
exports.withoutCallerStamp = require_sleep.withoutCallerStamp;
|
|
113525
115736
|
exports.withoutField = withoutField;
|
|
115737
|
+
exports.withoutKeyedArrayItem = withoutKeyedArrayItem;
|
|
113526
115738
|
exports.writeModelBoundSetting = writeModelBoundSetting;
|
|
113527
115739
|
exports.zodEntriesToConfigUI = zodEntriesToConfigUI;
|
|
113528
115740
|
exports.zoneAnalyticsCapability = zoneAnalyticsCapability;
|