@camstack/types 1.2.303 → 1.2.305
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/addon.js +1 -2
- package/dist/addon.mjs +1 -2
- package/dist/capabilities/custom-model-registry.cap.d.ts +2 -2
- package/dist/capabilities/device-admin-link-url.d.ts +2 -2
- package/dist/capabilities/device-admin-link.cap.d.ts +1 -1
- package/dist/capabilities/index.d.ts +8 -7
- package/dist/capabilities/local-network.cap.d.ts +18 -8
- package/dist/capabilities/model-convert.cap.d.ts +1 -1
- package/dist/capabilities/model-distributor.cap.d.ts +10 -4
- package/dist/capabilities/notification-rules.cap.d.ts +34 -2
- package/dist/capabilities/osd-manager.cap.d.ts +5 -18
- package/dist/capabilities/osd.cap.d.ts +4 -0
- package/dist/capabilities/pipeline-executor.cap.d.ts +5 -5
- package/dist/capabilities/pipeline-runner.cap.d.ts +54 -0
- package/dist/capabilities/stream-broker.cap.d.ts +4 -4
- package/dist/capabilities/viewer-link-url.d.ts +104 -0
- package/dist/encode-profile.d.ts +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +338 -91
- package/dist/index.mjs +328 -92
- package/dist/interfaces/event-bus.d.ts +23 -0
- package/dist/interfaces/pipeline-runner-capability.d.ts +6 -0
- package/dist/notification/alarm-settings.d.ts +25 -0
- package/dist/types/model-variant-groups.d.ts +2 -2
- package/dist/types/models.d.ts +7 -6
- package/dist/types/pipeline-step.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5148,7 +5148,7 @@ function tierLabel(family, baseName) {
|
|
|
5148
5148
|
}
|
|
5149
5149
|
function variantLabel(precision, optimization) {
|
|
5150
5150
|
const parts = [];
|
|
5151
|
-
if (optimization === "
|
|
5151
|
+
if (optimization === "test") parts.push("Test");
|
|
5152
5152
|
parts.push(precision === "int8" ? "Int8" : "Standard");
|
|
5153
5153
|
return parts.join(" · ");
|
|
5154
5154
|
}
|
|
@@ -5172,7 +5172,7 @@ var PRECISION_ORDER = ["fp32", "int8"];
|
|
|
5172
5172
|
/**
|
|
5173
5173
|
* Fold a flat catalog into the `family → tier → variant` tree. Deterministic
|
|
5174
5174
|
* ordering: tiers by the canonical size ladder (unknown tiers appended
|
|
5175
|
-
* alphabetically), variants standard-before-int8 and
|
|
5175
|
+
* alphabetically), variants standard-before-int8 and test last.
|
|
5176
5176
|
*/
|
|
5177
5177
|
function buildModelVariantGroups(models) {
|
|
5178
5178
|
const byFamily = /* @__PURE__ */ new Map();
|
|
@@ -5203,7 +5203,7 @@ function buildModelVariantGroups(models) {
|
|
|
5203
5203
|
};
|
|
5204
5204
|
}).toSorted((a, b) => {
|
|
5205
5205
|
if (a.resolution !== b.resolution) return (b.resolution ?? Infinity) - (a.resolution ?? Infinity);
|
|
5206
|
-
if (a.optimization !== b.optimization) return a.optimization === "
|
|
5206
|
+
if (a.optimization !== b.optimization) return a.optimization === "test" ? 1 : -1;
|
|
5207
5207
|
return PRECISION_ORDER.indexOf(a.precision) - PRECISION_ORDER.indexOf(b.precision);
|
|
5208
5208
|
});
|
|
5209
5209
|
const base = options.find((o) => o.precision === "fp32" && o.optimization === "standard") ?? options[0];
|
|
@@ -5416,11 +5416,11 @@ var ModelVariantGroupSchema = zod.z.object({
|
|
|
5416
5416
|
/** Quantization axis. Omit ⇒ the fp32 base build. */
|
|
5417
5417
|
precision: zod.z.enum(["fp32", "int8"]).optional(),
|
|
5418
5418
|
/**
|
|
5419
|
-
*
|
|
5420
|
-
*
|
|
5421
|
-
*
|
|
5419
|
+
* Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
|
|
5420
|
+
* an alternate training of the same family (Scrypted `relu_test`); chip
|
|
5421
|
+
* label is "Test".
|
|
5422
5422
|
*/
|
|
5423
|
-
optimization: zod.z.enum(["standard", "
|
|
5423
|
+
optimization: zod.z.enum(["standard", "test"]).optional(),
|
|
5424
5424
|
/**
|
|
5425
5425
|
* Input-resolution axis (square input side, px). Omit ⇒ the family's native
|
|
5426
5426
|
* resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
|
|
@@ -5495,9 +5495,10 @@ var ModelLicenseRecordSchema = zod.z.object({
|
|
|
5495
5495
|
* are per upstream. A persisted custom-model row written when this field was a
|
|
5496
5496
|
* string still parses — the string is lifted into `{ weights }`.
|
|
5497
5497
|
*
|
|
5498
|
-
* Every licence surface (the
|
|
5499
|
-
*
|
|
5500
|
-
*
|
|
5498
|
+
* Every machine licence surface (`THIRD_PARTY_MODELS.md`, the Hugging Face
|
|
5499
|
+
* model table) is GENERATED from these records by
|
|
5500
|
+
* `scripts/gen-model-licenses.ts` (D661). Operator-facing docs live in
|
|
5501
|
+
* `camstack/docs` → `/docs/detection/models`.
|
|
5501
5502
|
*/
|
|
5502
5503
|
var ModelLicenseSchema = zod.z.preprocess((value) => typeof value === "string" ? { weights: value } : value, ModelLicenseRecordSchema);
|
|
5503
5504
|
var ModelCatalogEntrySchema = zod.z.object({
|
|
@@ -12459,7 +12460,7 @@ var detectionPipelineCapability = {
|
|
|
12459
12460
|
* This matters here more than anywhere else in the repo, because every provider
|
|
12460
12461
|
* that knows a device's host knows its PASSWORD too: `{ host, port, username,
|
|
12461
12462
|
* password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
|
|
12462
|
-
* and `http://admin:hunter2@192.168.
|
|
12463
|
+
* and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
|
|
12463
12464
|
* camera's own page will ask for its own login. That is correct, and pre-
|
|
12464
12465
|
* filling it is the operator's business, not ours.
|
|
12465
12466
|
*
|
|
@@ -17345,9 +17346,15 @@ var modelConvertCapability = {
|
|
|
17345
17346
|
* needs the Moleculer broker + the deploy-stage registry, which a forked addon
|
|
17346
17347
|
* can't reach. `addon-model-studio` drives it via `ctx.api` and owns the
|
|
17347
17348
|
* per-node availability map.
|
|
17349
|
+
*
|
|
17350
|
+
* The destination is `targetNodeId`, NOT `nodeId`. Cap routers and the
|
|
17351
|
+
* Moleculer tRPC link strip an input field named `nodeId` and use it as a
|
|
17352
|
+
* route pin (resolve the provider ON that node). Naming the destination
|
|
17353
|
+
* `nodeId` routed the call to the agent — which does not host this
|
|
17354
|
+
* singleton — and handed the provider an input with the destination missing.
|
|
17348
17355
|
*/
|
|
17349
17356
|
var ModelDistributeInputSchema = zod.z.object({
|
|
17350
|
-
|
|
17357
|
+
targetNodeId: zod.z.string(),
|
|
17351
17358
|
modelId: zod.z.string(),
|
|
17352
17359
|
format: zod.z.enum(MODEL_FORMATS),
|
|
17353
17360
|
entry: ModelCatalogEntrySchema
|
|
@@ -20497,8 +20504,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
|
|
|
20497
20504
|
disabledTargetIds: zod.z.array(zod.z.string()).default([])
|
|
20498
20505
|
});
|
|
20499
20506
|
/**
|
|
20500
|
-
* The state-summary SECTIONS (D647 / D698): the D637 kind groups that
|
|
20501
|
-
* still-true state. `
|
|
20507
|
+
* The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
|
|
20508
|
+
* report a still-true state. `addons` is the crash-looped addons only and
|
|
20509
|
+
* `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
|
|
20502
20510
|
* job is not an open state, and the alarm stays instant.
|
|
20503
20511
|
*/
|
|
20504
20512
|
var NcStateSummarySectionIdSchema = zod.z.enum([
|
|
@@ -20510,6 +20518,7 @@ var NcStateSummarySectionIdSchema = zod.z.enum([
|
|
|
20510
20518
|
"detection-blind",
|
|
20511
20519
|
"nodes",
|
|
20512
20520
|
"addons",
|
|
20521
|
+
"addon-updates",
|
|
20513
20522
|
"updates"
|
|
20514
20523
|
]);
|
|
20515
20524
|
/** One section of a previewed state summary. `unavailable` = its state could not be read. */
|
|
@@ -21548,7 +21557,19 @@ var NcAlarmModeDelaysSchema = zod.z.object({
|
|
|
21548
21557
|
* When this mode may be armed. Absent / null = always allowed (same as a
|
|
21549
21558
|
* rule with no `schedule`). Evaluated with {@link isScheduleActive}.
|
|
21550
21559
|
*/
|
|
21551
|
-
schedule: NcScheduleSchema.optional()
|
|
21560
|
+
schedule: NcScheduleSchema.optional(),
|
|
21561
|
+
/**
|
|
21562
|
+
* D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
|
|
21563
|
+
* intrusion naming the locations)? Absent = false — the entry-delay notification is the
|
|
21564
|
+
* only one, and the matches ride the triggered notification's mosaic (D705).
|
|
21565
|
+
*/
|
|
21566
|
+
notifyDuringEntryDelay: zod.z.boolean().optional(),
|
|
21567
|
+
/**
|
|
21568
|
+
* D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
|
|
21569
|
+
* Absent = false (logged, not sent). Even when true it is not sent when that same sensor
|
|
21570
|
+
* is the one that starts the entry delay — the entry-delay notification already names it.
|
|
21571
|
+
*/
|
|
21572
|
+
notifySensorRewatched: zod.z.boolean().optional()
|
|
21552
21573
|
});
|
|
21553
21574
|
var NcAlarmModeDelaysListSchema = zod.z.array(NcAlarmModeDelaysSchema).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
|
|
21554
21575
|
/**
|
|
@@ -21563,7 +21584,11 @@ var NcAlarmModeDelaysEditSchema = zod.z.object({
|
|
|
21563
21584
|
triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
|
|
21564
21585
|
postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
|
|
21565
21586
|
/** Set a schedule, or `null` to clear (mode always allowed again). */
|
|
21566
|
-
schedule: NcScheduleSchema.nullable().optional()
|
|
21587
|
+
schedule: NcScheduleSchema.nullable().optional(),
|
|
21588
|
+
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
21589
|
+
notifyDuringEntryDelay: zod.z.boolean().nullable().optional(),
|
|
21590
|
+
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
21591
|
+
notifySensorRewatched: zod.z.boolean().nullable().optional()
|
|
21567
21592
|
});
|
|
21568
21593
|
var NcAlarmModeDelaysEditListSchema = zod.z.array(NcAlarmModeDelaysEditSchema).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
|
|
21569
21594
|
/** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
|
|
@@ -22793,39 +22818,19 @@ var CLUSTER_MODEL_SCOPED_STEPS = [{
|
|
|
22793
22818
|
label: "Face recognition model",
|
|
22794
22819
|
defaultModelId: "auraface-r100",
|
|
22795
22820
|
indexName: "the enrolled face gallery",
|
|
22796
|
-
options: [
|
|
22797
|
-
|
|
22798
|
-
|
|
22799
|
-
|
|
22800
|
-
},
|
|
22801
|
-
{
|
|
22802
|
-
id: "arcface-r100",
|
|
22803
|
-
label: "ArcFace (ResNet34)"
|
|
22804
|
-
},
|
|
22805
|
-
{
|
|
22806
|
-
id: "inception-resnet-v1",
|
|
22807
|
-
label: "Inception ResNet V1"
|
|
22808
|
-
}
|
|
22809
|
-
]
|
|
22821
|
+
options: [{
|
|
22822
|
+
id: "auraface-r100",
|
|
22823
|
+
label: "AuraFace R100"
|
|
22824
|
+
}]
|
|
22810
22825
|
}, {
|
|
22811
22826
|
stepId: "clip-embedding",
|
|
22812
22827
|
label: "Semantic search model",
|
|
22813
|
-
defaultModelId: "
|
|
22828
|
+
defaultModelId: "siglip2-b16-224",
|
|
22814
22829
|
indexName: "the object semantic-search index",
|
|
22815
|
-
options: [
|
|
22816
|
-
|
|
22817
|
-
|
|
22818
|
-
|
|
22819
|
-
},
|
|
22820
|
-
{
|
|
22821
|
-
id: "mobileclip-s2",
|
|
22822
|
-
label: "MobileCLIP S2"
|
|
22823
|
-
},
|
|
22824
|
-
{
|
|
22825
|
-
id: "siglip2-b16-224",
|
|
22826
|
-
label: "SigLIP2 B/16 (Apache-2.0)"
|
|
22827
|
-
}
|
|
22828
|
-
]
|
|
22830
|
+
options: [{
|
|
22831
|
+
id: "siglip2-b16-224",
|
|
22832
|
+
label: "SigLIP2 B/16 (Apache-2.0)"
|
|
22833
|
+
}]
|
|
22829
22834
|
}];
|
|
22830
22835
|
/**
|
|
22831
22836
|
* Store identity of the cluster row inside `pipeline-orchestrator`'s GLOBAL
|
|
@@ -26814,6 +26819,22 @@ var MotionSourceEnum = zod.z.enum([
|
|
|
26814
26819
|
"device-activity"
|
|
26815
26820
|
]);
|
|
26816
26821
|
/**
|
|
26822
|
+
* What opened an on-motion detection SESSION: the motion source that passed the
|
|
26823
|
+
* camera's `motionSources` gate, and what raised it (the camera itself, or a
|
|
26824
|
+
* sensor the operator attached — D672). `sensorName` is the attached sensor's
|
|
26825
|
+
* device name as the orchestrator's camera-sensors resolution last read it;
|
|
26826
|
+
* absent when unknown or when the camera itself triggered.
|
|
26827
|
+
*
|
|
26828
|
+
* Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
|
|
26829
|
+
* can say what started the session (D672 rule 11, amended 2026-10-06). The
|
|
26830
|
+
* runner never decides anything on it.
|
|
26831
|
+
*/
|
|
26832
|
+
var SessionTriggerSchema = zod.z.object({
|
|
26833
|
+
source: MotionSourceEnum,
|
|
26834
|
+
triggeredBy: MotionTriggeredBySchema,
|
|
26835
|
+
sensorName: zod.z.string().optional()
|
|
26836
|
+
});
|
|
26837
|
+
/**
|
|
26817
26838
|
* List of motion sources active on a camera. Empty array is valid:
|
|
26818
26839
|
* "no source" — happens for battery cams without firmware motion when
|
|
26819
26840
|
* the operator hasn't opted into the SW analyzer (would hold the
|
|
@@ -27070,6 +27091,14 @@ var RunnerCameraConfigSchema = zod.z.object({
|
|
|
27070
27091
|
*/
|
|
27071
27092
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
27072
27093
|
/**
|
|
27094
|
+
* What opened this attach, on a SESSION attach only (see
|
|
27095
|
+
* {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
|
|
27096
|
+
* standing attach, an occupancy burst, a re-dispatch with no motion event
|
|
27097
|
+
* behind it, and every attach from an orchestrator older than the field — the
|
|
27098
|
+
* runner then names no source on the phase event.
|
|
27099
|
+
*/
|
|
27100
|
+
sessionTrigger: SessionTriggerSchema.optional(),
|
|
27101
|
+
/**
|
|
27073
27102
|
* WHICH root detector runs for this camera. The detection counterpart of
|
|
27074
27103
|
* {@link motionSources}, same shape and same discipline: a per-camera list
|
|
27075
27104
|
* of sources the system understands, vendor-agnostic, owned here.
|
|
@@ -32225,6 +32254,122 @@ var CLIP_PLAYBACK_OPTIONS = {
|
|
|
32225
32254
|
}
|
|
32226
32255
|
};
|
|
32227
32256
|
//#endregion
|
|
32257
|
+
//#region src/capabilities/viewer-link-url.ts
|
|
32258
|
+
/** The central link domain the viewer app claims (Universal Links / App Links). */
|
|
32259
|
+
var CAMSTACK_APP_LINK_ORIGIN = "https://camstack.zentik.app";
|
|
32260
|
+
/** Where the hub serves the viewer SPA. */
|
|
32261
|
+
var HUB_VIEWER_MOUNT = "/viewer/camstack";
|
|
32262
|
+
/** True when `baseUrl` names the CamStack app link rather than a hub address. */
|
|
32263
|
+
function isAppLinkBase(baseUrl) {
|
|
32264
|
+
if (baseUrl === null || baseUrl === void 0 || baseUrl === "") return false;
|
|
32265
|
+
try {
|
|
32266
|
+
return new URL(baseUrl).origin === CAMSTACK_APP_LINK_ORIGIN;
|
|
32267
|
+
} catch {
|
|
32268
|
+
return false;
|
|
32269
|
+
}
|
|
32270
|
+
}
|
|
32271
|
+
/**
|
|
32272
|
+
* The base a viewer link is built on, from the flagged notification address:
|
|
32273
|
+
* the effective address is the explicit choice, else AUTO's `resolved`. The
|
|
32274
|
+
* one reading of that answer — the NC's tap and the Network page's preview
|
|
32275
|
+
* both go through it.
|
|
32276
|
+
*/
|
|
32277
|
+
function viewerLinkBaseOf(endpoint) {
|
|
32278
|
+
const flagged = endpoint.baseUrl ?? endpoint.resolved;
|
|
32279
|
+
return isAppLinkBase(flagged) ? {
|
|
32280
|
+
form: "app",
|
|
32281
|
+
hubBaseUrl: endpoint.appLinkHub ?? null
|
|
32282
|
+
} : {
|
|
32283
|
+
form: "hub",
|
|
32284
|
+
hubBaseUrl: flagged
|
|
32285
|
+
};
|
|
32286
|
+
}
|
|
32287
|
+
/**
|
|
32288
|
+
* Reduce a base URL to the bare origin the central page accepts as `hub=`,
|
|
32289
|
+
* or `null` when it cannot be one: not http(s), carries credentials, or does
|
|
32290
|
+
* not parse. A path/query/fragment is dropped — the central page mounts the
|
|
32291
|
+
* viewer under the origin itself.
|
|
32292
|
+
*/
|
|
32293
|
+
function toAppLinkHubOrigin(baseUrl) {
|
|
32294
|
+
let parsed;
|
|
32295
|
+
try {
|
|
32296
|
+
parsed = new URL(baseUrl);
|
|
32297
|
+
} catch {
|
|
32298
|
+
return null;
|
|
32299
|
+
}
|
|
32300
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") return null;
|
|
32301
|
+
if (parsed.username !== "" || parsed.password !== "") return null;
|
|
32302
|
+
if (parsed.hostname === "") return null;
|
|
32303
|
+
return parsed.origin;
|
|
32304
|
+
}
|
|
32305
|
+
/**
|
|
32306
|
+
* The hub address an app link carries as `hub=`, chosen from the hub's OWN
|
|
32307
|
+
* advertised palette so it always agrees with what the Network page lists:
|
|
32308
|
+
* the public tunnel first, then the mesh (Tailscale MagicDNS) — HTTPS only,
|
|
32309
|
+
* because the app and the hosted viewer reach it from off the LAN. `null`
|
|
32310
|
+
* when the hub advertises neither.
|
|
32311
|
+
*/
|
|
32312
|
+
function pickAppLinkHub(endpoints) {
|
|
32313
|
+
const rank = (e) => {
|
|
32314
|
+
if (e.kind !== "public" || !e.baseUrl.startsWith("https://")) return null;
|
|
32315
|
+
if (e.interfaceKind === "public") return 0;
|
|
32316
|
+
if (e.interfaceKind === "vpn") return 1;
|
|
32317
|
+
return null;
|
|
32318
|
+
};
|
|
32319
|
+
return endpoints.flatMap((e) => {
|
|
32320
|
+
const r = rank(e);
|
|
32321
|
+
const origin = toAppLinkHubOrigin(e.baseUrl);
|
|
32322
|
+
return r === null || origin === null ? [] : [{
|
|
32323
|
+
r,
|
|
32324
|
+
p: e.priority,
|
|
32325
|
+
origin
|
|
32326
|
+
}];
|
|
32327
|
+
}).toSorted((a, b) => a.r - b.r || a.p - b.p)[0]?.origin ?? null;
|
|
32328
|
+
}
|
|
32329
|
+
/** The viewer route for a destination, or null when it names nothing. */
|
|
32330
|
+
function viewerRoute(destination) {
|
|
32331
|
+
switch (destination.kind) {
|
|
32332
|
+
case "camera": {
|
|
32333
|
+
if (!Number.isInteger(destination.deviceId) || destination.deviceId <= 0) return null;
|
|
32334
|
+
const at = destination.atMs;
|
|
32335
|
+
return {
|
|
32336
|
+
path: `/camera/${String(destination.deviceId)}`,
|
|
32337
|
+
query: at !== void 0 && Number.isFinite(at) ? [["at", String(Math.trunc(at))]] : []
|
|
32338
|
+
};
|
|
32339
|
+
}
|
|
32340
|
+
case "events": return {
|
|
32341
|
+
path: "/events",
|
|
32342
|
+
query: []
|
|
32343
|
+
};
|
|
32344
|
+
case "notifications": return {
|
|
32345
|
+
path: "/notifications",
|
|
32346
|
+
query: []
|
|
32347
|
+
};
|
|
32348
|
+
}
|
|
32349
|
+
}
|
|
32350
|
+
function encodeQuery(query) {
|
|
32351
|
+
if (query.length === 0) return "";
|
|
32352
|
+
return `?${query.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join("&")}`;
|
|
32353
|
+
}
|
|
32354
|
+
/**
|
|
32355
|
+
* The link for a viewer destination, or `null` when none can be minted: an
|
|
32356
|
+
* unknown destination, or the `hub` form with no reachable base (a dead link
|
|
32357
|
+
* is worse than none).
|
|
32358
|
+
*/
|
|
32359
|
+
function buildViewerLink(input) {
|
|
32360
|
+
const route = viewerRoute(input.destination);
|
|
32361
|
+
if (route === null) return null;
|
|
32362
|
+
const raw = input.base.hubBaseUrl;
|
|
32363
|
+
const base = raw === null ? "" : raw.replace(/\/+$/, "");
|
|
32364
|
+
if (input.base.form === "app") {
|
|
32365
|
+
const origin = base === "" ? null : toAppLinkHubOrigin(base);
|
|
32366
|
+
const query = origin === null ? route.query : [...route.query, ["hub", origin]];
|
|
32367
|
+
return `${CAMSTACK_APP_LINK_ORIGIN}${route.path}${encodeQuery(query)}`;
|
|
32368
|
+
}
|
|
32369
|
+
if (base === "" || isAppLinkBase(base)) return null;
|
|
32370
|
+
return `${base}${HUB_VIEWER_MOUNT}${route.path}${encodeQuery(route.query)}`;
|
|
32371
|
+
}
|
|
32372
|
+
//#endregion
|
|
32228
32373
|
//#region src/capabilities/webrtc-session.cap.ts
|
|
32229
32374
|
/**
|
|
32230
32375
|
* Optional client-side hints sent at session creation to help the provider
|
|
@@ -37098,7 +37243,7 @@ var LocalInterfaceSchema = zod.z.object({
|
|
|
37098
37243
|
name: zod.z.string(),
|
|
37099
37244
|
family: zod.z.enum(["IPv4", "IPv6"]),
|
|
37100
37245
|
address: zod.z.string(),
|
|
37101
|
-
/** CIDR shorthand (e.g. `192.168.
|
|
37246
|
+
/** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
|
|
37102
37247
|
cidr: zod.z.string(),
|
|
37103
37248
|
/** OS netmask. Stable across calls so the SDK can hash on it. */
|
|
37104
37249
|
netmask: zod.z.string(),
|
|
@@ -37152,7 +37297,8 @@ var ConnectionEndpointSchema = zod.z.object({
|
|
|
37152
37297
|
"lan-ipv4",
|
|
37153
37298
|
"lan-ipv6",
|
|
37154
37299
|
"public",
|
|
37155
|
-
"loopback"
|
|
37300
|
+
"loopback",
|
|
37301
|
+
"app-link"
|
|
37156
37302
|
]),
|
|
37157
37303
|
/**
|
|
37158
37304
|
* Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
|
|
@@ -37221,15 +37367,27 @@ var GetConnectionEndpointsResultSchema = zod.z.object({
|
|
|
37221
37367
|
localPort: AdvertisedLocalPortSchema
|
|
37222
37368
|
});
|
|
37223
37369
|
/**
|
|
37224
|
-
* The
|
|
37225
|
-
*
|
|
37226
|
-
*
|
|
37370
|
+
* The address flagged for notification links. `baseUrl: null` = AUTO, which
|
|
37371
|
+
* since D709 is the CamStack app link; `resolved` reports the effective value,
|
|
37372
|
+
* so the UI can show it either way.
|
|
37227
37373
|
*/
|
|
37228
37374
|
var NotificationEndpointSchema = zod.z.object({
|
|
37229
37375
|
/** The operator's explicit choice, or null for AUTO. */
|
|
37230
37376
|
baseUrl: zod.z.string().nullable(),
|
|
37231
|
-
/**
|
|
37232
|
-
|
|
37377
|
+
/**
|
|
37378
|
+
* The effective flagged address: the explicit choice, else (AUTO) the
|
|
37379
|
+
* CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
|
|
37380
|
+
* answered the public tunnel / mesh here, or null.
|
|
37381
|
+
*/
|
|
37382
|
+
resolved: zod.z.string().nullable(),
|
|
37383
|
+
/**
|
|
37384
|
+
* The hub origin an app link carries as `hub=` (D709): the hub's best
|
|
37385
|
+
* public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
|
|
37386
|
+
* picked from this cap's own palette by `pickAppLinkHub`. `null` when the
|
|
37387
|
+
* hub advertises neither; the app link is then minted without `hub=`.
|
|
37388
|
+
* Absent on a pre-D709 hub.
|
|
37389
|
+
*/
|
|
37390
|
+
appLinkHub: zod.z.string().nullable()
|
|
37233
37391
|
});
|
|
37234
37392
|
/**
|
|
37235
37393
|
* The URLs the SDK / viewer should race for API access. `baseUrls` empty =
|
|
@@ -37297,7 +37455,7 @@ var localNetworkCapability = {
|
|
|
37297
37455
|
* every client a second authority on a socket only the hub binds. A viewer
|
|
37298
37456
|
* configured with a port-less public URL (`https://camstack.example.top`)
|
|
37299
37457
|
* infers 443 from the scheme, asks with 443, and was handed
|
|
37300
|
-
* `https://192.168.
|
|
37458
|
+
* `https://192.168.10.9:443` for a hub listening on 4443. That candidate
|
|
37301
37459
|
* cannot ever answer, and losing its race reads in the log exactly like
|
|
37302
37460
|
* "the LAN was tried and it was slower" — so an operator sitting on his own
|
|
37303
37461
|
* WiFi stayed on the public tunnel for weeks, with the LAN candidate born
|
|
@@ -37330,13 +37488,21 @@ var localNetworkCapability = {
|
|
|
37330
37488
|
* Pass `'https'` when the caller is itself loaded over HTTPS
|
|
37331
37489
|
* to avoid mixed-content blocks in the browser. The public
|
|
37332
37490
|
* tunnel always emits `https://` regardless. */
|
|
37333
|
-
scheme: zod.z.enum(["http", "https"]).optional()
|
|
37491
|
+
scheme: zod.z.enum(["http", "https"]).optional(),
|
|
37492
|
+
/** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
|
|
37493
|
+
* an address notification links can be flagged with, not a hub
|
|
37494
|
+
* route. Default `false`: racers and rankers never see it. */
|
|
37495
|
+
includeAppLink: zod.z.boolean().optional()
|
|
37334
37496
|
}), GetConnectionEndpointsResultSchema),
|
|
37335
37497
|
/**
|
|
37336
|
-
* The
|
|
37337
|
-
*
|
|
37338
|
-
*
|
|
37339
|
-
*
|
|
37498
|
+
* The address notification links are flagged with. `baseUrl: null` means
|
|
37499
|
+
* AUTO, which is the CamStack app link (D709): viewer taps go through
|
|
37500
|
+
* `https://camstack.zentik.app/…?hub=<appLinkHub>` and open the app. Any
|
|
37501
|
+
* hub address the palette lists can be flagged instead; then viewer taps,
|
|
37502
|
+
* attachment links and action buttons all use it. Signed media and
|
|
37503
|
+
* buttons never use the app link — with it flagged (or AUTO) they keep
|
|
37504
|
+
* the ranked hub ladder (a configured origin, a connected tunnel, then
|
|
37505
|
+
* the LAN), never loopback.
|
|
37340
37506
|
*
|
|
37341
37507
|
* Why an explicit marker: the automatic ranking cannot know which of
|
|
37342
37508
|
* several reachable addresses the RECIPIENT can actually open. A link is
|
|
@@ -37756,7 +37922,7 @@ var MeshPeerSchema = zod.z.object({
|
|
|
37756
37922
|
tags: zod.z.array(zod.z.string()).readonly(),
|
|
37757
37923
|
/** True when the peer advertises itself as an exit-node candidate. */
|
|
37758
37924
|
exitNodeOption: zod.z.boolean(),
|
|
37759
|
-
/** Subnet routes the peer advertises (e.g. `["192.168.
|
|
37925
|
+
/** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
|
|
37760
37926
|
advertisedRoutes: zod.z.array(zod.z.string()).readonly(),
|
|
37761
37927
|
/** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
|
|
37762
37928
|
userLogin: zod.z.string().nullable(),
|
|
@@ -39434,7 +39600,13 @@ var OsdOverlaySchema = zod.z.object({
|
|
|
39434
39600
|
*/
|
|
39435
39601
|
availablePositions: zod.z.array(OsdPositionEnum).readonly(),
|
|
39436
39602
|
/** Firmware does not allow editing the `text` field (e.g. timestamp). */
|
|
39437
|
-
readOnly: zod.z.boolean().optional()
|
|
39603
|
+
readOnly: zod.z.boolean().optional(),
|
|
39604
|
+
/**
|
|
39605
|
+
* Firmware text ceiling for this overlay. Absent = no known limit.
|
|
39606
|
+
* The OSD manager truncates here on every write — never stores its own
|
|
39607
|
+
* copy on the binding.
|
|
39608
|
+
*/
|
|
39609
|
+
maxCharacters: zod.z.number().int().positive().optional()
|
|
39438
39610
|
});
|
|
39439
39611
|
var OsdStatusSchema = zod.z.object({ overlays: zod.z.array(OsdOverlaySchema).readonly() });
|
|
39440
39612
|
var OsdOverlayPatchSchema = zod.z.object({
|
|
@@ -39552,7 +39724,9 @@ var OsdTemplateBindingSchema = zod.z.object({
|
|
|
39552
39724
|
valuePath: zod.z.string().min(1).max(64),
|
|
39553
39725
|
/** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
|
|
39554
39726
|
displayUnit: zod.z.string().max(16).optional(),
|
|
39555
|
-
maxDecimals: zod.z.number().int().min(0).max(4).default(1)
|
|
39727
|
+
maxDecimals: zod.z.number().int().min(0).max(4).default(1),
|
|
39728
|
+
/** Raw value → display text (same shape as slot binding). Empty string hides. */
|
|
39729
|
+
valueMap: zod.z.record(zod.z.string(), zod.z.string()).optional()
|
|
39556
39730
|
});
|
|
39557
39731
|
/**
|
|
39558
39732
|
* A named template: bindings (alias → leaf field) + a parser that
|
|
@@ -39602,18 +39776,11 @@ var OsdSlotBindingSchema = zod.z.object({
|
|
|
39602
39776
|
source: OsdSourceSchema,
|
|
39603
39777
|
/** `${value}` and `${unit}` are substituted; every occurrence. */
|
|
39604
39778
|
template: zod.z.string().max(96).default("${value}"),
|
|
39605
|
-
/** Truncate with an ellipsis past this length. Absent = no limit. */
|
|
39606
|
-
maxCharacters: zod.z.number().int().min(4).max(64).optional(),
|
|
39607
39779
|
/**
|
|
39608
39780
|
* Decimal places for a numeric value. `0` yields an integer — the
|
|
39609
39781
|
* documented workaround for firmwares that reject `.` in overlay text.
|
|
39610
39782
|
*/
|
|
39611
39783
|
maxDecimals: zod.z.number().int().min(0).max(4).default(1),
|
|
39612
|
-
/**
|
|
39613
|
-
* Appended via `${unit}` when no unit conversion produces a label.
|
|
39614
|
-
* Prefer `source.displayUnit` for converted device-state values.
|
|
39615
|
-
*/
|
|
39616
|
-
unitLabel: zod.z.string().max(8).optional(),
|
|
39617
39784
|
/** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
|
|
39618
39785
|
valueMap: zod.z.record(zod.z.string(), zod.z.string()).optional(),
|
|
39619
39786
|
/** Time windows in which the slot is shown. Absent = always. */
|
|
@@ -39622,9 +39789,7 @@ var OsdSlotBindingSchema = zod.z.object({
|
|
|
39622
39789
|
* Display gate, in the notification centre's condition vocabulary.
|
|
39623
39790
|
* Only the keys reported by `getConditionSupport` are accepted.
|
|
39624
39791
|
*/
|
|
39625
|
-
conditions: NcConditionsSchema.optional()
|
|
39626
|
-
/** Rendered when the gate is closed or the value unreadable. Empty = hide. */
|
|
39627
|
-
fallbackText: zod.z.string().max(64).default("")
|
|
39792
|
+
conditions: NcConditionsSchema.optional()
|
|
39628
39793
|
});
|
|
39629
39794
|
/** One camera slot, as the operator sees it: firmware truth + our binding. */
|
|
39630
39795
|
var OsdSlotViewSchema = zod.z.object({
|
|
@@ -66916,12 +67081,14 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
66916
67081
|
{
|
|
66917
67082
|
id: "addons",
|
|
66918
67083
|
family: "system",
|
|
66919
|
-
label: "Addons",
|
|
66920
|
-
kinds: [
|
|
66921
|
-
|
|
66922
|
-
|
|
66923
|
-
|
|
66924
|
-
|
|
67084
|
+
label: "Addons stopped",
|
|
67085
|
+
kinds: ["addon-crash-loop"]
|
|
67086
|
+
},
|
|
67087
|
+
{
|
|
67088
|
+
id: "addon-updates",
|
|
67089
|
+
family: "system",
|
|
67090
|
+
label: "Addon updates",
|
|
67091
|
+
kinds: ["addon-update-available", "addon-updated"]
|
|
66925
67092
|
},
|
|
66926
67093
|
{
|
|
66927
67094
|
id: "updates",
|
|
@@ -67768,6 +67935,26 @@ var NC_ALARM_DELAY_FIELDS = [
|
|
|
67768
67935
|
"triggeredDurationSec"
|
|
67769
67936
|
];
|
|
67770
67937
|
/**
|
|
67938
|
+
* The STOCK after-trigger duration a panel seeds and every mode inherits unless it sets its
|
|
67939
|
+
* own (D706: 30 s, was 10 s under D701). Only the seed: a persisted value is never rewritten.
|
|
67940
|
+
* The panel's defaults, its one-shot migration and the admin UI's "pick a timed action" fill
|
|
67941
|
+
* all read this one constant.
|
|
67942
|
+
*/
|
|
67943
|
+
var NC_ALARM_DEFAULT_TRIGGERED_DURATION_SEC = 30;
|
|
67944
|
+
var NC_ALARM_NOTIFY_FIELDS = ["notifyDuringEntryDelay", "notifySensorRewatched"];
|
|
67945
|
+
/**
|
|
67946
|
+
* The switches `mode` runs on. There is no global value: absent is OFF (operator decision
|
|
67947
|
+
* 2026-10-06 — the entry-delay notification is the only one by default, and "watched again"
|
|
67948
|
+
* is not sent). An answer from an older hub carries no switch and reads as off.
|
|
67949
|
+
*/
|
|
67950
|
+
function resolveModeNotifyPolicy(settings, mode) {
|
|
67951
|
+
const entry = (settings.modeDelays ?? []).find((e) => e.mode === mode);
|
|
67952
|
+
return {
|
|
67953
|
+
notifyDuringEntryDelay: entry?.notifyDuringEntryDelay === true,
|
|
67954
|
+
notifySensorRewatched: entry?.notifySensorRewatched === true
|
|
67955
|
+
};
|
|
67956
|
+
}
|
|
67957
|
+
/**
|
|
67771
67958
|
* Derive the post-triggered action from a stored blob that may predate the field:
|
|
67772
67959
|
* a positive duration meant re-arm; zero/absent meant stay triggered.
|
|
67773
67960
|
*/
|
|
@@ -67816,6 +68003,10 @@ function editedAction(current, edit) {
|
|
|
67816
68003
|
if (edit === void 0) return current;
|
|
67817
68004
|
return edit === null ? void 0 : edit;
|
|
67818
68005
|
}
|
|
68006
|
+
function editedFlag(current, edit) {
|
|
68007
|
+
if (edit === void 0) return current;
|
|
68008
|
+
return edit === null ? void 0 : edit;
|
|
68009
|
+
}
|
|
67819
68010
|
function editedSchedule(current, edit) {
|
|
67820
68011
|
if (edit === void 0) return current;
|
|
67821
68012
|
return edit === null ? void 0 : edit;
|
|
@@ -67850,15 +68041,19 @@ function applyModeDelaysEdits(current, edits) {
|
|
|
67850
68041
|
const triggered = edited(base.triggeredDurationSec, edit.triggeredDurationSec);
|
|
67851
68042
|
const action = editedAction(base.postTriggeredAction, edit.postTriggeredAction);
|
|
67852
68043
|
const schedule = editedSchedule(base.schedule, edit.schedule);
|
|
68044
|
+
const duringEntry = editedFlag(base.notifyDuringEntryDelay, edit.notifyDuringEntryDelay);
|
|
68045
|
+
const rewatched = editedFlag(base.notifySensorRewatched, edit.notifySensorRewatched);
|
|
67853
68046
|
if (exit !== void 0) next.exitDelaySec = exit;
|
|
67854
68047
|
if (entry !== void 0) next.entryDelaySec = entry;
|
|
67855
68048
|
if (triggered !== void 0) next.triggeredDurationSec = triggered;
|
|
67856
68049
|
if (action !== void 0) next.postTriggeredAction = action;
|
|
67857
68050
|
if (schedule !== void 0) next.schedule = schedule;
|
|
68051
|
+
if (duringEntry !== void 0) next.notifyDuringEntryDelay = duringEntry;
|
|
68052
|
+
if (rewatched !== void 0) next.notifySensorRewatched = rewatched;
|
|
67858
68053
|
if (at >= 0) out[at] = next;
|
|
67859
68054
|
else out.push(next);
|
|
67860
68055
|
}
|
|
67861
|
-
return out.filter((e) => e.exitDelaySec !== void 0 || e.entryDelaySec !== void 0 || e.triggeredDurationSec !== void 0 || e.postTriggeredAction !== void 0 || e.schedule !== void 0);
|
|
68056
|
+
return out.filter((e) => e.exitDelaySec !== void 0 || e.entryDelaySec !== void 0 || e.triggeredDurationSec !== void 0 || e.postTriggeredAction !== void 0 || e.schedule !== void 0 || e.notifyDuringEntryDelay !== void 0 || e.notifySensorRewatched !== void 0);
|
|
67862
68057
|
}
|
|
67863
68058
|
/**
|
|
67864
68059
|
* Put ONE device on, or take it off, ONE mode's device-id list. A no-op answers
|
|
@@ -68003,6 +68198,12 @@ function alarmPatchLanded(patch, returned) {
|
|
|
68003
68198
|
const got = entry?.postTriggeredAction;
|
|
68004
68199
|
if (edit.postTriggeredAction === null ? got !== void 0 : got !== edit.postTriggeredAction) return false;
|
|
68005
68200
|
}
|
|
68201
|
+
for (const field of NC_ALARM_NOTIFY_FIELDS) {
|
|
68202
|
+
const want = edit[field];
|
|
68203
|
+
if (want === void 0) continue;
|
|
68204
|
+
const got = entry?.[field];
|
|
68205
|
+
if (want === null ? got !== void 0 : got !== want) return false;
|
|
68206
|
+
}
|
|
68006
68207
|
if (edit.schedule !== void 0) {
|
|
68007
68208
|
const got = entry?.schedule;
|
|
68008
68209
|
if (edit.schedule === null ? got !== void 0 : !sameSchedule(got, edit.schedule)) return false;
|
|
@@ -68399,13 +68600,15 @@ var STATE_SUMMARY_SECTION_VARS = [
|
|
|
68399
68600
|
},
|
|
68400
68601
|
{
|
|
68401
68602
|
name: "summaryAddons",
|
|
68402
|
-
label: "Summary: addons",
|
|
68403
|
-
example: "
|
|
68404
|
-
kinds: [
|
|
68405
|
-
|
|
68406
|
-
|
|
68407
|
-
|
|
68408
|
-
|
|
68603
|
+
label: "Summary: addons stopped",
|
|
68604
|
+
example: "hub — recorder stopped after repeated crashes",
|
|
68605
|
+
kinds: ["addon-crash-loop"]
|
|
68606
|
+
},
|
|
68607
|
+
{
|
|
68608
|
+
name: "summaryAddonUpdates",
|
|
68609
|
+
label: "Summary: addon updates",
|
|
68610
|
+
example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
|
|
68611
|
+
kinds: ["addon-update-available", "addon-updated"]
|
|
68409
68612
|
},
|
|
68410
68613
|
{
|
|
68411
68614
|
name: "summaryUpdates",
|
|
@@ -68746,6 +68949,16 @@ var NC_TEMPLATE_VARS = [
|
|
|
68746
68949
|
kinds: ["system"],
|
|
68747
68950
|
systemEventKinds: [...DEVICE_EVENTS]
|
|
68748
68951
|
},
|
|
68952
|
+
{
|
|
68953
|
+
name: "locations",
|
|
68954
|
+
label: "Intrusion locations",
|
|
68955
|
+
example: "Ingresso, Corridoio, Salone",
|
|
68956
|
+
group: "system",
|
|
68957
|
+
families: ["rule"],
|
|
68958
|
+
fields: [...RULE_TEXT],
|
|
68959
|
+
kinds: ["system"],
|
|
68960
|
+
systemEventKinds: [...COMBINED_ALARM]
|
|
68961
|
+
},
|
|
68749
68962
|
{
|
|
68750
68963
|
name: "deviceId",
|
|
68751
68964
|
label: "Device id",
|
|
@@ -68835,7 +69048,7 @@ var NC_TEMPLATE_VARS = [
|
|
|
68835
69048
|
{
|
|
68836
69049
|
name: "devices",
|
|
68837
69050
|
label: "Devices",
|
|
68838
|
-
description: "node-inference-unavailable: the affected cameras, comma-joined. Alarm arm / refusal: HOW MANY devices are armed (or open).",
|
|
69051
|
+
description: "node-inference-unavailable: the affected cameras, comma-joined. Alarm arm / arming / refusal: HOW MANY devices are armed (or open).",
|
|
68839
69052
|
example: "Ingresso, Garage",
|
|
68840
69053
|
group: "system",
|
|
68841
69054
|
families: ["rule"],
|
|
@@ -68844,6 +69057,7 @@ var NC_TEMPLATE_VARS = [
|
|
|
68844
69057
|
systemEventKinds: [
|
|
68845
69058
|
"node-inference-unavailable",
|
|
68846
69059
|
"alarm-armed",
|
|
69060
|
+
"alarm-arming",
|
|
68847
69061
|
"alarm-arm-refused"
|
|
68848
69062
|
]
|
|
68849
69063
|
},
|
|
@@ -69064,18 +69278,18 @@ var NC_TEMPLATE_VARS = [
|
|
|
69064
69278
|
{
|
|
69065
69279
|
name: "rules",
|
|
69066
69280
|
label: "Covering rules",
|
|
69067
|
-
description: "How many enabled rules the armed mode gates.",
|
|
69281
|
+
description: "How many enabled rules the armed / arming mode gates.",
|
|
69068
69282
|
example: "2",
|
|
69069
69283
|
group: "system",
|
|
69070
69284
|
families: ["rule"],
|
|
69071
69285
|
fields: [...RULE_TEXT],
|
|
69072
69286
|
kinds: ["system"],
|
|
69073
|
-
systemEventKinds: ["alarm-armed"]
|
|
69287
|
+
systemEventKinds: ["alarm-armed", "alarm-arming"]
|
|
69074
69288
|
},
|
|
69075
69289
|
{
|
|
69076
69290
|
name: "names",
|
|
69077
69291
|
label: "Device names",
|
|
69078
|
-
description: "Armed: the devices
|
|
69292
|
+
description: "Armed / arming: the Active devices (or every skipped name when none are Active). Refusal: the open sensors.",
|
|
69079
69293
|
example: "Ingresso, Garage",
|
|
69080
69294
|
group: "system",
|
|
69081
69295
|
families: ["rule"],
|
|
@@ -69096,7 +69310,29 @@ var NC_TEMPLATE_VARS = [
|
|
|
69096
69310
|
families: ["rule"],
|
|
69097
69311
|
fields: [...RULE_TEXT],
|
|
69098
69312
|
kinds: ["system"],
|
|
69099
|
-
systemEventKinds: ["alarm-armed"]
|
|
69313
|
+
systemEventKinds: ["alarm-armed", "alarm-arming"]
|
|
69314
|
+
},
|
|
69315
|
+
{
|
|
69316
|
+
name: "active",
|
|
69317
|
+
label: "Active count",
|
|
69318
|
+
description: "How many named devices the armed / arming mode is watching (title: n attivi / n active).",
|
|
69319
|
+
example: "3",
|
|
69320
|
+
group: "system",
|
|
69321
|
+
families: ["rule"],
|
|
69322
|
+
fields: [...RULE_TEXT],
|
|
69323
|
+
kinds: ["system"],
|
|
69324
|
+
systemEventKinds: ["alarm-armed", "alarm-arming"]
|
|
69325
|
+
},
|
|
69326
|
+
{
|
|
69327
|
+
name: "skipped",
|
|
69328
|
+
label: "Skipped count",
|
|
69329
|
+
description: "How many named devices the mode cannot arm — muted, detection off, offline (title: m saltati).",
|
|
69330
|
+
example: "1",
|
|
69331
|
+
group: "system",
|
|
69332
|
+
families: ["rule"],
|
|
69333
|
+
fields: [...RULE_TEXT],
|
|
69334
|
+
kinds: ["system"],
|
|
69335
|
+
systemEventKinds: ["alarm-armed", "alarm-arming"]
|
|
69100
69336
|
},
|
|
69101
69337
|
{
|
|
69102
69338
|
name: "bypassedNames",
|
|
@@ -69439,7 +69675,7 @@ function sendTimesForEditor(schedule) {
|
|
|
69439
69675
|
approximated: times.length > 0
|
|
69440
69676
|
};
|
|
69441
69677
|
}
|
|
69442
|
-
var SUMMARY_CONTENT_VAR = /\{\{\s*summary(?:Text|Devices|Streams|Battery|Consumables|Tanks|Detection|Nodes|Addons|Updates)\s*\}\}/;
|
|
69678
|
+
var SUMMARY_CONTENT_VAR = /\{\{\s*summary(?:Text|Devices|Streams|Battery|Consumables|Tanks|Detection|Nodes|Addons|AddonUpdates|Updates)\s*\}\}/;
|
|
69443
69679
|
/**
|
|
69444
69680
|
* Does a custom BODY carry the summary's content (`{{summaryText}}` or a
|
|
69445
69681
|
* section variable)? A body that does not would send a summary with nothing
|
|
@@ -72653,6 +72889,7 @@ exports.CAMERA_SENSORS_SETTINGS_KEY = CAMERA_SENSORS_SETTINGS_KEY;
|
|
|
72653
72889
|
exports.CAMERA_SWITCH_CATALOG = CAMERA_SWITCH_CATALOG;
|
|
72654
72890
|
exports.CAMERA_SWITCH_ORDER = CAMERA_SWITCH_ORDER;
|
|
72655
72891
|
exports.CAMERA_TRIGGER = CAMERA_TRIGGER;
|
|
72892
|
+
exports.CAMSTACK_APP_LINK_ORIGIN = CAMSTACK_APP_LINK_ORIGIN;
|
|
72656
72893
|
exports.CAM_PROFILE_ORDER = require_sleep.CAM_PROFILE_ORDER;
|
|
72657
72894
|
exports.CAPABILITY_NAMES = CAPABILITY_NAMES;
|
|
72658
72895
|
exports.CAPABILITY_ROUTER_KEYS = CAPABILITY_ROUTER_KEYS;
|
|
@@ -73089,6 +73326,7 @@ exports.HAP_KEYFRAME_INTERVAL_SEC = HAP_KEYFRAME_INTERVAL_SEC;
|
|
|
73089
73326
|
exports.HF_BASE_URL = HF_BASE_URL;
|
|
73090
73327
|
exports.HF_REPO = HF_REPO;
|
|
73091
73328
|
exports.HOURS_PER_DAY = HOURS_PER_DAY;
|
|
73329
|
+
exports.HUB_VIEWER_MOUNT = HUB_VIEWER_MOUNT;
|
|
73092
73330
|
exports.HWACCEL_OPTIONS = HWACCEL_OPTIONS;
|
|
73093
73331
|
exports.HealthStatusSchema = HealthStatusSchema;
|
|
73094
73332
|
exports.HfModelResolutionSchema = HfModelResolutionSchema;
|
|
@@ -73306,9 +73544,11 @@ exports.NAVIGATION_LIGHT_LEVEL_MIN = NAVIGATION_LIGHT_LEVEL_MIN;
|
|
|
73306
73544
|
exports.NC_ALARM_CONTROLLABLE_CAPS = NC_ALARM_CONTROLLABLE_CAPS;
|
|
73307
73545
|
exports.NC_ALARM_DEFAULT_PROFILE_ID = NC_ALARM_DEFAULT_PROFILE_ID;
|
|
73308
73546
|
exports.NC_ALARM_DEFAULT_PROFILE_NAME = NC_ALARM_DEFAULT_PROFILE_NAME;
|
|
73547
|
+
exports.NC_ALARM_DEFAULT_TRIGGERED_DURATION_SEC = NC_ALARM_DEFAULT_TRIGGERED_DURATION_SEC;
|
|
73309
73548
|
exports.NC_ALARM_DELAY_FIELDS = NC_ALARM_DELAY_FIELDS;
|
|
73310
73549
|
exports.NC_ALARM_DELAY_MAX_SEC = NC_ALARM_DELAY_MAX_SEC;
|
|
73311
73550
|
exports.NC_ALARM_NONBLOCKING_MAX = NC_ALARM_NONBLOCKING_MAX;
|
|
73551
|
+
exports.NC_ALARM_NOTIFY_FIELDS = NC_ALARM_NOTIFY_FIELDS;
|
|
73312
73552
|
exports.NC_ALARM_OPENING_EVENT_KINDS = NC_ALARM_OPENING_EVENT_KINDS;
|
|
73313
73553
|
exports.NC_ALARM_SENSORS_MAX = NC_ALARM_SENSORS_MAX;
|
|
73314
73554
|
exports.NC_ALARM_SYSTEM_DEFAULT_DELAYS = NC_ALARM_SYSTEM_DEFAULT_DELAYS;
|
|
@@ -73784,6 +74024,7 @@ exports.ServerUpdateActionResultSchema = ServerUpdateActionResultSchema;
|
|
|
73784
74024
|
exports.ServerUpdateCheckResultSchema = ServerUpdateCheckResultSchema;
|
|
73785
74025
|
exports.ServerUpdateOutcomeSchema = ServerUpdateOutcomeSchema;
|
|
73786
74026
|
exports.ServerUpdateStateSchema = ServerUpdateStateSchema;
|
|
74027
|
+
exports.SessionTriggerSchema = SessionTriggerSchema;
|
|
73787
74028
|
exports.SetCameraSensorsInputSchema = SetCameraSensorsInputSchema;
|
|
73788
74029
|
exports.SetLoggingSettingsInputSchema = SetLoggingSettingsInputSchema;
|
|
73789
74030
|
exports.SetSiteLocationInputSchema = SetSiteLocationInputSchema;
|
|
@@ -74067,6 +74308,7 @@ exports.buildNcTaxonomy = buildNcTaxonomy;
|
|
|
74067
74308
|
exports.buildRoleScopes = buildRoleScopes;
|
|
74068
74309
|
exports.buildStreamParamsConfigSchema = buildStreamParamsConfigSchema;
|
|
74069
74310
|
exports.buildVideoArgs = require_composition.buildVideoArgs;
|
|
74311
|
+
exports.buildViewerLink = buildViewerLink;
|
|
74070
74312
|
exports.builtCapabilityBlockers = builtCapabilityBlockers;
|
|
74071
74313
|
exports.buttonCapability = buttonCapability;
|
|
74072
74314
|
exports.calendarSourceCapability = calendarSourceCapability;
|
|
@@ -74296,6 +74538,7 @@ exports.invertPresetFeature = invertPresetFeature;
|
|
|
74296
74538
|
exports.invocationFromEncodeProfile = require_composition.invocationFromEncodeProfile;
|
|
74297
74539
|
exports.isAgentOnlyPlacement = isAgentOnlyPlacement;
|
|
74298
74540
|
exports.isAlarmControllableCap = isAlarmControllableCap;
|
|
74541
|
+
exports.isAppLinkBase = isAppLinkBase;
|
|
74299
74542
|
exports.isArrayOutputSchema = isArrayOutputSchema;
|
|
74300
74543
|
exports.isAudioChunkFormat = require_sleep.isAudioChunkFormat;
|
|
74301
74544
|
exports.isAudioClassName = isAudioClassName;
|
|
@@ -74442,6 +74685,7 @@ exports.parseStreamParamsFormPatch = parseStreamParamsFormPatch;
|
|
|
74442
74685
|
exports.patchAudio = patchAudio;
|
|
74443
74686
|
exports.petFeederCapability = petFeederCapability;
|
|
74444
74687
|
exports.pickAccessoryControl = pickAccessoryControl;
|
|
74688
|
+
exports.pickAppLinkHub = pickAppLinkHub;
|
|
74445
74689
|
exports.pickClusterStepModels = pickClusterStepModels;
|
|
74446
74690
|
exports.pickClusterStepSettings = pickClusterStepSettings;
|
|
74447
74691
|
exports.pickDetailCropConvention = pickDetailCropConvention;
|
|
@@ -74521,6 +74765,7 @@ exports.resolveLocationIcon = resolveLocationIcon;
|
|
|
74521
74765
|
exports.resolveLocationMode = resolveLocationMode;
|
|
74522
74766
|
exports.resolveMethodAuth = resolveMethodAuth;
|
|
74523
74767
|
exports.resolveModeDelays = resolveModeDelays;
|
|
74768
|
+
exports.resolveModeNotifyPolicy = resolveModeNotifyPolicy;
|
|
74524
74769
|
exports.resolveMutate = resolveMutate;
|
|
74525
74770
|
exports.resolvePoolMemoryPolicy = resolvePoolMemoryPolicy;
|
|
74526
74771
|
exports.resolveRecordingProfiles = resolveRecordingProfiles;
|
|
@@ -74629,6 +74874,7 @@ exports.templateVarsFor = templateVarsFor;
|
|
|
74629
74874
|
exports.terminalSessionCapability = terminalSessionCapability;
|
|
74630
74875
|
exports.textToHtml = textToHtml;
|
|
74631
74876
|
exports.timeOfDayToMinutes = timeOfDayToMinutes;
|
|
74877
|
+
exports.toAppLinkHubOrigin = toAppLinkHubOrigin;
|
|
74632
74878
|
exports.toDeviceSummary = toDeviceSummary;
|
|
74633
74879
|
exports.toExpressionValue = require_composition.toExpressionValue;
|
|
74634
74880
|
exports.toNodeId = require_sleep.toNodeId;
|
|
@@ -74656,6 +74902,7 @@ exports.vectorIndexDimConflictError = vectorIndexDimConflictError;
|
|
|
74656
74902
|
exports.vectorStoreCapability = vectorStoreCapability;
|
|
74657
74903
|
exports.vibrationCapability = vibrationCapability;
|
|
74658
74904
|
exports.videoclipsCapability = videoclipsCapability;
|
|
74905
|
+
exports.viewerLinkBaseOf = viewerLinkBaseOf;
|
|
74659
74906
|
exports.viewerUiCapability = require_sleep.viewerUiCapability;
|
|
74660
74907
|
exports.waterHeaterCapability = waterHeaterCapability;
|
|
74661
74908
|
exports.weatherCapability = weatherCapability;
|