@camstack/addon-post-analysis 1.2.280 → 1.2.282
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/{dist-Z6AO1MsY.mjs → dist-C3zTKShG.mjs} +552 -25
- package/dist/{dist-VeiAavYR.js → dist-D0zzdvSd.js} +599 -24
- package/dist/embedding-encoder/index.js +1 -1
- package/dist/embedding-encoder/index.mjs +1 -1
- package/dist/pipeline-analytics/_stub.js +2 -2
- package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-C_C1P6Bk.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-B9WQ8rry.mjs} +2 -2
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DT-cQNv-.mjs +26 -0
- package/dist/pipeline-analytics/{_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-B62fofgN.mjs → _virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DWPDYuJS.mjs} +1 -1
- package/dist/pipeline-analytics/{hostInit-B5__n3rE.mjs → hostInit-lUAYfFf-.mjs} +2 -2
- package/dist/pipeline-analytics/index.js +592 -26
- package/dist/pipeline-analytics/index.mjs +592 -26
- package/dist/pipeline-analytics/remoteEntry.js +1 -1
- package/package.json +1 -1
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DBnj0lb3.mjs +0 -26
|
@@ -29,6 +29,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
29
29
|
enumerable: true
|
|
30
30
|
}) : target, mod));
|
|
31
31
|
//#endregion
|
|
32
|
+
let node_crypto = require("node:crypto");
|
|
32
33
|
//#region ../types/dist/event-category-BVDXG4tB.mjs
|
|
33
34
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
34
35
|
EventCategory["SystemBoot"] = "system.boot";
|
|
@@ -5390,7 +5391,7 @@ var ZodIssueCode = {
|
|
|
5390
5391
|
var ZodFirstPartyTypeKind;
|
|
5391
5392
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5392
5393
|
//#endregion
|
|
5393
|
-
//#region ../types/dist/sleep-
|
|
5394
|
+
//#region ../types/dist/sleep-DU7mu4wb.mjs
|
|
5394
5395
|
/**
|
|
5395
5396
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5396
5397
|
* window to float samples (D455).
|
|
@@ -7598,6 +7599,39 @@ function sleep(ms) {
|
|
|
7598
7599
|
return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
|
|
7599
7600
|
}
|
|
7600
7601
|
//#endregion
|
|
7602
|
+
//#region ../types/dist/canonical-hash-CPK2Dy60.mjs
|
|
7603
|
+
/**
|
|
7604
|
+
* Deterministic SHA-256 hash of an arbitrary serialisable value. The
|
|
7605
|
+
* canonical form sorts object keys alphabetically at every depth so two
|
|
7606
|
+
* structurally-equal inputs with different key insertion orders produce
|
|
7607
|
+
* the same hash. Returns a 64-char lowercase hex digest.
|
|
7608
|
+
*
|
|
7609
|
+
* Used by export adapters (Alexa, HAP) to short-circuit re-discovery /
|
|
7610
|
+
* accessory-rebuild work when the upstream shape is byte-identical to
|
|
7611
|
+
* the last applied state — preventing user-visible "re-discovery"
|
|
7612
|
+
* notifications on every addon-runner respawn. Each respawn re-fires
|
|
7613
|
+
* `DeviceBindingsChanged` for every cap registration, which without
|
|
7614
|
+
* this guard would propagate redundant pushes.
|
|
7615
|
+
*
|
|
7616
|
+
* Note: this is a SYMPTOMATIC fix layered on top of the binding-change
|
|
7617
|
+
* subscription. The proper fix is a single "device ready" lifecycle
|
|
7618
|
+
* barrier so exports react only when the full cap set has landed —
|
|
7619
|
+
* tracked separately for post-HA-integration work.
|
|
7620
|
+
*/
|
|
7621
|
+
function canonicalHash(value) {
|
|
7622
|
+
const canonical = JSON.stringify(value, replaceWithSortedKeys);
|
|
7623
|
+
return (0, node_crypto.createHash)("sha256").update(canonical ?? "").digest("hex");
|
|
7624
|
+
}
|
|
7625
|
+
function replaceWithSortedKeys(_key, value) {
|
|
7626
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
7627
|
+
const obj = value;
|
|
7628
|
+
const out = {};
|
|
7629
|
+
for (const k of Object.keys(obj).toSorted()) out[k] = obj[k];
|
|
7630
|
+
return out;
|
|
7631
|
+
}
|
|
7632
|
+
return value;
|
|
7633
|
+
}
|
|
7634
|
+
//#endregion
|
|
7601
7635
|
//#region ../types/dist/err-msg-IQTHeDzc.mjs
|
|
7602
7636
|
/**
|
|
7603
7637
|
import { errMsg } from '@camstack/types'
|
|
@@ -18175,6 +18209,16 @@ var NcCrossingSchema = _enum([
|
|
|
18175
18209
|
"exit",
|
|
18176
18210
|
"any"
|
|
18177
18211
|
]);
|
|
18212
|
+
/**
|
|
18213
|
+
* Which edge of a BOOLEAN sensor fires a device-event rule (D640).
|
|
18214
|
+
* - `raised` — the sensor went high: water detected, smoke, open, tampered.
|
|
18215
|
+
* - `cleared` — it went back: dry, clear, closed.
|
|
18216
|
+
* - absent — both edges, which is what every rule authored before this did.
|
|
18217
|
+
*
|
|
18218
|
+
* There is no third member for "both": absence already says it, and a value
|
|
18219
|
+
* that means the same as absence is a second way to write one rule.
|
|
18220
|
+
*/
|
|
18221
|
+
var NcSensorTransitionSchema = _enum(["raised", "cleared"]);
|
|
18178
18222
|
/** Admin-zone membership condition (zone IDs as stamped by the ZoneEngine). */
|
|
18179
18223
|
var NcZoneConditionSchema = object({
|
|
18180
18224
|
ids: array(string().min(1)).min(1),
|
|
@@ -18364,6 +18408,20 @@ var NcConditionsSchema = object({
|
|
|
18364
18408
|
scene: NcSceneConditionSchema.optional(),
|
|
18365
18409
|
/** Device scope — absent = all devices. */
|
|
18366
18410
|
devices: array(number()).optional(),
|
|
18411
|
+
/**
|
|
18412
|
+
* Device EXCLUSION (D641) — "every device except these". Judged on the SAME
|
|
18413
|
+
* subject ids {@link devices} is judged on (the camera, the sensor that
|
|
18414
|
+
* fired, a linked set's sensor and row cameras), so a sensor fanned out per
|
|
18415
|
+
* linked camera is excluded exactly where an include would have tested it.
|
|
18416
|
+
* `min(1)`: an empty exclusion excludes nothing and is written as absent.
|
|
18417
|
+
*
|
|
18418
|
+
* Not for `system-event` rules — those carry their own
|
|
18419
|
+
* `systemEvent.excludeDeviceIds` (D636), and the hub refuses this key there.
|
|
18420
|
+
* Editors present the two lists as ONE field (All | Only these | All except
|
|
18421
|
+
* these); the engine evaluates each independently, so a legacy rule
|
|
18422
|
+
* carrying both still means "these, minus those".
|
|
18423
|
+
*/
|
|
18424
|
+
devicesExclude: array(number()).min(1).optional(),
|
|
18367
18425
|
/** Detector class names (any overlap with the record's class set). */
|
|
18368
18426
|
classes: array(string().min(1)).optional(),
|
|
18369
18427
|
/** Veto classes — any overlap fails the rule. */
|
|
@@ -18497,6 +18555,16 @@ var NcConditionsSchema = object({
|
|
|
18497
18555
|
*/
|
|
18498
18556
|
sensorKinds: array(string().min(1)).optional(),
|
|
18499
18557
|
/**
|
|
18558
|
+
* DEVICE-EVENT only (D640). Fire on one edge of a boolean sensor —
|
|
18559
|
+
* {@link NcSensorTransitionSchema}. Which field of the slice means "raised"
|
|
18560
|
+
* is `@camstack/types` → `notification/sensor-raised.ts`. A reading the
|
|
18561
|
+
* engine cannot place (a kind with no raise, an unreadable slice) PASSES:
|
|
18562
|
+
* the condition fails open towards notifying, never towards silence. Editors
|
|
18563
|
+
* offer it only when every chosen {@link sensorKinds} member has a raise
|
|
18564
|
+
* (`sensorTransitionOffered`), and the hub refuses it on any other delivery.
|
|
18565
|
+
*/
|
|
18566
|
+
sensorTransition: NcSensorTransitionSchema.optional(),
|
|
18567
|
+
/**
|
|
18500
18568
|
* PACKAGE-EVENT only. Which package phase fires the rule — `delivered`
|
|
18501
18569
|
* (a parked parcel appeared), `picked-up` (it departed), or `both`. Fails
|
|
18502
18570
|
* when the subject's phase does not match (a subject always carries a phase
|
|
@@ -18996,9 +19064,29 @@ var NcTestResultSchema = object({
|
|
|
18996
19064
|
className: string().optional(),
|
|
18997
19065
|
label: string().optional()
|
|
18998
19066
|
});
|
|
18999
|
-
/** The
|
|
19000
|
-
*
|
|
19067
|
+
/** The rule kinds, as data. `NcRuleKind` in `notification/rule-kinds.ts` is the
|
|
19068
|
+
* same union; the template-vars spec pins the two together. `mixed` is DERIVED
|
|
19069
|
+
* (a stored system rule whose kinds span families, D637) and never authored. */
|
|
19001
19070
|
var NcRuleKindSchema = _enum([
|
|
19071
|
+
"detection",
|
|
19072
|
+
"sensor",
|
|
19073
|
+
"occupancy",
|
|
19074
|
+
"sound",
|
|
19075
|
+
"device-events",
|
|
19076
|
+
"system",
|
|
19077
|
+
"alarm",
|
|
19078
|
+
"mixed"
|
|
19079
|
+
]);
|
|
19080
|
+
/**
|
|
19081
|
+
* The kinds a SERVED template-variable descriptor may name: the five that
|
|
19082
|
+
* existed before D637, frozen. `getTemplateCatalog` ships `kinds` to every
|
|
19083
|
+
* installed viewer, and a viewer at `@camstack/types` 1.2.25x parses them with a
|
|
19084
|
+
* strict five-member enum — one `device-events` in one descriptor fails the
|
|
19085
|
+
* whole catalog parse. So the WIRE says `system`, and the MATCH widens it:
|
|
19086
|
+
* `templateVarKindApplies` reads a `system` descriptor as applying to every
|
|
19087
|
+
* system rule kind (`device-events`, `system`, `alarm`, `mixed`).
|
|
19088
|
+
*/
|
|
19089
|
+
var NcTemplateVarKindSchema = _enum([
|
|
19002
19090
|
"detection",
|
|
19003
19091
|
"sensor",
|
|
19004
19092
|
"occupancy",
|
|
@@ -19036,7 +19124,7 @@ var NcTemplateVarGroupSchema = _enum([
|
|
|
19036
19124
|
*
|
|
19037
19125
|
* `families` / `fields` / `kinds` / `deliveries` / `systemEventKinds` say WHERE
|
|
19038
19126
|
* it has a value; absent = no restriction on that axis. `systemEventKinds` is
|
|
19039
|
-
* read only for a
|
|
19127
|
+
* read only for a system-event rule (any family, or `mixed`). `dynamic` declares a FAMILY of names
|
|
19040
19128
|
* (`count_<class>`): the descriptor's `name` is the example member.
|
|
19041
19129
|
*/
|
|
19042
19130
|
var NcTemplateVarDescriptorSchema = object({
|
|
@@ -19047,7 +19135,7 @@ var NcTemplateVarDescriptorSchema = object({
|
|
|
19047
19135
|
group: NcTemplateVarGroupSchema,
|
|
19048
19136
|
families: array(NcTemplateFamilySchema).min(1),
|
|
19049
19137
|
fields: array(NcTemplateFieldSchema).optional(),
|
|
19050
|
-
kinds: array(
|
|
19138
|
+
kinds: array(NcTemplateVarKindSchema).optional(),
|
|
19051
19139
|
deliveries: array(NcDeliverySchema).optional(),
|
|
19052
19140
|
systemEventKinds: array(NcSystemEventKindSchema).optional(),
|
|
19053
19141
|
dynamic: object({
|
|
@@ -19095,6 +19183,7 @@ var NcConditionDescriptorSchema = object({
|
|
|
19095
19183
|
/** Editor widget the UI renders — never hardcode per-condition forms. */
|
|
19096
19184
|
valueType: _enum([
|
|
19097
19185
|
"deviceIdList",
|
|
19186
|
+
"deviceIdExcludeList",
|
|
19098
19187
|
"stringList",
|
|
19099
19188
|
"number01",
|
|
19100
19189
|
"number",
|
|
@@ -19105,6 +19194,7 @@ var NcConditionDescriptorSchema = object({
|
|
|
19105
19194
|
"plateMatcher",
|
|
19106
19195
|
"packagePhase",
|
|
19107
19196
|
"crossingSelect",
|
|
19197
|
+
"sensorTransition",
|
|
19108
19198
|
"polygonDraw",
|
|
19109
19199
|
"occupancy",
|
|
19110
19200
|
"audio",
|
|
@@ -19303,6 +19393,21 @@ var NC_CONDITION_CATALOG = [
|
|
|
19303
19393
|
phase: "P1",
|
|
19304
19394
|
description: "Restrict the rule to these devices; absent = all devices. A sensor event matches either the SENSOR that fired or the camera it is attributed to, so a rule may name either one."
|
|
19305
19395
|
},
|
|
19396
|
+
{
|
|
19397
|
+
id: "devicesExclude",
|
|
19398
|
+
group: "scope",
|
|
19399
|
+
label: "Excluded devices",
|
|
19400
|
+
valueType: "deviceIdExcludeList",
|
|
19401
|
+
operator: "notIn",
|
|
19402
|
+
appliesTo: [
|
|
19403
|
+
"immediate",
|
|
19404
|
+
"track-end",
|
|
19405
|
+
"device-event",
|
|
19406
|
+
"package-event"
|
|
19407
|
+
],
|
|
19408
|
+
phase: "P1",
|
|
19409
|
+
description: "Every device except these. Judged on the same device ids as Devices: a sensor event is excluded by the SENSOR that fired or by the camera it is attributed to."
|
|
19410
|
+
},
|
|
19306
19411
|
{
|
|
19307
19412
|
id: "classes",
|
|
19308
19413
|
group: "class",
|
|
@@ -19559,6 +19664,33 @@ var NC_CONDITION_CATALOG = [
|
|
|
19559
19664
|
phase: "P1",
|
|
19560
19665
|
description: "Raw device event-type tokens (e.g. doorbell press / press_long) from the event-emitter slice; absent on doorbell-pulse / passive sensors."
|
|
19561
19666
|
},
|
|
19667
|
+
{
|
|
19668
|
+
id: "sensorTransition",
|
|
19669
|
+
group: "device",
|
|
19670
|
+
label: "Notify when",
|
|
19671
|
+
valueType: "sensorTransition",
|
|
19672
|
+
options: [
|
|
19673
|
+
{
|
|
19674
|
+
value: "",
|
|
19675
|
+
label: "It triggers and when it clears",
|
|
19676
|
+
hint: "Every change: water detected, and back to dry."
|
|
19677
|
+
},
|
|
19678
|
+
{
|
|
19679
|
+
value: "raised",
|
|
19680
|
+
label: "Only when it triggers",
|
|
19681
|
+
hint: "Water detected, smoke, a contact opening — never the return to normal."
|
|
19682
|
+
},
|
|
19683
|
+
{
|
|
19684
|
+
value: "cleared",
|
|
19685
|
+
label: "Only when it clears",
|
|
19686
|
+
hint: "Back to dry, smoke gone, a contact closing — never the alert itself."
|
|
19687
|
+
}
|
|
19688
|
+
],
|
|
19689
|
+
operator: "in",
|
|
19690
|
+
appliesTo: ["device-event"],
|
|
19691
|
+
phase: "P2",
|
|
19692
|
+
description: "Fire on one edge of a boolean sensor. Offered only when every chosen sensor kind raises and clears; a reading that cannot be placed still notifies."
|
|
19693
|
+
},
|
|
19562
19694
|
{
|
|
19563
19695
|
id: "packagePhase",
|
|
19564
19696
|
group: "package",
|
|
@@ -19742,6 +19874,28 @@ var NcHistoryFilterSchema = object({
|
|
|
19742
19874
|
limit: number().int().min(1).max(500).default(100)
|
|
19743
19875
|
});
|
|
19744
19876
|
/**
|
|
19877
|
+
* Every rule's last run, in one answer.
|
|
19878
|
+
*
|
|
19879
|
+
* A rule ABSENT from `runs` produced no delivery inside `horizonMs` — how far
|
|
19880
|
+
* back this answer looked, in ms before the hub's now. It is the outbox prune
|
|
19881
|
+
* window (7 days by default, operator-configurable), NARROWED when the read hit
|
|
19882
|
+
* its row bound: the answer never claims a window it did not read. `null` means
|
|
19883
|
+
* the operator keeps the outbox forever AND the read reached its end, so absent
|
|
19884
|
+
* means "never on record". A UI derives its "not in the last N days" from this
|
|
19885
|
+
* value, never from a constant — and only when the call ANSWERED (D315).
|
|
19886
|
+
*/
|
|
19887
|
+
var NcRuleLastRunsSchema = object({
|
|
19888
|
+
runs: array(object({
|
|
19889
|
+
ruleId: string(),
|
|
19890
|
+
/** Fire time of the newest row (`createdAt`, epoch ms). */
|
|
19891
|
+
lastAt: number(),
|
|
19892
|
+
status: NcHistoryStatusSchema,
|
|
19893
|
+
/** The camera/device of that row (a digest row files under its first camera). */
|
|
19894
|
+
deviceId: number()
|
|
19895
|
+
})),
|
|
19896
|
+
horizonMs: number().nonnegative().nullable()
|
|
19897
|
+
});
|
|
19898
|
+
/**
|
|
19745
19899
|
* What a snooze covers. Broader scopes win when several overlap, so one window
|
|
19746
19900
|
* leaves ONE digest rather than a rule snooze and a whole-feed snooze both
|
|
19747
19901
|
* summarising the same silence.
|
|
@@ -19923,6 +20077,14 @@ var NcAlarmModeCoverageSchema = object({
|
|
|
19923
20077
|
/** Ids named by the covering rules. A SUBSET when `allDevices` is true. */
|
|
19924
20078
|
deviceIds: array(number().int()),
|
|
19925
20079
|
/**
|
|
20080
|
+
* D641: the ids NOT covered although `allDevices` is true — every unscoped
|
|
20081
|
+
* covering rule EXCLUDES them (`conditions.devicesExclude`) and no named rule
|
|
20082
|
+
* covers them. Always `[]` when `allDevices` is false. Excluded by the rules,
|
|
20083
|
+
* which is not the same as skipped by a switch: never in `skippedDevices`.
|
|
20084
|
+
* Defaulted so an answer computed before this field parses as "none".
|
|
20085
|
+
*/
|
|
20086
|
+
allDevicesExcept: array(number().int()).default([]),
|
|
20087
|
+
/**
|
|
19926
20088
|
* Devices this mode NAMES but cannot actually arm, each with the switch that
|
|
19927
20089
|
* excludes it.
|
|
19928
20090
|
*
|
|
@@ -20146,6 +20308,15 @@ var notificationRulesCapability = {
|
|
|
20146
20308
|
*/
|
|
20147
20309
|
getHistory: method(object({ filter: NcHistoryFilterSchema.default({ limit: 100 }) }), object({ entries: array(NcHistoryEntrySchema) }), { auth: "admin" }),
|
|
20148
20310
|
/**
|
|
20311
|
+
* The newest delivery of every rule, in ONE bounded read of the outbox —
|
|
20312
|
+
* the "Last run" column. Never a `getHistory` per rule. A rule with no
|
|
20313
|
+
* delivery inside `horizonMs` is absent from `runs`; see
|
|
20314
|
+
* {@link NcRuleLastRunsSchema} for what absent means. A store that cannot
|
|
20315
|
+
* answer FAILS the call rather than answering "nothing ran". Admin-only,
|
|
20316
|
+
* like `getHistory`, of which it is a projection.
|
|
20317
|
+
*/
|
|
20318
|
+
getRuleLastRuns: method(object({}), NcRuleLastRunsSchema, { auth: "admin" }),
|
|
20319
|
+
/**
|
|
20149
20320
|
* Mint a fresh, externally-reachable URL for one artefact a history row
|
|
20150
20321
|
* named in {@link NcHistoryEntrySchema.shape.artifactIds} — the SAME
|
|
20151
20322
|
* signed-link mechanism the dispatcher uses to attach media to an
|
|
@@ -33200,7 +33371,30 @@ var RenameNodeResultSchema = object({
|
|
|
33200
33371
|
nodeId: string(),
|
|
33201
33372
|
name: string()
|
|
33202
33373
|
});
|
|
33203
|
-
|
|
33374
|
+
/**
|
|
33375
|
+
* The cheap node list. A consumer's rule for a STORED node id (a rule's
|
|
33376
|
+
* `nodeIds`) that is missing from `nodes`, whatever `complete` says: render it
|
|
33377
|
+
* as a removable chip labelled unknown, never drop it (D49). Even a complete
|
|
33378
|
+
* list omits a node that joined and left between two history captures, so a
|
|
33379
|
+
* missing id means "not known to the hub", never "removed". Only the operator
|
|
33380
|
+
* removes it.
|
|
33381
|
+
*
|
|
33382
|
+
* `complete` changes only the WORDING: `false` = no history read has ever
|
|
33383
|
+
* answered, so the list may be missing offline nodes the hub does know (D315).
|
|
33384
|
+
*
|
|
33385
|
+
* `name` is the history row's name (≤ 30 s behind a rename), or the id when
|
|
33386
|
+
* the history has none.
|
|
33387
|
+
*/
|
|
33388
|
+
var NodeDirectorySchema = object({
|
|
33389
|
+
nodes: array(object({
|
|
33390
|
+
id: string(),
|
|
33391
|
+
name: string(),
|
|
33392
|
+
isHub: boolean(),
|
|
33393
|
+
isOnline: boolean()
|
|
33394
|
+
})).readonly(),
|
|
33395
|
+
complete: boolean()
|
|
33396
|
+
});
|
|
33397
|
+
method(_void(), array(TopologyNodeSchema).readonly(), { auth: "admin" }), method(_void(), NodeDirectorySchema, { auth: "admin" }), method(NodeAddonInputSchema, SuccessSchema, {
|
|
33204
33398
|
kind: "mutation",
|
|
33205
33399
|
auth: "admin"
|
|
33206
33400
|
}), method(NodeAddonInputSchema, SuccessSchema, {
|
|
@@ -44726,6 +44920,12 @@ Object.freeze({
|
|
|
44726
44920
|
addonId: null,
|
|
44727
44921
|
access: "create"
|
|
44728
44922
|
},
|
|
44923
|
+
"nodes.directory": {
|
|
44924
|
+
capName: "nodes",
|
|
44925
|
+
capScope: "system",
|
|
44926
|
+
addonId: null,
|
|
44927
|
+
access: "view"
|
|
44928
|
+
},
|
|
44729
44929
|
"nodes.executeQuery": {
|
|
44730
44930
|
capName: "nodes",
|
|
44731
44931
|
capScope: "system",
|
|
@@ -44894,6 +45094,12 @@ Object.freeze({
|
|
|
44894
45094
|
addonId: null,
|
|
44895
45095
|
access: "view"
|
|
44896
45096
|
},
|
|
45097
|
+
"notificationRules.getRuleLastRuns": {
|
|
45098
|
+
capName: "notification-rules",
|
|
45099
|
+
capScope: "system",
|
|
45100
|
+
addonId: null,
|
|
45101
|
+
access: "view"
|
|
45102
|
+
},
|
|
44897
45103
|
"notificationRules.getTemplateCatalog": {
|
|
44898
45104
|
capName: "notification-rules",
|
|
44899
45105
|
capScope: "system",
|
|
@@ -50510,6 +50716,253 @@ function audioModeOf(value) {
|
|
|
50510
50716
|
return null;
|
|
50511
50717
|
}
|
|
50512
50718
|
new Set(["devices", "classes"]);
|
|
50719
|
+
/** Every filter, for the callers that must cover all four (guards, tests). */
|
|
50720
|
+
var NC_SYSTEM_EVENT_FILTER_KEYS = [
|
|
50721
|
+
"deviceIds",
|
|
50722
|
+
"deviceTypes",
|
|
50723
|
+
"nodeIds",
|
|
50724
|
+
"packageNames"
|
|
50725
|
+
];
|
|
50726
|
+
/**
|
|
50727
|
+
* Does `filter` say anything about `kind`?
|
|
50728
|
+
*
|
|
50729
|
+
* `false` means the filter is not part of this kind's vocabulary: the engine
|
|
50730
|
+
* ignores it and an editor hides its input. It never means "excluded".
|
|
50731
|
+
*/
|
|
50732
|
+
function systemEventFilterApplies(kind, filter) {
|
|
50733
|
+
switch (filter) {
|
|
50734
|
+
case "deviceIds": return kind.startsWith("device-") || kind.startsWith("stream-") || kind === "detection-blind" || kind === "alarm-triggered";
|
|
50735
|
+
case "deviceTypes": return kind.startsWith("device-") || kind === "detection-blind";
|
|
50736
|
+
case "nodeIds": return kind.startsWith("node-") || kind === "addon-crash-loop" || kind === "addon-update-available" || kind === "addon-updated" || kind === "server-update-available" || kind === "wrapper-update-available" || kind === "server-updated";
|
|
50737
|
+
case "packageNames": return kind.endsWith("update-available") || kind === "addon-updated" || kind === "server-updated";
|
|
50738
|
+
}
|
|
50739
|
+
}
|
|
50740
|
+
/**
|
|
50741
|
+
* WHICH FAMILY every system-event kind belongs to, and which narrowing filters
|
|
50742
|
+
* each family may carry: one table, read by the hub validator, by `ruleKindOf`
|
|
50743
|
+
* and by both rule editors (D637).
|
|
50744
|
+
*
|
|
50745
|
+
* A system rule used to be one editor for thirty-one kinds and five filters.
|
|
50746
|
+
* "Eventi di sistema" carried battery kinds under a liveness `deviceTypes` filter
|
|
50747
|
+
* and went silent for two weeks (D636). The three families are three questions:
|
|
50748
|
+
* about devices, about the installation, and about the alarm panel. A rule
|
|
50749
|
+
* answers one of them. The engine never needed to know, and it still does not:
|
|
50750
|
+
* a mixed stored rule keeps firing. Only AUTHORING is strict.
|
|
50751
|
+
*
|
|
50752
|
+
* The legacy `camera-*` tail has no family (`null`). It is parsed, never produced,
|
|
50753
|
+
* never offered.
|
|
50754
|
+
*/
|
|
50755
|
+
var NC_SYSTEM_EVENT_FAMILIES = [
|
|
50756
|
+
"device-events",
|
|
50757
|
+
"system",
|
|
50758
|
+
"alarm"
|
|
50759
|
+
];
|
|
50760
|
+
function isSystemEventFamily(value) {
|
|
50761
|
+
return NC_SYSTEM_EVENT_FAMILIES.some((family) => family === value);
|
|
50762
|
+
}
|
|
50763
|
+
/** Total over the enum: a kind added to the cap without a family fails tsc here. */
|
|
50764
|
+
var NC_SYSTEM_EVENT_FAMILY = {
|
|
50765
|
+
"device-online": "device-events",
|
|
50766
|
+
"device-offline": "device-events",
|
|
50767
|
+
"device-disabled": "device-events",
|
|
50768
|
+
"device-enabled": "device-events",
|
|
50769
|
+
"device-battery-low": "device-events",
|
|
50770
|
+
"device-battery-normal": "device-events",
|
|
50771
|
+
"device-consumable-low": "device-events",
|
|
50772
|
+
"device-consumable-normal": "device-events",
|
|
50773
|
+
"stream-online": "device-events",
|
|
50774
|
+
"stream-offline": "device-events",
|
|
50775
|
+
"detection-blind": "device-events",
|
|
50776
|
+
"node-online": "system",
|
|
50777
|
+
"node-offline": "system",
|
|
50778
|
+
"node-inference-unavailable": "system",
|
|
50779
|
+
"addon-crash-loop": "system",
|
|
50780
|
+
"addon-update-available": "system",
|
|
50781
|
+
"addon-updated": "system",
|
|
50782
|
+
"server-update-available": "system",
|
|
50783
|
+
"server-updated": "system",
|
|
50784
|
+
"wrapper-update-available": "system",
|
|
50785
|
+
"backup-completed": "system",
|
|
50786
|
+
"export-completed": "system",
|
|
50787
|
+
"alarm-triggered": "alarm",
|
|
50788
|
+
"alarm-armed": "alarm",
|
|
50789
|
+
"alarm-disarmed": "alarm",
|
|
50790
|
+
"alarm-arming": "alarm",
|
|
50791
|
+
"alarm-arm-refused": "alarm",
|
|
50792
|
+
"alarm-pending": "alarm",
|
|
50793
|
+
"alarm-rearmed": "alarm",
|
|
50794
|
+
"alarm-sensor-bypass": "alarm",
|
|
50795
|
+
"alarm-check-failed": "alarm",
|
|
50796
|
+
"camera-online": null,
|
|
50797
|
+
"camera-offline": null,
|
|
50798
|
+
"camera-disabled": null,
|
|
50799
|
+
"camera-enabled": null
|
|
50800
|
+
};
|
|
50801
|
+
new Map(Object.entries(NC_SYSTEM_EVENT_FAMILY));
|
|
50802
|
+
var NC_SYSTEM_EVENT_CONDITION_FILTER_KEYS = [...NC_SYSTEM_EVENT_FILTER_KEYS, "excludeDeviceIds"];
|
|
50803
|
+
/**
|
|
50804
|
+
* The filters a family may carry. The four base filters are the union of
|
|
50805
|
+
* `systemEventFilterApplies` over the family's kinds (the spec pins that
|
|
50806
|
+
* equality). `excludeDeviceIds` is a device-events filter only: an alarm is
|
|
50807
|
+
* narrowed to the camera that triggered it and excludes nothing.
|
|
50808
|
+
*/
|
|
50809
|
+
var NC_SYSTEM_EVENT_FAMILY_FILTERS = {
|
|
50810
|
+
"device-events": [
|
|
50811
|
+
"deviceIds",
|
|
50812
|
+
"excludeDeviceIds",
|
|
50813
|
+
"deviceTypes"
|
|
50814
|
+
],
|
|
50815
|
+
system: ["nodeIds", "packageNames"],
|
|
50816
|
+
alarm: ["deviceIds"]
|
|
50817
|
+
};
|
|
50818
|
+
var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
50819
|
+
{
|
|
50820
|
+
id: "device-state",
|
|
50821
|
+
family: "device-events",
|
|
50822
|
+
label: "Device state",
|
|
50823
|
+
kinds: [
|
|
50824
|
+
"device-offline",
|
|
50825
|
+
"device-online",
|
|
50826
|
+
"device-disabled",
|
|
50827
|
+
"device-enabled"
|
|
50828
|
+
]
|
|
50829
|
+
},
|
|
50830
|
+
{
|
|
50831
|
+
id: "streams",
|
|
50832
|
+
family: "device-events",
|
|
50833
|
+
label: "Streams",
|
|
50834
|
+
kinds: ["stream-offline", "stream-online"]
|
|
50835
|
+
},
|
|
50836
|
+
{
|
|
50837
|
+
id: "battery",
|
|
50838
|
+
family: "device-events",
|
|
50839
|
+
label: "Battery",
|
|
50840
|
+
kinds: ["device-battery-low", "device-battery-normal"]
|
|
50841
|
+
},
|
|
50842
|
+
{
|
|
50843
|
+
id: "consumables",
|
|
50844
|
+
family: "device-events",
|
|
50845
|
+
label: "Consumables",
|
|
50846
|
+
kinds: ["device-consumable-low", "device-consumable-normal"]
|
|
50847
|
+
},
|
|
50848
|
+
{
|
|
50849
|
+
id: "detection-blind",
|
|
50850
|
+
family: "device-events",
|
|
50851
|
+
label: "Detecting nothing",
|
|
50852
|
+
kinds: ["detection-blind"]
|
|
50853
|
+
},
|
|
50854
|
+
{
|
|
50855
|
+
id: "nodes",
|
|
50856
|
+
family: "system",
|
|
50857
|
+
label: "Nodes",
|
|
50858
|
+
kinds: [
|
|
50859
|
+
"node-offline",
|
|
50860
|
+
"node-online",
|
|
50861
|
+
"node-inference-unavailable"
|
|
50862
|
+
]
|
|
50863
|
+
},
|
|
50864
|
+
{
|
|
50865
|
+
id: "addons",
|
|
50866
|
+
family: "system",
|
|
50867
|
+
label: "Addons",
|
|
50868
|
+
kinds: [
|
|
50869
|
+
"addon-crash-loop",
|
|
50870
|
+
"addon-update-available",
|
|
50871
|
+
"addon-updated"
|
|
50872
|
+
]
|
|
50873
|
+
},
|
|
50874
|
+
{
|
|
50875
|
+
id: "updates",
|
|
50876
|
+
family: "system",
|
|
50877
|
+
label: "Server & container updates",
|
|
50878
|
+
kinds: [
|
|
50879
|
+
"server-update-available",
|
|
50880
|
+
"server-updated",
|
|
50881
|
+
"wrapper-update-available"
|
|
50882
|
+
]
|
|
50883
|
+
},
|
|
50884
|
+
{
|
|
50885
|
+
id: "backups-exports",
|
|
50886
|
+
family: "system",
|
|
50887
|
+
label: "Backups & exports",
|
|
50888
|
+
kinds: ["backup-completed", "export-completed"]
|
|
50889
|
+
},
|
|
50890
|
+
{
|
|
50891
|
+
id: "alarm",
|
|
50892
|
+
family: "alarm",
|
|
50893
|
+
label: "Alarm",
|
|
50894
|
+
kinds: NC_ALARM_SYSTEM_EVENT_KINDS
|
|
50895
|
+
}
|
|
50896
|
+
];
|
|
50897
|
+
function systemEventKindsOfFamily(family) {
|
|
50898
|
+
return NC_SYSTEM_EVENT_KIND_GROUP_SPECS.filter((g) => g.family === family).flatMap((g) => g.kinds);
|
|
50899
|
+
}
|
|
50900
|
+
/**
|
|
50901
|
+
* Why the hub refuses this condition on a new or updated rule. Empty = accepted.
|
|
50902
|
+
* Families are reported in `NC_SYSTEM_EVENT_FAMILIES` order, and filters in
|
|
50903
|
+
* `NC_SYSTEM_EVENT_CONDITION_FILTER_KEYS` order, so a refusal reads the same
|
|
50904
|
+
* every time.
|
|
50905
|
+
*/
|
|
50906
|
+
function systemEventFamilyProblems(condition) {
|
|
50907
|
+
if (condition === void 0 || condition.kinds.length === 0) return [{ code: "no-kinds" }];
|
|
50908
|
+
const problems = [];
|
|
50909
|
+
const present = /* @__PURE__ */ new Set();
|
|
50910
|
+
for (const kind of condition.kinds) {
|
|
50911
|
+
const family = NC_SYSTEM_EVENT_FAMILY[kind];
|
|
50912
|
+
if (family === null) problems.push({
|
|
50913
|
+
code: "legacy-kind",
|
|
50914
|
+
kind
|
|
50915
|
+
});
|
|
50916
|
+
else present.add(family);
|
|
50917
|
+
}
|
|
50918
|
+
const families = NC_SYSTEM_EVENT_FAMILIES.filter((f) => present.has(f));
|
|
50919
|
+
if (families.length > 1) problems.push({
|
|
50920
|
+
code: "mixed-families",
|
|
50921
|
+
families
|
|
50922
|
+
});
|
|
50923
|
+
const [family] = families;
|
|
50924
|
+
if (families.length !== 1 || family === void 0) return problems;
|
|
50925
|
+
const allowed = NC_SYSTEM_EVENT_FAMILY_FILTERS[family];
|
|
50926
|
+
for (const filter of NC_SYSTEM_EVENT_CONDITION_FILTER_KEYS) if (condition[filter] !== void 0 && !allowed.includes(filter)) problems.push({
|
|
50927
|
+
code: "filter-outside-family",
|
|
50928
|
+
filter,
|
|
50929
|
+
family
|
|
50930
|
+
});
|
|
50931
|
+
return problems;
|
|
50932
|
+
}
|
|
50933
|
+
function describeSystemEventFamilyProblem(problem) {
|
|
50934
|
+
switch (problem.code) {
|
|
50935
|
+
case "no-kinds": return "a system-event rule needs at least one event kind";
|
|
50936
|
+
case "legacy-kind": return `'${problem.kind}' is a legacy kind and cannot be authored`;
|
|
50937
|
+
case "mixed-families": return `event kinds span ${problem.families.join(" + ")} — one rule per family`;
|
|
50938
|
+
case "filter-outside-family": return `filter '${problem.filter}' is not allowed on a ${problem.family} rule`;
|
|
50939
|
+
}
|
|
50940
|
+
}
|
|
50941
|
+
/** Every kind a `system-event` rule can derive — the three families and `mixed`. */
|
|
50942
|
+
var NC_SYSTEM_RULE_KINDS = [
|
|
50943
|
+
"device-events",
|
|
50944
|
+
"system",
|
|
50945
|
+
"alarm",
|
|
50946
|
+
"mixed"
|
|
50947
|
+
];
|
|
50948
|
+
/** Is this a kind a `system-event` rule derives (any family, or `mixed`)? */
|
|
50949
|
+
function isSystemRuleKind(kind) {
|
|
50950
|
+
return NC_SYSTEM_RULE_KINDS.some((k) => k === kind);
|
|
50951
|
+
}
|
|
50952
|
+
/** The family a kind authors, or undefined (a camera kind, or `mixed`). */
|
|
50953
|
+
function systemFamilyOfKind(kind) {
|
|
50954
|
+
return isSystemEventFamily(kind) ? kind : void 0;
|
|
50955
|
+
}
|
|
50956
|
+
/** The delivery a system rule rides — named once, compared everywhere. */
|
|
50957
|
+
var NC_SYSTEM_DELIVERY = "system-event";
|
|
50958
|
+
/**
|
|
50959
|
+
* Is this a SYSTEM rule — one about the installation rather than about anything
|
|
50960
|
+
* a camera saw? Takes a plain `string` so a rule carrying a delivery this build
|
|
50961
|
+
* has never heard of still gets an answer instead of a type error.
|
|
50962
|
+
*/
|
|
50963
|
+
function isSystemDelivery(delivery) {
|
|
50964
|
+
return delivery === NC_SYSTEM_DELIVERY;
|
|
50965
|
+
}
|
|
50513
50966
|
NC_AUDIO_DEFAULTS.hitPercent, NC_AUDIO_DEFAULTS.samplingSeconds;
|
|
50514
50967
|
var WEEKDAY_TO_DAY = {
|
|
50515
50968
|
Sun: 0,
|
|
@@ -50571,6 +51024,66 @@ function isScheduleActive(schedule, atMs) {
|
|
|
50571
51024
|
}
|
|
50572
51025
|
return schedule.invert === true ? !inside : inside;
|
|
50573
51026
|
}
|
|
51027
|
+
var ARMED_WORD_PREFIX = "armed_";
|
|
51028
|
+
var ALARM_PANEL_CAP = "alarm-panel";
|
|
51029
|
+
var ALARM_PANEL_TRIGGER_METHOD = "trigger";
|
|
51030
|
+
/**
|
|
51031
|
+
* A rule belongs to the alarm when its `deviceState` gate names ANY device's
|
|
51032
|
+
* `armed_*` word, or an ENABLED `onTrigger` sequence pulls the alarm panel's
|
|
51033
|
+
* trigger (D630).
|
|
51034
|
+
*/
|
|
51035
|
+
function ruleBelongsToAlarm(rule) {
|
|
51036
|
+
if ((rule.conditions.deviceState?.states ?? []).some((s) => s.trim().toLowerCase().startsWith(ARMED_WORD_PREFIX))) return true;
|
|
51037
|
+
return (rule.onTrigger ?? []).some((sequence) => sequence.enabled && sequence.actions.some((step) => step.kind === "cap" && step.cap === ALARM_PANEL_CAP && step.method === ALARM_PANEL_TRIGGER_METHOD));
|
|
51038
|
+
}
|
|
51039
|
+
/**
|
|
51040
|
+
* WHICH WAY A BOOLEAN SENSOR MOVED — read off the one slice a sensor event
|
|
51041
|
+
* persists (D640 "a sensor rule fires on the raise, the clear, or both").
|
|
51042
|
+
*
|
|
51043
|
+
* A device-event rule over a flood sensor notified on BOTH edges: water
|
|
51044
|
+
* detected, and back to dry. `NcConditions.sensorTransition` lets the rule
|
|
51045
|
+
* name one edge; this file answers, for one `SensorEvent`, which edge it is.
|
|
51046
|
+
*
|
|
51047
|
+
* NOT A SECOND TABLE. The "which boolean of this cap counts as HIGH" question
|
|
51048
|
+
* already has one answer, `SOURCE_CAP_ACTIVE_FIELD`
|
|
51049
|
+
* (`catalogs/sensor-active-state.ts`, the doorbell's and the recorder's edge
|
|
51050
|
+
* table), and a sensor event names its kind, not its cap. So the table here is
|
|
51051
|
+
* DERIVED: event kind → cap (`EVENT_KIND_BY_CAP`) → that cap's active field.
|
|
51052
|
+
* Only kinds whose taxonomy category is `sensor` take part — a switch has an
|
|
51053
|
+
* `on` boolean too, but "it triggers / it clears" is not a sentence about a
|
|
51054
|
+
* light, and offering it there would be a knob with a misleading label.
|
|
51055
|
+
* `presence` is a WORD (`home` / `not_home` / a zone), not a boolean, and is
|
|
51056
|
+
* absent from the source table, so it is absent here.
|
|
51057
|
+
*
|
|
51058
|
+
* `undefined` = never guessed: a kind with no raise (a doorbell press, a
|
|
51059
|
+
* button, a cover), or a slice whose field is missing or not a boolean. The
|
|
51060
|
+
* engine then does NOT filter — a flood alert must not go silent because one
|
|
51061
|
+
* read came back unreadable (the same stance as the alarm's `sensorEdgeOf`).
|
|
51062
|
+
*
|
|
51063
|
+
* Pure, RN-safe: the viewer imports the support rule from here.
|
|
51064
|
+
*/
|
|
51065
|
+
/** Event kind → the boolean field of its cap slice that means "raised". */
|
|
51066
|
+
var NC_SENSOR_RAISED_FIELD_BY_KIND = Object.freeze(Object.fromEntries(Object.entries(EVENT_KIND_BY_CAP).flatMap(([capName, descriptor]) => {
|
|
51067
|
+
const field = SOURCE_CAP_ACTIVE_FIELD[capName];
|
|
51068
|
+
if (field === void 0 || descriptor.category !== "sensor") return [];
|
|
51069
|
+
return [[descriptor.kind, field]];
|
|
51070
|
+
})));
|
|
51071
|
+
/** The sensor kinds `sensorTransition` means something for. */
|
|
51072
|
+
var NC_SENSOR_TRANSITION_KINDS = Object.freeze(Object.keys(NC_SENSOR_RAISED_FIELD_BY_KIND));
|
|
51073
|
+
function normaliseKind(kind) {
|
|
51074
|
+
return kind.trim().toLowerCase();
|
|
51075
|
+
}
|
|
51076
|
+
/**
|
|
51077
|
+
* true = the sensor is raised (water, smoke, open, tampered…), false = it
|
|
51078
|
+
* cleared, undefined = this kind has no raise or the slice cannot say.
|
|
51079
|
+
*/
|
|
51080
|
+
function sensorRaisedOf(kind, value) {
|
|
51081
|
+
if (value === null) return void 0;
|
|
51082
|
+
const field = NC_SENSOR_RAISED_FIELD_BY_KIND[normaliseKind(kind)];
|
|
51083
|
+
if (field === void 0) return void 0;
|
|
51084
|
+
const raw = Object.entries(value).find(([key]) => key === field)?.[1];
|
|
51085
|
+
return typeof raw === "boolean" ? raw : void 0;
|
|
51086
|
+
}
|
|
50574
51087
|
var RULE_BODY_ONLY = ["body"];
|
|
50575
51088
|
var RULE_TEXT = ["title", "body"];
|
|
50576
51089
|
var BATTERY = ["device-battery-low", "device-battery-normal"];
|
|
@@ -51308,10 +51821,38 @@ var CAPTION_VARS = {
|
|
|
51308
51821
|
function onAxis(declared, asked) {
|
|
51309
51822
|
return declared === void 0 || asked === void 0 || declared.includes(asked);
|
|
51310
51823
|
}
|
|
51311
|
-
|
|
51312
|
-
|
|
51824
|
+
/**
|
|
51825
|
+
* Does a descriptor declared for `declared` kinds have a value for a rule of
|
|
51826
|
+
* `kind`?
|
|
51827
|
+
*
|
|
51828
|
+
* `system` on the WIRE stands for every system rule kind (D637): the served
|
|
51829
|
+
* catalog keeps the five pre-D637 tokens so installed viewers still parse it
|
|
51830
|
+
* (`NcTemplateVarKindSchema`), and the family split lives here, in the match.
|
|
51831
|
+
* Exported so the admin's local interpreter of the served catalog asks the
|
|
51832
|
+
* same question instead of restating it.
|
|
51833
|
+
*/
|
|
51834
|
+
function templateVarKindApplies(declared, kind) {
|
|
51835
|
+
if (declared === void 0 || kind === void 0) return true;
|
|
51836
|
+
if (declared.some((k) => k === kind)) return true;
|
|
51837
|
+
return isSystemRuleKind(kind) && declared.includes("system");
|
|
51838
|
+
}
|
|
51839
|
+
/**
|
|
51840
|
+
* Is a descriptor that names `systemEventKinds` on the event-kind axis of a
|
|
51841
|
+
* system rule? Read only for a system rule kind; any other kind ignores it.
|
|
51842
|
+
*
|
|
51843
|
+
* Event kinds chosen: the descriptor must speak about one of them. None chosen
|
|
51844
|
+
* yet: a FAMILY kind watches its own family's event kinds (a device-events rule
|
|
51845
|
+
* is never offered the alarm's `{{mode}}`), and `mixed` watches all of them.
|
|
51846
|
+
*/
|
|
51847
|
+
function templateVarSystemEventApplies(d, ctx) {
|
|
51848
|
+
if (!isSystemRuleKind(ctx.kind) || d.systemEventKinds === void 0) return true;
|
|
51849
|
+
const declared = d.systemEventKinds;
|
|
51313
51850
|
const asked = ctx.systemEventKinds ?? [];
|
|
51314
|
-
|
|
51851
|
+
if (asked.length > 0) return asked.some((k) => declared.includes(k));
|
|
51852
|
+
const family = ctx.kind === void 0 ? void 0 : systemFamilyOfKind(ctx.kind);
|
|
51853
|
+
if (family === void 0) return true;
|
|
51854
|
+
const own = systemEventKindsOfFamily(family);
|
|
51855
|
+
return declared.some((k) => own.includes(k));
|
|
51315
51856
|
}
|
|
51316
51857
|
/**
|
|
51317
51858
|
* The variables that have a value in `ctx`, in catalog order. Pure.
|
|
@@ -51325,27 +51866,13 @@ function templateVarsFor(ctx) {
|
|
|
51325
51866
|
const allowed = CAPTION_VARS[ctx.field];
|
|
51326
51867
|
return NC_TEMPLATE_VARS.filter((d) => d.families.includes(ctx.family) && allowed.includes(d.name) && d.dynamic === void 0);
|
|
51327
51868
|
}
|
|
51328
|
-
return NC_TEMPLATE_VARS.filter((d) => d.families.includes(ctx.family) && onAxis(d.fields, ctx.field) &&
|
|
51869
|
+
return NC_TEMPLATE_VARS.filter((d) => d.families.includes(ctx.family) && onAxis(d.fields, ctx.field) && templateVarKindApplies(d.kinds, ctx.kind) && onAxis(d.deliveries, ctx.delivery) && templateVarSystemEventApplies(d, ctx));
|
|
51329
51870
|
}
|
|
51330
51871
|
/** True when `name` is supplied in `ctx`, dynamic families (`count_<class>`) included. */
|
|
51331
51872
|
function isKnownTemplateVar(name, ctx) {
|
|
51332
51873
|
return templateVarsFor(ctx).some((d) => d.dynamic !== void 0 ? name.startsWith(d.dynamic.prefix) && name.length > d.dynamic.prefix.length : d.name === name);
|
|
51333
51874
|
}
|
|
51334
51875
|
/**
|
|
51335
|
-
* Does `filter` say anything about `kind`?
|
|
51336
|
-
*
|
|
51337
|
-
* `false` means the filter is not part of this kind's vocabulary: the engine
|
|
51338
|
-
* ignores it and an editor hides its input. It never means "excluded".
|
|
51339
|
-
*/
|
|
51340
|
-
function systemEventFilterApplies(kind, filter) {
|
|
51341
|
-
switch (filter) {
|
|
51342
|
-
case "deviceIds": return kind.startsWith("device-") || kind.startsWith("stream-") || kind === "detection-blind" || kind === "alarm-triggered" || kind === "export-completed";
|
|
51343
|
-
case "deviceTypes": return kind.startsWith("device-") || kind === "detection-blind";
|
|
51344
|
-
case "nodeIds": return kind.startsWith("node-") || kind === "addon-crash-loop" || kind === "addon-update-available" || kind === "addon-updated" || kind === "server-update-available" || kind === "wrapper-update-available" || kind === "server-updated";
|
|
51345
|
-
case "packageNames": return kind.endsWith("update-available") || kind === "addon-updated" || kind === "server-updated";
|
|
51346
|
-
}
|
|
51347
|
-
}
|
|
51348
|
-
/**
|
|
51349
51876
|
* TimelapseRule — the STANDALONE scheduled timelapse producer's rule model.
|
|
51350
51877
|
*
|
|
51351
51878
|
* Spec: `docs/superpowers/specs/2026-07-24-nc-occupancy-timelapse-design.md`
|
|
@@ -52547,6 +53074,12 @@ Object.defineProperty(exports, "NC_DEFAULT_SNOOZE_MINUTES", {
|
|
|
52547
53074
|
return NC_DEFAULT_SNOOZE_MINUTES;
|
|
52548
53075
|
}
|
|
52549
53076
|
});
|
|
53077
|
+
Object.defineProperty(exports, "NC_SENSOR_TRANSITION_KINDS", {
|
|
53078
|
+
enumerable: true,
|
|
53079
|
+
get: function() {
|
|
53080
|
+
return NC_SENSOR_TRANSITION_KINDS;
|
|
53081
|
+
}
|
|
53082
|
+
});
|
|
52550
53083
|
Object.defineProperty(exports, "NC_SNOOZE_MAX_MINUTES", {
|
|
52551
53084
|
enumerable: true,
|
|
52552
53085
|
get: function() {
|
|
@@ -52583,6 +53116,12 @@ Object.defineProperty(exports, "NcConditionDescriptorSchema", {
|
|
|
52583
53116
|
return NcConditionDescriptorSchema;
|
|
52584
53117
|
}
|
|
52585
53118
|
});
|
|
53119
|
+
Object.defineProperty(exports, "NcConditionsSchema", {
|
|
53120
|
+
enumerable: true,
|
|
53121
|
+
get: function() {
|
|
53122
|
+
return NcConditionsSchema;
|
|
53123
|
+
}
|
|
53124
|
+
});
|
|
52586
53125
|
Object.defineProperty(exports, "NcRuleInputSchema", {
|
|
52587
53126
|
enumerable: true,
|
|
52588
53127
|
get: function() {
|
|
@@ -52823,6 +53362,12 @@ Object.defineProperty(exports, "buildEventKindDescriptor", {
|
|
|
52823
53362
|
return buildEventKindDescriptor;
|
|
52824
53363
|
}
|
|
52825
53364
|
});
|
|
53365
|
+
Object.defineProperty(exports, "canonicalHash", {
|
|
53366
|
+
enumerable: true,
|
|
53367
|
+
get: function() {
|
|
53368
|
+
return canonicalHash;
|
|
53369
|
+
}
|
|
53370
|
+
});
|
|
52826
53371
|
Object.defineProperty(exports, "cosineSimilarity", {
|
|
52827
53372
|
enumerable: true,
|
|
52828
53373
|
get: function() {
|
|
@@ -52853,6 +53398,12 @@ Object.defineProperty(exports, "deriveRecordingMode", {
|
|
|
52853
53398
|
return deriveRecordingMode;
|
|
52854
53399
|
}
|
|
52855
53400
|
});
|
|
53401
|
+
Object.defineProperty(exports, "describeSystemEventFamilyProblem", {
|
|
53402
|
+
enumerable: true,
|
|
53403
|
+
get: function() {
|
|
53404
|
+
return describeSystemEventFamilyProblem;
|
|
53405
|
+
}
|
|
53406
|
+
});
|
|
52856
53407
|
Object.defineProperty(exports, "discriminatedUnion", {
|
|
52857
53408
|
enumerable: true,
|
|
52858
53409
|
get: function() {
|
|
@@ -52955,6 +53506,12 @@ Object.defineProperty(exports, "isSourceCap", {
|
|
|
52955
53506
|
return isSourceCap;
|
|
52956
53507
|
}
|
|
52957
53508
|
});
|
|
53509
|
+
Object.defineProperty(exports, "isSystemDelivery", {
|
|
53510
|
+
enumerable: true,
|
|
53511
|
+
get: function() {
|
|
53512
|
+
return isSystemDelivery;
|
|
53513
|
+
}
|
|
53514
|
+
});
|
|
52958
53515
|
Object.defineProperty(exports, "kebabToCamel", {
|
|
52959
53516
|
enumerable: true,
|
|
52960
53517
|
get: function() {
|
|
@@ -53063,12 +53620,24 @@ Object.defineProperty(exports, "resolvePoolMemoryPolicy", {
|
|
|
53063
53620
|
return resolvePoolMemoryPolicy;
|
|
53064
53621
|
}
|
|
53065
53622
|
});
|
|
53623
|
+
Object.defineProperty(exports, "ruleBelongsToAlarm", {
|
|
53624
|
+
enumerable: true,
|
|
53625
|
+
get: function() {
|
|
53626
|
+
return ruleBelongsToAlarm;
|
|
53627
|
+
}
|
|
53628
|
+
});
|
|
53066
53629
|
Object.defineProperty(exports, "sceneMonitorCapability", {
|
|
53067
53630
|
enumerable: true,
|
|
53068
53631
|
get: function() {
|
|
53069
53632
|
return sceneMonitorCapability;
|
|
53070
53633
|
}
|
|
53071
53634
|
});
|
|
53635
|
+
Object.defineProperty(exports, "sensorRaisedOf", {
|
|
53636
|
+
enumerable: true,
|
|
53637
|
+
get: function() {
|
|
53638
|
+
return sensorRaisedOf;
|
|
53639
|
+
}
|
|
53640
|
+
});
|
|
53072
53641
|
Object.defineProperty(exports, "sleep", {
|
|
53073
53642
|
enumerable: true,
|
|
53074
53643
|
get: function() {
|
|
@@ -53093,6 +53662,12 @@ Object.defineProperty(exports, "subKindsOf", {
|
|
|
53093
53662
|
return subKindsOf;
|
|
53094
53663
|
}
|
|
53095
53664
|
});
|
|
53665
|
+
Object.defineProperty(exports, "systemEventFamilyProblems", {
|
|
53666
|
+
enumerable: true,
|
|
53667
|
+
get: function() {
|
|
53668
|
+
return systemEventFamilyProblems;
|
|
53669
|
+
}
|
|
53670
|
+
});
|
|
53096
53671
|
Object.defineProperty(exports, "systemEventFilterApplies", {
|
|
53097
53672
|
enumerable: true,
|
|
53098
53673
|
get: function() {
|