@camstack/types 1.2.254 → 1.2.255

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/index.js CHANGED
@@ -18328,9 +18328,29 @@ var NcTestResultSchema = zod.z.object({
18328
18328
  className: zod.z.string().optional(),
18329
18329
  label: zod.z.string().optional()
18330
18330
  });
18331
- /** The five rule kinds, as data. `NcRuleKind` in `notification/rule-kinds.ts`
18332
- * is the same union; the template-vars spec pins the two together. */
18331
+ /** The rule kinds, as data. `NcRuleKind` in `notification/rule-kinds.ts` is the
18332
+ * same union; the template-vars spec pins the two together. `mixed` is DERIVED
18333
+ * (a stored system rule whose kinds span families, D637) and never authored. */
18333
18334
  var NcRuleKindSchema = zod.z.enum([
18335
+ "detection",
18336
+ "sensor",
18337
+ "occupancy",
18338
+ "sound",
18339
+ "device-events",
18340
+ "system",
18341
+ "alarm",
18342
+ "mixed"
18343
+ ]);
18344
+ /**
18345
+ * The kinds a SERVED template-variable descriptor may name: the five that
18346
+ * existed before D637, frozen. `getTemplateCatalog` ships `kinds` to every
18347
+ * installed viewer, and a viewer at `@camstack/types` 1.2.25x parses them with a
18348
+ * strict five-member enum — one `device-events` in one descriptor fails the
18349
+ * whole catalog parse. So the WIRE says `system`, and the MATCH widens it:
18350
+ * `templateVarKindApplies` reads a `system` descriptor as applying to every
18351
+ * system rule kind (`device-events`, `system`, `alarm`, `mixed`).
18352
+ */
18353
+ var NcTemplateVarKindSchema = zod.z.enum([
18334
18354
  "detection",
18335
18355
  "sensor",
18336
18356
  "occupancy",
@@ -18368,7 +18388,7 @@ var NcTemplateVarGroupSchema = zod.z.enum([
18368
18388
  *
18369
18389
  * `families` / `fields` / `kinds` / `deliveries` / `systemEventKinds` say WHERE
18370
18390
  * it has a value; absent = no restriction on that axis. `systemEventKinds` is
18371
- * read only for a `system` rule. `dynamic` declares a FAMILY of names
18391
+ * read only for a system-event rule (any family, or `mixed`). `dynamic` declares a FAMILY of names
18372
18392
  * (`count_<class>`): the descriptor's `name` is the example member.
18373
18393
  */
18374
18394
  var NcTemplateVarDescriptorSchema = zod.z.object({
@@ -18379,7 +18399,7 @@ var NcTemplateVarDescriptorSchema = zod.z.object({
18379
18399
  group: NcTemplateVarGroupSchema,
18380
18400
  families: zod.z.array(NcTemplateFamilySchema).min(1),
18381
18401
  fields: zod.z.array(NcTemplateFieldSchema).optional(),
18382
- kinds: zod.z.array(NcRuleKindSchema).optional(),
18402
+ kinds: zod.z.array(NcTemplateVarKindSchema).optional(),
18383
18403
  deliveries: zod.z.array(NcDeliverySchema).optional(),
18384
18404
  systemEventKinds: zod.z.array(NcSystemEventKindSchema).optional(),
18385
18405
  dynamic: zod.z.object({
@@ -35747,6 +35767,35 @@ var RenameNodeResultSchema = zod.z.object({
35747
35767
  name: zod.z.string()
35748
35768
  });
35749
35769
  /**
35770
+ * One row of the CHEAP node list (D637): what a node picker needs and nothing
35771
+ * else. Read from the hub's in-memory registry plus the durable node history.
35772
+ * No per-node RPC, unlike `topology`, which walks the whole cluster (32–51 s).
35773
+ */
35774
+ var NodeDirectoryEntrySchema = zod.z.object({
35775
+ id: zod.z.string(),
35776
+ name: zod.z.string(),
35777
+ isHub: zod.z.boolean(),
35778
+ isOnline: zod.z.boolean()
35779
+ });
35780
+ /**
35781
+ * The cheap node list. A consumer's rule for a STORED node id (a rule's
35782
+ * `nodeIds`) that is missing from `nodes`, whatever `complete` says: render it
35783
+ * as a removable chip labelled unknown, never drop it (D49). Even a complete
35784
+ * list omits a node that joined and left between two history captures, so a
35785
+ * missing id means "not known to the hub", never "removed". Only the operator
35786
+ * removes it.
35787
+ *
35788
+ * `complete` changes only the WORDING: `false` = no history read has ever
35789
+ * answered, so the list may be missing offline nodes the hub does know (D315).
35790
+ *
35791
+ * `name` is the history row's name (≤ 30 s behind a rename), or the id when
35792
+ * the history has none.
35793
+ */
35794
+ var NodeDirectorySchema = zod.z.object({
35795
+ nodes: zod.z.array(NodeDirectoryEntrySchema).readonly(),
35796
+ complete: zod.z.boolean()
35797
+ });
35798
+ /**
35750
35799
  * `nodes` is a **hub-centric** cluster-management cap: the hub hosts
35751
35800
  * the single provider and every per-node method (`getNodeAddons`,
35752
35801
  * `restartProcess`, `restartNode`, `undeployAddon`, …) takes `nodeId`
@@ -35765,6 +35814,12 @@ var nodesCapability = {
35765
35814
  nodeIdMode: "data",
35766
35815
  methods: {
35767
35816
  topology: require_sleep.method(zod.z.void(), zod.z.array(TopologyNodeSchema).readonly(), { auth: "admin" }),
35817
+ /**
35818
+ * The cheap node list for pickers (D637): the hub's in-memory registry plus
35819
+ * the durable node history, no per-node RPC. `complete: false` when the
35820
+ * history could not be read.
35821
+ */
35822
+ directory: require_sleep.method(zod.z.void(), NodeDirectorySchema, { auth: "admin" }),
35768
35823
  deployAddon: require_sleep.method(NodeAddonInputSchema, SuccessSchema, {
35769
35824
  kind: "mutation",
35770
35825
  auth: "admin"
@@ -52634,6 +52689,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
52634
52689
  addonId: null,
52635
52690
  access: "create"
52636
52691
  },
52692
+ "nodes.directory": {
52693
+ capName: "nodes",
52694
+ capScope: "system",
52695
+ addonId: null,
52696
+ access: "view"
52697
+ },
52637
52698
  "nodes.executeQuery": {
52638
52699
  capName: "nodes",
52639
52700
  capScope: "system",
@@ -59616,6 +59677,7 @@ function createSystemProxy(api) {
59616
59677
  networkQuality: { getAllStats: (input) => dispatch("networkQuality", "getAllStats", "query", input) },
59617
59678
  nodes: {
59618
59679
  topology: (input) => dispatch("nodes", "topology", "query", input),
59680
+ directory: (input) => dispatch("nodes", "directory", "query", input),
59619
59681
  deployAddon: (input) => dispatch("nodes", "deployAddon", "mutation", input),
59620
59682
  undeployAddon: (input) => dispatch("nodes", "undeployAddon", "mutation", input),
59621
59683
  restartAddon: (input) => dispatch("nodes", "restartAddon", "mutation", input),
@@ -60668,7 +60730,285 @@ function prepareNotification(caps, n) {
60668
60730
  };
60669
60731
  }
60670
60732
  //#endregion
60733
+ //#region src/notification/system-event-filters.ts
60734
+ /** Every filter, for the callers that must cover all four (guards, tests). */
60735
+ var NC_SYSTEM_EVENT_FILTER_KEYS = [
60736
+ "deviceIds",
60737
+ "deviceTypes",
60738
+ "nodeIds",
60739
+ "packageNames"
60740
+ ];
60741
+ /**
60742
+ * Does `filter` say anything about `kind`?
60743
+ *
60744
+ * `false` means the filter is not part of this kind's vocabulary: the engine
60745
+ * ignores it and an editor hides its input. It never means "excluded".
60746
+ */
60747
+ function systemEventFilterApplies(kind, filter) {
60748
+ switch (filter) {
60749
+ case "deviceIds": return kind.startsWith("device-") || kind.startsWith("stream-") || kind === "detection-blind" || kind === "alarm-triggered";
60750
+ case "deviceTypes": return kind.startsWith("device-") || kind === "detection-blind";
60751
+ 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";
60752
+ case "packageNames": return kind.endsWith("update-available") || kind === "addon-updated" || kind === "server-updated";
60753
+ }
60754
+ }
60755
+ /**
60756
+ * Does `filter` say anything about AT LEAST ONE of the selected kinds?
60757
+ *
60758
+ * The editor's question: a rule selects several kinds at once and renders one
60759
+ * filter input for the set, so a filter is shown when any selected kind can be
60760
+ * narrowed by it. The kinds it cannot narrow are then simply not narrowed —
60761
+ * which is the engine's half of the same rule.
60762
+ */
60763
+ function systemEventFilterAppliesToAnyKind(kinds, filter) {
60764
+ return kinds.some((kind) => systemEventFilterApplies(kind, filter));
60765
+ }
60766
+ //#endregion
60767
+ //#region src/notification/system-event-families.ts
60768
+ /**
60769
+ * WHICH FAMILY every system-event kind belongs to, and which narrowing filters
60770
+ * each family may carry: one table, read by the hub validator, by `ruleKindOf`
60771
+ * and by both rule editors (D637).
60772
+ *
60773
+ * A system rule used to be one editor for thirty-one kinds and five filters.
60774
+ * "Eventi di sistema" carried battery kinds under a liveness `deviceTypes` filter
60775
+ * and went silent for two weeks (D636). The three families are three questions:
60776
+ * about devices, about the installation, and about the alarm panel. A rule
60777
+ * answers one of them. The engine never needed to know, and it still does not:
60778
+ * a mixed stored rule keeps firing. Only AUTHORING is strict.
60779
+ *
60780
+ * The legacy `camera-*` tail has no family (`null`). It is parsed, never produced,
60781
+ * never offered.
60782
+ */
60783
+ var NC_SYSTEM_EVENT_FAMILIES = [
60784
+ "device-events",
60785
+ "system",
60786
+ "alarm"
60787
+ ];
60788
+ function isSystemEventFamily(value) {
60789
+ return NC_SYSTEM_EVENT_FAMILIES.some((family) => family === value);
60790
+ }
60791
+ /** Total over the enum: a kind added to the cap without a family fails tsc here. */
60792
+ var NC_SYSTEM_EVENT_FAMILY = {
60793
+ "device-online": "device-events",
60794
+ "device-offline": "device-events",
60795
+ "device-disabled": "device-events",
60796
+ "device-enabled": "device-events",
60797
+ "device-battery-low": "device-events",
60798
+ "device-battery-normal": "device-events",
60799
+ "device-consumable-low": "device-events",
60800
+ "device-consumable-normal": "device-events",
60801
+ "stream-online": "device-events",
60802
+ "stream-offline": "device-events",
60803
+ "detection-blind": "device-events",
60804
+ "node-online": "system",
60805
+ "node-offline": "system",
60806
+ "node-inference-unavailable": "system",
60807
+ "addon-crash-loop": "system",
60808
+ "addon-update-available": "system",
60809
+ "addon-updated": "system",
60810
+ "server-update-available": "system",
60811
+ "server-updated": "system",
60812
+ "wrapper-update-available": "system",
60813
+ "backup-completed": "system",
60814
+ "export-completed": "system",
60815
+ "alarm-triggered": "alarm",
60816
+ "alarm-armed": "alarm",
60817
+ "alarm-disarmed": "alarm",
60818
+ "alarm-arming": "alarm",
60819
+ "alarm-arm-refused": "alarm",
60820
+ "alarm-pending": "alarm",
60821
+ "alarm-rearmed": "alarm",
60822
+ "alarm-sensor-bypass": "alarm",
60823
+ "alarm-check-failed": "alarm",
60824
+ "camera-online": null,
60825
+ "camera-offline": null,
60826
+ "camera-disabled": null,
60827
+ "camera-enabled": null
60828
+ };
60829
+ /** Read by NAME, for kinds that arrive as plain strings (a newer hub, the viewer's mirror). */
60830
+ var FAMILY_BY_NAME = new Map(Object.entries(NC_SYSTEM_EVENT_FAMILY));
60831
+ var NC_SYSTEM_EVENT_CONDITION_FILTER_KEYS = [...NC_SYSTEM_EVENT_FILTER_KEYS, "excludeDeviceIds"];
60832
+ /**
60833
+ * The filters a family may carry. The four base filters are the union of
60834
+ * `systemEventFilterApplies` over the family's kinds (the spec pins that
60835
+ * equality). `excludeDeviceIds` is a device-events filter only: an alarm is
60836
+ * narrowed to the camera that triggered it and excludes nothing.
60837
+ */
60838
+ var NC_SYSTEM_EVENT_FAMILY_FILTERS = {
60839
+ "device-events": [
60840
+ "deviceIds",
60841
+ "excludeDeviceIds",
60842
+ "deviceTypes"
60843
+ ],
60844
+ system: ["nodeIds", "packageNames"],
60845
+ alarm: ["deviceIds"]
60846
+ };
60847
+ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
60848
+ {
60849
+ id: "device-state",
60850
+ family: "device-events",
60851
+ label: "Device state",
60852
+ kinds: [
60853
+ "device-offline",
60854
+ "device-online",
60855
+ "device-disabled",
60856
+ "device-enabled"
60857
+ ]
60858
+ },
60859
+ {
60860
+ id: "streams",
60861
+ family: "device-events",
60862
+ label: "Streams",
60863
+ kinds: ["stream-offline", "stream-online"]
60864
+ },
60865
+ {
60866
+ id: "battery",
60867
+ family: "device-events",
60868
+ label: "Battery",
60869
+ kinds: ["device-battery-low", "device-battery-normal"]
60870
+ },
60871
+ {
60872
+ id: "consumables",
60873
+ family: "device-events",
60874
+ label: "Consumables",
60875
+ kinds: ["device-consumable-low", "device-consumable-normal"]
60876
+ },
60877
+ {
60878
+ id: "detection-blind",
60879
+ family: "device-events",
60880
+ label: "Detecting nothing",
60881
+ kinds: ["detection-blind"]
60882
+ },
60883
+ {
60884
+ id: "nodes",
60885
+ family: "system",
60886
+ label: "Nodes",
60887
+ kinds: [
60888
+ "node-offline",
60889
+ "node-online",
60890
+ "node-inference-unavailable"
60891
+ ]
60892
+ },
60893
+ {
60894
+ id: "addons",
60895
+ family: "system",
60896
+ label: "Addons",
60897
+ kinds: [
60898
+ "addon-crash-loop",
60899
+ "addon-update-available",
60900
+ "addon-updated"
60901
+ ]
60902
+ },
60903
+ {
60904
+ id: "updates",
60905
+ family: "system",
60906
+ label: "Server & container updates",
60907
+ kinds: [
60908
+ "server-update-available",
60909
+ "server-updated",
60910
+ "wrapper-update-available"
60911
+ ]
60912
+ },
60913
+ {
60914
+ id: "backups-exports",
60915
+ family: "system",
60916
+ label: "Backups & exports",
60917
+ kinds: ["backup-completed", "export-completed"]
60918
+ },
60919
+ {
60920
+ id: "alarm",
60921
+ family: "alarm",
60922
+ label: "Alarm",
60923
+ kinds: NC_ALARM_SYSTEM_EVENT_KINDS
60924
+ }
60925
+ ];
60926
+ function systemEventKindsOfFamily(family) {
60927
+ return NC_SYSTEM_EVENT_KIND_GROUP_SPECS.filter((g) => g.family === family).flatMap((g) => g.kinds);
60928
+ }
60929
+ /** The kind names on an UNTYPED condition, or `undefined` when it has none. */
60930
+ function systemEventKindNamesOf(condition) {
60931
+ if (typeof condition !== "object" || condition === null || !("kinds" in condition)) return void 0;
60932
+ const kinds = condition.kinds;
60933
+ if (!Array.isArray(kinds)) return void 0;
60934
+ return kinds.filter((kind) => typeof kind === "string");
60935
+ }
60936
+ /**
60937
+ * One family, or `mixed`. Mixed covers kinds that span families, a legacy kind,
60938
+ * a kind this build does not know (it fails toward read-only and never toward
60939
+ * editable), and an empty selection (nothing to decide on).
60940
+ */
60941
+ function systemEventFamilyOf(kindNames) {
60942
+ const families = /* @__PURE__ */ new Set();
60943
+ for (const name of kindNames) {
60944
+ const family = FAMILY_BY_NAME.get(name);
60945
+ if (family === void 0 || family === null) return { kind: "mixed" };
60946
+ families.add(family);
60947
+ }
60948
+ const [only] = [...families];
60949
+ return families.size === 1 && only !== void 0 ? {
60950
+ kind: "family",
60951
+ family: only
60952
+ } : { kind: "mixed" };
60953
+ }
60954
+ /**
60955
+ * Why the hub refuses this condition on a new or updated rule. Empty = accepted.
60956
+ * Families are reported in `NC_SYSTEM_EVENT_FAMILIES` order, and filters in
60957
+ * `NC_SYSTEM_EVENT_CONDITION_FILTER_KEYS` order, so a refusal reads the same
60958
+ * every time.
60959
+ */
60960
+ function systemEventFamilyProblems(condition) {
60961
+ if (condition === void 0 || condition.kinds.length === 0) return [{ code: "no-kinds" }];
60962
+ const problems = [];
60963
+ const present = /* @__PURE__ */ new Set();
60964
+ for (const kind of condition.kinds) {
60965
+ const family = NC_SYSTEM_EVENT_FAMILY[kind];
60966
+ if (family === null) problems.push({
60967
+ code: "legacy-kind",
60968
+ kind
60969
+ });
60970
+ else present.add(family);
60971
+ }
60972
+ const families = NC_SYSTEM_EVENT_FAMILIES.filter((f) => present.has(f));
60973
+ if (families.length > 1) problems.push({
60974
+ code: "mixed-families",
60975
+ families
60976
+ });
60977
+ const [family] = families;
60978
+ if (families.length !== 1 || family === void 0) return problems;
60979
+ const allowed = NC_SYSTEM_EVENT_FAMILY_FILTERS[family];
60980
+ for (const filter of NC_SYSTEM_EVENT_CONDITION_FILTER_KEYS) if (condition[filter] !== void 0 && !allowed.includes(filter)) problems.push({
60981
+ code: "filter-outside-family",
60982
+ filter,
60983
+ family
60984
+ });
60985
+ return problems;
60986
+ }
60987
+ function describeSystemEventFamilyProblem(problem) {
60988
+ switch (problem.code) {
60989
+ case "no-kinds": return "a system-event rule needs at least one event kind";
60990
+ case "legacy-kind": return `'${problem.kind}' is a legacy kind and cannot be authored`;
60991
+ case "mixed-families": return `event kinds span ${problem.families.join(" + ")} — one rule per family`;
60992
+ case "filter-outside-family": return `filter '${problem.filter}' is not allowed on a ${problem.family} rule`;
60993
+ }
60994
+ }
60995
+ //#endregion
60671
60996
  //#region src/notification/rule-kinds.ts
60997
+ /** Every kind a `system-event` rule can derive — the three families and `mixed`. */
60998
+ var NC_SYSTEM_RULE_KINDS = [
60999
+ "device-events",
61000
+ "system",
61001
+ "alarm",
61002
+ "mixed"
61003
+ ];
61004
+ /** Is this a kind a `system-event` rule derives (any family, or `mixed`)? */
61005
+ function isSystemRuleKind(kind) {
61006
+ return NC_SYSTEM_RULE_KINDS.some((k) => k === kind);
61007
+ }
61008
+ /** The family a kind authors, or undefined (a camera kind, or `mixed`). */
61009
+ function systemFamilyOfKind(kind) {
61010
+ return isSystemEventFamily(kind) ? kind : void 0;
61011
+ }
60672
61012
  /**
60673
61013
  * Reasons, written once. Each names the SUBJECT FIELD the engine reads and
60674
61014
  * finds absent — that is what makes the exclusion checkable against the engine
@@ -60686,6 +61026,7 @@ var NC_RULE_KIND_SPECS = [
60686
61026
  kind: "detection",
60687
61027
  label: "Conditions",
60688
61028
  excluded: {},
61029
+ editable: true,
60689
61030
  carriesMedia: true,
60690
61031
  carriesSubjectCrop: true
60691
61032
  },
@@ -60694,6 +61035,7 @@ var NC_RULE_KIND_SPECS = [
60694
61035
  label: "Conditions",
60695
61036
  /** Same argument as `detection`: `occupancy` converts, it does not confuse. */
60696
61037
  excluded: {},
61038
+ editable: true,
60697
61039
  carriesMedia: true,
60698
61040
  carriesSubjectCrop: true,
60699
61041
  blurb: "A doorbell press or a linked sensor changing state. The picture comes from the camera the sensor is attributed to."
@@ -60707,6 +61049,7 @@ var NC_RULE_KIND_SPECS = [
60707
61049
  eventTypeTokens: NO_EVENT_TOKEN,
60708
61050
  source: OCCUPANCY_SOURCE
60709
61051
  },
61052
+ editable: true,
60710
61053
  carriesMedia: true,
60711
61054
  carriesSubjectCrop: true,
60712
61055
  blurb: "Fires when the count in a camera frame or a zone crosses your threshold and holds. Pick the camera first — the zone list is that camera’s."
@@ -60729,25 +61072,66 @@ var NC_RULE_KIND_SPECS = [
60729
61072
  plates: SOUND_NOT_A_PICTURE,
60730
61073
  source: AUDIO_SOURCE
60731
61074
  },
61075
+ editable: true,
60732
61076
  carriesMedia: true,
60733
61077
  carriesSubjectCrop: false,
60734
61078
  blurb: "Fires on a confirmed sampling window of audio, never on a picture. Name the sounds and/or keep a level threshold — with neither it can never match.",
60735
61079
  mediaBlurb: "A sound owns no frame, so the picture is a photograph of the camera taken at the moment of the match — the whole scene, never a crop. The GIF and the clip are cut around the same instant, from the camera."
60736
61080
  },
61081
+ {
61082
+ kind: "device-events",
61083
+ label: "Device events",
61084
+ discriminator: "systemEvent",
61085
+ excluded: {},
61086
+ editable: true,
61087
+ carriesMedia: false,
61088
+ carriesSubjectCrop: false,
61089
+ blurb: "A device or its stream going away or coming back, switched off or on, a battery or consumable running low, a camera detecting nothing. There is no frame to attach."
61090
+ },
60737
61091
  {
60738
61092
  kind: "system",
60739
- label: "Events",
61093
+ label: "System events",
61094
+ discriminator: "systemEvent",
61095
+ excluded: {},
61096
+ editable: true,
61097
+ carriesMedia: false,
61098
+ carriesSubjectCrop: false,
61099
+ blurb: "The installation itself: a node leaving, an addon crash-looping, an update available or installed, a backup or an export finishing."
61100
+ },
61101
+ {
61102
+ kind: "alarm",
61103
+ label: "Alarm",
61104
+ discriminator: "systemEvent",
61105
+ excluded: {},
61106
+ editable: true,
61107
+ carriesMedia: false,
61108
+ carriesSubjectCrop: false,
61109
+ blurb: "The alarm panel: refused, arming, armed, entry delay, triggered, re-armed, sensor bypass, disarmed.",
61110
+ mediaBlurb: "An alarm set off by a rule arrives with THAT rule's pictures, combined into one notification. This rule adds none of its own."
61111
+ },
61112
+ {
61113
+ kind: "mixed",
61114
+ label: "To recreate",
60740
61115
  discriminator: "systemEvent",
60741
61116
  excluded: {},
61117
+ editable: false,
60742
61118
  carriesMedia: false,
60743
61119
  carriesSubjectCrop: false,
60744
- blurb: "The installation itself: a camera or stream dropping, a node leaving, an update landing. There is no detection behind it and no frame to attach."
61120
+ blurb: "This rule mixes events from more than one family (device events, system, alarm). It keeps firing as it is, but it can no longer be edited: create one rule per family, then delete this one."
60745
61121
  }
60746
61122
  ];
60747
61123
  /** The spec for a kind. Total by construction — every member has an entry. */
60748
61124
  function ruleKindSpec(kind) {
60749
61125
  return NC_RULE_KIND_SPECS.find((s) => s.kind === kind) ?? NC_RULE_KIND_SPECS[0];
60750
61126
  }
61127
+ /**
61128
+ * Every kind a discriminator makes — one kind for `audio` and `occupancy`, the
61129
+ * whole system group for `systemEvent`. Empty for a condition that makes no
61130
+ * kind. See {@link NcRuleKindSpec.discriminator}.
61131
+ */
61132
+ function kindsForDiscriminator(discriminator) {
61133
+ return NC_RULE_KIND_SPECS.filter((s) => s.discriminator === discriminator).map((s) => s.kind);
61134
+ }
60751
61135
  /** The delivery a system rule rides — named once, compared everywhere. */
60752
61136
  var NC_SYSTEM_DELIVERY = "system-event";
60753
61137
  /**
@@ -60765,16 +61149,28 @@ function isSystemDelivery(delivery) {
60765
61149
  * the order below is the engine's own: `evaluateRule` checks the system branch
60766
61150
  * first, then the occupancy and audio gates. Takes a plain `delivery` string so
60767
61151
  * a trigger this build does not know still classifies (as `detection`, which is
60768
- * the read-only path's own fallback).
61152
+ * the read-only path's own fallback). A system rule classifies by the FAMILY of
61153
+ * its event kinds (D637) — see {@link systemRuleKindOf}.
60769
61154
  */
60770
61155
  function ruleKindOf(rule) {
60771
- if (isSystemDelivery(rule.delivery)) return "system";
61156
+ if (isSystemDelivery(rule.delivery)) return systemRuleKindOf(rule.conditions.systemEvent);
60772
61157
  if (rule.conditions.occupancy !== void 0 && rule.delivery === "device-event") return "occupancy";
60773
61158
  if (rule.conditions.audio !== void 0 && rule.delivery === "immediate") return "sound";
60774
61159
  if (rule.delivery === "device-event") return "sensor";
60775
61160
  return "detection";
60776
61161
  }
60777
61162
  /**
61163
+ * A system rule's kind: its one family, or `mixed` (D637).
61164
+ *
61165
+ * Takes the UNTYPED condition for the same reason {@link NcRuleConditionsSubject}
61166
+ * is structural. `mixed` covers kinds across families, a legacy or unknown kind,
61167
+ * and no kinds at all — it fails toward read-only, never toward editable.
61168
+ */
61169
+ function systemRuleKindOf(condition) {
61170
+ const verdict = systemEventFamilyOf(systemEventKindNamesOf(condition) ?? []);
61171
+ return verdict.kind === "family" ? verdict.family : "mixed";
61172
+ }
61173
+ /**
60778
61174
  * Is this condition visible — and authorable — for a rule of this kind?
60779
61175
  *
60780
61176
  * The COMPOSITION, and the only function that decides it: `appliesTo` is the
@@ -60815,35 +61211,64 @@ var NC_RULE_SECTIONS = [
60815
61211
  label: "All rules",
60816
61212
  blurb: "Every notification rule, whatever its trigger. Each rule picks a trigger, matches conditions and fans out to one or more delivery targets.",
60817
61213
  newRuleLabel: "New rule",
60818
- emptyHint: "No notification rules yet. Create one to be told what your cameras see."
61214
+ emptyHint: "No notification rules yet. Create one to be told what your cameras see.",
61215
+ creatable: true
60819
61216
  },
60820
61217
  {
60821
61218
  key: "detection",
60822
61219
  label: "Detections & devices",
60823
61220
  blurb: "Rules driven by what the cameras and sensors SEE — detections, tracks, doorbell presses and package events.",
60824
61221
  newRuleLabel: "New detection rule",
60825
- emptyHint: "No detection rules yet. Create one to be told what your cameras see."
61222
+ emptyHint: "No detection rules yet. Create one to be told what your cameras see.",
61223
+ creatable: true
60826
61224
  },
60827
61225
  {
60828
61226
  key: "audio",
60829
61227
  label: "Sound",
60830
61228
  blurb: "Rules on what the cameras HEAR: a sustained window of sound loud enough, or classified as one of the sounds you name. A sound rule fires only on a confirmed sampling window, never on a picture.",
60831
61229
  newRuleLabel: "New sound rule",
60832
- emptyHint: "No sound rules yet. A new sound rule opens on the sound condition already filled in with a level threshold, so you only have to name the sounds and the targets."
61230
+ emptyHint: "No sound rules yet. A new sound rule opens on the sound condition already filled in with a level threshold, so you only have to name the sounds and the targets.",
61231
+ creatable: true
60833
61232
  },
60834
61233
  {
60835
61234
  key: "occupancy",
60836
61235
  label: "Occupancy",
60837
61236
  blurb: "Rules on how many objects are in a camera frame or a zone, and for how long: \"the driveway became occupied\", \"the garden emptied\".",
60838
61237
  newRuleLabel: "New occupancy rule",
60839
- emptyHint: "No occupancy rules yet. A new occupancy rule opens on the occupancy condition; pick the camera first, then the zone and the count."
61238
+ emptyHint: "No occupancy rules yet. A new occupancy rule opens on the occupancy condition; pick the camera first, then the zone and the count.",
61239
+ creatable: true
61240
+ },
61241
+ {
61242
+ key: "device-events",
61243
+ label: "Device events",
61244
+ blurb: "Rules about your devices: offline or back, switched off or on, a stream dropping, a battery or consumable running low, a camera detecting nothing.",
61245
+ newRuleLabel: "New device-event rule",
61246
+ emptyHint: "No device-event rules yet. These tell you when a device drops, a battery runs low or a camera goes blind.",
61247
+ creatable: true
60840
61248
  },
60841
61249
  {
60842
61250
  key: "system",
60843
61251
  label: "System events",
60844
- blurb: "Rules about the installation itself: a camera or stream dropping, a node leaving the cluster, an addon or server update becoming available. These carry no image and are not tied to a detection.",
61252
+ blurb: "Rules about the installation: a node leaving the cluster, an addon crash-looping, an update available or installed, a backup or export finishing.",
60845
61253
  newRuleLabel: "New system rule",
60846
- emptyHint: "No system-event rules yet. These tell you when a camera drops, a node leaves or an update lands."
61254
+ emptyHint: "No system rules yet. These tell you when a node leaves, an update lands or a backup finishes.",
61255
+ creatable: true
61256
+ },
61257
+ {
61258
+ key: "alarm",
61259
+ label: "Alarm",
61260
+ blurb: "Rules about the alarm panel: arming, armed, triggered, disarmed, and the refusals in between.",
61261
+ newRuleLabel: "New alarm rule",
61262
+ emptyHint: "No alarm rules yet. These tell you when the alarm arms, goes off or is disarmed.",
61263
+ creatable: true
61264
+ },
61265
+ {
61266
+ key: "mixed",
61267
+ label: "To recreate",
61268
+ blurb: "System rules authored before the three families existed. Each mixes families, keeps firing as it is, and can only be read or deleted: recreate it as one rule per family.",
61269
+ newRuleLabel: "New rule",
61270
+ emptyHint: "Nothing to recreate.",
61271
+ creatable: false
60847
61272
  }
60848
61273
  ];
60849
61274
  /** The section for a key, or `undefined` — the lookup behind every label. */
@@ -60866,8 +61291,9 @@ function isOccupancyRule(subject) {
60866
61291
  * Does a rule belong in this section?
60867
61292
  *
60868
61293
  * `all` always matches — a section that hides a rule is how an operator
60869
- * concludes it was deleted. The other four PARTITION the list: sound and
60870
- * occupancy are claimed by their condition, system by its trigger, and
61294
+ * concludes it was deleted. The others PARTITION the list: sound and
61295
+ * occupancy are claimed by their condition, a system-event rule by its trigger
61296
+ * and then by the family of its event kinds (or `mixed`, D637), and
60871
61297
  * everything left over — including a trigger this build has never heard of —
60872
61298
  * counts as a detection rule so it stays visible somewhere.
60873
61299
  *
@@ -60879,21 +61305,23 @@ function isOccupancyRule(subject) {
60879
61305
  */
60880
61306
  function ruleMatchesSection(subject, section) {
60881
61307
  if (section === "all") return true;
60882
- if (section === "system") return isSystemDelivery(subject.delivery);
61308
+ if (isSystemDelivery(subject.delivery)) return ruleKindOf(subject) === section;
60883
61309
  if (section === "audio") return isAudioRule(subject);
60884
61310
  if (section === "occupancy") return isOccupancyRule(subject);
60885
- return !isSystemDelivery(subject.delivery) && !isAudioRule(subject) && !isOccupancyRule(subject);
61311
+ if (section === "detection") return !isAudioRule(subject) && !isOccupancyRule(subject);
61312
+ return false;
60886
61313
  }
60887
61314
  /**
60888
61315
  * Which section OWNS this rule — the counter behind a section strip.
60889
61316
  *
60890
- * Derived from {@link ruleMatchesSection} rather than restated, so the strip's
60891
- * counts and the strip's contents can never disagree.
61317
+ * The same order as {@link ruleMatchesSection} — trigger first, then the
61318
+ * discriminating condition — and the section spec asserts the two agree on
61319
+ * every subject, so the strip's counts and its contents cannot disagree.
60892
61320
  */
60893
61321
  function ruleSectionOf(subject) {
60894
- if (ruleMatchesSection(subject, "system")) return "system";
60895
- if (ruleMatchesSection(subject, "audio")) return "audio";
60896
- if (ruleMatchesSection(subject, "occupancy")) return "occupancy";
61322
+ if (isSystemDelivery(subject.delivery)) return systemRuleKindOf(subject.conditions.systemEvent);
61323
+ if (isAudioRule(subject)) return "audio";
61324
+ if (isOccupancyRule(subject)) return "occupancy";
60897
61325
  return "detection";
60898
61326
  }
60899
61327
  /**
@@ -60931,9 +61359,17 @@ var NC_AUDIO_SEED = {
60931
61359
  };
60932
61360
  function ruleSeedForSection(section) {
60933
61361
  switch (section) {
61362
+ case "device-events": return {
61363
+ delivery: NC_SYSTEM_DELIVERY,
61364
+ conditions: { systemEvent: { kinds: ["device-offline", "device-online"] } }
61365
+ };
60934
61366
  case "system": return {
60935
61367
  delivery: NC_SYSTEM_DELIVERY,
60936
- conditions: {}
61368
+ conditions: { systemEvent: { kinds: ["node-offline", "node-online"] } }
61369
+ };
61370
+ case "alarm": return {
61371
+ delivery: NC_SYSTEM_DELIVERY,
61372
+ conditions: { systemEvent: { kinds: ["alarm-triggered"] } }
60937
61373
  };
60938
61374
  case "audio": return {
60939
61375
  delivery: "immediate",
@@ -60975,7 +61411,7 @@ var EDITOR_SECTION_LABELS = {
60975
61411
  *
60976
61412
  * Two rules, both of them about a control that would decide nothing:
60977
61413
  *
60978
- * - a `system-event` rule has no device scope — `conditions.devices` is not
61414
+ * - a system-event rule (any family) has no device scope — `conditions.devices` is not
60979
61415
  * evaluated for it and the input builder refuses to write it — so the
60980
61416
  * Cameras section is DROPPED rather than shown and ignored;
60981
61417
  * - a sound or occupancy rule is NAMED on its conditions section. Neither has
@@ -60993,7 +61429,7 @@ function ruleEditorSectionsForKind(kind) {
60993
61429
  const spec = ruleKindSpec(kind);
60994
61430
  const sections = [];
60995
61431
  for (const key of NC_RULE_EDITOR_SECTION_ORDER) {
60996
- if (key === "devices" && kind === "system") continue;
61432
+ if (key === "devices" && isSystemRuleKind(kind)) continue;
60997
61433
  sections.push({
60998
61434
  key,
60999
61435
  label: key === "conditions" ? spec.label : EDITOR_SECTION_LABELS[key]
@@ -61802,10 +62238,38 @@ var CAPTION_VARS = {
61802
62238
  function onAxis(declared, asked) {
61803
62239
  return declared === void 0 || asked === void 0 || declared.includes(asked);
61804
62240
  }
61805
- function onSystemAxis(d, ctx) {
61806
- if (ctx.kind !== "system" || d.systemEventKinds === void 0) return true;
62241
+ /**
62242
+ * Does a descriptor declared for `declared` kinds have a value for a rule of
62243
+ * `kind`?
62244
+ *
62245
+ * `system` on the WIRE stands for every system rule kind (D637): the served
62246
+ * catalog keeps the five pre-D637 tokens so installed viewers still parse it
62247
+ * (`NcTemplateVarKindSchema`), and the family split lives here, in the match.
62248
+ * Exported so the admin's local interpreter of the served catalog asks the
62249
+ * same question instead of restating it.
62250
+ */
62251
+ function templateVarKindApplies(declared, kind) {
62252
+ if (declared === void 0 || kind === void 0) return true;
62253
+ if (declared.some((k) => k === kind)) return true;
62254
+ return isSystemRuleKind(kind) && declared.includes("system");
62255
+ }
62256
+ /**
62257
+ * Is a descriptor that names `systemEventKinds` on the event-kind axis of a
62258
+ * system rule? Read only for a system rule kind; any other kind ignores it.
62259
+ *
62260
+ * Event kinds chosen: the descriptor must speak about one of them. None chosen
62261
+ * yet: a FAMILY kind watches its own family's event kinds (a device-events rule
62262
+ * is never offered the alarm's `{{mode}}`), and `mixed` watches all of them.
62263
+ */
62264
+ function templateVarSystemEventApplies(d, ctx) {
62265
+ if (!isSystemRuleKind(ctx.kind) || d.systemEventKinds === void 0) return true;
62266
+ const declared = d.systemEventKinds;
61807
62267
  const asked = ctx.systemEventKinds ?? [];
61808
- return asked.length === 0 || asked.some((k) => d.systemEventKinds?.includes(k) === true);
62268
+ if (asked.length > 0) return asked.some((k) => declared.includes(k));
62269
+ const family = ctx.kind === void 0 ? void 0 : systemFamilyOfKind(ctx.kind);
62270
+ if (family === void 0) return true;
62271
+ const own = systemEventKindsOfFamily(family);
62272
+ return declared.some((k) => own.includes(k));
61809
62273
  }
61810
62274
  /**
61811
62275
  * The variables that have a value in `ctx`, in catalog order. Pure.
@@ -61819,45 +62283,85 @@ function templateVarsFor(ctx) {
61819
62283
  const allowed = CAPTION_VARS[ctx.field];
61820
62284
  return NC_TEMPLATE_VARS.filter((d) => d.families.includes(ctx.family) && allowed.includes(d.name) && d.dynamic === void 0);
61821
62285
  }
61822
- return NC_TEMPLATE_VARS.filter((d) => d.families.includes(ctx.family) && onAxis(d.fields, ctx.field) && onAxis(d.kinds, ctx.kind) && onAxis(d.deliveries, ctx.delivery) && onSystemAxis(d, ctx));
62286
+ 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));
61823
62287
  }
61824
62288
  /** True when `name` is supplied in `ctx`, dynamic families (`count_<class>`) included. */
61825
62289
  function isKnownTemplateVar(name, ctx) {
61826
62290
  return templateVarsFor(ctx).some((d) => d.dynamic !== void 0 ? name.startsWith(d.dynamic.prefix) && name.length > d.dynamic.prefix.length : d.name === name);
61827
62291
  }
61828
62292
  //#endregion
61829
- //#region src/notification/system-event-filters.ts
61830
- /** Every filter, for the callers that must cover all four (guards, tests). */
61831
- var NC_SYSTEM_EVENT_FILTER_KEYS = [
61832
- "deviceIds",
61833
- "deviceTypes",
61834
- "nodeIds",
61835
- "packageNames"
61836
- ];
62293
+ //#region src/notification/scope-picker-items.ts
62294
+ function nodePickerItems(nodes) {
62295
+ return nodes.map((node) => ({
62296
+ id: node.id,
62297
+ name: node.name,
62298
+ type: node.isHub ? "hub" : "agent",
62299
+ location: node.isOnline ? "online" : "offline",
62300
+ ...node.name !== node.id ? { detail: node.id } : {}
62301
+ }));
62302
+ }
61837
62303
  /**
61838
- * Does `filter` say anything about `kind`?
61839
- *
61840
- * `false` means the filter is not part of this kind's vocabulary: the engine
61841
- * ignores it and an editor hides its input. It never means "excluded".
61842
- */
61843
- function systemEventFilterApplies(kind, filter) {
61844
- switch (filter) {
61845
- case "deviceIds": return kind.startsWith("device-") || kind.startsWith("stream-") || kind === "detection-blind" || kind === "alarm-triggered" || kind === "export-completed";
61846
- case "deviceTypes": return kind.startsWith("device-") || kind === "detection-blind";
61847
- 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";
61848
- case "packageNames": return kind.endsWith("update-available") || kind === "addon-updated" || kind === "server-updated";
61849
- }
62304
+ * The server's own package name: `server-update-available` / `server-updated`
62305
+ * carry it, and `addons.listPackages` does not list it.
62306
+ */
62307
+ var NC_SERVER_PACKAGE_NAME = "@camstack/server";
62308
+ /**
62309
+ * Every package name an update EVENT carries as `packageName`, one per
62310
+ * producer. The package picker offers each of them whether or not
62311
+ * `addons.listPackages` lists it, because a rule scoped to a name no event
62312
+ * carries can never fire (and one an event carries must be pickable).
62313
+ *
62314
+ * - `@camstack/server` — `server-update-available` / `server-updated`: the hub
62315
+ * root package (`HUB_ROOT_SPEC.packageName`, `@camstack/node-root`).
62316
+ * - `@camstack/system` — `server-update-available` from the framework check,
62317
+ * which checks `[SYSTEM_PACKAGE]` only (`AddonPackageService.listFrameworkPackages`).
62318
+ * `@camstack/types` / `@camstack/sdk` are framework packages for upload
62319
+ * routing but are never announced, so they are NOT here.
62320
+ * - `camstack-wrapper` — `wrapper-update-available` (`WRAPPER_PACKAGE_NAME`,
62321
+ * `wrapper-update-checker.ts`).
62322
+ *
62323
+ * Types cannot import those producers; the backend spec
62324
+ * `core/updates/__tests__/update-event-package-names.spec.ts` pins each literal
62325
+ * to its producer constant. This is a picker list, never a routing list.
62326
+ */
62327
+ var NC_UPDATE_EVENT_PACKAGE_NAMES = [
62328
+ NC_SERVER_PACKAGE_NAME,
62329
+ "@camstack/system",
62330
+ "camstack-wrapper"
62331
+ ];
62332
+ var UPDATE_EVENT_PACKAGE_TYPE = {
62333
+ "@camstack/server": "server",
62334
+ "@camstack/system": "framework",
62335
+ "camstack-wrapper": "wrapper"
62336
+ };
62337
+ function isUpdateEventPackageName(name) {
62338
+ return NC_UPDATE_EVENT_PACKAGE_NAMES.some((pinned) => pinned === name);
61850
62339
  }
61851
62340
  /**
61852
- * Does `filter` say anything about AT LEAST ONE of the selected kinds?
61853
- *
61854
- * The editor's question: a rule selects several kinds at once and renders one
61855
- * filter input for the set, so a filter is shown when any selected kind can be
61856
- * narrowed by it. The kinds it cannot narrow are then simply not narrowed —
61857
- * which is the engine's half of the same rule.
62341
+ * Every update-event package first (always offered: an event carries it), in
62342
+ * `NC_UPDATE_EVENT_PACKAGE_NAMES` order, then the installed addons sorted by
62343
+ * name. An installed version is the second line.
61858
62344
  */
61859
- function systemEventFilterAppliesToAnyKind(kinds, filter) {
61860
- return kinds.some((kind) => systemEventFilterApplies(kind, filter));
62345
+ function packagePickerItems(packages) {
62346
+ const versions = new Map(packages.map((pkg) => [pkg.name, pkg.version]));
62347
+ const pinned = NC_UPDATE_EVENT_PACKAGE_NAMES.map((name) => {
62348
+ const version = versions.get(name);
62349
+ return {
62350
+ id: name,
62351
+ name,
62352
+ type: UPDATE_EVENT_PACKAGE_TYPE[name],
62353
+ location: null,
62354
+ ...version !== void 0 ? { detail: version } : {}
62355
+ };
62356
+ });
62357
+ const addons = packages.filter((pkg) => !isUpdateEventPackageName(pkg.name)).map((pkg) => ({
62358
+ id: pkg.name,
62359
+ name: pkg.name,
62360
+ type: "addon",
62361
+ location: null,
62362
+ detail: pkg.version
62363
+ })).sort((a, b) => a.name.localeCompare(b.name));
62364
+ return [...pinned, ...addons];
61861
62365
  }
61862
62366
  //#endregion
61863
62367
  //#region src/notification/timelapse-rule.ts
@@ -65442,11 +65946,19 @@ exports.NC_RULE_CLEARABLE_KEYS = NC_RULE_CLEARABLE_KEYS;
65442
65946
  exports.NC_RULE_EDITOR_SECTION_ORDER = NC_RULE_EDITOR_SECTION_ORDER;
65443
65947
  exports.NC_RULE_KIND_SPECS = NC_RULE_KIND_SPECS;
65444
65948
  exports.NC_RULE_SECTIONS = NC_RULE_SECTIONS;
65949
+ exports.NC_SERVER_PACKAGE_NAME = NC_SERVER_PACKAGE_NAME;
65445
65950
  exports.NC_SNOOZE_MAX_MINUTES = NC_SNOOZE_MAX_MINUTES;
65446
65951
  exports.NC_SYSTEM_DELIVERY = NC_SYSTEM_DELIVERY;
65952
+ exports.NC_SYSTEM_EVENT_CONDITION_FILTER_KEYS = NC_SYSTEM_EVENT_CONDITION_FILTER_KEYS;
65953
+ exports.NC_SYSTEM_EVENT_FAMILIES = NC_SYSTEM_EVENT_FAMILIES;
65954
+ exports.NC_SYSTEM_EVENT_FAMILY = NC_SYSTEM_EVENT_FAMILY;
65955
+ exports.NC_SYSTEM_EVENT_FAMILY_FILTERS = NC_SYSTEM_EVENT_FAMILY_FILTERS;
65447
65956
  exports.NC_SYSTEM_EVENT_FILTER_KEYS = NC_SYSTEM_EVENT_FILTER_KEYS;
65957
+ exports.NC_SYSTEM_EVENT_KIND_GROUP_SPECS = NC_SYSTEM_EVENT_KIND_GROUP_SPECS;
65958
+ exports.NC_SYSTEM_RULE_KINDS = NC_SYSTEM_RULE_KINDS;
65448
65959
  exports.NC_TAXONOMY = NC_TAXONOMY;
65449
65960
  exports.NC_TEMPLATE_VARS = NC_TEMPLATE_VARS;
65961
+ exports.NC_UPDATE_EVENT_PACKAGE_NAMES = NC_UPDATE_EVENT_PACKAGE_NAMES;
65450
65962
  exports.NETWORK_LINK_TYPES = NETWORK_LINK_TYPES;
65451
65963
  exports.NETWORK_LINK_UNKNOWN = NETWORK_LINK_UNKNOWN;
65452
65964
  exports.NativeCropBboxSchema = NativeCropBboxSchema;
@@ -65526,6 +66038,7 @@ exports.NcTemplatePreviewSchema = NcTemplatePreviewSchema;
65526
66038
  exports.NcTemplateVarContextSchema = NcTemplateVarContextSchema;
65527
66039
  exports.NcTemplateVarDescriptorSchema = NcTemplateVarDescriptorSchema;
65528
66040
  exports.NcTemplateVarGroupSchema = NcTemplateVarGroupSchema;
66041
+ exports.NcTemplateVarKindSchema = NcTemplateVarKindSchema;
65529
66042
  exports.NcTestResultSchema = NcTestResultSchema;
65530
66043
  exports.NcThrottleGranularitySchema = NcThrottleGranularitySchema;
65531
66044
  exports.NcThrottleSchema = NcThrottleSchema;
@@ -65534,6 +66047,8 @@ exports.NetworkAccessStatusSchema = NetworkAccessStatusSchema;
65534
66047
  exports.NetworkAddressSchema = NetworkAddressSchema;
65535
66048
  exports.NetworkEndpointSchema = NetworkEndpointSchema;
65536
66049
  exports.NetworkLinkStatusSchema = NetworkLinkStatusSchema;
66050
+ exports.NodeDirectoryEntrySchema = NodeDirectoryEntrySchema;
66051
+ exports.NodeDirectorySchema = NodeDirectorySchema;
65537
66052
  exports.NotificationActionIconSchema = NotificationActionIconSchema;
65538
66053
  exports.NotificationActionSchema = NotificationActionSchema;
65539
66054
  exports.NotificationFormatSchema = NotificationFormatSchema;
@@ -66129,6 +66644,7 @@ exports.describeCustomActions = require_sleep.describeCustomActions;
66129
66644
  exports.describeModelVariant = describeModelVariant;
66130
66645
  exports.describeOnboardClamp = describeOnboardClamp;
66131
66646
  exports.describeOnboardRefusal = describeOnboardRefusal;
66647
+ exports.describeSystemEventFamilyProblem = describeSystemEventFamilyProblem;
66132
66648
  exports.detectAccessRole = detectAccessRole;
66133
66649
  exports.detectionPipelineCapability = detectionPipelineCapability;
66134
66650
  exports.deviceAdminLinkCapability = deviceAdminLinkCapability;
@@ -66243,10 +66759,13 @@ exports.isSoftwareDecode = require_canonical_hash.isSoftwareDecode;
66243
66759
  exports.isSourceCap = isSourceCap;
66244
66760
  exports.isStorageLocationMode = isStorageLocationMode;
66245
66761
  exports.isSystemDelivery = isSystemDelivery;
66762
+ exports.isSystemEventFamily = isSystemEventFamily;
66763
+ exports.isSystemRuleKind = isSystemRuleKind;
66246
66764
  exports.isVoidInput = isVoidInput;
66247
66765
  exports.ituDbfsFromPreEpoch = ituDbfsFromPreEpoch;
66248
66766
  exports.jobKindSchema = jobKindSchema;
66249
66767
  exports.kebabToCamel = kebabToCamel;
66768
+ exports.kindsForDiscriminator = kindsForDiscriminator;
66250
66769
  exports.knownValues = knownValues;
66251
66770
  exports.lawnMowerControlCapability = lawnMowerControlCapability;
66252
66771
  exports.legacyAutoLinkIds = legacyAutoLinkIds;
@@ -66299,6 +66818,7 @@ exports.navigationCapability = navigationCapability;
66299
66818
  exports.networkAccessCapability = networkAccessCapability;
66300
66819
  exports.networkLinkCapability = networkLinkCapability;
66301
66820
  exports.networkQualityCapability = networkQualityCapability;
66821
+ exports.nodePickerItems = nodePickerItems;
66302
66822
  exports.nodePin = require_sleep.nodePin;
66303
66823
  exports.nodesCapability = nodesCapability;
66304
66824
  exports.normalizeAddonInitResult = require_sleep.normalizeAddonInitResult;
@@ -66317,6 +66837,7 @@ exports.optionalMethod = require_sleep.optionalMethod;
66317
66837
  exports.osdCapability = osdCapability;
66318
66838
  exports.osdManagerCapability = osdManagerCapability;
66319
66839
  exports.overlayClusterStepSettings = overlayClusterStepSettings;
66840
+ exports.packagePickerItems = packagePickerItems;
66320
66841
  exports.parseAdminBase = parseAdminBase;
66321
66842
  exports.parseCameraStreamConfig = parseCameraStreamConfig;
66322
66843
  exports.parseExpression = parseExpression;
@@ -66462,13 +66983,21 @@ exports.switchCapability = switchCapability;
66462
66983
  exports.switchedOffIds = switchedOffIds;
66463
66984
  exports.synthesizeSourceInfo = synthesizeSourceInfo;
66464
66985
  exports.systemCapability = systemCapability;
66986
+ exports.systemEventFamilyOf = systemEventFamilyOf;
66987
+ exports.systemEventFamilyProblems = systemEventFamilyProblems;
66465
66988
  exports.systemEventFilterApplies = systemEventFilterApplies;
66466
66989
  exports.systemEventFilterAppliesToAnyKind = systemEventFilterAppliesToAnyKind;
66990
+ exports.systemEventKindNamesOf = systemEventKindNamesOf;
66991
+ exports.systemEventKindsOfFamily = systemEventKindsOfFamily;
66992
+ exports.systemFamilyOfKind = systemFamilyOfKind;
66993
+ exports.systemRuleKindOf = systemRuleKindOf;
66467
66994
  exports.tamperCapability = tamperCapability;
66468
66995
  exports.taskLogEntrySchema = taskLogEntrySchema;
66469
66996
  exports.taskPhaseSchema = taskPhaseSchema;
66470
66997
  exports.taskTargetSchema = taskTargetSchema;
66471
66998
  exports.temperatureSensorCapability = temperatureSensorCapability;
66999
+ exports.templateVarKindApplies = templateVarKindApplies;
67000
+ exports.templateVarSystemEventApplies = templateVarSystemEventApplies;
66472
67001
  exports.templateVarsFor = templateVarsFor;
66473
67002
  exports.terminalSessionCapability = terminalSessionCapability;
66474
67003
  exports.textToHtml = textToHtml;