@camstack/types 1.2.406 → 1.2.408
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/capabilities/battery.cap.d.ts +46 -0
- package/dist/capabilities/capability-definition.d.ts +8 -0
- package/dist/capabilities/composer.cap.d.ts +22 -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 +3 -3
- package/dist/capabilities/motion.cap.d.ts +39 -0
- package/dist/capabilities/running-state.cap.d.ts +68 -4
- package/dist/catalogs/sensor-active-state.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/client.mjs +1 -1
- 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-xz-ud5EQ.mjs → composition-BJ8iAZb3.mjs} +1 -1
- package/dist/{composition-RmnnN39T.js → composition-CSLSFGTO.js} +1 -1
- package/dist/generated/customize-catalog.d.ts +229 -0
- package/dist/index.d.ts +14 -1
- package/dist/index.js +2277 -292
- package/dist/index.mjs +2254 -288
- package/dist/node.js +1 -1
- package/dist/node.mjs +1 -1
- package/dist/running-state/defaults.d.ts +3 -0
- package/dist/running-state/from-operation.d.ts +4 -4
- package/package.json +1 -1
- package/dist/composition/presets/doorbell-feature.d.ts +0 -20
- package/dist/running-state/assignment.d.ts +0 -34
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_sleep = require("./sleep-UP964hNP.js");
|
|
3
3
|
const require_event_category = require("./event-category-DG6Vir8Z.js");
|
|
4
|
-
const require_composition = require("./composition-
|
|
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");
|
|
@@ -12766,6 +12766,13 @@ var ComposerUnreadableBlockSchema = zod.z.object({
|
|
|
12766
12766
|
/** The parse error, in the operator's words. */
|
|
12767
12767
|
error: zod.z.string()
|
|
12768
12768
|
});
|
|
12769
|
+
/** A confirmed release the hub did not accept. `deviceId` is the claim's device. */
|
|
12770
|
+
var UnreleasedClaimSchema = zod.z.object({
|
|
12771
|
+
deviceId: zod.z.number().int(),
|
|
12772
|
+
capName: zod.z.string(),
|
|
12773
|
+
owner: zod.z.string(),
|
|
12774
|
+
error: zod.z.string()
|
|
12775
|
+
});
|
|
12769
12776
|
var ComposerApplyInputSchema = zod.z.object({
|
|
12770
12777
|
/** The shared Blocks integration; null until `core-blocks` has reconciled it. */
|
|
12771
12778
|
integrationId: zod.z.string().nullable(),
|
|
@@ -12775,7 +12782,13 @@ var ComposerApplyInputSchema = zod.z.object({
|
|
|
12775
12782
|
/** Operator restarts: rebuild these runtimes and re-resolve their sources. Stores nothing (D62). */
|
|
12776
12783
|
restartBlockIds: zod.z.array(zod.z.string()),
|
|
12777
12784
|
/** Composition rows that exist but do not parse: held, never withdrawn, reported failed. */
|
|
12778
|
-
unreadableBlocks: zod.z.array(ComposerUnreadableBlockSchema)
|
|
12785
|
+
unreadableBlocks: zod.z.array(ComposerUnreadableBlockSchema),
|
|
12786
|
+
/**
|
|
12787
|
+
* Operator-confirmed deletions. Their claims are released on this apply,
|
|
12788
|
+
* before any replacement block claims. A block that merely vanished from the
|
|
12789
|
+
* snapshot is not listed here and still waits for two applies (D49).
|
|
12790
|
+
*/
|
|
12791
|
+
retiredBlockIds: zod.z.array(zod.z.string()).optional()
|
|
12779
12792
|
});
|
|
12780
12793
|
var ComposerBlockVerdictSchema = zod.z.object({
|
|
12781
12794
|
blockId: zod.z.string(),
|
|
@@ -12789,7 +12802,13 @@ var ComposerApplyResultSchema = zod.z.object({
|
|
|
12789
12802
|
* integration unknown, its own rows unread or read empty once). An empty
|
|
12790
12803
|
* apply the caller owes is paid off only by one the composer acted on (D49).
|
|
12791
12804
|
*/
|
|
12792
|
-
acted: zod.z.boolean()
|
|
12805
|
+
acted: zod.z.boolean(),
|
|
12806
|
+
/**
|
|
12807
|
+
* Confirmed releases this apply tried and the hub did not accept. Empty when
|
|
12808
|
+
* every one landed (or there was nothing to hand back). Absent on a result
|
|
12809
|
+
* that never got that far.
|
|
12810
|
+
*/
|
|
12811
|
+
unreleasedClaims: zod.z.array(UnreleasedClaimSchema).optional()
|
|
12793
12812
|
});
|
|
12794
12813
|
var composerCapability = {
|
|
12795
12814
|
name: "composer",
|
|
@@ -60326,20 +60345,68 @@ var BatteryStatusSchema = zod.z.object({
|
|
|
60326
60345
|
*/
|
|
60327
60346
|
binary: zod.z.boolean().optional()
|
|
60328
60347
|
});
|
|
60348
|
+
var BATTERY_DEVICE_TYPES = [
|
|
60349
|
+
require_err_msg.DeviceType.Camera,
|
|
60350
|
+
require_err_msg.DeviceType.Sensor,
|
|
60351
|
+
require_err_msg.DeviceType.Button,
|
|
60352
|
+
require_err_msg.DeviceType.Switch,
|
|
60353
|
+
require_err_msg.DeviceType.PetFeeder,
|
|
60354
|
+
require_err_msg.DeviceType.Container,
|
|
60355
|
+
require_err_msg.DeviceType.Thermostat
|
|
60356
|
+
];
|
|
60357
|
+
/** Generic Customize target for the percentage reading (D936). */
|
|
60358
|
+
var batteryCustomize = {
|
|
60359
|
+
version: 1,
|
|
60360
|
+
targets: [{
|
|
60361
|
+
id: "percentage",
|
|
60362
|
+
cardinality: "scalar",
|
|
60363
|
+
vocabulary: {
|
|
60364
|
+
cap: "battery",
|
|
60365
|
+
stateField: "percentage"
|
|
60366
|
+
},
|
|
60367
|
+
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
60368
|
+
apply: "add-or-replace",
|
|
60369
|
+
path: "percentage",
|
|
60370
|
+
sources: [{
|
|
60371
|
+
kind: "field",
|
|
60372
|
+
valueKinds: ["number", "string"],
|
|
60373
|
+
transforms: [{ kind: "identity" }, {
|
|
60374
|
+
kind: "linear",
|
|
60375
|
+
defaultScale: 1,
|
|
60376
|
+
defaultOffset: 0,
|
|
60377
|
+
clampMin: 0,
|
|
60378
|
+
clampMax: 100
|
|
60379
|
+
}]
|
|
60380
|
+
}],
|
|
60381
|
+
companions: [
|
|
60382
|
+
{
|
|
60383
|
+
kind: "constant",
|
|
60384
|
+
path: "charging",
|
|
60385
|
+
value: "unknown",
|
|
60386
|
+
when: "add"
|
|
60387
|
+
},
|
|
60388
|
+
{
|
|
60389
|
+
kind: "constant",
|
|
60390
|
+
path: "sleeping",
|
|
60391
|
+
value: false,
|
|
60392
|
+
when: "add"
|
|
60393
|
+
},
|
|
60394
|
+
{
|
|
60395
|
+
kind: "clock",
|
|
60396
|
+
path: "lastUpdated",
|
|
60397
|
+
when: "add"
|
|
60398
|
+
}
|
|
60399
|
+
],
|
|
60400
|
+
sourceReport: { status: "assignment-status" },
|
|
60401
|
+
advancedExpression: true
|
|
60402
|
+
}]
|
|
60403
|
+
};
|
|
60329
60404
|
var batteryCapability = {
|
|
60330
60405
|
name: "battery",
|
|
60331
60406
|
scope: "device",
|
|
60332
60407
|
deviceNative: true,
|
|
60333
60408
|
mode: "singleton",
|
|
60334
|
-
deviceTypes:
|
|
60335
|
-
require_err_msg.DeviceType.Camera,
|
|
60336
|
-
require_err_msg.DeviceType.Sensor,
|
|
60337
|
-
require_err_msg.DeviceType.Button,
|
|
60338
|
-
require_err_msg.DeviceType.Switch,
|
|
60339
|
-
require_err_msg.DeviceType.PetFeeder,
|
|
60340
|
-
require_err_msg.DeviceType.Container,
|
|
60341
|
-
require_err_msg.DeviceType.Thermostat
|
|
60342
|
-
],
|
|
60409
|
+
deviceTypes: BATTERY_DEVICE_TYPES,
|
|
60343
60410
|
methods: {
|
|
60344
60411
|
/**
|
|
60345
60412
|
* Explicitly wake the camera from low-power sleep ahead of a
|
|
@@ -60423,6 +60490,7 @@ onStatusChanged: { data: zod.z.object({
|
|
|
60423
60490
|
kind: "gauge",
|
|
60424
60491
|
unit: "%"
|
|
60425
60492
|
} } },
|
|
60493
|
+
customize: batteryCustomize,
|
|
60426
60494
|
/** Clock fields: written, but excluded from the compare that decides
|
|
60427
60495
|
* whether persisting is worth a SQLite commit. */
|
|
60428
60496
|
volatileStateFields: ["lastUpdated"]
|
|
@@ -61621,6 +61689,106 @@ var ConsumablesStatusSchema = zod.z.object({
|
|
|
61621
61689
|
items: zod.z.array(ConsumableItemSchema),
|
|
61622
61690
|
lastChangedAt: zod.z.number()
|
|
61623
61691
|
});
|
|
61692
|
+
/** Synthesize seed for a link-built status (no native provider).
|
|
61693
|
+
*
|
|
61694
|
+
* ⚠ NO LIVE CALLER since 2026-08-08 (device-links deleted; see
|
|
61695
|
+
* `CapabilityStatusSchema.empty`). The wiring guidance below was written for
|
|
61696
|
+
* exactly the case the operator is asking about again — a Dreame's HA
|
|
61697
|
+
* consumable-life sensors — so it is kept for that conversation, not because
|
|
61698
|
+
* anything reads it today. */
|
|
61699
|
+
var EMPTY_STATUS = {
|
|
61700
|
+
items: [],
|
|
61701
|
+
lastChangedAt: 0
|
|
61702
|
+
};
|
|
61703
|
+
/** Seed for a NEW link-built consumable item. `key`/`label` are overwritten
|
|
61704
|
+
* with the link's `itemKey` (see `status.itemArray`), so the placeholder
|
|
61705
|
+
* empty strings never survive into a validated item. Link-built items are
|
|
61706
|
+
* not resettable — there is no native provider to receive `reset()`.
|
|
61707
|
+
*
|
|
61708
|
+
* Wiring guidance (HA vacuum consumable-life sensors):
|
|
61709
|
+
* - a percent-remaining source (`numeric-sensor`, unit '%') → `level` via
|
|
61710
|
+
* `identity` (or `linear` scale 1 offset 0 clamp [0,100] to be safe);
|
|
61711
|
+
* - an hours-remaining source (e.g. Dreame 'Main Brush Time Left', unit 'h')
|
|
61712
|
+
* → `level` via `linear` with scale = 100 / max-hours for that item
|
|
61713
|
+
* (e.g. main brush 300 h → scale 0.3333) + clamp [0,100];
|
|
61714
|
+
* - a discrete source (`enum-sensor`, e.g. mop pad 'installed') → `status`
|
|
61715
|
+
* via `enum-map` (e.g. { installed: 'ok', missing: 'replace' }).
|
|
61716
|
+
* A numeric→'replace' THRESHOLD (level < 10 → 'replace') is NOT expressible
|
|
61717
|
+
* with the current transform kinds — leave `status` null (valid) until the
|
|
61718
|
+
* expression transform lands. */
|
|
61719
|
+
/** Generic Customize target for one consumable item (D936). Native rows stay read-only. */
|
|
61720
|
+
var consumablesCustomize = {
|
|
61721
|
+
version: 1,
|
|
61722
|
+
targets: [{
|
|
61723
|
+
id: "items",
|
|
61724
|
+
cardinality: "keyedArray",
|
|
61725
|
+
vocabulary: { cap: "consumables" },
|
|
61726
|
+
deviceTypes: Object.values(require_err_msg.DeviceType),
|
|
61727
|
+
apply: "add",
|
|
61728
|
+
path: "items",
|
|
61729
|
+
keyField: "key",
|
|
61730
|
+
labelField: "label",
|
|
61731
|
+
itemSchema: ConsumableItemSchema,
|
|
61732
|
+
nativeItems: "read-only",
|
|
61733
|
+
sourceReport: { status: "assignment-status" },
|
|
61734
|
+
fields: [
|
|
61735
|
+
{
|
|
61736
|
+
path: "level",
|
|
61737
|
+
sources: [{
|
|
61738
|
+
kind: "numeric",
|
|
61739
|
+
transforms: [{ kind: "identity" }, {
|
|
61740
|
+
kind: "linear",
|
|
61741
|
+
defaultScale: 1,
|
|
61742
|
+
defaultOffset: 0,
|
|
61743
|
+
clampMin: 0,
|
|
61744
|
+
clampMax: 100
|
|
61745
|
+
}]
|
|
61746
|
+
}]
|
|
61747
|
+
},
|
|
61748
|
+
{
|
|
61749
|
+
path: "remaining.value",
|
|
61750
|
+
sources: [{
|
|
61751
|
+
kind: "numeric",
|
|
61752
|
+
transforms: [{ kind: "identity" }]
|
|
61753
|
+
}],
|
|
61754
|
+
literals: [{
|
|
61755
|
+
path: "remaining.unit",
|
|
61756
|
+
values: [...ConsumableRemainingUnitSchema.options]
|
|
61757
|
+
}]
|
|
61758
|
+
},
|
|
61759
|
+
{
|
|
61760
|
+
path: "status",
|
|
61761
|
+
sources: [{
|
|
61762
|
+
kind: "enum",
|
|
61763
|
+
transforms: [{
|
|
61764
|
+
kind: "enum-map",
|
|
61765
|
+
outputValues: [...ConsumableStatusSchema.options],
|
|
61766
|
+
unmapped: null
|
|
61767
|
+
}]
|
|
61768
|
+
}]
|
|
61769
|
+
}
|
|
61770
|
+
],
|
|
61771
|
+
traits: [{
|
|
61772
|
+
path: "kind",
|
|
61773
|
+
values: [...ConsumableKindSchema.options],
|
|
61774
|
+
defaultValue: "wear"
|
|
61775
|
+
}, {
|
|
61776
|
+
path: "form",
|
|
61777
|
+
values: [...ConsumableFormSchema.options],
|
|
61778
|
+
defaultValue: "part"
|
|
61779
|
+
}],
|
|
61780
|
+
companions: [{
|
|
61781
|
+
kind: "clock",
|
|
61782
|
+
path: "lastChangedAt",
|
|
61783
|
+
when: "add"
|
|
61784
|
+
}, {
|
|
61785
|
+
kind: "clock",
|
|
61786
|
+
path: "lastFetchedAt",
|
|
61787
|
+
when: "add"
|
|
61788
|
+
}],
|
|
61789
|
+
advancedExpression: true
|
|
61790
|
+
}]
|
|
61791
|
+
};
|
|
61624
61792
|
var consumablesCapability = {
|
|
61625
61793
|
name: "consumables",
|
|
61626
61794
|
scope: "device",
|
|
@@ -61658,10 +61826,7 @@ reset: require_sleep.method(zod.z.object({
|
|
|
61658
61826
|
status: {
|
|
61659
61827
|
schema: ConsumablesStatusSchema,
|
|
61660
61828
|
kind: "push",
|
|
61661
|
-
empty:
|
|
61662
|
-
items: [],
|
|
61663
|
-
lastChangedAt: 0
|
|
61664
|
-
},
|
|
61829
|
+
empty: EMPTY_STATUS,
|
|
61665
61830
|
itemArray: {
|
|
61666
61831
|
path: "items",
|
|
61667
61832
|
keyField: "key",
|
|
@@ -61697,6 +61862,7 @@ reset: require_sleep.method(zod.z.object({
|
|
|
61697
61862
|
* brush's remaining life and a dishwasher's salt are each recorded the moment
|
|
61698
61863
|
* their provider reports them; an item that appears later gets its series.
|
|
61699
61864
|
*/
|
|
61865
|
+
customize: consumablesCustomize,
|
|
61700
61866
|
history: {
|
|
61701
61867
|
fields: {},
|
|
61702
61868
|
items: {
|
|
@@ -62499,6 +62665,38 @@ var dishwasherCapability = {
|
|
|
62499
62665
|
};
|
|
62500
62666
|
//#endregion
|
|
62501
62667
|
//#region src/capabilities/doorbell.cap.ts
|
|
62668
|
+
/** A rise closer than this to the previous one is the same press (D671). */
|
|
62669
|
+
var DOORBELL_RISE_DEBOUNCE_MS = 2e3;
|
|
62670
|
+
/** Pulse override: a rising edge advances `lastPressedAt` and the press count. */
|
|
62671
|
+
var doorbellCustomize = {
|
|
62672
|
+
version: 1,
|
|
62673
|
+
targets: [{
|
|
62674
|
+
id: "pressed",
|
|
62675
|
+
cardinality: "event",
|
|
62676
|
+
shape: "pulse",
|
|
62677
|
+
vocabulary: {
|
|
62678
|
+
cap: "doorbell",
|
|
62679
|
+
eventName: "onPressed"
|
|
62680
|
+
},
|
|
62681
|
+
deviceTypes: [require_err_msg.DeviceType.Camera],
|
|
62682
|
+
apply: "add",
|
|
62683
|
+
applyAuthority: { kind: "composition-claim" },
|
|
62684
|
+
eventName: "onPressed",
|
|
62685
|
+
edges: ["rising"],
|
|
62686
|
+
timestampPath: "lastPressedAt",
|
|
62687
|
+
counterPath: "pressCountSinceStart",
|
|
62688
|
+
highWater: "composer-advance",
|
|
62689
|
+
combine: "any",
|
|
62690
|
+
debounce: {
|
|
62691
|
+
kind: "rising-edge",
|
|
62692
|
+
defaultDebounceMs: DOORBELL_RISE_DEBOUNCE_MS,
|
|
62693
|
+
changedAtRequired: true
|
|
62694
|
+
},
|
|
62695
|
+
sources: [{ kind: "binary" }, { kind: "switch" }],
|
|
62696
|
+
sourceReport: { status: "assignment-status" },
|
|
62697
|
+
advancedExpression: true
|
|
62698
|
+
}]
|
|
62699
|
+
};
|
|
62502
62700
|
var DoorbellStatusSchema = zod.z.object({
|
|
62503
62701
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
62504
62702
|
lastPressedAt: zod.z.number().nullable(),
|
|
@@ -62565,7 +62763,8 @@ onPressed: {
|
|
|
62565
62763
|
/**
|
|
62566
62764
|
* History (D850): none — `pressCountSinceStart` resets with the addon, so it is not a monotonic meter; presses live in the events ledger.
|
|
62567
62765
|
*/
|
|
62568
|
-
history: "none"
|
|
62766
|
+
history: "none",
|
|
62767
|
+
customize: doorbellCustomize
|
|
62569
62768
|
};
|
|
62570
62769
|
//#endregion
|
|
62571
62770
|
//#region src/capabilities/enum-sensor.cap.ts
|
|
@@ -65312,6 +65511,44 @@ authKey: zod.z.string().optional() }), zod.z.object({
|
|
|
65312
65511
|
//#endregion
|
|
65313
65512
|
//#region src/capabilities/motion.cap.ts
|
|
65314
65513
|
/**
|
|
65514
|
+
* Span timeout for a camera's attached sensors. This is the pipeline-runner
|
|
65515
|
+
* `motionCooldownMs` default: the window after which a heartbeat-only edge
|
|
65516
|
+
* no longer counts. The span does not declare a separate cooldown.
|
|
65517
|
+
*/
|
|
65518
|
+
var MOTION_SPAN_TIMEOUT_MS = 3e4;
|
|
65519
|
+
/** Span override: start on a rising edge, end on a fall or this timeout. */
|
|
65520
|
+
var motionCustomize = {
|
|
65521
|
+
version: 1,
|
|
65522
|
+
targets: [{
|
|
65523
|
+
id: "detected",
|
|
65524
|
+
cardinality: "event",
|
|
65525
|
+
shape: "span",
|
|
65526
|
+
vocabulary: {
|
|
65527
|
+
cap: "motion",
|
|
65528
|
+
eventName: "onMotionChanged"
|
|
65529
|
+
},
|
|
65530
|
+
deviceTypes: [require_err_msg.DeviceType.Camera],
|
|
65531
|
+
apply: "replace",
|
|
65532
|
+
applyAuthority: {
|
|
65533
|
+
kind: "camera-sensors",
|
|
65534
|
+
timeoutField: "motionCooldownMs"
|
|
65535
|
+
},
|
|
65536
|
+
eventName: "onMotionChanged",
|
|
65537
|
+
start: "rising-edge",
|
|
65538
|
+
end: "falling-edge-or-timeout",
|
|
65539
|
+
timeoutMs: MOTION_SPAN_TIMEOUT_MS,
|
|
65540
|
+
combine: "any",
|
|
65541
|
+
sourceModes: [
|
|
65542
|
+
"in-addition",
|
|
65543
|
+
"confirm",
|
|
65544
|
+
"replace"
|
|
65545
|
+
],
|
|
65546
|
+
sources: [{ kind: "binary" }, { kind: "switch" }],
|
|
65547
|
+
sourceReport: { status: "assignment-status" },
|
|
65548
|
+
advancedExpression: false
|
|
65549
|
+
}]
|
|
65550
|
+
};
|
|
65551
|
+
/**
|
|
65315
65552
|
* Hardware / firmware motion sensor cap — binary detected state plus
|
|
65316
65553
|
* a timestamp of the last observation. Distinct from
|
|
65317
65554
|
* `motion-detection.cap.ts` which owns the LOCAL ML motion pipeline;
|
|
@@ -65475,7 +65712,8 @@ onMotionChanged: { data: MotionOnMotionChangedDataSchema } },
|
|
|
65475
65712
|
history: { fields: { detected: {
|
|
65476
65713
|
kind: "boolean",
|
|
65477
65714
|
excludeDeviceTypes: [require_err_msg.DeviceType.Camera]
|
|
65478
|
-
} } }
|
|
65715
|
+
} } },
|
|
65716
|
+
customize: motionCustomize
|
|
65479
65717
|
};
|
|
65480
65718
|
//#endregion
|
|
65481
65719
|
//#region src/capabilities/motion-trigger.cap.ts
|
|
@@ -69589,6 +69827,19 @@ var ptzAutotrackCapability = {
|
|
|
69589
69827
|
history: "none"
|
|
69590
69828
|
};
|
|
69591
69829
|
//#endregion
|
|
69830
|
+
//#region src/running-state/defaults.ts
|
|
69831
|
+
var RUNNING_POWER_THRESHOLD_WATTS = 5;
|
|
69832
|
+
var RUNNING_POWER_START_DELAY_MS = 3e4;
|
|
69833
|
+
var RUNNING_POWER_STOP_DELAY_MS = 18e4;
|
|
69834
|
+
/** Before any provider reading — all fields unknown (D933). */
|
|
69835
|
+
var RUNNING_STATE_COLD = {
|
|
69836
|
+
running: null,
|
|
69837
|
+
since: null,
|
|
69838
|
+
source: "native",
|
|
69839
|
+
phase: null,
|
|
69840
|
+
lastFetchedAt: null
|
|
69841
|
+
};
|
|
69842
|
+
//#endregion
|
|
69592
69843
|
//#region src/capabilities/running-state.cap.ts
|
|
69593
69844
|
var RunningStateSourceSchema = zod.z.enum(["native", "assigned"]);
|
|
69594
69845
|
var RunningStateStatusSchema = zod.z.object({
|
|
@@ -69598,19 +69849,100 @@ var RunningStateStatusSchema = zod.z.object({
|
|
|
69598
69849
|
since: zod.z.number().nullable(),
|
|
69599
69850
|
source: RunningStateSourceSchema,
|
|
69600
69851
|
phase: zod.z.string().nullable(),
|
|
69601
|
-
|
|
69852
|
+
/** null until a reading has been published (D393). */
|
|
69853
|
+
lastFetchedAt: zod.z.number().nullable()
|
|
69602
69854
|
});
|
|
69603
69855
|
var RunningFlipEventDataSchema = zod.z.object({
|
|
69604
69856
|
deviceId: zod.z.number(),
|
|
69605
69857
|
since: zod.z.number().nullable(),
|
|
69606
69858
|
phase: zod.z.string().nullable()
|
|
69607
69859
|
});
|
|
69860
|
+
var RUNNING_DEVICE_TYPES = Object.values(require_err_msg.DeviceType);
|
|
69861
|
+
/** Generic Customize target for the running boolean (D936). */
|
|
69862
|
+
var runningCustomize = {
|
|
69863
|
+
version: 1,
|
|
69864
|
+
targets: [{
|
|
69865
|
+
id: "running",
|
|
69866
|
+
cardinality: "scalar",
|
|
69867
|
+
vocabulary: {
|
|
69868
|
+
cap: "running-state",
|
|
69869
|
+
stateField: "running"
|
|
69870
|
+
},
|
|
69871
|
+
deviceTypes: [
|
|
69872
|
+
require_err_msg.DeviceType.Dishwasher,
|
|
69873
|
+
require_err_msg.DeviceType.Vacuum,
|
|
69874
|
+
require_err_msg.DeviceType.LawnMower,
|
|
69875
|
+
require_err_msg.DeviceType.MediaPlayer,
|
|
69876
|
+
require_err_msg.DeviceType.WaterHeater,
|
|
69877
|
+
require_err_msg.DeviceType.Humidifier,
|
|
69878
|
+
require_err_msg.DeviceType.Fan,
|
|
69879
|
+
require_err_msg.DeviceType.Climate,
|
|
69880
|
+
require_err_msg.DeviceType.Thermostat,
|
|
69881
|
+
require_err_msg.DeviceType.PetFeeder
|
|
69882
|
+
],
|
|
69883
|
+
apply: "add-or-replace",
|
|
69884
|
+
path: "running",
|
|
69885
|
+
sources: [
|
|
69886
|
+
{
|
|
69887
|
+
kind: "switch",
|
|
69888
|
+
transforms: [{ kind: "identity" }]
|
|
69889
|
+
},
|
|
69890
|
+
{
|
|
69891
|
+
kind: "binary",
|
|
69892
|
+
transforms: [{ kind: "identity" }, { kind: "invert" }]
|
|
69893
|
+
},
|
|
69894
|
+
{
|
|
69895
|
+
kind: "numeric",
|
|
69896
|
+
requiredUnit: "W",
|
|
69897
|
+
transforms: [{
|
|
69898
|
+
kind: "threshold",
|
|
69899
|
+
comparison: "gte",
|
|
69900
|
+
defaultThreshold: 5,
|
|
69901
|
+
defaultStartDwellMs: RUNNING_POWER_START_DELAY_MS,
|
|
69902
|
+
defaultStopDwellMs: RUNNING_POWER_STOP_DELAY_MS,
|
|
69903
|
+
thresholdUnit: "W"
|
|
69904
|
+
}]
|
|
69905
|
+
}
|
|
69906
|
+
],
|
|
69907
|
+
companions: [
|
|
69908
|
+
{
|
|
69909
|
+
kind: "constant",
|
|
69910
|
+
path: "source",
|
|
69911
|
+
value: "assigned",
|
|
69912
|
+
when: "always"
|
|
69913
|
+
},
|
|
69914
|
+
{
|
|
69915
|
+
kind: "constant",
|
|
69916
|
+
path: "phase",
|
|
69917
|
+
value: null,
|
|
69918
|
+
when: "always"
|
|
69919
|
+
},
|
|
69920
|
+
{
|
|
69921
|
+
kind: "clock",
|
|
69922
|
+
path: "lastFetchedAt",
|
|
69923
|
+
when: "always"
|
|
69924
|
+
},
|
|
69925
|
+
{
|
|
69926
|
+
kind: "transition-time",
|
|
69927
|
+
path: "since",
|
|
69928
|
+
sourceChangedAt: "prefer"
|
|
69929
|
+
}
|
|
69930
|
+
],
|
|
69931
|
+
sourceReport: {
|
|
69932
|
+
status: "assignment-status",
|
|
69933
|
+
runtimeField: "source",
|
|
69934
|
+
nativeValue: "native",
|
|
69935
|
+
assignedValue: "assigned"
|
|
69936
|
+
},
|
|
69937
|
+
advancedExpression: true
|
|
69938
|
+
}]
|
|
69939
|
+
};
|
|
69608
69940
|
var runningStateCapability = {
|
|
69609
69941
|
name: "running-state",
|
|
69610
69942
|
scope: "device",
|
|
69611
69943
|
deviceNative: true,
|
|
69612
69944
|
mode: "singleton",
|
|
69613
|
-
deviceTypes:
|
|
69945
|
+
deviceTypes: RUNNING_DEVICE_TYPES,
|
|
69614
69946
|
methods: {},
|
|
69615
69947
|
events: {
|
|
69616
69948
|
onStarted: { data: RunningFlipEventDataSchema },
|
|
@@ -69623,7 +69955,8 @@ var runningStateCapability = {
|
|
|
69623
69955
|
runtimeState: RunningStateStatusSchema,
|
|
69624
69956
|
durability: "restored",
|
|
69625
69957
|
history: { fields: { running: { kind: "boolean" } } },
|
|
69626
|
-
volatileStateFields: ["lastFetchedAt"]
|
|
69958
|
+
volatileStateFields: ["lastFetchedAt"],
|
|
69959
|
+
customize: runningCustomize
|
|
69627
69960
|
};
|
|
69628
69961
|
//#endregion
|
|
69629
69962
|
//#region src/capabilities/reboot.cap.ts
|
|
@@ -75852,213 +76185,58 @@ var PIPELINE_OWNER_CAPABILITY_NAMES = [
|
|
|
75852
76185
|
"pipeline-runner"
|
|
75853
76186
|
];
|
|
75854
76187
|
//#endregion
|
|
75855
|
-
//#region src/running-state/assignment.ts
|
|
75856
|
-
function constant(literal) {
|
|
75857
|
-
return {
|
|
75858
|
-
kind: "expression",
|
|
75859
|
-
expr: literal,
|
|
75860
|
-
bindings: {}
|
|
75861
|
-
};
|
|
75862
|
-
}
|
|
75863
|
-
function fromRead(source, cap, fieldPath) {
|
|
75864
|
-
return {
|
|
75865
|
-
kind: "from",
|
|
75866
|
-
source,
|
|
75867
|
-
cap,
|
|
75868
|
-
fieldPath
|
|
75869
|
-
};
|
|
75870
|
-
}
|
|
75871
|
-
function sortKeys(value) {
|
|
75872
|
-
if (Array.isArray(value)) return value.map(sortKeys);
|
|
75873
|
-
if (typeof value !== "object" || value === null) return value;
|
|
75874
|
-
return Object.fromEntries(Object.entries(value).toSorted(([a], [b]) => a.localeCompare(b)).map(([key, inner]) => [key, sortKeys(inner)]));
|
|
75875
|
-
}
|
|
75876
|
-
function sameFeature(a, b) {
|
|
75877
|
-
return JSON.stringify(sortKeys(a)) === JSON.stringify(sortKeys(b));
|
|
75878
|
-
}
|
|
75879
|
-
function booleanRunningField(input) {
|
|
75880
|
-
if (input.source.kind !== "boolean") return null;
|
|
75881
|
-
const read = fromRead(input.source.source, input.source.cap, input.source.fieldPath);
|
|
75882
|
-
if (!input.invert) return read;
|
|
75883
|
-
return {
|
|
75884
|
-
kind: "expression",
|
|
75885
|
-
expr: "!x",
|
|
75886
|
-
bindings: { x: read }
|
|
75887
|
-
};
|
|
75888
|
-
}
|
|
75889
|
-
function sinceField(input) {
|
|
75890
|
-
if (input.source.kind === "boolean" && input.changedAtField !== null) return fromRead(input.source.source, input.source.cap, input.changedAtField);
|
|
75891
|
-
return {
|
|
75892
|
-
kind: "expression",
|
|
75893
|
-
expr: "latchedAt(running)",
|
|
75894
|
-
bindings: { running: fromRead(input.target, "running-state", "running") }
|
|
75895
|
-
};
|
|
75896
|
-
}
|
|
75897
|
-
function powerRunningField(input) {
|
|
75898
|
-
if (input.source.kind !== "number") return null;
|
|
75899
|
-
if (!Number.isFinite(input.thresholdWatts) || !Number.isFinite(input.startDelayMs) || !Number.isFinite(input.stopDelayMs) || input.thresholdWatts < 0 || input.startDelayMs < 0 || input.stopDelayMs < 0) return null;
|
|
75900
|
-
const read = fromRead(input.source.source, input.source.cap, input.source.fieldPath);
|
|
75901
|
-
return {
|
|
75902
|
-
kind: "expression",
|
|
75903
|
-
expr: `dwell(x >= ${input.thresholdWatts}, ${input.startDelayMs}, ${input.stopDelayMs})`,
|
|
75904
|
-
bindings: { x: read }
|
|
75905
|
-
};
|
|
75906
|
-
}
|
|
75907
|
-
function runningAssignmentFeature(input) {
|
|
75908
|
-
const running = input.source.kind === "number" ? powerRunningField(input) : booleanRunningField(input);
|
|
75909
|
-
if (running === null) return null;
|
|
75910
|
-
return {
|
|
75911
|
-
kind: "fields",
|
|
75912
|
-
cap: "running-state",
|
|
75913
|
-
fields: {
|
|
75914
|
-
source: constant("\"assigned\""),
|
|
75915
|
-
phase: constant("null"),
|
|
75916
|
-
lastFetchedAt: constant("now"),
|
|
75917
|
-
running,
|
|
75918
|
-
since: sinceField(input)
|
|
75919
|
-
}
|
|
75920
|
-
};
|
|
75921
|
-
}
|
|
75922
|
-
function booleanSourceFromRunningField(source) {
|
|
75923
|
-
if (source === void 0) return null;
|
|
75924
|
-
if (source.kind === "from") return {
|
|
75925
|
-
source: source.source,
|
|
75926
|
-
cap: source.cap,
|
|
75927
|
-
fieldPath: source.fieldPath,
|
|
75928
|
-
kind: "boolean"
|
|
75929
|
-
};
|
|
75930
|
-
if (source.kind !== "expression" || source.expr !== "!x") return null;
|
|
75931
|
-
const x = source.bindings["x"];
|
|
75932
|
-
if (x === void 0 || x.kind !== "from") return null;
|
|
75933
|
-
return {
|
|
75934
|
-
source: x.source,
|
|
75935
|
-
cap: x.cap,
|
|
75936
|
-
fieldPath: x.fieldPath,
|
|
75937
|
-
kind: "boolean"
|
|
75938
|
-
};
|
|
75939
|
-
}
|
|
75940
|
-
function recoverPowerRunning(running) {
|
|
75941
|
-
if (running === void 0 || running.kind !== "expression") return null;
|
|
75942
|
-
const match = /^dwell\(x >= ([\d.]+), (\d+), (\d+)\)$/.exec(running.expr);
|
|
75943
|
-
if (match === null) return null;
|
|
75944
|
-
const x = running.bindings["x"];
|
|
75945
|
-
if (x === void 0 || x.kind !== "from") return null;
|
|
75946
|
-
const thresholdWatts = Number(match[1]);
|
|
75947
|
-
const startDelayMs = Number(match[2]);
|
|
75948
|
-
const stopDelayMs = Number(match[3]);
|
|
75949
|
-
if (!Number.isFinite(thresholdWatts) || !Number.isFinite(startDelayMs) || !Number.isFinite(stopDelayMs)) return null;
|
|
75950
|
-
return {
|
|
75951
|
-
source: {
|
|
75952
|
-
...x,
|
|
75953
|
-
kind: "number"
|
|
75954
|
-
},
|
|
75955
|
-
invert: false,
|
|
75956
|
-
thresholdWatts,
|
|
75957
|
-
startDelayMs,
|
|
75958
|
-
stopDelayMs
|
|
75959
|
-
};
|
|
75960
|
-
}
|
|
75961
|
-
/** Recover what {@link runningAssignmentFeature} wrote, else null. */
|
|
75962
|
-
function runningAssignmentRecovered(stored, target) {
|
|
75963
|
-
if (stored.cap !== "running-state" || stored.kind !== "fields") return null;
|
|
75964
|
-
const power = recoverPowerRunning(stored.fields["running"]);
|
|
75965
|
-
if (power !== null) return power;
|
|
75966
|
-
const booleanSource = booleanSourceFromRunningField(stored.fields["running"]);
|
|
75967
|
-
if (booleanSource === null) return null;
|
|
75968
|
-
const since = stored.fields["since"];
|
|
75969
|
-
let changedAtField = null;
|
|
75970
|
-
if (since?.kind === "from" && since.cap === booleanSource.cap && since.source.addonId === booleanSource.source.addonId && since.source.stableId === booleanSource.source.stableId) changedAtField = since.fieldPath;
|
|
75971
|
-
const rebuilt = runningAssignmentFeature({
|
|
75972
|
-
mode: "replace",
|
|
75973
|
-
target,
|
|
75974
|
-
source: booleanSource,
|
|
75975
|
-
changedAtField,
|
|
75976
|
-
invert: stored.fields["running"]?.kind === "expression" && stored.fields["running"].expr === "!x",
|
|
75977
|
-
thresholdWatts: 0,
|
|
75978
|
-
startDelayMs: 0,
|
|
75979
|
-
stopDelayMs: 0
|
|
75980
|
-
});
|
|
75981
|
-
if (rebuilt === null) return null;
|
|
75982
|
-
const { enabled: _e, ...rest } = stored;
|
|
75983
|
-
if (!sameFeature(rest, rebuilt)) return null;
|
|
75984
|
-
return {
|
|
75985
|
-
source: booleanSource,
|
|
75986
|
-
invert: stored.fields["running"]?.kind === "expression" && stored.fields["running"].expr === "!x",
|
|
75987
|
-
thresholdWatts: 0,
|
|
75988
|
-
startDelayMs: 0,
|
|
75989
|
-
stopDelayMs: 0
|
|
75990
|
-
};
|
|
75991
|
-
}
|
|
75992
|
-
function isRunningAssignmentFeature(stored, mode, target) {
|
|
75993
|
-
const recovered = runningAssignmentRecovered(stored, target);
|
|
75994
|
-
if (recovered === null) return false;
|
|
75995
|
-
const rebuilt = recovered.source.kind === "number" ? runningAssignmentFeature({
|
|
75996
|
-
mode,
|
|
75997
|
-
target,
|
|
75998
|
-
source: recovered.source,
|
|
75999
|
-
changedAtField: null,
|
|
76000
|
-
invert: false,
|
|
76001
|
-
thresholdWatts: recovered.thresholdWatts,
|
|
76002
|
-
startDelayMs: recovered.startDelayMs,
|
|
76003
|
-
stopDelayMs: recovered.stopDelayMs
|
|
76004
|
-
}) : runningAssignmentFeature({
|
|
76005
|
-
mode,
|
|
76006
|
-
target,
|
|
76007
|
-
source: recovered.source,
|
|
76008
|
-
changedAtField: stored.fields["since"]?.kind === "from" ? stored.fields["since"].fieldPath : null,
|
|
76009
|
-
invert: recovered.invert,
|
|
76010
|
-
thresholdWatts: 0,
|
|
76011
|
-
startDelayMs: 0,
|
|
76012
|
-
stopDelayMs: 0
|
|
76013
|
-
});
|
|
76014
|
-
if (rebuilt === null) return false;
|
|
76015
|
-
const { enabled: _enabled, ...rest } = stored;
|
|
76016
|
-
return sameFeature(rest, rebuilt);
|
|
76017
|
-
}
|
|
76018
|
-
//#endregion
|
|
76019
|
-
//#region src/running-state/defaults.ts
|
|
76020
|
-
var RUNNING_POWER_THRESHOLD_WATTS = 5;
|
|
76021
|
-
var RUNNING_POWER_START_DELAY_MS = 3e4;
|
|
76022
|
-
var RUNNING_POWER_STOP_DELAY_MS = 18e4;
|
|
76023
|
-
//#endregion
|
|
76024
76188
|
//#region src/running-state/from-operation.ts
|
|
76025
|
-
function
|
|
76189
|
+
function programStartFromRemaining(running, remainingSeconds, fetchedAt) {
|
|
76190
|
+
if (!running || remainingSeconds === null || remainingSeconds === void 0) return null;
|
|
76191
|
+
if (remainingSeconds <= 0) return null;
|
|
76192
|
+
return fetchedAt - remainingSeconds * 1e3;
|
|
76193
|
+
}
|
|
76194
|
+
function resolveSince(running, previous, transitionAtMs, bootstrapSinceMs) {
|
|
76026
76195
|
if (running === null) return null;
|
|
76027
|
-
|
|
76028
|
-
|
|
76196
|
+
const prevRunning = previous?.running ?? null;
|
|
76197
|
+
if (prevRunning === null) return bootstrapSinceMs;
|
|
76198
|
+
if (prevRunning !== running) return transitionAtMs;
|
|
76199
|
+
return previous?.since ?? null;
|
|
76029
76200
|
}
|
|
76030
|
-
function nativeSlice(running, phase, previous,
|
|
76201
|
+
function nativeSlice(running, phase, previous, transitionAtMs, fetchedAt, bootstrapSinceMs) {
|
|
76031
76202
|
return {
|
|
76032
76203
|
running,
|
|
76033
|
-
since: resolveSince(running, previous,
|
|
76204
|
+
since: resolveSince(running, previous, transitionAtMs, bootstrapSinceMs),
|
|
76034
76205
|
source: "native",
|
|
76035
76206
|
phase: running === null ? null : phase,
|
|
76036
|
-
lastFetchedAt:
|
|
76207
|
+
lastFetchedAt: fetchedAt
|
|
76037
76208
|
};
|
|
76038
76209
|
}
|
|
76039
|
-
function runningFromDishwasherOperation(operation, program, previous,
|
|
76040
|
-
|
|
76041
|
-
if (operation ===
|
|
76042
|
-
if (operation === "
|
|
76043
|
-
|
|
76044
|
-
|
|
76045
|
-
|
|
76046
|
-
if (
|
|
76047
|
-
|
|
76048
|
-
|
|
76049
|
-
|
|
76050
|
-
|
|
76051
|
-
|
|
76052
|
-
if (
|
|
76053
|
-
if (
|
|
76054
|
-
|
|
76055
|
-
|
|
76056
|
-
|
|
76057
|
-
|
|
76058
|
-
if (
|
|
76059
|
-
if (
|
|
76060
|
-
if (
|
|
76061
|
-
return nativeSlice(false,
|
|
76210
|
+
function runningFromDishwasherOperation(operation, program, previous, fetchedAt, remainingSeconds, transitionAt) {
|
|
76211
|
+
const transitionAtMs = transitionAt ?? fetchedAt;
|
|
76212
|
+
if (operation === null) return nativeSlice(null, null, previous, transitionAtMs, fetchedAt, null);
|
|
76213
|
+
if (operation === "Run" || operation === "Aborting") {
|
|
76214
|
+
const bootstrap = programStartFromRemaining(true, remainingSeconds, fetchedAt);
|
|
76215
|
+
return nativeSlice(true, program ?? operation, previous, transitionAtMs, fetchedAt, bootstrap);
|
|
76216
|
+
}
|
|
76217
|
+
if (operation === "Pause") return nativeSlice(false, "Pause", previous, transitionAtMs, fetchedAt, null);
|
|
76218
|
+
return nativeSlice(false, operation, previous, transitionAtMs, fetchedAt, null);
|
|
76219
|
+
}
|
|
76220
|
+
function runningFromVacuumState(state, previous, fetchedAt, transitionAt) {
|
|
76221
|
+
const transitionAtMs = transitionAt ?? fetchedAt;
|
|
76222
|
+
if (state === null) return nativeSlice(null, null, previous, transitionAtMs, fetchedAt, null);
|
|
76223
|
+
if (state === "cleaning" || state === "returning" || state === "drying") return nativeSlice(true, state, previous, transitionAtMs, fetchedAt, null);
|
|
76224
|
+
if (state === "paused") return nativeSlice(false, "paused", previous, transitionAtMs, fetchedAt, null);
|
|
76225
|
+
return nativeSlice(false, state, previous, transitionAtMs, fetchedAt, null);
|
|
76226
|
+
}
|
|
76227
|
+
function runningFromLawnMower(activity, previous, fetchedAt, transitionAt) {
|
|
76228
|
+
const transitionAtMs = transitionAt ?? fetchedAt;
|
|
76229
|
+
if (activity === null) return nativeSlice(null, null, previous, transitionAtMs, fetchedAt, null);
|
|
76230
|
+
if (activity === "mowing") return nativeSlice(true, activity, previous, transitionAtMs, fetchedAt, null);
|
|
76231
|
+
if (activity === "paused") return nativeSlice(false, "paused", previous, transitionAtMs, fetchedAt, null);
|
|
76232
|
+
return nativeSlice(false, activity, previous, transitionAtMs, fetchedAt, null);
|
|
76233
|
+
}
|
|
76234
|
+
function runningFromMediaPlayer(state, previous, fetchedAt, transitionAt) {
|
|
76235
|
+
const transitionAtMs = transitionAt ?? fetchedAt;
|
|
76236
|
+
if (state === null) return nativeSlice(null, null, previous, transitionAtMs, fetchedAt, null);
|
|
76237
|
+
if (state === "playing" || state === "buffering") return nativeSlice(true, state, previous, transitionAtMs, fetchedAt, null);
|
|
76238
|
+
if (state === "paused") return nativeSlice(false, "paused", previous, transitionAtMs, fetchedAt, null);
|
|
76239
|
+
return nativeSlice(false, state, previous, transitionAtMs, fetchedAt, null);
|
|
76062
76240
|
}
|
|
76063
76241
|
//#endregion
|
|
76064
76242
|
//#region src/clips/clip-event-labels.ts
|
|
@@ -76950,74 +77128,6 @@ function feederCustomizationExample(sources) {
|
|
|
76950
77128
|
});
|
|
76951
77129
|
}
|
|
76952
77130
|
//#endregion
|
|
76953
|
-
//#region src/composition/presets/doorbell-feature.ts
|
|
76954
|
-
/**
|
|
76955
|
-
* The doorbell of a camera as a customization (D671). ONE builder: the admin
|
|
76956
|
-
* UI's Customize → Doorbell card writes every doorbell feature through it, and
|
|
76957
|
-
* edits one only when it is exactly what this builds (`isDoorbellPresetFeature`)
|
|
76958
|
-
* — a composed doorbell has one canonical shape.
|
|
76959
|
-
*/
|
|
76960
|
-
/** A rise closer than this to the previous one is the same press (D671). */
|
|
76961
|
-
var DOORBELL_RISE_DEBOUNCE_MS = 2e3;
|
|
76962
|
-
/** Every source cap of `source` that `SOURCE_CAP_ACTIVE_FIELD` knows AND the device has bound. */
|
|
76963
|
-
function doorbellFeatureSources(source, boundCaps) {
|
|
76964
|
-
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) => {
|
|
76965
|
-
const activeField = require_composition.SOURCE_CAP_ACTIVE_FIELD[cap];
|
|
76966
|
-
const changedAtField = require_composition.SOURCE_CAP_CHANGED_AT_FIELD[cap];
|
|
76967
|
-
return activeField === void 0 || changedAtField === void 0 ? [] : [{
|
|
76968
|
-
source,
|
|
76969
|
-
cap,
|
|
76970
|
-
activeField,
|
|
76971
|
-
changedAtField
|
|
76972
|
-
}];
|
|
76973
|
-
});
|
|
76974
|
-
}
|
|
76975
|
-
/** The canonical D671 doorbell feature. Throws on zero sources. */
|
|
76976
|
-
function buildDoorbellCompositionFeature(input) {
|
|
76977
|
-
const sources = [...input.sources].toSorted((a, b) => `${a.source.addonId}/${a.source.stableId}#${a.cap}`.localeCompare(`${b.source.addonId}/${b.source.stableId}#${b.cap}`));
|
|
76978
|
-
if (sources.length === 0) throw new Error("doorbell composition needs at least one source");
|
|
76979
|
-
const edgeBindings = {};
|
|
76980
|
-
sources.forEach((entry, index) => {
|
|
76981
|
-
edgeBindings[`active${index}`] = {
|
|
76982
|
-
kind: "from",
|
|
76983
|
-
source: entry.source,
|
|
76984
|
-
cap: entry.cap,
|
|
76985
|
-
fieldPath: entry.activeField
|
|
76986
|
-
};
|
|
76987
|
-
edgeBindings[`changed${index}`] = {
|
|
76988
|
-
kind: "from",
|
|
76989
|
-
source: entry.source,
|
|
76990
|
-
cap: entry.cap,
|
|
76991
|
-
fieldPath: entry.changedAtField
|
|
76992
|
-
};
|
|
76993
|
-
});
|
|
76994
|
-
return {
|
|
76995
|
-
kind: "fields",
|
|
76996
|
-
cap: "doorbell",
|
|
76997
|
-
enabled: input.enabled,
|
|
76998
|
-
fields: {
|
|
76999
|
-
lastPressedAt: {
|
|
77000
|
-
kind: "expression",
|
|
77001
|
-
expr: `latest(${sources.map((_, index) => `rose(active${index}, changed${index}, ${DOORBELL_RISE_DEBOUNCE_MS})`).join(", ")})`,
|
|
77002
|
-
bindings: edgeBindings
|
|
77003
|
-
},
|
|
77004
|
-
pressCountSinceStart: {
|
|
77005
|
-
kind: "expression",
|
|
77006
|
-
expr: "count(lastPressedAt)",
|
|
77007
|
-
bindings: { lastPressedAt: {
|
|
77008
|
-
kind: "from",
|
|
77009
|
-
source: {
|
|
77010
|
-
addonId: input.camera.addonId,
|
|
77011
|
-
stableId: input.camera.stableId
|
|
77012
|
-
},
|
|
77013
|
-
cap: "doorbell",
|
|
77014
|
-
fieldPath: "lastPressedAt"
|
|
77015
|
-
} }
|
|
77016
|
-
}
|
|
77017
|
-
}
|
|
77018
|
-
};
|
|
77019
|
-
}
|
|
77020
|
-
//#endregion
|
|
77021
77131
|
//#region src/composition/presets/numeric-transforms.ts
|
|
77022
77132
|
/**
|
|
77023
77133
|
* Self-only invert / unit-convert composition features (D663). The Numeric
|
|
@@ -100291,6 +100401,1862 @@ function historyFieldsFor(capName) {
|
|
|
100291
100401
|
return HISTORY_CATALOG[capName] ?? {};
|
|
100292
100402
|
}
|
|
100293
100403
|
//#endregion
|
|
100404
|
+
//#region src/generated/customize-catalog.ts
|
|
100405
|
+
/**
|
|
100406
|
+
* Customize catalog, projected from every `*.cap.ts` `customize` block.
|
|
100407
|
+
* 5 caps. Field keys are `runtimeState` paths. No Zod.
|
|
100408
|
+
*/
|
|
100409
|
+
var CAP_CUSTOMIZE_CATALOG = {
|
|
100410
|
+
"battery": {
|
|
100411
|
+
version: 1,
|
|
100412
|
+
targets: [{
|
|
100413
|
+
id: "percentage",
|
|
100414
|
+
cardinality: "scalar",
|
|
100415
|
+
deviceTypes: [
|
|
100416
|
+
require_err_msg.DeviceType.Camera,
|
|
100417
|
+
require_err_msg.DeviceType.Sensor,
|
|
100418
|
+
require_err_msg.DeviceType.Button,
|
|
100419
|
+
require_err_msg.DeviceType.Switch,
|
|
100420
|
+
require_err_msg.DeviceType.PetFeeder,
|
|
100421
|
+
require_err_msg.DeviceType.Container,
|
|
100422
|
+
require_err_msg.DeviceType.Thermostat
|
|
100423
|
+
],
|
|
100424
|
+
apply: "add-or-replace",
|
|
100425
|
+
vocabularyCap: "battery",
|
|
100426
|
+
vocabularyStateField: "percentage",
|
|
100427
|
+
sources: [{
|
|
100428
|
+
kind: "field",
|
|
100429
|
+
valueKinds: ["number", "string"],
|
|
100430
|
+
transformKinds: ["identity", "linear"]
|
|
100431
|
+
}],
|
|
100432
|
+
sourceReport: { status: "assignment-status" },
|
|
100433
|
+
advancedExpression: true,
|
|
100434
|
+
path: "percentage",
|
|
100435
|
+
valueKind: "number",
|
|
100436
|
+
nullable: true,
|
|
100437
|
+
companions: [
|
|
100438
|
+
{
|
|
100439
|
+
kind: "constant",
|
|
100440
|
+
path: "charging",
|
|
100441
|
+
value: "unknown",
|
|
100442
|
+
when: "add"
|
|
100443
|
+
},
|
|
100444
|
+
{
|
|
100445
|
+
kind: "constant",
|
|
100446
|
+
path: "sleeping",
|
|
100447
|
+
value: false,
|
|
100448
|
+
when: "add"
|
|
100449
|
+
},
|
|
100450
|
+
{
|
|
100451
|
+
kind: "clock",
|
|
100452
|
+
path: "lastUpdated",
|
|
100453
|
+
when: "add"
|
|
100454
|
+
}
|
|
100455
|
+
]
|
|
100456
|
+
}]
|
|
100457
|
+
},
|
|
100458
|
+
"consumables": {
|
|
100459
|
+
version: 1,
|
|
100460
|
+
targets: [{
|
|
100461
|
+
id: "items",
|
|
100462
|
+
cardinality: "keyedArray",
|
|
100463
|
+
deviceTypes: [
|
|
100464
|
+
require_err_msg.DeviceType.Camera,
|
|
100465
|
+
require_err_msg.DeviceType.Hub,
|
|
100466
|
+
require_err_msg.DeviceType.Light,
|
|
100467
|
+
require_err_msg.DeviceType.Siren,
|
|
100468
|
+
require_err_msg.DeviceType.Switch,
|
|
100469
|
+
require_err_msg.DeviceType.Sensor,
|
|
100470
|
+
require_err_msg.DeviceType.Thermostat,
|
|
100471
|
+
require_err_msg.DeviceType.Climate,
|
|
100472
|
+
require_err_msg.DeviceType.Button,
|
|
100473
|
+
require_err_msg.DeviceType.EventEmitter,
|
|
100474
|
+
require_err_msg.DeviceType.Update,
|
|
100475
|
+
require_err_msg.DeviceType.Generic,
|
|
100476
|
+
require_err_msg.DeviceType.Notifier,
|
|
100477
|
+
require_err_msg.DeviceType.Script,
|
|
100478
|
+
require_err_msg.DeviceType.Automation,
|
|
100479
|
+
require_err_msg.DeviceType.Lock,
|
|
100480
|
+
require_err_msg.DeviceType.Cover,
|
|
100481
|
+
require_err_msg.DeviceType.Valve,
|
|
100482
|
+
require_err_msg.DeviceType.Humidifier,
|
|
100483
|
+
require_err_msg.DeviceType.WaterHeater,
|
|
100484
|
+
require_err_msg.DeviceType.Fan,
|
|
100485
|
+
require_err_msg.DeviceType.MediaPlayer,
|
|
100486
|
+
require_err_msg.DeviceType.AlarmPanel,
|
|
100487
|
+
require_err_msg.DeviceType.Control,
|
|
100488
|
+
require_err_msg.DeviceType.Presence,
|
|
100489
|
+
require_err_msg.DeviceType.Weather,
|
|
100490
|
+
require_err_msg.DeviceType.Vacuum,
|
|
100491
|
+
require_err_msg.DeviceType.LawnMower,
|
|
100492
|
+
require_err_msg.DeviceType.Container,
|
|
100493
|
+
require_err_msg.DeviceType.Image,
|
|
100494
|
+
require_err_msg.DeviceType.PetFeeder,
|
|
100495
|
+
require_err_msg.DeviceType.Dishwasher
|
|
100496
|
+
],
|
|
100497
|
+
apply: "add",
|
|
100498
|
+
vocabularyCap: "consumables",
|
|
100499
|
+
sources: [],
|
|
100500
|
+
sourceReport: { status: "assignment-status" },
|
|
100501
|
+
advancedExpression: true,
|
|
100502
|
+
path: "items",
|
|
100503
|
+
keyField: "key",
|
|
100504
|
+
labelField: "label",
|
|
100505
|
+
nativeItems: "read-only",
|
|
100506
|
+
fields: [
|
|
100507
|
+
{
|
|
100508
|
+
path: "level",
|
|
100509
|
+
valueKind: "number",
|
|
100510
|
+
nullable: true,
|
|
100511
|
+
sources: [{
|
|
100512
|
+
kind: "numeric",
|
|
100513
|
+
transformKinds: ["identity", "linear"]
|
|
100514
|
+
}]
|
|
100515
|
+
},
|
|
100516
|
+
{
|
|
100517
|
+
path: "remaining.value",
|
|
100518
|
+
valueKind: "number",
|
|
100519
|
+
nullable: true,
|
|
100520
|
+
sources: [{
|
|
100521
|
+
kind: "numeric",
|
|
100522
|
+
transformKinds: ["identity"]
|
|
100523
|
+
}],
|
|
100524
|
+
literals: [{
|
|
100525
|
+
path: "remaining.unit",
|
|
100526
|
+
values: [
|
|
100527
|
+
"days",
|
|
100528
|
+
"hours",
|
|
100529
|
+
"cycles"
|
|
100530
|
+
]
|
|
100531
|
+
}]
|
|
100532
|
+
},
|
|
100533
|
+
{
|
|
100534
|
+
path: "status",
|
|
100535
|
+
valueKind: "enum",
|
|
100536
|
+
nullable: true,
|
|
100537
|
+
enumValues: [
|
|
100538
|
+
"ok",
|
|
100539
|
+
"low",
|
|
100540
|
+
"empty",
|
|
100541
|
+
"full",
|
|
100542
|
+
"replace"
|
|
100543
|
+
],
|
|
100544
|
+
sources: [{
|
|
100545
|
+
kind: "enum",
|
|
100546
|
+
transformKinds: ["enum-map"]
|
|
100547
|
+
}]
|
|
100548
|
+
}
|
|
100549
|
+
],
|
|
100550
|
+
traits: [{
|
|
100551
|
+
path: "kind",
|
|
100552
|
+
values: [
|
|
100553
|
+
"wear",
|
|
100554
|
+
"supply",
|
|
100555
|
+
"waste"
|
|
100556
|
+
],
|
|
100557
|
+
defaultValue: "wear"
|
|
100558
|
+
}, {
|
|
100559
|
+
path: "form",
|
|
100560
|
+
values: [
|
|
100561
|
+
"part",
|
|
100562
|
+
"tank",
|
|
100563
|
+
"product",
|
|
100564
|
+
"bin"
|
|
100565
|
+
],
|
|
100566
|
+
defaultValue: "part"
|
|
100567
|
+
}],
|
|
100568
|
+
companions: [{
|
|
100569
|
+
kind: "clock",
|
|
100570
|
+
path: "lastChangedAt",
|
|
100571
|
+
when: "add"
|
|
100572
|
+
}, {
|
|
100573
|
+
kind: "clock",
|
|
100574
|
+
path: "lastFetchedAt",
|
|
100575
|
+
when: "add"
|
|
100576
|
+
}]
|
|
100577
|
+
}]
|
|
100578
|
+
},
|
|
100579
|
+
"doorbell": {
|
|
100580
|
+
version: 1,
|
|
100581
|
+
targets: [{
|
|
100582
|
+
id: "pressed",
|
|
100583
|
+
cardinality: "event",
|
|
100584
|
+
deviceTypes: [require_err_msg.DeviceType.Camera],
|
|
100585
|
+
apply: "add",
|
|
100586
|
+
vocabularyCap: "doorbell",
|
|
100587
|
+
vocabularyEvent: "onPressed",
|
|
100588
|
+
sources: [{
|
|
100589
|
+
kind: "binary",
|
|
100590
|
+
transformKinds: []
|
|
100591
|
+
}, {
|
|
100592
|
+
kind: "switch",
|
|
100593
|
+
transformKinds: []
|
|
100594
|
+
}],
|
|
100595
|
+
sourceReport: { status: "assignment-status" },
|
|
100596
|
+
advancedExpression: true,
|
|
100597
|
+
shape: "pulse",
|
|
100598
|
+
applyAuthority: { kind: "composition-claim" },
|
|
100599
|
+
eventName: "onPressed",
|
|
100600
|
+
combine: "any",
|
|
100601
|
+
edges: ["rising"],
|
|
100602
|
+
timestampPath: "lastPressedAt",
|
|
100603
|
+
counterPath: "pressCountSinceStart",
|
|
100604
|
+
highWater: "composer-advance",
|
|
100605
|
+
debounceMs: 2e3
|
|
100606
|
+
}]
|
|
100607
|
+
},
|
|
100608
|
+
"motion": {
|
|
100609
|
+
version: 1,
|
|
100610
|
+
targets: [{
|
|
100611
|
+
id: "detected",
|
|
100612
|
+
cardinality: "event",
|
|
100613
|
+
deviceTypes: [require_err_msg.DeviceType.Camera],
|
|
100614
|
+
apply: "replace",
|
|
100615
|
+
vocabularyCap: "motion",
|
|
100616
|
+
vocabularyEvent: "onMotionChanged",
|
|
100617
|
+
sources: [{
|
|
100618
|
+
kind: "binary",
|
|
100619
|
+
transformKinds: []
|
|
100620
|
+
}, {
|
|
100621
|
+
kind: "switch",
|
|
100622
|
+
transformKinds: []
|
|
100623
|
+
}],
|
|
100624
|
+
sourceReport: { status: "assignment-status" },
|
|
100625
|
+
advancedExpression: false,
|
|
100626
|
+
shape: "span",
|
|
100627
|
+
applyAuthority: {
|
|
100628
|
+
kind: "camera-sensors",
|
|
100629
|
+
timeoutField: "motionCooldownMs"
|
|
100630
|
+
},
|
|
100631
|
+
eventName: "onMotionChanged",
|
|
100632
|
+
combine: "any",
|
|
100633
|
+
start: "rising-edge",
|
|
100634
|
+
end: "falling-edge-or-timeout",
|
|
100635
|
+
timeoutMs: 3e4,
|
|
100636
|
+
sourceModes: [
|
|
100637
|
+
"in-addition",
|
|
100638
|
+
"confirm",
|
|
100639
|
+
"replace"
|
|
100640
|
+
]
|
|
100641
|
+
}]
|
|
100642
|
+
},
|
|
100643
|
+
"running-state": {
|
|
100644
|
+
version: 1,
|
|
100645
|
+
targets: [{
|
|
100646
|
+
id: "running",
|
|
100647
|
+
cardinality: "scalar",
|
|
100648
|
+
deviceTypes: [
|
|
100649
|
+
require_err_msg.DeviceType.Dishwasher,
|
|
100650
|
+
require_err_msg.DeviceType.Vacuum,
|
|
100651
|
+
require_err_msg.DeviceType.LawnMower,
|
|
100652
|
+
require_err_msg.DeviceType.MediaPlayer,
|
|
100653
|
+
require_err_msg.DeviceType.WaterHeater,
|
|
100654
|
+
require_err_msg.DeviceType.Humidifier,
|
|
100655
|
+
require_err_msg.DeviceType.Fan,
|
|
100656
|
+
require_err_msg.DeviceType.Climate,
|
|
100657
|
+
require_err_msg.DeviceType.Thermostat,
|
|
100658
|
+
require_err_msg.DeviceType.PetFeeder
|
|
100659
|
+
],
|
|
100660
|
+
apply: "add-or-replace",
|
|
100661
|
+
vocabularyCap: "running-state",
|
|
100662
|
+
vocabularyStateField: "running",
|
|
100663
|
+
sources: [
|
|
100664
|
+
{
|
|
100665
|
+
kind: "switch",
|
|
100666
|
+
transformKinds: ["identity"]
|
|
100667
|
+
},
|
|
100668
|
+
{
|
|
100669
|
+
kind: "binary",
|
|
100670
|
+
transformKinds: ["identity", "invert"]
|
|
100671
|
+
},
|
|
100672
|
+
{
|
|
100673
|
+
kind: "numeric",
|
|
100674
|
+
requiredUnit: "W",
|
|
100675
|
+
transformKinds: ["threshold"]
|
|
100676
|
+
}
|
|
100677
|
+
],
|
|
100678
|
+
sourceReport: {
|
|
100679
|
+
status: "assignment-status",
|
|
100680
|
+
runtimeField: "source",
|
|
100681
|
+
nativeValue: "native",
|
|
100682
|
+
assignedValue: "assigned"
|
|
100683
|
+
},
|
|
100684
|
+
advancedExpression: true,
|
|
100685
|
+
path: "running",
|
|
100686
|
+
valueKind: "boolean",
|
|
100687
|
+
nullable: true,
|
|
100688
|
+
companions: [
|
|
100689
|
+
{
|
|
100690
|
+
kind: "constant",
|
|
100691
|
+
path: "source",
|
|
100692
|
+
value: "assigned",
|
|
100693
|
+
when: "always"
|
|
100694
|
+
},
|
|
100695
|
+
{
|
|
100696
|
+
kind: "constant",
|
|
100697
|
+
path: "phase",
|
|
100698
|
+
value: null,
|
|
100699
|
+
when: "always"
|
|
100700
|
+
},
|
|
100701
|
+
{
|
|
100702
|
+
kind: "clock",
|
|
100703
|
+
path: "lastFetchedAt",
|
|
100704
|
+
when: "always"
|
|
100705
|
+
},
|
|
100706
|
+
{
|
|
100707
|
+
kind: "transition-time",
|
|
100708
|
+
path: "since",
|
|
100709
|
+
sourceChangedAt: "prefer"
|
|
100710
|
+
}
|
|
100711
|
+
]
|
|
100712
|
+
}]
|
|
100713
|
+
}
|
|
100714
|
+
};
|
|
100715
|
+
//#endregion
|
|
100716
|
+
//#region src/composition/customize/override-draft.ts
|
|
100717
|
+
/**
|
|
100718
|
+
* A saved Customize assignment (D936). The schema is the type: callers use
|
|
100719
|
+
* `z.infer`, they do not restate the shape.
|
|
100720
|
+
*/
|
|
100721
|
+
var OverrideSourceSchema = zod.z.object({
|
|
100722
|
+
addonId: zod.z.string().min(1),
|
|
100723
|
+
stableId: zod.z.string().min(1),
|
|
100724
|
+
cap: zod.z.string().min(1),
|
|
100725
|
+
fieldPath: zod.z.string().min(1)
|
|
100726
|
+
});
|
|
100727
|
+
var IdentityTransformDraftSchema = zod.z.object({ kind: zod.z.literal("identity") });
|
|
100728
|
+
var InvertTransformDraftSchema = zod.z.object({ kind: zod.z.literal("invert") });
|
|
100729
|
+
var ThresholdTransformDraftSchema = zod.z.object({
|
|
100730
|
+
kind: zod.z.literal("threshold"),
|
|
100731
|
+
comparison: zod.z.enum(["gte", "lte"]),
|
|
100732
|
+
threshold: zod.z.number(),
|
|
100733
|
+
startDwellMs: zod.z.number().nonnegative(),
|
|
100734
|
+
stopDwellMs: zod.z.number().nonnegative()
|
|
100735
|
+
});
|
|
100736
|
+
var LinearTransformDraftSchema = zod.z.object({
|
|
100737
|
+
kind: zod.z.literal("linear"),
|
|
100738
|
+
scale: zod.z.number(),
|
|
100739
|
+
offset: zod.z.number(),
|
|
100740
|
+
clampMin: zod.z.number().optional(),
|
|
100741
|
+
clampMax: zod.z.number().optional()
|
|
100742
|
+
});
|
|
100743
|
+
var EnumMapTransformDraftSchema = zod.z.object({
|
|
100744
|
+
kind: zod.z.literal("enum-map"),
|
|
100745
|
+
mapping: zod.z.record(zod.z.string(), zod.z.string().nullable())
|
|
100746
|
+
});
|
|
100747
|
+
var NumberBridgeTransformDraftSchema = zod.z.object({ kind: zod.z.literal("number") });
|
|
100748
|
+
var CustomizeTransformDraftSchema = zod.z.discriminatedUnion("kind", [
|
|
100749
|
+
IdentityTransformDraftSchema,
|
|
100750
|
+
InvertTransformDraftSchema,
|
|
100751
|
+
ThresholdTransformDraftSchema,
|
|
100752
|
+
LinearTransformDraftSchema,
|
|
100753
|
+
EnumMapTransformDraftSchema,
|
|
100754
|
+
NumberBridgeTransformDraftSchema
|
|
100755
|
+
]);
|
|
100756
|
+
var ScalarOverrideDraftSchema = zod.z.object({
|
|
100757
|
+
kind: zod.z.literal("scalar"),
|
|
100758
|
+
cap: zod.z.string().min(1),
|
|
100759
|
+
targetId: zod.z.string().min(1),
|
|
100760
|
+
source: OverrideSourceSchema,
|
|
100761
|
+
transform: CustomizeTransformDraftSchema
|
|
100762
|
+
});
|
|
100763
|
+
var KeyedArrayOverrideDraftSchema = zod.z.object({
|
|
100764
|
+
kind: zod.z.literal("keyedArray"),
|
|
100765
|
+
cap: zod.z.string().min(1),
|
|
100766
|
+
targetId: zod.z.string().min(1),
|
|
100767
|
+
key: zod.z.string().min(1),
|
|
100768
|
+
label: zod.z.string().min(1),
|
|
100769
|
+
fieldPath: zod.z.string().min(1),
|
|
100770
|
+
source: OverrideSourceSchema,
|
|
100771
|
+
transform: CustomizeTransformDraftSchema
|
|
100772
|
+
});
|
|
100773
|
+
var PulseOverrideDraftSchema = zod.z.object({
|
|
100774
|
+
kind: zod.z.literal("pulse"),
|
|
100775
|
+
cap: zod.z.string().min(1),
|
|
100776
|
+
targetId: zod.z.string().min(1),
|
|
100777
|
+
enabled: zod.z.boolean(),
|
|
100778
|
+
debounceMs: zod.z.number().nonnegative(),
|
|
100779
|
+
sources: zod.z.array(OverrideSourceSchema).min(1)
|
|
100780
|
+
});
|
|
100781
|
+
var SpanSourceDraftSchema = OverrideSourceSchema.extend({ mode: zod.z.enum([
|
|
100782
|
+
"in-addition",
|
|
100783
|
+
"confirm",
|
|
100784
|
+
"replace"
|
|
100785
|
+
]).optional() });
|
|
100786
|
+
var SpanOverrideDraftSchema = zod.z.object({
|
|
100787
|
+
kind: zod.z.literal("span"),
|
|
100788
|
+
cap: zod.z.string().min(1),
|
|
100789
|
+
targetId: zod.z.string().min(1),
|
|
100790
|
+
timeoutMs: zod.z.number().nonnegative(),
|
|
100791
|
+
cooldownMs: zod.z.number().nonnegative().optional(),
|
|
100792
|
+
sources: zod.z.array(SpanSourceDraftSchema)
|
|
100793
|
+
});
|
|
100794
|
+
var OverrideDraftSchema = zod.z.discriminatedUnion("kind", [
|
|
100795
|
+
ScalarOverrideDraftSchema,
|
|
100796
|
+
KeyedArrayOverrideDraftSchema,
|
|
100797
|
+
PulseOverrideDraftSchema,
|
|
100798
|
+
SpanOverrideDraftSchema
|
|
100799
|
+
]);
|
|
100800
|
+
/** Effective authority for one declared target. Not a second stored switch. */
|
|
100801
|
+
var CustomizeAssignmentStatusSchema = zod.z.object({
|
|
100802
|
+
targetId: zod.z.string().min(1),
|
|
100803
|
+
configured: zod.z.boolean(),
|
|
100804
|
+
source: zod.z.enum(["native", "assigned"]),
|
|
100805
|
+
state: zod.z.enum([
|
|
100806
|
+
"active",
|
|
100807
|
+
"stale",
|
|
100808
|
+
"released",
|
|
100809
|
+
"unavailable"
|
|
100810
|
+
]),
|
|
100811
|
+
reason: zod.z.string().nullable()
|
|
100812
|
+
});
|
|
100813
|
+
//#endregion
|
|
100814
|
+
//#region src/composition/customize/field-source.ts
|
|
100815
|
+
function fromRead(source, cap, fieldPath) {
|
|
100816
|
+
return {
|
|
100817
|
+
kind: "from",
|
|
100818
|
+
source,
|
|
100819
|
+
cap,
|
|
100820
|
+
fieldPath
|
|
100821
|
+
};
|
|
100822
|
+
}
|
|
100823
|
+
function expression(expr, bindings) {
|
|
100824
|
+
return {
|
|
100825
|
+
kind: "expression",
|
|
100826
|
+
expr,
|
|
100827
|
+
bindings
|
|
100828
|
+
};
|
|
100829
|
+
}
|
|
100830
|
+
function literal(expr) {
|
|
100831
|
+
return expression(expr, {});
|
|
100832
|
+
}
|
|
100833
|
+
function isLiteral(source, expr) {
|
|
100834
|
+
return source?.kind === "expression" && source.expr === expr && Object.keys(source.bindings).length === 0;
|
|
100835
|
+
}
|
|
100836
|
+
//#endregion
|
|
100837
|
+
//#region src/composition/customize/scalar-expr.ts
|
|
100838
|
+
var UNSIGNED = /^\d+(?:\.\d+)?$/;
|
|
100839
|
+
var SIGNED = /^-?\d+(?:\.\d+)?$/;
|
|
100840
|
+
var DWELL = /^dwell\(x (>=|<=) (\d+(?:\.\d+)?), (\d+(?:\.\d+)?), (\d+(?:\.\d+)?)\)$/;
|
|
100841
|
+
var LINEAR_CLAMP = /^clamp\((x|number\(x\)) \* (-?\d+(?:\.\d+)?) \+ (-?\d+(?:\.\d+)?), (-?\d+(?:\.\d+)?), (-?\d+(?:\.\d+)?)\)$/;
|
|
100842
|
+
var LINEAR_BARE = /^(x|number\(x\)) \* (-?\d+(?:\.\d+)?) \+ (-?\d+(?:\.\d+)?)$/;
|
|
100843
|
+
var IDENT = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
100844
|
+
function unsignedToken(value) {
|
|
100845
|
+
return token(value, UNSIGNED);
|
|
100846
|
+
}
|
|
100847
|
+
function signedToken(value) {
|
|
100848
|
+
return token(value, SIGNED);
|
|
100849
|
+
}
|
|
100850
|
+
function constantExpr(value) {
|
|
100851
|
+
if (typeof value === "string") return JSON.stringify(value);
|
|
100852
|
+
if (typeof value === "number") return signedToken(value);
|
|
100853
|
+
if (typeof value === "boolean") return value ? "true" : "false";
|
|
100854
|
+
return "null";
|
|
100855
|
+
}
|
|
100856
|
+
function isIdentifier(path) {
|
|
100857
|
+
return IDENT.test(path);
|
|
100858
|
+
}
|
|
100859
|
+
function dwellExpr(comparison, threshold, start, stop) {
|
|
100860
|
+
return `dwell(x ${comparison === "gte" ? ">=" : "<="} ${threshold}, ${start}, ${stop})`;
|
|
100861
|
+
}
|
|
100862
|
+
function linearExpr(inner, scale, offset, clampMin, clampMax) {
|
|
100863
|
+
const arithmetic = `${inner} * ${scale} + ${offset}`;
|
|
100864
|
+
if (clampMin === null || clampMax === null) return arithmetic;
|
|
100865
|
+
return `clamp(${arithmetic}, ${clampMin}, ${clampMax})`;
|
|
100866
|
+
}
|
|
100867
|
+
function parseDwell(expr) {
|
|
100868
|
+
const match = DWELL.exec(expr);
|
|
100869
|
+
if (match === null) return null;
|
|
100870
|
+
const threshold = Number(match[2]);
|
|
100871
|
+
const startDwellMs = Number(match[3]);
|
|
100872
|
+
const stopDwellMs = Number(match[4]);
|
|
100873
|
+
if (!Number.isFinite(threshold) || !Number.isFinite(startDwellMs) || !Number.isFinite(stopDwellMs)) return null;
|
|
100874
|
+
return {
|
|
100875
|
+
comparison: match[1] === "<=" ? "lte" : "gte",
|
|
100876
|
+
threshold,
|
|
100877
|
+
startDwellMs,
|
|
100878
|
+
stopDwellMs
|
|
100879
|
+
};
|
|
100880
|
+
}
|
|
100881
|
+
function parseLinear(expr) {
|
|
100882
|
+
const clamped = LINEAR_CLAMP.exec(expr);
|
|
100883
|
+
if (clamped !== null) return linearFrom(clamped[1], clamped[2], clamped[3], clamped[4], clamped[5]);
|
|
100884
|
+
const bare = LINEAR_BARE.exec(expr);
|
|
100885
|
+
if (bare === null) return null;
|
|
100886
|
+
return linearFrom(bare[1], bare[2], bare[3], void 0, void 0);
|
|
100887
|
+
}
|
|
100888
|
+
function singleFrom(source) {
|
|
100889
|
+
if (source.kind === "from") return {
|
|
100890
|
+
cap: source.cap,
|
|
100891
|
+
fieldPath: source.fieldPath,
|
|
100892
|
+
addonId: source.source.addonId,
|
|
100893
|
+
stableId: source.source.stableId
|
|
100894
|
+
};
|
|
100895
|
+
if (source.kind !== "expression" || Object.keys(source.bindings).length !== 1) return null;
|
|
100896
|
+
const bound = source.bindings["x"];
|
|
100897
|
+
if (bound === void 0 || bound.kind !== "from") return null;
|
|
100898
|
+
return {
|
|
100899
|
+
cap: bound.cap,
|
|
100900
|
+
fieldPath: bound.fieldPath,
|
|
100901
|
+
addonId: bound.source.addonId,
|
|
100902
|
+
stableId: bound.source.stableId
|
|
100903
|
+
};
|
|
100904
|
+
}
|
|
100905
|
+
function token(value, pattern) {
|
|
100906
|
+
if (!Number.isFinite(value)) return null;
|
|
100907
|
+
const text = Object.is(value, -0) ? "0" : String(value);
|
|
100908
|
+
return pattern.test(text) ? text : null;
|
|
100909
|
+
}
|
|
100910
|
+
function linearFrom(inner, scale, offset, clampMin, clampMax) {
|
|
100911
|
+
if (inner !== "x" && inner !== "number(x)") return null;
|
|
100912
|
+
if (scale === void 0 || offset === void 0) return null;
|
|
100913
|
+
const parsedScale = Number(scale);
|
|
100914
|
+
const parsedOffset = Number(offset);
|
|
100915
|
+
if (!Number.isFinite(parsedScale) || !Number.isFinite(parsedOffset)) return null;
|
|
100916
|
+
if (clampMin === void 0 || clampMax === void 0) return {
|
|
100917
|
+
inner,
|
|
100918
|
+
scale: parsedScale,
|
|
100919
|
+
offset: parsedOffset
|
|
100920
|
+
};
|
|
100921
|
+
const parsedMin = Number(clampMin);
|
|
100922
|
+
const parsedMax = Number(clampMax);
|
|
100923
|
+
if (!Number.isFinite(parsedMin) || !Number.isFinite(parsedMax)) return null;
|
|
100924
|
+
return {
|
|
100925
|
+
inner,
|
|
100926
|
+
scale: parsedScale,
|
|
100927
|
+
offset: parsedOffset,
|
|
100928
|
+
clampMin: parsedMin,
|
|
100929
|
+
clampMax: parsedMax
|
|
100930
|
+
};
|
|
100931
|
+
}
|
|
100932
|
+
//#endregion
|
|
100933
|
+
//#region src/composition/customize/scalar-compile.ts
|
|
100934
|
+
var catalog$4 = CAP_CUSTOMIZE_CATALOG;
|
|
100935
|
+
function compileScalarOverride(input) {
|
|
100936
|
+
const target = catalogTarget$4(input.draft.cap, input.draft.targetId);
|
|
100937
|
+
if (target === null || target.cardinality !== "scalar" || target.path === void 0) return fail$2("target");
|
|
100938
|
+
if (input.draft.transform.kind === "enum-map") return fail$2("enum");
|
|
100939
|
+
const source = sourceSpec$1(target, input.sourceValueKind, input.draft.source.cap);
|
|
100940
|
+
if (source === null) return fail$2("source-kind");
|
|
100941
|
+
if (source.requiredUnit !== void 0 && input.sourceUnit !== source.requiredUnit) return fail$2("unit");
|
|
100942
|
+
const allowed = input.draft.transform.kind === "number" ? "identity" : input.draft.transform.kind;
|
|
100943
|
+
if (!source.transformKinds.includes(allowed)) return fail$2("transform");
|
|
100944
|
+
const value = compileValue$1(input);
|
|
100945
|
+
if (!value.ok) return value;
|
|
100946
|
+
const fields = compileCompanions$1(input, target, value.value);
|
|
100947
|
+
if (!fields.ok) return fields;
|
|
100948
|
+
return {
|
|
100949
|
+
ok: true,
|
|
100950
|
+
value: {
|
|
100951
|
+
kind: "fields",
|
|
100952
|
+
cap: input.draft.cap,
|
|
100953
|
+
fields: fields.value
|
|
100954
|
+
}
|
|
100955
|
+
};
|
|
100956
|
+
}
|
|
100957
|
+
function fail$2(reason) {
|
|
100958
|
+
return {
|
|
100959
|
+
ok: false,
|
|
100960
|
+
reason
|
|
100961
|
+
};
|
|
100962
|
+
}
|
|
100963
|
+
function catalogTarget$4(cap, targetId) {
|
|
100964
|
+
const entry = catalog$4[cap];
|
|
100965
|
+
if (entry === void 0) return null;
|
|
100966
|
+
return entry.targets.find((target) => target.id === targetId) ?? null;
|
|
100967
|
+
}
|
|
100968
|
+
function sourceSpec$1(target, valueKind, sourceCap) {
|
|
100969
|
+
if (valueKind === "boolean" && sourceCap === "switch") return target.sources.find((source) => source.kind === "switch") ?? null;
|
|
100970
|
+
if (valueKind === "boolean") return target.sources.find((source) => source.kind === "binary") ?? fieldSource(target, "boolean");
|
|
100971
|
+
if (valueKind === "number") return target.sources.find((source) => source.kind === "numeric") ?? fieldSource(target, "number");
|
|
100972
|
+
return fieldSource(target, "string");
|
|
100973
|
+
}
|
|
100974
|
+
function fieldSource(target, valueKind) {
|
|
100975
|
+
return target.sources.find((source) => source.kind === "field" && (source.valueKinds ?? []).includes(valueKind)) ?? null;
|
|
100976
|
+
}
|
|
100977
|
+
function compileValue$1(input) {
|
|
100978
|
+
const read = fromRead(refOf$1(input.draft), input.draft.source.cap, input.draft.source.fieldPath);
|
|
100979
|
+
const transform = input.draft.transform;
|
|
100980
|
+
if (transform.kind === "identity" || transform.kind === "number") return {
|
|
100981
|
+
ok: true,
|
|
100982
|
+
value: identityValue(read, input.sourceValueKind)
|
|
100983
|
+
};
|
|
100984
|
+
if (transform.kind === "invert") {
|
|
100985
|
+
if (input.sourceValueKind !== "boolean") return fail$2("source-kind");
|
|
100986
|
+
return {
|
|
100987
|
+
ok: true,
|
|
100988
|
+
value: expression("!x", { x: read })
|
|
100989
|
+
};
|
|
100990
|
+
}
|
|
100991
|
+
if (transform.kind === "threshold") return thresholdValue(transform, read);
|
|
100992
|
+
if (transform.kind === "linear") return linearValue$1(transform, read, input.sourceValueKind);
|
|
100993
|
+
return fail$2("transform");
|
|
100994
|
+
}
|
|
100995
|
+
function identityValue(read, valueKind) {
|
|
100996
|
+
if (valueKind === "string") return expression("number(x)", { x: read });
|
|
100997
|
+
return read;
|
|
100998
|
+
}
|
|
100999
|
+
function thresholdValue(transform, read) {
|
|
101000
|
+
const threshold = unsignedToken(transform.threshold);
|
|
101001
|
+
if (threshold === null) return fail$2("threshold");
|
|
101002
|
+
const start = unsignedToken(transform.startDwellMs);
|
|
101003
|
+
const stop = unsignedToken(transform.stopDwellMs);
|
|
101004
|
+
if (start === null || stop === null) return fail$2("dwell");
|
|
101005
|
+
return {
|
|
101006
|
+
ok: true,
|
|
101007
|
+
value: expression(dwellExpr(transform.comparison, threshold, start, stop), { x: read })
|
|
101008
|
+
};
|
|
101009
|
+
}
|
|
101010
|
+
function linearValue$1(transform, read, valueKind) {
|
|
101011
|
+
const scale = signedToken(transform.scale);
|
|
101012
|
+
const offset = signedToken(transform.offset);
|
|
101013
|
+
if (scale === null || offset === null) return fail$2("scale");
|
|
101014
|
+
const clamps = clampTokens$1(transform.clampMin, transform.clampMax);
|
|
101015
|
+
if (!clamps.ok) return clamps;
|
|
101016
|
+
return {
|
|
101017
|
+
ok: true,
|
|
101018
|
+
value: expression(linearExpr(valueKind === "string" ? "number(x)" : "x", scale, offset, clamps.value.min, clamps.value.max), { x: read })
|
|
101019
|
+
};
|
|
101020
|
+
}
|
|
101021
|
+
function clampTokens$1(clampMin, clampMax) {
|
|
101022
|
+
if (clampMin === void 0 && clampMax === void 0) return {
|
|
101023
|
+
ok: true,
|
|
101024
|
+
value: {
|
|
101025
|
+
min: null,
|
|
101026
|
+
max: null
|
|
101027
|
+
}
|
|
101028
|
+
};
|
|
101029
|
+
if (clampMin === void 0 || clampMax === void 0) return fail$2("clamp");
|
|
101030
|
+
const min = signedToken(clampMin);
|
|
101031
|
+
const max = signedToken(clampMax);
|
|
101032
|
+
if (min === null || max === null || clampMin > clampMax) return fail$2("clamp");
|
|
101033
|
+
return {
|
|
101034
|
+
ok: true,
|
|
101035
|
+
value: {
|
|
101036
|
+
min,
|
|
101037
|
+
max
|
|
101038
|
+
}
|
|
101039
|
+
};
|
|
101040
|
+
}
|
|
101041
|
+
function compileCompanions$1(input, target, value) {
|
|
101042
|
+
if (target.path === void 0) return fail$2("target");
|
|
101043
|
+
const path = target.path;
|
|
101044
|
+
return (target.companions ?? []).filter((companion) => companionIncluded$1(companion, input.apply)).reduce((acc, companion) => {
|
|
101045
|
+
if (!acc.ok) return acc;
|
|
101046
|
+
const built = companionField(input, path, companion);
|
|
101047
|
+
if (!built.ok) return {
|
|
101048
|
+
ok: false,
|
|
101049
|
+
reason: built.reason
|
|
101050
|
+
};
|
|
101051
|
+
return {
|
|
101052
|
+
ok: true,
|
|
101053
|
+
value: {
|
|
101054
|
+
...acc.value,
|
|
101055
|
+
[companion.path]: built.value
|
|
101056
|
+
}
|
|
101057
|
+
};
|
|
101058
|
+
}, {
|
|
101059
|
+
ok: true,
|
|
101060
|
+
value: { [path]: value }
|
|
101061
|
+
});
|
|
101062
|
+
}
|
|
101063
|
+
function companionIncluded$1(companion, apply) {
|
|
101064
|
+
if (companion.kind === "transition-time") return true;
|
|
101065
|
+
return companion.when === "always" || apply === "add";
|
|
101066
|
+
}
|
|
101067
|
+
function companionField(input, path, companion) {
|
|
101068
|
+
if (companion.kind === "constant") {
|
|
101069
|
+
const expr = constantExpr(companion.value);
|
|
101070
|
+
if (expr === null) return fail$2("scale");
|
|
101071
|
+
return {
|
|
101072
|
+
ok: true,
|
|
101073
|
+
value: literal(expr)
|
|
101074
|
+
};
|
|
101075
|
+
}
|
|
101076
|
+
if (companion.kind === "clock") return {
|
|
101077
|
+
ok: true,
|
|
101078
|
+
value: literal("now")
|
|
101079
|
+
};
|
|
101080
|
+
return transitionField(input, path, companion.sourceChangedAt);
|
|
101081
|
+
}
|
|
101082
|
+
function transitionField(input, path, sourceChangedAt) {
|
|
101083
|
+
if (sourceChangedAt === "prefer" && input.sourceValueKind === "boolean" && input.changedAtField !== null && isIdentifier(input.changedAtField)) return {
|
|
101084
|
+
ok: true,
|
|
101085
|
+
value: fromRead(refOf$1(input.draft), input.draft.source.cap, input.changedAtField)
|
|
101086
|
+
};
|
|
101087
|
+
if (!isIdentifier(path)) return fail$2("transform");
|
|
101088
|
+
const bindings = { [path]: fromRead(input.device, input.draft.cap, path) };
|
|
101089
|
+
return {
|
|
101090
|
+
ok: true,
|
|
101091
|
+
value: expression(`latchedAt(${path})`, bindings)
|
|
101092
|
+
};
|
|
101093
|
+
}
|
|
101094
|
+
function refOf$1(draft) {
|
|
101095
|
+
return {
|
|
101096
|
+
addonId: draft.source.addonId,
|
|
101097
|
+
stableId: draft.source.stableId
|
|
101098
|
+
};
|
|
101099
|
+
}
|
|
101100
|
+
//#endregion
|
|
101101
|
+
//#region src/composition/customize/normalize.ts
|
|
101102
|
+
function sortKeys(value) {
|
|
101103
|
+
if (Array.isArray(value)) return value.map(sortKeys);
|
|
101104
|
+
if (typeof value !== "object" || value === null) return value;
|
|
101105
|
+
return Object.fromEntries(Object.entries(value).toSorted(([a], [b]) => a.localeCompare(b)).map(([key, inner]) => [key, sortKeys(inner)]));
|
|
101106
|
+
}
|
|
101107
|
+
/** Key order is not part of the stored contract. Array order is. */
|
|
101108
|
+
function normalizeStored(stored) {
|
|
101109
|
+
return sortKeys(stored);
|
|
101110
|
+
}
|
|
101111
|
+
function sameStored(a, b) {
|
|
101112
|
+
return JSON.stringify(normalizeStored(a)) === JSON.stringify(normalizeStored(b));
|
|
101113
|
+
}
|
|
101114
|
+
//#endregion
|
|
101115
|
+
//#region src/composition/customize/scalar-decode.ts
|
|
101116
|
+
var catalog$3 = CAP_CUSTOMIZE_CATALOG;
|
|
101117
|
+
function decodeScalarOverride(input) {
|
|
101118
|
+
const target = catalogTarget$3(input.cap, input.targetId);
|
|
101119
|
+
if (target === null || target.cardinality !== "scalar" || target.path === void 0) return null;
|
|
101120
|
+
if (input.feature.cap !== input.cap || input.feature.kind !== "fields") return null;
|
|
101121
|
+
const outputKind = scalarOutputKind(target.valueKind);
|
|
101122
|
+
if (outputKind === null) return null;
|
|
101123
|
+
const value = input.feature.fields[target.path];
|
|
101124
|
+
const read = readValue(value, outputKind, input.cap, input.targetId);
|
|
101125
|
+
if (read === null) return null;
|
|
101126
|
+
const apply = inferApply$1(target, input.feature.fields);
|
|
101127
|
+
if (apply === null) return null;
|
|
101128
|
+
const changedAtField = inferChangedAt(target, input.feature.fields, read);
|
|
101129
|
+
const sourceUnit = unitFor(target, read.sourceValueKind, read.draft.source.cap);
|
|
101130
|
+
const decoded = {
|
|
101131
|
+
...read,
|
|
101132
|
+
apply,
|
|
101133
|
+
changedAtField,
|
|
101134
|
+
sourceUnit
|
|
101135
|
+
};
|
|
101136
|
+
return reproduces$1(decoded, input.device, input.feature) ? decoded : null;
|
|
101137
|
+
}
|
|
101138
|
+
function catalogTarget$3(cap, targetId) {
|
|
101139
|
+
const entry = catalog$3[cap];
|
|
101140
|
+
if (entry === void 0) return null;
|
|
101141
|
+
return entry.targets.find((target) => target.id === targetId) ?? null;
|
|
101142
|
+
}
|
|
101143
|
+
function scalarOutputKind(valueKind) {
|
|
101144
|
+
if (valueKind === "boolean" || valueKind === "number" || valueKind === "string") return valueKind;
|
|
101145
|
+
return null;
|
|
101146
|
+
}
|
|
101147
|
+
function readValue(field, outputKind, cap, targetId) {
|
|
101148
|
+
if (field === void 0) return null;
|
|
101149
|
+
if (field.kind === "from") return drafted(field, { kind: "identity" }, outputKind, cap, targetId);
|
|
101150
|
+
if (field.kind !== "expression") return null;
|
|
101151
|
+
if (field.expr === "number(x)" && outputKind === "number") return drafted(field, { kind: "identity" }, "string", cap, targetId);
|
|
101152
|
+
if (field.expr === "!x" && outputKind === "boolean") return drafted(field, { kind: "invert" }, "boolean", cap, targetId);
|
|
101153
|
+
const dwell = parseDwell(field.expr);
|
|
101154
|
+
if (dwell !== null) return drafted(field, {
|
|
101155
|
+
kind: "threshold",
|
|
101156
|
+
comparison: dwell.comparison,
|
|
101157
|
+
threshold: dwell.threshold,
|
|
101158
|
+
startDwellMs: dwell.startDwellMs,
|
|
101159
|
+
stopDwellMs: dwell.stopDwellMs
|
|
101160
|
+
}, "number", cap, targetId);
|
|
101161
|
+
const linear = parseLinear(field.expr);
|
|
101162
|
+
if (linear === null || outputKind !== "number") return null;
|
|
101163
|
+
return drafted(field, {
|
|
101164
|
+
kind: "linear",
|
|
101165
|
+
scale: linear.scale,
|
|
101166
|
+
offset: linear.offset,
|
|
101167
|
+
...linear.clampMin === void 0 || linear.clampMax === void 0 ? {} : {
|
|
101168
|
+
clampMin: linear.clampMin,
|
|
101169
|
+
clampMax: linear.clampMax
|
|
101170
|
+
}
|
|
101171
|
+
}, linear.inner === "number(x)" ? "string" : "number", cap, targetId);
|
|
101172
|
+
}
|
|
101173
|
+
function drafted(field, transform, sourceValueKind, cap, targetId) {
|
|
101174
|
+
const bound = singleFrom(field);
|
|
101175
|
+
if (bound === null) return null;
|
|
101176
|
+
return {
|
|
101177
|
+
sourceValueKind,
|
|
101178
|
+
draft: {
|
|
101179
|
+
kind: "scalar",
|
|
101180
|
+
cap,
|
|
101181
|
+
targetId,
|
|
101182
|
+
source: {
|
|
101183
|
+
addonId: bound.addonId,
|
|
101184
|
+
stableId: bound.stableId,
|
|
101185
|
+
cap: bound.cap,
|
|
101186
|
+
fieldPath: bound.fieldPath
|
|
101187
|
+
},
|
|
101188
|
+
transform
|
|
101189
|
+
}
|
|
101190
|
+
};
|
|
101191
|
+
}
|
|
101192
|
+
function inferApply$1(target, fields) {
|
|
101193
|
+
const addPaths = (target.companions ?? []).flatMap((companion) => companion.kind !== "transition-time" && companion.when === "add" ? [companion.path] : []);
|
|
101194
|
+
if (addPaths.length === 0) return "replace";
|
|
101195
|
+
const present = addPaths.filter((path) => fields[path] !== void 0);
|
|
101196
|
+
if (present.length === addPaths.length) return "add";
|
|
101197
|
+
if (present.length === 0) return "replace";
|
|
101198
|
+
return null;
|
|
101199
|
+
}
|
|
101200
|
+
function inferChangedAt(target, fields, read) {
|
|
101201
|
+
if (read.sourceValueKind !== "boolean") return null;
|
|
101202
|
+
const transition = (target.companions ?? []).find((companion) => companion.kind === "transition-time");
|
|
101203
|
+
if (transition === void 0 || transition.sourceChangedAt !== "prefer") return null;
|
|
101204
|
+
const since = fields[transition.path];
|
|
101205
|
+
if (since?.kind !== "from") return null;
|
|
101206
|
+
if (since.cap !== read.draft.source.cap) return null;
|
|
101207
|
+
if (since.source.addonId !== read.draft.source.addonId || since.source.stableId !== read.draft.source.stableId) return null;
|
|
101208
|
+
return since.fieldPath;
|
|
101209
|
+
}
|
|
101210
|
+
function unitFor(target, valueKind, sourceCap) {
|
|
101211
|
+
if (valueKind === "boolean" && sourceCap === "switch") return null;
|
|
101212
|
+
if (valueKind === "number") return target.sources.find((source) => source.kind === "numeric")?.requiredUnit ?? null;
|
|
101213
|
+
return null;
|
|
101214
|
+
}
|
|
101215
|
+
function reproduces$1(decoded, device, stored) {
|
|
101216
|
+
const compiled = compileScalarOverride({
|
|
101217
|
+
draft: decoded.draft,
|
|
101218
|
+
device,
|
|
101219
|
+
apply: decoded.apply,
|
|
101220
|
+
sourceValueKind: decoded.sourceValueKind,
|
|
101221
|
+
changedAtField: decoded.changedAtField,
|
|
101222
|
+
sourceUnit: decoded.sourceUnit
|
|
101223
|
+
});
|
|
101224
|
+
if (!compiled.ok) return false;
|
|
101225
|
+
return sameFeature$2(compiled.value, stored);
|
|
101226
|
+
}
|
|
101227
|
+
function sameFeature$2(compiled, stored) {
|
|
101228
|
+
return sameStored(wrap$2(withoutEnabled(compiled)), wrap$2(withoutEnabled(stored)));
|
|
101229
|
+
}
|
|
101230
|
+
function withoutEnabled(feature) {
|
|
101231
|
+
const { enabled: _enabled, ...rest } = feature;
|
|
101232
|
+
return rest;
|
|
101233
|
+
}
|
|
101234
|
+
function wrap$2(feature) {
|
|
101235
|
+
return {
|
|
101236
|
+
family: "composition",
|
|
101237
|
+
target: {
|
|
101238
|
+
addonId: "t",
|
|
101239
|
+
stableId: "t"
|
|
101240
|
+
},
|
|
101241
|
+
feature
|
|
101242
|
+
};
|
|
101243
|
+
}
|
|
101244
|
+
//#endregion
|
|
101245
|
+
//#region src/composition/customize/scalar-status.ts
|
|
101246
|
+
function projectScalarAssignment(input) {
|
|
101247
|
+
if (input.stored.kind === "pending") return unanswered$1(input.targetId, "pending", null);
|
|
101248
|
+
if (input.stored.kind === "unknown") return unanswered$1(input.targetId, "unknown", input.stored.reason ?? "unknown");
|
|
101249
|
+
if (input.stored.value === null) return native$2(input.targetId);
|
|
101250
|
+
const decoded = decodeScalarOverride({
|
|
101251
|
+
feature: input.stored.value,
|
|
101252
|
+
device: input.device,
|
|
101253
|
+
cap: input.cap,
|
|
101254
|
+
targetId: input.targetId
|
|
101255
|
+
});
|
|
101256
|
+
if (decoded === null) return {
|
|
101257
|
+
text: "unknown",
|
|
101258
|
+
status: status$1(input.targetId, true, "assigned", "unavailable", "not-canonical")
|
|
101259
|
+
};
|
|
101260
|
+
return projectDecoded$1(input, decoded.apply, sourceLabel(decoded.draft.source.cap, decoded.draft.source.fieldPath));
|
|
101261
|
+
}
|
|
101262
|
+
function projectDecoded$1(input, apply, label) {
|
|
101263
|
+
if (input.sourcePresence === "pending") return {
|
|
101264
|
+
text: "pending",
|
|
101265
|
+
status: status$1(input.targetId, true, "assigned", "stale", null)
|
|
101266
|
+
};
|
|
101267
|
+
if (input.sourcePresence === "unknown") return {
|
|
101268
|
+
text: "unknown",
|
|
101269
|
+
status: status$1(input.targetId, true, "assigned", "stale", input.sourceUnknownReason ?? "unknown")
|
|
101270
|
+
};
|
|
101271
|
+
if (input.sourcePresence === "absent" && apply === "replace") return {
|
|
101272
|
+
text: "Native · source missing",
|
|
101273
|
+
status: status$1(input.targetId, true, "native", "released", "source-missing")
|
|
101274
|
+
};
|
|
101275
|
+
if (input.sourcePresence === "absent") return {
|
|
101276
|
+
text: `Assigned · ${label}`,
|
|
101277
|
+
status: status$1(input.targetId, true, "assigned", "unavailable", "source-missing")
|
|
101278
|
+
};
|
|
101279
|
+
return {
|
|
101280
|
+
text: `Assigned · ${label}`,
|
|
101281
|
+
status: status$1(input.targetId, true, "assigned", "active", null)
|
|
101282
|
+
};
|
|
101283
|
+
}
|
|
101284
|
+
function native$2(targetId) {
|
|
101285
|
+
return {
|
|
101286
|
+
text: "Native",
|
|
101287
|
+
status: status$1(targetId, false, "native", "active", null)
|
|
101288
|
+
};
|
|
101289
|
+
}
|
|
101290
|
+
function unanswered$1(targetId, text, reason) {
|
|
101291
|
+
return {
|
|
101292
|
+
text,
|
|
101293
|
+
status: status$1(targetId, false, "native", text === "pending" ? "unavailable" : "stale", reason)
|
|
101294
|
+
};
|
|
101295
|
+
}
|
|
101296
|
+
function sourceLabel(cap, fieldPath) {
|
|
101297
|
+
return `${cap}.${fieldPath}`;
|
|
101298
|
+
}
|
|
101299
|
+
function status$1(targetId, configured, source, state, reason) {
|
|
101300
|
+
return {
|
|
101301
|
+
targetId,
|
|
101302
|
+
configured,
|
|
101303
|
+
source,
|
|
101304
|
+
state,
|
|
101305
|
+
reason
|
|
101306
|
+
};
|
|
101307
|
+
}
|
|
101308
|
+
//#endregion
|
|
101309
|
+
//#region src/composition/customize/event-compile.ts
|
|
101310
|
+
var catalog$2 = CAP_CUSTOMIZE_CATALOG;
|
|
101311
|
+
function compilePulseOverride(input) {
|
|
101312
|
+
const target = catalogTarget$2(input.draft.cap, input.draft.targetId);
|
|
101313
|
+
if (target === null || target.shape !== "pulse") return fail$1("target");
|
|
101314
|
+
const timestampPath = target.timestampPath;
|
|
101315
|
+
const counterPath = target.counterPath;
|
|
101316
|
+
if (timestampPath === void 0 || counterPath === void 0 || !isIdentifier(timestampPath) || !isIdentifier(counterPath)) return fail$1("path");
|
|
101317
|
+
if (!(target.edges ?? []).includes("rising")) return fail$1("edge");
|
|
101318
|
+
const pairs = pairSources(input);
|
|
101319
|
+
if (!pairs.ok) return pairs;
|
|
101320
|
+
if (pairs.value.length === 0) return fail$1("sources");
|
|
101321
|
+
const debounce = unsignedToken(input.draft.debounceMs);
|
|
101322
|
+
if (debounce === null) return fail$1("debounce");
|
|
101323
|
+
const ordered = pairs.value.toSorted((a, b) => pairKey(a).localeCompare(pairKey(b)));
|
|
101324
|
+
return {
|
|
101325
|
+
ok: true,
|
|
101326
|
+
value: {
|
|
101327
|
+
kind: "fields",
|
|
101328
|
+
cap: input.draft.cap,
|
|
101329
|
+
enabled: input.draft.enabled,
|
|
101330
|
+
fields: {
|
|
101331
|
+
[timestampPath]: expression(pulseExpr(ordered.length, debounce), pulseBindings(ordered)),
|
|
101332
|
+
[counterPath]: expression(`count(${timestampPath})`, { [timestampPath]: fromRead(input.device, input.draft.cap, timestampPath) })
|
|
101333
|
+
}
|
|
101334
|
+
}
|
|
101335
|
+
};
|
|
101336
|
+
}
|
|
101337
|
+
function compileSpanOverride(input) {
|
|
101338
|
+
const target = catalogTarget$2(input.draft.cap, input.draft.targetId);
|
|
101339
|
+
if (target === null || target.shape !== "span") return fail$1("target");
|
|
101340
|
+
if (target.applyAuthority?.kind !== "camera-sensors") return fail$1("authority");
|
|
101341
|
+
if (input.draft.timeoutMs < 0 || !Number.isFinite(input.draft.timeoutMs)) return fail$1("timeout");
|
|
101342
|
+
if (target.cooldownMs === void 0 && input.draft.cooldownMs !== void 0) return fail$1("cooldown");
|
|
101343
|
+
if (input.draft.cooldownMs !== void 0 && input.draft.cooldownMs < 0) return fail$1("cooldown");
|
|
101344
|
+
const sensors = sensorEntries(input.draft.sources, input.device, target.sourceModes);
|
|
101345
|
+
if (!sensors.ok) return sensors;
|
|
101346
|
+
if (sensors.value.length === 0) return {
|
|
101347
|
+
ok: true,
|
|
101348
|
+
value: {
|
|
101349
|
+
config: null,
|
|
101350
|
+
timeoutMs: input.draft.timeoutMs,
|
|
101351
|
+
cooldownMs: input.draft.cooldownMs
|
|
101352
|
+
}
|
|
101353
|
+
};
|
|
101354
|
+
const parsed = CameraSensorsConfigSchema.safeParse({ sensors: sensors.value });
|
|
101355
|
+
if (!parsed.success) {
|
|
101356
|
+
const issue = parsed.error.issues[0];
|
|
101357
|
+
return fail$1(issue === void 0 ? "cameraSensors" : issue.message);
|
|
101358
|
+
}
|
|
101359
|
+
return {
|
|
101360
|
+
ok: true,
|
|
101361
|
+
value: {
|
|
101362
|
+
config: parsed.data,
|
|
101363
|
+
timeoutMs: input.draft.timeoutMs,
|
|
101364
|
+
cooldownMs: input.draft.cooldownMs
|
|
101365
|
+
}
|
|
101366
|
+
};
|
|
101367
|
+
}
|
|
101368
|
+
function pairSources(input) {
|
|
101369
|
+
if (input.changedAtFields.length !== input.draft.sources.length) return fail$1("changed-at");
|
|
101370
|
+
const pairs = input.draft.sources.map((source, index) => {
|
|
101371
|
+
return {
|
|
101372
|
+
source,
|
|
101373
|
+
changedAtField: input.changedAtFields[index] ?? ""
|
|
101374
|
+
};
|
|
101375
|
+
});
|
|
101376
|
+
if (pairs.some((pair) => pair.changedAtField.length === 0 || pair.source.fieldPath.length === 0)) return fail$1("changed-at");
|
|
101377
|
+
return {
|
|
101378
|
+
ok: true,
|
|
101379
|
+
value: pairs
|
|
101380
|
+
};
|
|
101381
|
+
}
|
|
101382
|
+
function pairKey(pair) {
|
|
101383
|
+
return `${pair.source.addonId}/${pair.source.stableId}#${pair.source.cap}#${pair.source.fieldPath}`;
|
|
101384
|
+
}
|
|
101385
|
+
function pulseExpr(count, debounce) {
|
|
101386
|
+
const roses = [];
|
|
101387
|
+
for (let index = 0; index < count; index += 1) roses.push(`rose(active${index}, changed${index}, ${debounce})`);
|
|
101388
|
+
return `latest(${roses.join(", ")})`;
|
|
101389
|
+
}
|
|
101390
|
+
function pulseBindings(pairs) {
|
|
101391
|
+
const bindings = {};
|
|
101392
|
+
pairs.forEach((pair, index) => {
|
|
101393
|
+
const ref = {
|
|
101394
|
+
addonId: pair.source.addonId,
|
|
101395
|
+
stableId: pair.source.stableId
|
|
101396
|
+
};
|
|
101397
|
+
bindings[`active${index}`] = fromRead(ref, pair.source.cap, pair.source.fieldPath);
|
|
101398
|
+
bindings[`changed${index}`] = fromRead(ref, pair.source.cap, pair.changedAtField);
|
|
101399
|
+
});
|
|
101400
|
+
return bindings;
|
|
101401
|
+
}
|
|
101402
|
+
function sensorEntries(sources, device, modes) {
|
|
101403
|
+
const entries = [];
|
|
101404
|
+
for (const source of sources) {
|
|
101405
|
+
if (source.addonId === device.addonId && source.stableId === device.stableId) return fail$1("self");
|
|
101406
|
+
const mode = source.mode ?? "in-addition";
|
|
101407
|
+
if (modes !== void 0 && !modes.includes(mode)) return fail$1("mode");
|
|
101408
|
+
if (modes === void 0 && source.mode !== void 0 && source.mode !== "in-addition") return fail$1("mode");
|
|
101409
|
+
entries.push({
|
|
101410
|
+
addonId: source.addonId,
|
|
101411
|
+
stableId: source.stableId,
|
|
101412
|
+
mode
|
|
101413
|
+
});
|
|
101414
|
+
}
|
|
101415
|
+
return {
|
|
101416
|
+
ok: true,
|
|
101417
|
+
value: entries
|
|
101418
|
+
};
|
|
101419
|
+
}
|
|
101420
|
+
function catalogTarget$2(cap, targetId) {
|
|
101421
|
+
const entry = catalog$2[cap];
|
|
101422
|
+
if (entry === void 0) return null;
|
|
101423
|
+
return entry.targets.find((target) => target.id === targetId) ?? null;
|
|
101424
|
+
}
|
|
101425
|
+
function fail$1(reason) {
|
|
101426
|
+
return {
|
|
101427
|
+
ok: false,
|
|
101428
|
+
reason
|
|
101429
|
+
};
|
|
101430
|
+
}
|
|
101431
|
+
//#endregion
|
|
101432
|
+
//#region src/composition/customize/event-decode.ts
|
|
101433
|
+
var ROSE_SOURCE = String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
|
|
101434
|
+
function decodePulseOverride(input) {
|
|
101435
|
+
if (input.feature.cap !== input.cap || input.feature.kind !== "fields") return null;
|
|
101436
|
+
if (input.feature.enabled === void 0) return null;
|
|
101437
|
+
const timestamp = input.feature.fields[input.timestampPath];
|
|
101438
|
+
const counter = input.feature.fields[input.counterPath];
|
|
101439
|
+
if (timestamp === void 0 || counter === void 0) return null;
|
|
101440
|
+
if (Object.keys(input.feature.fields).length !== 2) return null;
|
|
101441
|
+
const edges = readEdges(timestamp);
|
|
101442
|
+
if (edges === null) return null;
|
|
101443
|
+
if (readCount(counter, input) === null) return null;
|
|
101444
|
+
const draft = {
|
|
101445
|
+
kind: "pulse",
|
|
101446
|
+
cap: input.cap,
|
|
101447
|
+
targetId: input.targetId,
|
|
101448
|
+
enabled: input.feature.enabled,
|
|
101449
|
+
debounceMs: edges.debounceMs,
|
|
101450
|
+
sources: edges.sources
|
|
101451
|
+
};
|
|
101452
|
+
const decoded = {
|
|
101453
|
+
draft,
|
|
101454
|
+
changedAtFields: edges.changedAtFields
|
|
101455
|
+
};
|
|
101456
|
+
const compiled = compilePulseOverride({
|
|
101457
|
+
draft,
|
|
101458
|
+
device: input.device,
|
|
101459
|
+
changedAtFields: edges.changedAtFields
|
|
101460
|
+
});
|
|
101461
|
+
if (!compiled.ok) return null;
|
|
101462
|
+
return sameFeature$1(compiled.value, input.feature) ? decoded : null;
|
|
101463
|
+
}
|
|
101464
|
+
function readEdges(field) {
|
|
101465
|
+
if (field.kind !== "expression" || !field.expr.startsWith("latest(") || !field.expr.endsWith(")")) return null;
|
|
101466
|
+
const inner = field.expr.slice(7, -1);
|
|
101467
|
+
const found = [...inner.matchAll(new RegExp(ROSE_SOURCE, "g"))];
|
|
101468
|
+
if (found.length === 0 || found.map((match) => match[0]).join(", ") !== inner) return null;
|
|
101469
|
+
if (Object.keys(field.bindings).length !== found.length * 2) return null;
|
|
101470
|
+
const rows = found.map((match, index) => readRose(match, index, field.bindings));
|
|
101471
|
+
if (rows.some((row) => row === null)) return null;
|
|
101472
|
+
const edges = rows.filter((row) => row !== null);
|
|
101473
|
+
const debounceMs = edges[0]?.debounceMs;
|
|
101474
|
+
if (debounceMs === void 0 || edges.some((row) => row.debounceMs !== debounceMs)) return null;
|
|
101475
|
+
return {
|
|
101476
|
+
debounceMs,
|
|
101477
|
+
sources: edges.map((row) => row.source),
|
|
101478
|
+
changedAtFields: edges.map((row) => row.changedAtField)
|
|
101479
|
+
};
|
|
101480
|
+
}
|
|
101481
|
+
function readRose(match, index, bindings) {
|
|
101482
|
+
const activeIndex = Number(match[1]);
|
|
101483
|
+
const changedIndex = Number(match[2]);
|
|
101484
|
+
const debounceMs = Number(match[3]);
|
|
101485
|
+
if (activeIndex !== index || changedIndex !== index || !Number.isFinite(debounceMs)) return null;
|
|
101486
|
+
const active = fromBinding(bindings[`active${index}`]);
|
|
101487
|
+
const changed = fromBinding(bindings[`changed${index}`]);
|
|
101488
|
+
if (active === null || changed === null) return null;
|
|
101489
|
+
if (active.cap !== changed.cap) return null;
|
|
101490
|
+
if (active.source.addonId !== changed.source.addonId) return null;
|
|
101491
|
+
if (active.source.stableId !== changed.source.stableId) return null;
|
|
101492
|
+
return {
|
|
101493
|
+
debounceMs,
|
|
101494
|
+
changedAtField: changed.fieldPath,
|
|
101495
|
+
source: {
|
|
101496
|
+
addonId: active.source.addonId,
|
|
101497
|
+
stableId: active.source.stableId,
|
|
101498
|
+
cap: active.cap,
|
|
101499
|
+
fieldPath: active.fieldPath
|
|
101500
|
+
}
|
|
101501
|
+
};
|
|
101502
|
+
}
|
|
101503
|
+
function fromBinding(value) {
|
|
101504
|
+
if (value === void 0 || value.kind !== "from") return null;
|
|
101505
|
+
return value;
|
|
101506
|
+
}
|
|
101507
|
+
function readCount(field, input) {
|
|
101508
|
+
if (field.kind !== "expression" || field.expr !== `count(${input.timestampPath})`) return null;
|
|
101509
|
+
const binding = fromBinding(field.bindings[input.timestampPath]);
|
|
101510
|
+
if (binding === null) return null;
|
|
101511
|
+
if (Object.keys(field.bindings).length !== 1) return null;
|
|
101512
|
+
if (binding.cap !== input.cap || binding.fieldPath !== input.timestampPath) return null;
|
|
101513
|
+
if (binding.source.addonId !== input.device.addonId) return null;
|
|
101514
|
+
if (binding.source.stableId !== input.device.stableId) return null;
|
|
101515
|
+
return true;
|
|
101516
|
+
}
|
|
101517
|
+
function sameFeature$1(left, right) {
|
|
101518
|
+
return sameStored(wrap$1(left), wrap$1(right));
|
|
101519
|
+
}
|
|
101520
|
+
function wrap$1(feature) {
|
|
101521
|
+
return {
|
|
101522
|
+
family: "composition",
|
|
101523
|
+
target: {
|
|
101524
|
+
addonId: "t",
|
|
101525
|
+
stableId: "t"
|
|
101526
|
+
},
|
|
101527
|
+
feature
|
|
101528
|
+
};
|
|
101529
|
+
}
|
|
101530
|
+
//#endregion
|
|
101531
|
+
//#region src/composition/customize/event-eval.ts
|
|
101532
|
+
var INITIAL_PULSE = {
|
|
101533
|
+
priorActive: void 0,
|
|
101534
|
+
lastPressedAt: null,
|
|
101535
|
+
count: 0,
|
|
101536
|
+
acceptedAt: null
|
|
101537
|
+
};
|
|
101538
|
+
var INITIAL_SPAN = {
|
|
101539
|
+
open: false,
|
|
101540
|
+
startedAt: null,
|
|
101541
|
+
endedAt: null,
|
|
101542
|
+
quietUntil: null,
|
|
101543
|
+
priorActive: void 0
|
|
101544
|
+
};
|
|
101545
|
+
function stepPulse(state, sample, debounceMs) {
|
|
101546
|
+
if (sample.kind === "unread" || debounceMs < 0) return state;
|
|
101547
|
+
if (state.priorActive === void 0) return {
|
|
101548
|
+
...state,
|
|
101549
|
+
priorActive: sample.active
|
|
101550
|
+
};
|
|
101551
|
+
if (!sample.active) return {
|
|
101552
|
+
...state,
|
|
101553
|
+
priorActive: false
|
|
101554
|
+
};
|
|
101555
|
+
if (state.priorActive) return state;
|
|
101556
|
+
const at = finite(sample.changedAt);
|
|
101557
|
+
if (at === null) return {
|
|
101558
|
+
...state,
|
|
101559
|
+
priorActive: true
|
|
101560
|
+
};
|
|
101561
|
+
if (state.acceptedAt !== null && at - state.acceptedAt < debounceMs) return {
|
|
101562
|
+
...state,
|
|
101563
|
+
priorActive: true
|
|
101564
|
+
};
|
|
101565
|
+
return {
|
|
101566
|
+
priorActive: true,
|
|
101567
|
+
lastPressedAt: at,
|
|
101568
|
+
count: state.count + 1,
|
|
101569
|
+
acceptedAt: at
|
|
101570
|
+
};
|
|
101571
|
+
}
|
|
101572
|
+
function stepSpan(state, sample, timing) {
|
|
101573
|
+
const timed = expire(state, timing);
|
|
101574
|
+
if (sample.kind === "unread" || timing.timeoutMs < 0 || timing.cooldownMs < 0) return timed;
|
|
101575
|
+
if (timed.priorActive === void 0) return {
|
|
101576
|
+
...timed,
|
|
101577
|
+
priorActive: sample.active
|
|
101578
|
+
};
|
|
101579
|
+
if (timed.open && timed.priorActive && !sample.active) return finish(timed, finite(sample.changedAt) ?? timing.nowMs, timing.cooldownMs, false);
|
|
101580
|
+
if (!sample.active) return {
|
|
101581
|
+
...timed,
|
|
101582
|
+
priorActive: false
|
|
101583
|
+
};
|
|
101584
|
+
if (timed.priorActive || timed.open) return {
|
|
101585
|
+
...timed,
|
|
101586
|
+
priorActive: true
|
|
101587
|
+
};
|
|
101588
|
+
const at = finite(sample.changedAt) ?? timing.nowMs;
|
|
101589
|
+
if (timed.quietUntil !== null && at < timed.quietUntil) return {
|
|
101590
|
+
...timed,
|
|
101591
|
+
priorActive: true
|
|
101592
|
+
};
|
|
101593
|
+
return {
|
|
101594
|
+
open: true,
|
|
101595
|
+
startedAt: at,
|
|
101596
|
+
endedAt: null,
|
|
101597
|
+
quietUntil: null,
|
|
101598
|
+
priorActive: true
|
|
101599
|
+
};
|
|
101600
|
+
}
|
|
101601
|
+
function expire(state, timing) {
|
|
101602
|
+
if (!state.open || state.startedAt === null) return state;
|
|
101603
|
+
const deadline = state.startedAt + timing.timeoutMs;
|
|
101604
|
+
if (timing.nowMs < deadline) return state;
|
|
101605
|
+
return finish(state, deadline, timing.cooldownMs, state.priorActive === true);
|
|
101606
|
+
}
|
|
101607
|
+
function finish(state, endedAt, cooldownMs, priorActive) {
|
|
101608
|
+
return {
|
|
101609
|
+
open: false,
|
|
101610
|
+
startedAt: state.startedAt,
|
|
101611
|
+
endedAt,
|
|
101612
|
+
quietUntil: cooldownMs > 0 ? endedAt + cooldownMs : null,
|
|
101613
|
+
priorActive
|
|
101614
|
+
};
|
|
101615
|
+
}
|
|
101616
|
+
function finite(value) {
|
|
101617
|
+
return value !== null && Number.isFinite(value) ? value : null;
|
|
101618
|
+
}
|
|
101619
|
+
//#endregion
|
|
101620
|
+
//#region src/composition/customize/event-status.ts
|
|
101621
|
+
function projectPulseAssignment(input) {
|
|
101622
|
+
if (input.stored.kind === "pending") return held(input.targetId, "pending", null);
|
|
101623
|
+
if (input.stored.kind === "unknown") return held(input.targetId, "unknown", input.stored.reason ?? "unknown");
|
|
101624
|
+
if (input.stored.value === null) return native$1(input.targetId);
|
|
101625
|
+
const decoded = decodePulseOverride({
|
|
101626
|
+
feature: input.stored.value,
|
|
101627
|
+
device: input.device,
|
|
101628
|
+
cap: input.cap,
|
|
101629
|
+
targetId: input.targetId,
|
|
101630
|
+
timestampPath: input.timestampPath,
|
|
101631
|
+
counterPath: input.counterPath
|
|
101632
|
+
});
|
|
101633
|
+
if (decoded === null) return {
|
|
101634
|
+
text: "unknown",
|
|
101635
|
+
status: row(input.targetId, true, "assigned", "unavailable", "not-canonical")
|
|
101636
|
+
};
|
|
101637
|
+
if (input.sourcePresence === "pending") return {
|
|
101638
|
+
text: "pending",
|
|
101639
|
+
status: row(input.targetId, true, "assigned", "stale", null)
|
|
101640
|
+
};
|
|
101641
|
+
if (input.sourcePresence === "unknown") return {
|
|
101642
|
+
text: "unknown",
|
|
101643
|
+
status: row(input.targetId, true, "assigned", "stale", input.sourceUnknownReason ?? "unknown")
|
|
101644
|
+
};
|
|
101645
|
+
if (input.sourcePresence === "absent" && input.apply === "replace") return {
|
|
101646
|
+
text: "Native · source missing",
|
|
101647
|
+
status: row(input.targetId, true, "native", "released", "source-missing")
|
|
101648
|
+
};
|
|
101649
|
+
if (input.sourcePresence === "absent") return {
|
|
101650
|
+
text: "Assigned · source missing",
|
|
101651
|
+
status: row(input.targetId, true, "assigned", "unavailable", "source-missing")
|
|
101652
|
+
};
|
|
101653
|
+
const source = decoded.draft.sources[0];
|
|
101654
|
+
return {
|
|
101655
|
+
text: `Assigned · ${source === void 0 ? "assigned" : `${source.cap}.${source.fieldPath}`}`,
|
|
101656
|
+
status: row(input.targetId, true, "assigned", "active", null)
|
|
101657
|
+
};
|
|
101658
|
+
}
|
|
101659
|
+
function projectSpanAssignment(targetId, stored) {
|
|
101660
|
+
if (stored.kind === "pending") return {
|
|
101661
|
+
text: "pending",
|
|
101662
|
+
writable: false,
|
|
101663
|
+
rows: [],
|
|
101664
|
+
status: row(targetId, false, "native", "unavailable", null)
|
|
101665
|
+
};
|
|
101666
|
+
if (stored.kind === "unknown") return {
|
|
101667
|
+
text: "unknown",
|
|
101668
|
+
writable: false,
|
|
101669
|
+
rows: [],
|
|
101670
|
+
status: row(targetId, false, "native", "stale", stored.reason ?? "unknown")
|
|
101671
|
+
};
|
|
101672
|
+
if (stored.value.state === "unreadable") return {
|
|
101673
|
+
text: "unreadable",
|
|
101674
|
+
writable: false,
|
|
101675
|
+
rows: [],
|
|
101676
|
+
status: row(targetId, false, "assigned", "unavailable", stored.value.reason)
|
|
101677
|
+
};
|
|
101678
|
+
if (stored.value.state === "not-configured") return {
|
|
101679
|
+
text: "Native",
|
|
101680
|
+
writable: true,
|
|
101681
|
+
rows: [],
|
|
101682
|
+
status: row(targetId, false, "native", "active", null)
|
|
101683
|
+
};
|
|
101684
|
+
const rows = stored.value.sensors.map(sensorRow);
|
|
101685
|
+
const reason = spanReason(stored.value);
|
|
101686
|
+
return {
|
|
101687
|
+
text: rows.length === 0 ? "Native" : "Assigned",
|
|
101688
|
+
writable: true,
|
|
101689
|
+
rows,
|
|
101690
|
+
status: row(targetId, rows.length > 0, "assigned", "active", reason)
|
|
101691
|
+
};
|
|
101692
|
+
}
|
|
101693
|
+
function spanReason(status) {
|
|
101694
|
+
if (status.notForwarded !== void 0) return status.notForwarded;
|
|
101695
|
+
if (status.notEnforced !== void 0) return status.notEnforced;
|
|
101696
|
+
return status.sensors.map(attachmentReason).find((reason) => reason !== null) ?? null;
|
|
101697
|
+
}
|
|
101698
|
+
function sensorRow(sensor) {
|
|
101699
|
+
return {
|
|
101700
|
+
key: `${sensor.addonId}/${sensor.stableId}`,
|
|
101701
|
+
addonId: sensor.addonId,
|
|
101702
|
+
stableId: sensor.stableId,
|
|
101703
|
+
name: sensor.state === "missing" || sensor.state === "unreadable" ? sensor.stableId : sensor.name,
|
|
101704
|
+
mode: sensor.mode,
|
|
101705
|
+
state: sensor.state,
|
|
101706
|
+
reason: attachmentReason(sensor)
|
|
101707
|
+
};
|
|
101708
|
+
}
|
|
101709
|
+
function attachmentReason(sensor) {
|
|
101710
|
+
switch (sensor.state) {
|
|
101711
|
+
case "ready": return null;
|
|
101712
|
+
case "offline":
|
|
101713
|
+
case "missing":
|
|
101714
|
+
case "unsupported":
|
|
101715
|
+
case "unreadable": return sensor.reason;
|
|
101716
|
+
}
|
|
101717
|
+
}
|
|
101718
|
+
function native$1(targetId) {
|
|
101719
|
+
return {
|
|
101720
|
+
text: "Native",
|
|
101721
|
+
status: row(targetId, false, "native", "active", null)
|
|
101722
|
+
};
|
|
101723
|
+
}
|
|
101724
|
+
function held(targetId, text, reason) {
|
|
101725
|
+
return {
|
|
101726
|
+
text,
|
|
101727
|
+
status: row(targetId, false, "native", text === "pending" ? "unavailable" : "stale", reason)
|
|
101728
|
+
};
|
|
101729
|
+
}
|
|
101730
|
+
function row(targetId, configured, source, state, reason) {
|
|
101731
|
+
return {
|
|
101732
|
+
targetId,
|
|
101733
|
+
configured,
|
|
101734
|
+
source,
|
|
101735
|
+
state,
|
|
101736
|
+
reason
|
|
101737
|
+
};
|
|
101738
|
+
}
|
|
101739
|
+
//#endregion
|
|
101740
|
+
//#region src/composition/customize/keyed-array-expr.ts
|
|
101741
|
+
var STEP = /^x == ("(?:\\.|[^"\\])*") \? ("(?:\\.|[^"\\])*"|null) : ([\s\S]+)$/;
|
|
101742
|
+
function enumMapExpr(mapping) {
|
|
101743
|
+
const keys = Object.keys(mapping).toSorted();
|
|
101744
|
+
if (keys.length === 0) return null;
|
|
101745
|
+
return keys.reduceRight((rest, key) => {
|
|
101746
|
+
if (rest === null) return null;
|
|
101747
|
+
const value = mapping[key];
|
|
101748
|
+
if (value === void 0) return null;
|
|
101749
|
+
const rhs = value === null ? "null" : JSON.stringify(value);
|
|
101750
|
+
return `x == ${JSON.stringify(key)} ? ${rhs} : ${rest}`;
|
|
101751
|
+
}, "null");
|
|
101752
|
+
}
|
|
101753
|
+
function parseEnumMap(expr) {
|
|
101754
|
+
const mapping = {};
|
|
101755
|
+
let rest = expr;
|
|
101756
|
+
while (rest !== "null") {
|
|
101757
|
+
const match = STEP.exec(rest);
|
|
101758
|
+
if (match === null || match[1] === void 0 || match[2] === void 0 || match[3] === void 0) return null;
|
|
101759
|
+
const key = jsonString(match[1]);
|
|
101760
|
+
const value = match[2] === "null" ? null : jsonString(match[2]);
|
|
101761
|
+
if (key === null || match[2] !== "null" && value === null) return null;
|
|
101762
|
+
if (Object.prototype.hasOwnProperty.call(mapping, key)) return null;
|
|
101763
|
+
mapping[key] = value;
|
|
101764
|
+
rest = match[3];
|
|
101765
|
+
}
|
|
101766
|
+
return Object.keys(mapping).length === 0 ? null : mapping;
|
|
101767
|
+
}
|
|
101768
|
+
function enumMapDraft(mapping) {
|
|
101769
|
+
return {
|
|
101770
|
+
kind: "enum-map",
|
|
101771
|
+
mapping: { ...mapping }
|
|
101772
|
+
};
|
|
101773
|
+
}
|
|
101774
|
+
function jsonString(token) {
|
|
101775
|
+
try {
|
|
101776
|
+
const parsed = JSON.parse(token);
|
|
101777
|
+
return typeof parsed === "string" ? parsed : null;
|
|
101778
|
+
} catch {
|
|
101779
|
+
return null;
|
|
101780
|
+
}
|
|
101781
|
+
}
|
|
101782
|
+
//#endregion
|
|
101783
|
+
//#region src/composition/customize/keyed-array-compile.ts
|
|
101784
|
+
var catalog$1 = CAP_CUSTOMIZE_CATALOG;
|
|
101785
|
+
function compileKeyedArrayOverride(input) {
|
|
101786
|
+
const target = catalogTarget$1(input.cap, input.targetId);
|
|
101787
|
+
if (target === null || target.cardinality !== "keyedArray") return fail("target");
|
|
101788
|
+
if (input.items.length === 0) return fail("items");
|
|
101789
|
+
if (input.items.some((item) => item.draft.cap !== input.cap || item.draft.targetId !== input.targetId)) return fail("target");
|
|
101790
|
+
const keys = input.items.map((item) => item.draft.key);
|
|
101791
|
+
if (new Set(keys).size !== keys.length) return fail("key");
|
|
101792
|
+
const built = input.items.reduce((acc, item) => {
|
|
101793
|
+
if (!acc.ok) return acc;
|
|
101794
|
+
const entry = compileItem(target, item);
|
|
101795
|
+
if (!entry.ok) return entry;
|
|
101796
|
+
return {
|
|
101797
|
+
ok: true,
|
|
101798
|
+
value: {
|
|
101799
|
+
...acc.value,
|
|
101800
|
+
[item.draft.key]: entry.value
|
|
101801
|
+
}
|
|
101802
|
+
};
|
|
101803
|
+
}, {
|
|
101804
|
+
ok: true,
|
|
101805
|
+
value: {}
|
|
101806
|
+
});
|
|
101807
|
+
if (!built.ok) return built;
|
|
101808
|
+
const fields = compileCompanions(target, input.apply);
|
|
101809
|
+
if (!fields.ok) return fields;
|
|
101810
|
+
return {
|
|
101811
|
+
ok: true,
|
|
101812
|
+
value: {
|
|
101813
|
+
kind: "fields",
|
|
101814
|
+
cap: input.cap,
|
|
101815
|
+
fields: fields.value,
|
|
101816
|
+
items: { ...built.value }
|
|
101817
|
+
}
|
|
101818
|
+
};
|
|
101819
|
+
}
|
|
101820
|
+
/** Put one compiled item into an existing feature. Other items stay as stored. */
|
|
101821
|
+
function mergeKeyedArrayItem(current, compiled, key) {
|
|
101822
|
+
const item = compiled.items?.[key];
|
|
101823
|
+
if (item === void 0) return null;
|
|
101824
|
+
return {
|
|
101825
|
+
kind: "fields",
|
|
101826
|
+
cap: compiled.cap,
|
|
101827
|
+
...current?.enabled === void 0 ? {} : { enabled: current.enabled },
|
|
101828
|
+
fields: current === null ? compiled.fields : current.fields,
|
|
101829
|
+
items: {
|
|
101830
|
+
...current?.items,
|
|
101831
|
+
[key]: item
|
|
101832
|
+
}
|
|
101833
|
+
};
|
|
101834
|
+
}
|
|
101835
|
+
/** The feature without item `key`. Null when that item was the last one. */
|
|
101836
|
+
function withoutKeyedArrayItem(feature, key) {
|
|
101837
|
+
const rest = Object.fromEntries(Object.entries(feature.items ?? {}).filter(([name]) => name !== key));
|
|
101838
|
+
if (Object.keys(rest).length === 0) return null;
|
|
101839
|
+
return {
|
|
101840
|
+
...feature,
|
|
101841
|
+
items: rest
|
|
101842
|
+
};
|
|
101843
|
+
}
|
|
101844
|
+
function fail(reason) {
|
|
101845
|
+
return {
|
|
101846
|
+
ok: false,
|
|
101847
|
+
reason
|
|
101848
|
+
};
|
|
101849
|
+
}
|
|
101850
|
+
function catalogTarget$1(cap, targetId) {
|
|
101851
|
+
const entry = catalog$1[cap];
|
|
101852
|
+
if (entry === void 0) return null;
|
|
101853
|
+
return entry.targets.find((target) => target.id === targetId) ?? null;
|
|
101854
|
+
}
|
|
101855
|
+
function compileItem(target, item) {
|
|
101856
|
+
if (!require_composition.COMPOSITION_ITEM_KEY_RE.test(item.draft.key) || item.draft.label.trim() === "") return fail("key");
|
|
101857
|
+
const field = (target.fields ?? []).find((entry) => entry.path === item.draft.fieldPath);
|
|
101858
|
+
if (field === void 0) return fail("field");
|
|
101859
|
+
const source = sourceSpec(field, item);
|
|
101860
|
+
if (source === null) return fail("source-kind");
|
|
101861
|
+
if (source.requiredUnit !== void 0 && item.sourceUnit !== source.requiredUnit) return fail("unit");
|
|
101862
|
+
const allowed = item.draft.transform.kind;
|
|
101863
|
+
if (!source.transformKinds.includes(allowed)) return fail("transform");
|
|
101864
|
+
const value = compileValue(item, field);
|
|
101865
|
+
if (!value.ok) return value;
|
|
101866
|
+
const fields = compileLiterals(target, field, item, value.value);
|
|
101867
|
+
if (!fields.ok) return fields;
|
|
101868
|
+
return {
|
|
101869
|
+
ok: true,
|
|
101870
|
+
value: {
|
|
101871
|
+
label: item.draft.label.trim(),
|
|
101872
|
+
fields: fields.value
|
|
101873
|
+
}
|
|
101874
|
+
};
|
|
101875
|
+
}
|
|
101876
|
+
function sourceSpec(field, item) {
|
|
101877
|
+
if (item.sourceValueKind === "number") return field.sources.find((source) => source.kind === "numeric") ?? null;
|
|
101878
|
+
if (item.sourceValueKind === "enum" || item.sourceValueKind === "string") return field.sources.find((source) => source.kind === "enum") ?? null;
|
|
101879
|
+
return null;
|
|
101880
|
+
}
|
|
101881
|
+
function compileValue(item, field) {
|
|
101882
|
+
const read = fromRead(refOf(item.draft), item.draft.source.cap, item.draft.source.fieldPath);
|
|
101883
|
+
const transform = item.draft.transform;
|
|
101884
|
+
if (transform.kind === "identity") return {
|
|
101885
|
+
ok: true,
|
|
101886
|
+
value: read
|
|
101887
|
+
};
|
|
101888
|
+
if (transform.kind === "linear") return linearValue(transform, read);
|
|
101889
|
+
if (transform.kind === "enum-map") return enumValue(transform, read, field);
|
|
101890
|
+
return fail("transform");
|
|
101891
|
+
}
|
|
101892
|
+
function linearValue(transform, read) {
|
|
101893
|
+
const scale = signedToken(transform.scale);
|
|
101894
|
+
const offset = signedToken(transform.offset);
|
|
101895
|
+
if (scale === null || offset === null) return fail("scale");
|
|
101896
|
+
const clamps = clampTokens(transform.clampMin, transform.clampMax);
|
|
101897
|
+
if (!clamps.ok) return clamps;
|
|
101898
|
+
return {
|
|
101899
|
+
ok: true,
|
|
101900
|
+
value: expression(linearExpr("x", scale, offset, clamps.value.min, clamps.value.max), { x: read })
|
|
101901
|
+
};
|
|
101902
|
+
}
|
|
101903
|
+
function clampTokens(clampMin, clampMax) {
|
|
101904
|
+
if (clampMin === void 0 && clampMax === void 0) return {
|
|
101905
|
+
ok: true,
|
|
101906
|
+
value: {
|
|
101907
|
+
min: null,
|
|
101908
|
+
max: null
|
|
101909
|
+
}
|
|
101910
|
+
};
|
|
101911
|
+
if (clampMin === void 0 || clampMax === void 0) return fail("clamp");
|
|
101912
|
+
const min = signedToken(clampMin);
|
|
101913
|
+
const max = signedToken(clampMax);
|
|
101914
|
+
if (min === null || max === null || clampMin > clampMax) return fail("clamp");
|
|
101915
|
+
return {
|
|
101916
|
+
ok: true,
|
|
101917
|
+
value: {
|
|
101918
|
+
min,
|
|
101919
|
+
max
|
|
101920
|
+
}
|
|
101921
|
+
};
|
|
101922
|
+
}
|
|
101923
|
+
function enumValue(transform, read, field) {
|
|
101924
|
+
const allowed = new Set(field.enumValues ?? []);
|
|
101925
|
+
const entries = Object.entries(transform.mapping);
|
|
101926
|
+
if (entries.length === 0) return fail("enum");
|
|
101927
|
+
if (entries.some(([key, value]) => key.length === 0 || value !== null && !allowed.has(value))) return fail("enum");
|
|
101928
|
+
const expr = enumMapExpr(transform.mapping);
|
|
101929
|
+
if (expr === null) return fail("enum");
|
|
101930
|
+
return {
|
|
101931
|
+
ok: true,
|
|
101932
|
+
value: expression(expr, { x: read })
|
|
101933
|
+
};
|
|
101934
|
+
}
|
|
101935
|
+
function compileLiterals(target, field, item, value) {
|
|
101936
|
+
const required = new Set((field.literals ?? []).map((literalSpec) => literalSpec.path));
|
|
101937
|
+
const traits = new Map((target.traits ?? []).map((trait) => [trait.path, new Set(trait.values)]));
|
|
101938
|
+
if ([...required].filter((path) => !item.literals.some((literalSpec) => literalSpec.path === path)).length > 0) return fail("literal");
|
|
101939
|
+
return item.literals.reduce((acc, entry) => {
|
|
101940
|
+
if (!acc.ok) return acc;
|
|
101941
|
+
if (entry.path === field.path || acc.value[entry.path] !== void 0) return fail("literal");
|
|
101942
|
+
const allowed = allowedLiteral(field, traits, entry.path);
|
|
101943
|
+
if (allowed === null || !allowed.has(entry.value)) return fail("literal");
|
|
101944
|
+
const expr = constantExpr(entry.value);
|
|
101945
|
+
if (expr === null) return fail("literal");
|
|
101946
|
+
return {
|
|
101947
|
+
ok: true,
|
|
101948
|
+
value: {
|
|
101949
|
+
...acc.value,
|
|
101950
|
+
[entry.path]: literal(expr)
|
|
101951
|
+
}
|
|
101952
|
+
};
|
|
101953
|
+
}, {
|
|
101954
|
+
ok: true,
|
|
101955
|
+
value: { [field.path]: value }
|
|
101956
|
+
});
|
|
101957
|
+
}
|
|
101958
|
+
function allowedLiteral(field, traits, path) {
|
|
101959
|
+
const trait = traits.get(path);
|
|
101960
|
+
if (trait !== void 0) return trait;
|
|
101961
|
+
const required = (field.literals ?? []).find((entry) => entry.path === path);
|
|
101962
|
+
return required === void 0 ? null : new Set(required.values);
|
|
101963
|
+
}
|
|
101964
|
+
function compileCompanions(target, apply) {
|
|
101965
|
+
return (target.companions ?? []).filter((companion) => companionIncluded(companion, apply)).reduce((acc, companion) => {
|
|
101966
|
+
if (!acc.ok) return acc;
|
|
101967
|
+
if (companion.kind !== "clock") return fail("companion");
|
|
101968
|
+
return {
|
|
101969
|
+
ok: true,
|
|
101970
|
+
value: {
|
|
101971
|
+
...acc.value,
|
|
101972
|
+
[companion.path]: literal("now")
|
|
101973
|
+
}
|
|
101974
|
+
};
|
|
101975
|
+
}, {
|
|
101976
|
+
ok: true,
|
|
101977
|
+
value: {}
|
|
101978
|
+
});
|
|
101979
|
+
}
|
|
101980
|
+
function companionIncluded(companion, apply) {
|
|
101981
|
+
if (companion.kind === "transition-time") return false;
|
|
101982
|
+
return companion.when === "always" || apply === "add";
|
|
101983
|
+
}
|
|
101984
|
+
function refOf(draft) {
|
|
101985
|
+
return {
|
|
101986
|
+
addonId: draft.source.addonId,
|
|
101987
|
+
stableId: draft.source.stableId
|
|
101988
|
+
};
|
|
101989
|
+
}
|
|
101990
|
+
//#endregion
|
|
101991
|
+
//#region src/composition/customize/keyed-array-decode.ts
|
|
101992
|
+
var catalog = CAP_CUSTOMIZE_CATALOG;
|
|
101993
|
+
function readKeyedArrayItems(feature, cap, targetId) {
|
|
101994
|
+
const target = catalogTarget(cap, targetId);
|
|
101995
|
+
if (target === null || target.cardinality !== "keyedArray" || feature.cap !== cap) return null;
|
|
101996
|
+
const apply = inferApply(target, feature.fields);
|
|
101997
|
+
const canonical = apply !== null && companionsMatch(target, feature.fields, apply);
|
|
101998
|
+
const items = Object.entries(feature.items ?? {}).map(([key, item]) => viewOf(target, cap, targetId, key, item, canonical));
|
|
101999
|
+
return {
|
|
102000
|
+
canonical,
|
|
102001
|
+
apply: apply ?? "add",
|
|
102002
|
+
items
|
|
102003
|
+
};
|
|
102004
|
+
}
|
|
102005
|
+
function decodeKeyedArrayOverride(input) {
|
|
102006
|
+
const read = readKeyedArrayItems(input.feature, input.cap, input.targetId);
|
|
102007
|
+
if (read === null || !read.canonical) return null;
|
|
102008
|
+
if (read.items.some((item) => item.compile === null)) return null;
|
|
102009
|
+
const compiles = read.items.flatMap((item) => item.compile === null ? [] : [item.compile]);
|
|
102010
|
+
const compiled = compileKeyedArrayOverride({
|
|
102011
|
+
cap: input.cap,
|
|
102012
|
+
targetId: input.targetId,
|
|
102013
|
+
device: input.device,
|
|
102014
|
+
apply: read.apply,
|
|
102015
|
+
items: compiles
|
|
102016
|
+
});
|
|
102017
|
+
if (!compiled.ok) return null;
|
|
102018
|
+
return sameFeature(compiled.value, input.feature) ? read : null;
|
|
102019
|
+
}
|
|
102020
|
+
function viewOf(target, cap, targetId, key, item, canonical) {
|
|
102021
|
+
const blank = {
|
|
102022
|
+
key,
|
|
102023
|
+
label: item.label,
|
|
102024
|
+
recognized: false,
|
|
102025
|
+
compile: null
|
|
102026
|
+
};
|
|
102027
|
+
if (!canonical) return blank;
|
|
102028
|
+
const compile = compileOf(target, cap, targetId, key, item);
|
|
102029
|
+
if (compile === null) return blank;
|
|
102030
|
+
return {
|
|
102031
|
+
key,
|
|
102032
|
+
label: item.label,
|
|
102033
|
+
recognized: true,
|
|
102034
|
+
compile
|
|
102035
|
+
};
|
|
102036
|
+
}
|
|
102037
|
+
function compileOf(target, cap, targetId, key, item) {
|
|
102038
|
+
const assigned = assignedField(target, item);
|
|
102039
|
+
if (assigned === null) return null;
|
|
102040
|
+
const literals = literalFields(target, assigned.field, item, assigned.path);
|
|
102041
|
+
if (literals === null) return null;
|
|
102042
|
+
const draft = draftOf(cap, targetId, key, item.label, assigned);
|
|
102043
|
+
if (draft === null) return null;
|
|
102044
|
+
const compile = {
|
|
102045
|
+
draft,
|
|
102046
|
+
sourceValueKind: assigned.sourceValueKind,
|
|
102047
|
+
sourceUnit: null,
|
|
102048
|
+
literals
|
|
102049
|
+
};
|
|
102050
|
+
return reproduces(cap, targetId, key, compile, item) ? compile : null;
|
|
102051
|
+
}
|
|
102052
|
+
function assignedField(target, item) {
|
|
102053
|
+
const paths = Object.keys(item.fields).filter((path) => !isConstant(item.fields[path]));
|
|
102054
|
+
if (paths.length !== 1) return null;
|
|
102055
|
+
const path = paths[0];
|
|
102056
|
+
if (path === void 0) return null;
|
|
102057
|
+
const field = (target.fields ?? []).find((entry) => entry.path === path);
|
|
102058
|
+
const source = item.fields[path];
|
|
102059
|
+
if (field === void 0 || source === void 0) return null;
|
|
102060
|
+
const read = readTransform(source, field);
|
|
102061
|
+
if (read === null) return null;
|
|
102062
|
+
return {
|
|
102063
|
+
path,
|
|
102064
|
+
field,
|
|
102065
|
+
source,
|
|
102066
|
+
...read
|
|
102067
|
+
};
|
|
102068
|
+
}
|
|
102069
|
+
function readTransform(source, field) {
|
|
102070
|
+
if (source.kind === "from") return field.valueKind === "enum" ? {
|
|
102071
|
+
sourceValueKind: "enum",
|
|
102072
|
+
transform: { kind: "identity" }
|
|
102073
|
+
} : {
|
|
102074
|
+
sourceValueKind: "number",
|
|
102075
|
+
transform: { kind: "identity" }
|
|
102076
|
+
};
|
|
102077
|
+
if (source.kind !== "expression") return null;
|
|
102078
|
+
const mapped = parseEnumMap(source.expr);
|
|
102079
|
+
if (mapped !== null && field.valueKind === "enum") return {
|
|
102080
|
+
sourceValueKind: "enum",
|
|
102081
|
+
transform: enumMapDraft(mapped)
|
|
102082
|
+
};
|
|
102083
|
+
const linear = parseLinear(source.expr);
|
|
102084
|
+
if (linear === null || linear.inner !== "x" || field.valueKind !== "number") return null;
|
|
102085
|
+
return {
|
|
102086
|
+
sourceValueKind: "number",
|
|
102087
|
+
transform: {
|
|
102088
|
+
kind: "linear",
|
|
102089
|
+
scale: linear.scale,
|
|
102090
|
+
offset: linear.offset,
|
|
102091
|
+
...linear.clampMin === void 0 || linear.clampMax === void 0 ? {} : {
|
|
102092
|
+
clampMin: linear.clampMin,
|
|
102093
|
+
clampMax: linear.clampMax
|
|
102094
|
+
}
|
|
102095
|
+
}
|
|
102096
|
+
};
|
|
102097
|
+
}
|
|
102098
|
+
function literalFields(target, field, item, assignedPath) {
|
|
102099
|
+
const required = new Set((field.literals ?? []).map((entry) => entry.path));
|
|
102100
|
+
const traits = new Set((target.traits ?? []).map((trait) => trait.path));
|
|
102101
|
+
const found = Object.keys(item.fields).filter((path) => path !== assignedPath);
|
|
102102
|
+
if (found.some((path) => !required.has(path) && !traits.has(path))) return null;
|
|
102103
|
+
if ([...required].some((path) => !found.includes(path))) return null;
|
|
102104
|
+
const literals = found.map((path) => literalValue(item.fields[path], path));
|
|
102105
|
+
if (literals.some((entry) => entry === null)) return null;
|
|
102106
|
+
return literals.flatMap((entry) => entry === null ? [] : [entry]);
|
|
102107
|
+
}
|
|
102108
|
+
function literalValue(source, path) {
|
|
102109
|
+
if (source?.kind !== "expression" || Object.keys(source.bindings).length !== 0) return null;
|
|
102110
|
+
if (!(source.expr.startsWith("\"") && source.expr.endsWith("\""))) return null;
|
|
102111
|
+
try {
|
|
102112
|
+
const parsed = JSON.parse(source.expr);
|
|
102113
|
+
return typeof parsed === "string" ? {
|
|
102114
|
+
path,
|
|
102115
|
+
value: parsed
|
|
102116
|
+
} : null;
|
|
102117
|
+
} catch {
|
|
102118
|
+
return null;
|
|
102119
|
+
}
|
|
102120
|
+
}
|
|
102121
|
+
function draftOf(cap, targetId, key, label, assigned) {
|
|
102122
|
+
const bound = singleFrom(assigned.source);
|
|
102123
|
+
if (bound === null) return null;
|
|
102124
|
+
return {
|
|
102125
|
+
kind: "keyedArray",
|
|
102126
|
+
cap,
|
|
102127
|
+
targetId,
|
|
102128
|
+
key,
|
|
102129
|
+
label,
|
|
102130
|
+
fieldPath: assigned.path,
|
|
102131
|
+
source: {
|
|
102132
|
+
addonId: bound.addonId,
|
|
102133
|
+
stableId: bound.stableId,
|
|
102134
|
+
cap: bound.cap,
|
|
102135
|
+
fieldPath: bound.fieldPath
|
|
102136
|
+
},
|
|
102137
|
+
transform: assigned.transform
|
|
102138
|
+
};
|
|
102139
|
+
}
|
|
102140
|
+
function reproduces(cap, targetId, key, compile, item) {
|
|
102141
|
+
const compiled = compileKeyedArrayOverride({
|
|
102142
|
+
cap,
|
|
102143
|
+
targetId,
|
|
102144
|
+
device: {
|
|
102145
|
+
addonId: "t",
|
|
102146
|
+
stableId: "t"
|
|
102147
|
+
},
|
|
102148
|
+
apply: "add",
|
|
102149
|
+
items: [compile]
|
|
102150
|
+
});
|
|
102151
|
+
if (!compiled.ok) return false;
|
|
102152
|
+
const written = compiled.value.items?.[key];
|
|
102153
|
+
if (written === void 0) return false;
|
|
102154
|
+
return JSON.stringify(written) === JSON.stringify(item);
|
|
102155
|
+
}
|
|
102156
|
+
function isConstant(source) {
|
|
102157
|
+
return source?.kind === "expression" && Object.keys(source.bindings).length === 0;
|
|
102158
|
+
}
|
|
102159
|
+
function inferApply(target, fields) {
|
|
102160
|
+
const addPaths = (target.companions ?? []).flatMap((companion) => companion.kind !== "transition-time" && companion.when === "add" ? [companion.path] : []);
|
|
102161
|
+
if (addPaths.length === 0) return "replace";
|
|
102162
|
+
const present = addPaths.filter((path) => fields[path] !== void 0);
|
|
102163
|
+
if (present.length === addPaths.length) return "add";
|
|
102164
|
+
if (present.length === 0) return "replace";
|
|
102165
|
+
return null;
|
|
102166
|
+
}
|
|
102167
|
+
function companionsMatch(target, fields, apply) {
|
|
102168
|
+
const expected = (target.companions ?? []).flatMap((companion) => {
|
|
102169
|
+
if (companion.kind === "transition-time") return [];
|
|
102170
|
+
if (companion.when === "always" || apply === "add") return [companion.path];
|
|
102171
|
+
return [];
|
|
102172
|
+
});
|
|
102173
|
+
if (Object.keys(fields).toSorted().join(",") !== [...expected].toSorted().join(",")) return false;
|
|
102174
|
+
return expected.every((path) => isLiteral(fields[path], "now"));
|
|
102175
|
+
}
|
|
102176
|
+
function catalogTarget(cap, targetId) {
|
|
102177
|
+
const entry = catalog[cap];
|
|
102178
|
+
if (entry === void 0) return null;
|
|
102179
|
+
return entry.targets.find((target) => target.id === targetId) ?? null;
|
|
102180
|
+
}
|
|
102181
|
+
function sameFeature(compiled, stored) {
|
|
102182
|
+
return sameStored(wrap(stripEnabled(compiled)), wrap(stripEnabled(stored)));
|
|
102183
|
+
}
|
|
102184
|
+
function stripEnabled(feature) {
|
|
102185
|
+
const { enabled: _enabled, ...rest } = feature;
|
|
102186
|
+
return rest;
|
|
102187
|
+
}
|
|
102188
|
+
function wrap(feature) {
|
|
102189
|
+
return {
|
|
102190
|
+
family: "composition",
|
|
102191
|
+
target: {
|
|
102192
|
+
addonId: "t",
|
|
102193
|
+
stableId: "t"
|
|
102194
|
+
},
|
|
102195
|
+
feature
|
|
102196
|
+
};
|
|
102197
|
+
}
|
|
102198
|
+
//#endregion
|
|
102199
|
+
//#region src/composition/customize/keyed-array-status.ts
|
|
102200
|
+
function projectKeyedArrayAssignment(input) {
|
|
102201
|
+
if (input.stored.kind === "pending") return unanswered(input.targetId, "pending", null);
|
|
102202
|
+
if (input.stored.kind === "unknown") return unanswered(input.targetId, "unknown", input.stored.reason ?? "unknown");
|
|
102203
|
+
if (input.stored.value === null) return native(input.targetId);
|
|
102204
|
+
const read = readKeyedArrayItems(input.stored.value, input.cap, input.targetId);
|
|
102205
|
+
const count = read?.items.filter((item) => item.recognized).length ?? 0;
|
|
102206
|
+
if (read === null || !read.canonical || count === 0) return {
|
|
102207
|
+
text: "unknown",
|
|
102208
|
+
assignedCount: 0,
|
|
102209
|
+
status: status(input.targetId, true, "assigned", "unavailable", "not-canonical")
|
|
102210
|
+
};
|
|
102211
|
+
return projectDecoded(input, count);
|
|
102212
|
+
}
|
|
102213
|
+
function projectDecoded(input, count) {
|
|
102214
|
+
const text = `${count} assigned`;
|
|
102215
|
+
if (input.sourcePresence === "pending") return {
|
|
102216
|
+
text: "pending",
|
|
102217
|
+
assignedCount: count,
|
|
102218
|
+
status: status(input.targetId, true, "assigned", "stale", null)
|
|
102219
|
+
};
|
|
102220
|
+
if (input.sourcePresence === "unknown") return {
|
|
102221
|
+
text: "unknown",
|
|
102222
|
+
assignedCount: count,
|
|
102223
|
+
status: status(input.targetId, true, "assigned", "stale", input.sourceUnknownReason ?? "unknown")
|
|
102224
|
+
};
|
|
102225
|
+
if (input.sourcePresence === "absent") return {
|
|
102226
|
+
text,
|
|
102227
|
+
assignedCount: count,
|
|
102228
|
+
status: status(input.targetId, true, "assigned", "unavailable", "source-missing")
|
|
102229
|
+
};
|
|
102230
|
+
return {
|
|
102231
|
+
text,
|
|
102232
|
+
assignedCount: count,
|
|
102233
|
+
status: status(input.targetId, true, "assigned", "active", null)
|
|
102234
|
+
};
|
|
102235
|
+
}
|
|
102236
|
+
function native(targetId) {
|
|
102237
|
+
return {
|
|
102238
|
+
text: "Native",
|
|
102239
|
+
assignedCount: 0,
|
|
102240
|
+
status: status(targetId, false, "native", "active", null)
|
|
102241
|
+
};
|
|
102242
|
+
}
|
|
102243
|
+
function unanswered(targetId, text, reason) {
|
|
102244
|
+
return {
|
|
102245
|
+
text,
|
|
102246
|
+
assignedCount: 0,
|
|
102247
|
+
status: status(targetId, false, "native", text === "pending" ? "unavailable" : "stale", reason)
|
|
102248
|
+
};
|
|
102249
|
+
}
|
|
102250
|
+
function status(targetId, configured, source, state, reason) {
|
|
102251
|
+
return {
|
|
102252
|
+
targetId,
|
|
102253
|
+
configured,
|
|
102254
|
+
source,
|
|
102255
|
+
state,
|
|
102256
|
+
reason
|
|
102257
|
+
};
|
|
102258
|
+
}
|
|
102259
|
+
//#endregion
|
|
100294
102260
|
//#region src/generated/scope-presets.ts
|
|
100295
102261
|
var SCOPE_PRESETS = [
|
|
100296
102262
|
{
|
|
@@ -111026,6 +112992,7 @@ exports.CAMSTACK_EVENT_PREFIX = CAMSTACK_EVENT_PREFIX;
|
|
|
111026
112992
|
exports.CAM_PROFILE_ORDER = require_sleep.CAM_PROFILE_ORDER;
|
|
111027
112993
|
exports.CAPABILITY_NAMES = CAPABILITY_NAMES;
|
|
111028
112994
|
exports.CAPABILITY_ROUTER_KEYS = CAPABILITY_ROUTER_KEYS;
|
|
112995
|
+
exports.CAP_CUSTOMIZE_CATALOG = CAP_CUSTOMIZE_CATALOG;
|
|
111029
112996
|
exports.CAP_NAMES_WITH_STATUS = CAP_NAMES_WITH_STATUS;
|
|
111030
112997
|
exports.CAP_NODE_PIN_CONTEXT_KEY = require_sleep.CAP_NODE_PIN_CONTEXT_KEY;
|
|
111031
112998
|
exports.CAP_PROVIDER_KIND_MAP = CAP_PROVIDER_KIND_MAP;
|
|
@@ -111254,6 +113221,7 @@ exports.CredentialScopeSchema = CredentialScopeSchema;
|
|
|
111254
113221
|
exports.CredentialTokenClaimsSchema = CredentialTokenClaimsSchema;
|
|
111255
113222
|
exports.CustomActionInputSchema = CustomActionInputSchema;
|
|
111256
113223
|
exports.CustomModelDescriptorSchema = CustomModelDescriptorSchema;
|
|
113224
|
+
exports.CustomizeAssignmentStatusSchema = CustomizeAssignmentStatusSchema;
|
|
111257
113225
|
exports.DATABASE_SNAPSHOT_PARTIAL_SUFFIX = DATABASE_SNAPSHOT_PARTIAL_SUFFIX;
|
|
111258
113226
|
exports.DATABASE_SNAPSHOT_SUFFIX = DATABASE_SNAPSHOT_SUFFIX;
|
|
111259
113227
|
exports.DATABASE_SNAPSHOT_TIMEOUT_MS = DATABASE_SNAPSHOT_TIMEOUT_MS;
|
|
@@ -111595,6 +113563,8 @@ exports.ICON_ENTRIES = ICON_ENTRIES;
|
|
|
111595
113563
|
exports.ICON_KEYS = ICON_KEYS;
|
|
111596
113564
|
exports.ICON_VIEWER_MODULES = ICON_VIEWER_MODULES;
|
|
111597
113565
|
exports.INFERENCE_DEVICE_EXCLUSION_REASONS = INFERENCE_DEVICE_EXCLUSION_REASONS;
|
|
113566
|
+
exports.INITIAL_PULSE = INITIAL_PULSE;
|
|
113567
|
+
exports.INITIAL_SPAN = INITIAL_SPAN;
|
|
111598
113568
|
exports.INVERTIBLE_CAPS = INVERTIBLE_CAPS;
|
|
111599
113569
|
exports.IconKeySchema = IconKeySchema;
|
|
111600
113570
|
exports.ImageContractSchema = ImageContractSchema;
|
|
@@ -111776,6 +113746,7 @@ exports.MOTION_CROP_MAX_REGIONS = MOTION_CROP_MAX_REGIONS;
|
|
|
111776
113746
|
exports.MOTION_CROP_MOTION_PAD = MOTION_CROP_MOTION_PAD;
|
|
111777
113747
|
exports.MOTION_CROP_TRACKED_PAD = MOTION_CROP_TRACKED_PAD;
|
|
111778
113748
|
exports.MOTION_SOURCE_LABELS = MOTION_SOURCE_LABELS;
|
|
113749
|
+
exports.MOTION_SPAN_TIMEOUT_MS = MOTION_SPAN_TIMEOUT_MS;
|
|
111779
113750
|
exports.MOTION_TRIGGER_FEATURE = MOTION_TRIGGER_FEATURE;
|
|
111780
113751
|
exports.ManagedModelCatalogEntrySchema = ManagedModelCatalogEntrySchema;
|
|
111781
113752
|
exports.ManagedModelExtraFileSchema = ManagedModelExtraFileSchema;
|
|
@@ -112151,6 +114122,7 @@ exports.OsdTemplateBindingSchema = OsdTemplateBindingSchema;
|
|
|
112151
114122
|
exports.OsdTemplateFormatSchema = OsdTemplateFormatSchema;
|
|
112152
114123
|
exports.OsdTemplatePickSchema = OsdTemplatePickSchema;
|
|
112153
114124
|
exports.OsdTemplateTokenKindSchema = OsdTemplateTokenKindSchema;
|
|
114125
|
+
exports.OverrideDraftSchema = OverrideDraftSchema;
|
|
112154
114126
|
exports.PEER_BYTES_CHUNK_BYTES = require_sleep.PEER_BYTES_CHUNK_BYTES;
|
|
112155
114127
|
exports.PEER_BYTES_MAX_OUTSTANDING = require_sleep.PEER_BYTES_MAX_OUTSTANDING;
|
|
112156
114128
|
exports.PEER_BYTES_STALL_MS = require_sleep.PEER_BYTES_STALL_MS;
|
|
@@ -112314,6 +114286,7 @@ exports.ROOT_SUPPLIABLE_STEP_IDS = ROOT_SUPPLIABLE_STEP_IDS;
|
|
|
112314
114286
|
exports.RUNNING_POWER_START_DELAY_MS = RUNNING_POWER_START_DELAY_MS;
|
|
112315
114287
|
exports.RUNNING_POWER_STOP_DELAY_MS = RUNNING_POWER_STOP_DELAY_MS;
|
|
112316
114288
|
exports.RUNNING_POWER_THRESHOLD_WATTS = RUNNING_POWER_THRESHOLD_WATTS;
|
|
114289
|
+
exports.RUNNING_STATE_COLD = RUNNING_STATE_COLD;
|
|
112317
114290
|
exports.RUNTIME_DEFAULTS = require_sleep.RUNTIME_DEFAULTS;
|
|
112318
114291
|
exports.RUNTIME_STATE_POLICY = RUNTIME_STATE_POLICY;
|
|
112319
114292
|
exports.RUNTIME_STATE_REFRESH_MISS_COOLDOWN_MS = RUNTIME_STATE_REFRESH_MISS_COOLDOWN_MS;
|
|
@@ -112742,6 +114715,7 @@ exports.UninstallNodeResultSchema = UninstallNodeResultSchema;
|
|
|
112742
114715
|
exports.UninstallPackageResultSchema = UninstallPackageResultSchema;
|
|
112743
114716
|
exports.UnitConversionError = UnitConversionError;
|
|
112744
114717
|
exports.UnknownRecordKindError = require_sleep.UnknownRecordKindError;
|
|
114718
|
+
exports.UnreleasedClaimSchema = UnreleasedClaimSchema;
|
|
112745
114719
|
exports.UnstampedEventMediaCountSchema = UnstampedEventMediaCountSchema;
|
|
112746
114720
|
exports.UnstampedRowsSchema = UnstampedRowsSchema;
|
|
112747
114721
|
exports.UpdateBlockerSchema = UpdateBlockerSchema;
|
|
@@ -112906,7 +114880,6 @@ exports.buildCapabilityLookup = buildCapabilityLookup;
|
|
|
112906
114880
|
exports.buildDeviceAdminUrl = buildDeviceAdminUrl;
|
|
112907
114881
|
exports.buildDeviceEnrollmentLink = buildDeviceEnrollmentLink;
|
|
112908
114882
|
exports.buildDeviceSignatureMessage = buildDeviceSignatureMessage;
|
|
112909
|
-
exports.buildDoorbellCompositionFeature = buildDoorbellCompositionFeature;
|
|
112910
114883
|
exports.buildEventKindDescriptor = buildEventKindDescriptor;
|
|
112911
114884
|
exports.buildFfmpegArgs = require_composition.buildFfmpegArgs;
|
|
112912
114885
|
exports.buildFrigateClassMap = buildFrigateClassMap;
|
|
@@ -112980,6 +114953,10 @@ exports.commitWatchdogRestart = commitWatchdogRestart;
|
|
|
112980
114953
|
exports.compareToTarget = compareToTarget;
|
|
112981
114954
|
exports.compileExpression = require_composition.compileExpression;
|
|
112982
114955
|
exports.compileExpressionSafe = require_composition.compileExpressionSafe;
|
|
114956
|
+
exports.compileKeyedArrayOverride = compileKeyedArrayOverride;
|
|
114957
|
+
exports.compilePulseOverride = compilePulseOverride;
|
|
114958
|
+
exports.compileScalarOverride = compileScalarOverride;
|
|
114959
|
+
exports.compileSpanOverride = compileSpanOverride;
|
|
112983
114960
|
exports.composeSwitchedOff = composeSwitchedOff;
|
|
112984
114961
|
exports.composedDeviceRef = require_composition.composedDeviceRef;
|
|
112985
114962
|
exports.composedDeviceStableId = require_composition.composedDeviceStableId;
|
|
@@ -113044,6 +115021,9 @@ exports.dayOfWeekToIndex = dayOfWeekToIndex;
|
|
|
113044
115021
|
exports.declarationOwnerNodeId = declarationOwnerNodeId;
|
|
113045
115022
|
exports.declarationsOf = require_sleep.declarationsOf;
|
|
113046
115023
|
exports.declareLogChannel = declareLogChannel;
|
|
115024
|
+
exports.decodeKeyedArrayOverride = decodeKeyedArrayOverride;
|
|
115025
|
+
exports.decodePulseOverride = decodePulseOverride;
|
|
115026
|
+
exports.decodeScalarOverride = decodeScalarOverride;
|
|
113047
115027
|
exports.decodeVectorBase64 = decodeVectorBase64;
|
|
113048
115028
|
exports.decoderCapability = decoderCapability;
|
|
113049
115029
|
exports.defaultDeliveryForSection = defaultDeliveryForSection;
|
|
@@ -113102,7 +115082,6 @@ exports.dishwasherCapability = dishwasherCapability;
|
|
|
113102
115082
|
exports.doActionSelectValue = doActionSelectValue;
|
|
113103
115083
|
exports.dominantClipLabels = dominantClipLabels;
|
|
113104
115084
|
exports.doorbellCapability = doorbellCapability;
|
|
113105
|
-
exports.doorbellFeatureSources = doorbellFeatureSources;
|
|
113106
115085
|
exports.droppedConditionsForKind = droppedConditionsForKind;
|
|
113107
115086
|
exports.edgetpuDelegateDevice = edgetpuDelegateDevice;
|
|
113108
115087
|
exports.effectiveStepSettings = effectiveStepSettings;
|
|
@@ -113280,7 +115259,6 @@ exports.isRemovedModelId = isRemovedModelId;
|
|
|
113280
115259
|
exports.isRestoredCap = isRestoredCap;
|
|
113281
115260
|
exports.isRetiredClearKey = isRetiredClearKey;
|
|
113282
115261
|
exports.isRootSuppliableStepId = isRootSuppliableStepId;
|
|
113283
|
-
exports.isRunningAssignmentFeature = isRunningAssignmentFeature;
|
|
113284
115262
|
exports.isSameAddonId = isSameAddonId;
|
|
113285
115263
|
exports.isScheduleActive = isScheduleActive;
|
|
113286
115264
|
exports.isSecretClear = require_sleep.isSecretClear;
|
|
@@ -113355,6 +115333,7 @@ exports.measuredDetectorCells = measuredDetectorCells;
|
|
|
113355
115333
|
exports.mediaPlayerCapability = mediaPlayerCapability;
|
|
113356
115334
|
exports.memoizePinnedFfmpeg = memoizePinnedFfmpeg;
|
|
113357
115335
|
exports.mergeClipLabels = mergeClipLabels;
|
|
115336
|
+
exports.mergeKeyedArrayItem = mergeKeyedArrayItem;
|
|
113358
115337
|
exports.mergeSecretStatePaths = require_sleep.mergeSecretStatePaths;
|
|
113359
115338
|
exports.mergeSettingsBags = mergeSettingsBags;
|
|
113360
115339
|
exports.mergeSourceInfo = mergeSourceInfo;
|
|
@@ -113481,6 +115460,10 @@ exports.pressureSensorCapability = pressureSensorCapability;
|
|
|
113481
115460
|
exports.principalMayReachAddon = principalMayReachAddon;
|
|
113482
115461
|
exports.privacyMaskCapability = privacyMaskCapability;
|
|
113483
115462
|
exports.procedureAuthKey = procedureAuthKey;
|
|
115463
|
+
exports.projectKeyedArrayAssignment = projectKeyedArrayAssignment;
|
|
115464
|
+
exports.projectPulseAssignment = projectPulseAssignment;
|
|
115465
|
+
exports.projectScalarAssignment = projectScalarAssignment;
|
|
115466
|
+
exports.projectSpanAssignment = projectSpanAssignment;
|
|
113484
115467
|
exports.projectSubjectPath = projectSubjectPath;
|
|
113485
115468
|
exports.providerMotionEvent = providerMotionEvent;
|
|
113486
115469
|
exports.ptzAutotrackCapability = ptzAutotrackCapability;
|
|
@@ -113496,6 +115479,7 @@ exports.readErrorI18n = require_sleep.readErrorI18n;
|
|
|
113496
115479
|
exports.readFaceRescoreIntervalMinutes = readFaceRescoreIntervalMinutes;
|
|
113497
115480
|
exports.readHubMotionDetected = readHubMotionDetected;
|
|
113498
115481
|
exports.readHubMotionStatus = readHubMotionStatus;
|
|
115482
|
+
exports.readKeyedArrayItems = readKeyedArrayItems;
|
|
113499
115483
|
exports.readMotionTriggeredBy = readMotionTriggeredBy;
|
|
113500
115484
|
exports.readNativeLeaseOverride = readNativeLeaseOverride;
|
|
113501
115485
|
exports.readNodePin = require_sleep.readNodePin;
|
|
@@ -113598,8 +115582,6 @@ exports.ruleSectionOf = ruleSectionOf;
|
|
|
113598
115582
|
exports.ruleSeedForSection = ruleSeedForSection;
|
|
113599
115583
|
exports.ruleTriggerZoneIds = ruleTriggerZoneIds;
|
|
113600
115584
|
exports.runInferenceStep = runInferenceStep;
|
|
113601
|
-
exports.runningAssignmentFeature = runningAssignmentFeature;
|
|
113602
|
-
exports.runningAssignmentRecovered = runningAssignmentRecovered;
|
|
113603
115585
|
exports.runningFromDishwasherOperation = runningFromDishwasherOperation;
|
|
113604
115586
|
exports.runningFromLawnMower = runningFromLawnMower;
|
|
113605
115587
|
exports.runningFromMediaPlayer = runningFromMediaPlayer;
|
|
@@ -113662,7 +115644,9 @@ exports.startReachabilityPoll = startReachabilityPoll;
|
|
|
113662
115644
|
exports.stateLabel = stateLabel;
|
|
113663
115645
|
exports.stateVocabularyFor = stateVocabularyFor;
|
|
113664
115646
|
exports.stepModelRunsOnFormat = stepModelRunsOnFormat;
|
|
115647
|
+
exports.stepPulse = stepPulse;
|
|
113665
115648
|
exports.stepSettingSource = stepSettingSource;
|
|
115649
|
+
exports.stepSpan = stepSpan;
|
|
113666
115650
|
exports.storageAdminCapability = storageAdminCapability;
|
|
113667
115651
|
exports.storageCapability = storageCapability;
|
|
113668
115652
|
exports.storageEvictableCapability = storageEvictableCapability;
|
|
@@ -113780,6 +115764,7 @@ exports.withLocationMode = withLocationMode;
|
|
|
113780
115764
|
exports.withSystemEventClasses = withSystemEventClasses;
|
|
113781
115765
|
exports.withoutCallerStamp = require_sleep.withoutCallerStamp;
|
|
113782
115766
|
exports.withoutField = withoutField;
|
|
115767
|
+
exports.withoutKeyedArrayItem = withoutKeyedArrayItem;
|
|
113783
115768
|
exports.writeModelBoundSetting = writeModelBoundSetting;
|
|
113784
115769
|
exports.zodEntriesToConfigUI = zodEntriesToConfigUI;
|
|
113785
115770
|
exports.zoneAnalyticsCapability = zoneAnalyticsCapability;
|