@camstack/addon-provider-hikvision 1.1.27 → 1.1.29
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 +515 -5
- package/dist/addon.mjs +515 -5
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -7514,6 +7514,62 @@ var RecordingConfigSchema = object({
|
|
|
7514
7514
|
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7515
7515
|
});
|
|
7516
7516
|
/**
|
|
7517
|
+
* Ops-log — the durable, append-only operations audit shared by the
|
|
7518
|
+
* recordings and events management surfaces.
|
|
7519
|
+
*
|
|
7520
|
+
* ONE row shape is reused for both domains so a single "Activity" view can
|
|
7521
|
+
* merge the recorder's DurableState ring (recordings ops-log) and the
|
|
7522
|
+
* pipeline-analytics SQLite collection (events ops-log). Each row records a
|
|
7523
|
+
* management operation, WHY it ran (reason), and its measurable effect
|
|
7524
|
+
* (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
|
|
7525
|
+
* never fail the operation it records.
|
|
7526
|
+
*/
|
|
7527
|
+
/** Which management domain the operation belongs to. */
|
|
7528
|
+
var OpsLogDomainSchema = _enum(["recording", "events"]);
|
|
7529
|
+
/** The kind of management operation performed. */
|
|
7530
|
+
var OpsLogOpSchema = _enum([
|
|
7531
|
+
"prune",
|
|
7532
|
+
"manual-delete",
|
|
7533
|
+
"rescan",
|
|
7534
|
+
"retention-run"
|
|
7535
|
+
]);
|
|
7536
|
+
/** Why the operation ran. */
|
|
7537
|
+
var OpsLogReasonSchema = _enum([
|
|
7538
|
+
"retention",
|
|
7539
|
+
"quota",
|
|
7540
|
+
"manual",
|
|
7541
|
+
"operator"
|
|
7542
|
+
]);
|
|
7543
|
+
/** One audit row, shared verbatim by both domains. */
|
|
7544
|
+
var OpsLogEntrySchema = object({
|
|
7545
|
+
/** Unique row id. */
|
|
7546
|
+
id: string(),
|
|
7547
|
+
/** Epoch ms the operation completed. */
|
|
7548
|
+
at: number(),
|
|
7549
|
+
domain: OpsLogDomainSchema,
|
|
7550
|
+
op: OpsLogOpSchema,
|
|
7551
|
+
reason: OpsLogReasonSchema,
|
|
7552
|
+
/** The camera the op targeted; null for a cluster/global op. */
|
|
7553
|
+
deviceId: number().nullable(),
|
|
7554
|
+
/** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
|
|
7555
|
+
nodeId: string(),
|
|
7556
|
+
/** Buckets / rows deleted (op-specific unit). */
|
|
7557
|
+
itemsAffected: number(),
|
|
7558
|
+
/** Bytes reclaimed by the op (0 when not measurable). */
|
|
7559
|
+
bytesReclaimed: number(),
|
|
7560
|
+
/** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
|
|
7561
|
+
detail: string().nullable(),
|
|
7562
|
+
/** Who/what triggered the op. */
|
|
7563
|
+
actor: string()
|
|
7564
|
+
});
|
|
7565
|
+
/** Shared query input for the per-domain `listOpsLog` cap methods. */
|
|
7566
|
+
var OpsLogQueryInputSchema = object({
|
|
7567
|
+
/** Restrict to a single camera; omit for every row. */
|
|
7568
|
+
deviceId: number().optional(),
|
|
7569
|
+
/** Max rows returned, newest-first. */
|
|
7570
|
+
limit: number().int().min(1).max(1e3).optional()
|
|
7571
|
+
});
|
|
7572
|
+
/**
|
|
7517
7573
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
7518
7574
|
* storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
|
|
7519
7575
|
* so the persisted record schema and the consumer-facing cap can both consume it
|
|
@@ -7757,6 +7813,160 @@ var EncodeProfileSchema = object({
|
|
|
7757
7813
|
*/
|
|
7758
7814
|
outputArgs: array(string()).optional()
|
|
7759
7815
|
});
|
|
7816
|
+
var COCO_TO_MACRO = {
|
|
7817
|
+
mapping: {
|
|
7818
|
+
person: "person",
|
|
7819
|
+
bicycle: "vehicle",
|
|
7820
|
+
car: "vehicle",
|
|
7821
|
+
motorcycle: "vehicle",
|
|
7822
|
+
airplane: "vehicle",
|
|
7823
|
+
bus: "vehicle",
|
|
7824
|
+
train: "vehicle",
|
|
7825
|
+
truck: "vehicle",
|
|
7826
|
+
boat: "vehicle",
|
|
7827
|
+
bird: "animal",
|
|
7828
|
+
cat: "animal",
|
|
7829
|
+
dog: "animal",
|
|
7830
|
+
horse: "animal",
|
|
7831
|
+
sheep: "animal",
|
|
7832
|
+
cow: "animal",
|
|
7833
|
+
elephant: "animal",
|
|
7834
|
+
bear: "animal",
|
|
7835
|
+
zebra: "animal",
|
|
7836
|
+
giraffe: "animal",
|
|
7837
|
+
suitcase: "package",
|
|
7838
|
+
backpack: "package",
|
|
7839
|
+
handbag: "package"
|
|
7840
|
+
},
|
|
7841
|
+
preserveOriginal: false
|
|
7842
|
+
};
|
|
7843
|
+
var AUDIO_MACRO_LABELS = [
|
|
7844
|
+
{
|
|
7845
|
+
id: "speech",
|
|
7846
|
+
name: "Speech",
|
|
7847
|
+
icon: "🗣️"
|
|
7848
|
+
},
|
|
7849
|
+
{
|
|
7850
|
+
id: "scream",
|
|
7851
|
+
name: "Scream / Shout",
|
|
7852
|
+
icon: "😱"
|
|
7853
|
+
},
|
|
7854
|
+
{
|
|
7855
|
+
id: "crying",
|
|
7856
|
+
name: "Crying / Baby",
|
|
7857
|
+
icon: "😢"
|
|
7858
|
+
},
|
|
7859
|
+
{
|
|
7860
|
+
id: "laughter",
|
|
7861
|
+
name: "Laughter",
|
|
7862
|
+
icon: "😂"
|
|
7863
|
+
},
|
|
7864
|
+
{
|
|
7865
|
+
id: "music",
|
|
7866
|
+
name: "Music",
|
|
7867
|
+
icon: "🎵"
|
|
7868
|
+
},
|
|
7869
|
+
{
|
|
7870
|
+
id: "dog",
|
|
7871
|
+
name: "Dog",
|
|
7872
|
+
icon: "🐕"
|
|
7873
|
+
},
|
|
7874
|
+
{
|
|
7875
|
+
id: "cat",
|
|
7876
|
+
name: "Cat",
|
|
7877
|
+
icon: "🐈"
|
|
7878
|
+
},
|
|
7879
|
+
{
|
|
7880
|
+
id: "bird",
|
|
7881
|
+
name: "Bird",
|
|
7882
|
+
icon: "🐦"
|
|
7883
|
+
},
|
|
7884
|
+
{
|
|
7885
|
+
id: "animal",
|
|
7886
|
+
name: "Animal (other)",
|
|
7887
|
+
icon: "🐾"
|
|
7888
|
+
},
|
|
7889
|
+
{
|
|
7890
|
+
id: "alarm",
|
|
7891
|
+
name: "Alarm / Siren",
|
|
7892
|
+
icon: "🚨"
|
|
7893
|
+
},
|
|
7894
|
+
{
|
|
7895
|
+
id: "doorbell",
|
|
7896
|
+
name: "Doorbell / Knock",
|
|
7897
|
+
icon: "🔔"
|
|
7898
|
+
},
|
|
7899
|
+
{
|
|
7900
|
+
id: "glass_breaking",
|
|
7901
|
+
name: "Glass Breaking",
|
|
7902
|
+
icon: "💥"
|
|
7903
|
+
},
|
|
7904
|
+
{
|
|
7905
|
+
id: "gunshot",
|
|
7906
|
+
name: "Gunshot / Explosion",
|
|
7907
|
+
icon: "💣"
|
|
7908
|
+
},
|
|
7909
|
+
{
|
|
7910
|
+
id: "vehicle",
|
|
7911
|
+
name: "Vehicle",
|
|
7912
|
+
icon: "🚗"
|
|
7913
|
+
},
|
|
7914
|
+
{
|
|
7915
|
+
id: "siren",
|
|
7916
|
+
name: "Emergency Siren",
|
|
7917
|
+
icon: "🚑"
|
|
7918
|
+
},
|
|
7919
|
+
{
|
|
7920
|
+
id: "fire",
|
|
7921
|
+
name: "Fire / Smoke",
|
|
7922
|
+
icon: "🔥"
|
|
7923
|
+
},
|
|
7924
|
+
{
|
|
7925
|
+
id: "water",
|
|
7926
|
+
name: "Water",
|
|
7927
|
+
icon: "💧"
|
|
7928
|
+
},
|
|
7929
|
+
{
|
|
7930
|
+
id: "wind",
|
|
7931
|
+
name: "Wind / Weather",
|
|
7932
|
+
icon: "🌬️"
|
|
7933
|
+
},
|
|
7934
|
+
{
|
|
7935
|
+
id: "door",
|
|
7936
|
+
name: "Door",
|
|
7937
|
+
icon: "🚪"
|
|
7938
|
+
},
|
|
7939
|
+
{
|
|
7940
|
+
id: "footsteps",
|
|
7941
|
+
name: "Footsteps",
|
|
7942
|
+
icon: "👣"
|
|
7943
|
+
},
|
|
7944
|
+
{
|
|
7945
|
+
id: "crowd",
|
|
7946
|
+
name: "Crowd / Chatter",
|
|
7947
|
+
icon: "👥"
|
|
7948
|
+
},
|
|
7949
|
+
{
|
|
7950
|
+
id: "telephone",
|
|
7951
|
+
name: "Telephone",
|
|
7952
|
+
icon: "📞"
|
|
7953
|
+
},
|
|
7954
|
+
{
|
|
7955
|
+
id: "engine",
|
|
7956
|
+
name: "Engine / Motor",
|
|
7957
|
+
icon: "⚙️"
|
|
7958
|
+
},
|
|
7959
|
+
{
|
|
7960
|
+
id: "tools",
|
|
7961
|
+
name: "Tools / Construction",
|
|
7962
|
+
icon: "🔨"
|
|
7963
|
+
},
|
|
7964
|
+
{
|
|
7965
|
+
id: "silence",
|
|
7966
|
+
name: "Silence",
|
|
7967
|
+
icon: "🤫"
|
|
7968
|
+
}
|
|
7969
|
+
];
|
|
7760
7970
|
var YAMNET_TO_MACRO = {
|
|
7761
7971
|
mapping: {
|
|
7762
7972
|
Speech: "speech",
|
|
@@ -8023,6 +8233,125 @@ var _macroLookup = /* @__PURE__ */ new Map();
|
|
|
8023
8233
|
for (const [k, v] of Object.entries(YAMNET_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
8024
8234
|
for (const [k, v] of Object.entries(APPLE_SA_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
8025
8235
|
/**
|
|
8236
|
+
* Unified event-kind taxonomy — THE single source of truth for
|
|
8237
|
+
* `kind → { parentKind, category, level, color, iconId, labelKey, label,
|
|
8238
|
+
* icon }`.
|
|
8239
|
+
*
|
|
8240
|
+
* This dictionary folds together what used to be scattered across four
|
|
8241
|
+
* copies:
|
|
8242
|
+
* - `capabilities/sensor-event-kinds.ts` (sensor cap colors)
|
|
8243
|
+
* - `addon-post-analysis/.../services/event-kinds.ts`
|
|
8244
|
+
* (MOTION/PERSON/VEHICLE… _COLOR constants)
|
|
8245
|
+
* - `ui-library/composites/detection-colors.ts` (CLASS_COLORS)
|
|
8246
|
+
* - `addon-post-analysis/shared/frame/box-drawer.ts` (DEFAULT_COLOR)
|
|
8247
|
+
* - the COCO / audio class maps (macro ↔ sub relationships)
|
|
8248
|
+
*
|
|
8249
|
+
* The DATA (serializable — color/iconId/labelKey/parentKind) lives here in
|
|
8250
|
+
* `@camstack/types`. The UI-side mapping `iconId → lucide component` and
|
|
8251
|
+
* `labelKey → t()` lives in `@camstack/ui-library`. UIs never hardcode a
|
|
8252
|
+
* color or an icon: they read this dictionary (server descriptors carry the
|
|
8253
|
+
* fields inline; the client resolves color/icon/label from `iconId`/`kind`).
|
|
8254
|
+
*
|
|
8255
|
+
* Two levels only (v1 YAGNI): macro → sub. `person` is a leaf macro.
|
|
8256
|
+
*/
|
|
8257
|
+
var TAXONOMY_COLORS = {
|
|
8258
|
+
motion: "#f59e0b",
|
|
8259
|
+
audio: "#06b6d4",
|
|
8260
|
+
person: "#22c55e",
|
|
8261
|
+
vehicle: "#3b82f6",
|
|
8262
|
+
animal: "#f97316",
|
|
8263
|
+
package: "#a855f7",
|
|
8264
|
+
sensor: "#8b5cf6",
|
|
8265
|
+
control: "#10b981",
|
|
8266
|
+
genericDetection: "#64748b"
|
|
8267
|
+
};
|
|
8268
|
+
var DETECTION_SUB_COLORS = {
|
|
8269
|
+
car: "#f59e0b",
|
|
8270
|
+
truck: "#d97706",
|
|
8271
|
+
bus: "#b45309",
|
|
8272
|
+
motorcycle: "#eab308",
|
|
8273
|
+
bicycle: "#ca8a04",
|
|
8274
|
+
airplane: "#60a5fa",
|
|
8275
|
+
boat: "#2563eb",
|
|
8276
|
+
train: "#1d4ed8",
|
|
8277
|
+
bird: "#14b8a6",
|
|
8278
|
+
dog: "#84cc16",
|
|
8279
|
+
cat: "#f97316",
|
|
8280
|
+
horse: "#a16207",
|
|
8281
|
+
sheep: "#a3a3a3",
|
|
8282
|
+
cow: "#78716c",
|
|
8283
|
+
elephant: "#6b7280",
|
|
8284
|
+
bear: "#7c2d12",
|
|
8285
|
+
zebra: "#404040",
|
|
8286
|
+
giraffe: "#d4a373"
|
|
8287
|
+
};
|
|
8288
|
+
function titleCase(id) {
|
|
8289
|
+
return id.split(/[-_ ]/).filter((p) => p.length > 0).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(" ");
|
|
8290
|
+
}
|
|
8291
|
+
var entries = /* @__PURE__ */ new Map();
|
|
8292
|
+
function macro(kind, category, color, iconId, label) {
|
|
8293
|
+
entries.set(kind, {
|
|
8294
|
+
kind,
|
|
8295
|
+
parentKind: null,
|
|
8296
|
+
level: "macro",
|
|
8297
|
+
category,
|
|
8298
|
+
color,
|
|
8299
|
+
iconId,
|
|
8300
|
+
labelKey: `eventKind.${kind}`,
|
|
8301
|
+
label
|
|
8302
|
+
});
|
|
8303
|
+
}
|
|
8304
|
+
function sub(kind, parentKind, category, color, iconId, label) {
|
|
8305
|
+
entries.set(kind, {
|
|
8306
|
+
kind,
|
|
8307
|
+
parentKind,
|
|
8308
|
+
level: "sub",
|
|
8309
|
+
category,
|
|
8310
|
+
color,
|
|
8311
|
+
iconId,
|
|
8312
|
+
labelKey: `eventKind.${kind}`,
|
|
8313
|
+
label
|
|
8314
|
+
});
|
|
8315
|
+
}
|
|
8316
|
+
macro("motion", "motion", TAXONOMY_COLORS.motion, "motion", "Motion");
|
|
8317
|
+
macro("audio", "audio", TAXONOMY_COLORS.audio, "audio", "Audio");
|
|
8318
|
+
macro("person", "detection", TAXONOMY_COLORS.person, "person", "Person");
|
|
8319
|
+
macro("vehicle", "detection", TAXONOMY_COLORS.vehicle, "vehicle", "Vehicle");
|
|
8320
|
+
macro("animal", "detection", TAXONOMY_COLORS.animal, "animal", "Animal");
|
|
8321
|
+
macro("package", "package", TAXONOMY_COLORS.package, "package", "Package");
|
|
8322
|
+
macro("sensor", "sensor", TAXONOMY_COLORS.sensor, "sensor", "Sensor");
|
|
8323
|
+
macro("control", "control", TAXONOMY_COLORS.control, "control", "Control");
|
|
8324
|
+
for (const [cocoClass, macroClass] of Object.entries(COCO_TO_MACRO.mapping)) {
|
|
8325
|
+
if (macroClass !== "vehicle" && macroClass !== "animal") continue;
|
|
8326
|
+
if (entries.has(cocoClass)) continue;
|
|
8327
|
+
sub(cocoClass, macroClass, "detection", DETECTION_SUB_COLORS[cocoClass] ?? TAXONOMY_COLORS.genericDetection, cocoClass, titleCase(cocoClass));
|
|
8328
|
+
}
|
|
8329
|
+
sub("package-delivered", "package", "package", TAXONOMY_COLORS.package, "package", "Package delivered");
|
|
8330
|
+
sub("package-picked-up", "package", "package", TAXONOMY_COLORS.package, "package", "Package picked up");
|
|
8331
|
+
sub("contact", "sensor", "sensor", "#f59e0b", "door", "Contact");
|
|
8332
|
+
sub("motion-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "pir", "Motion sensor");
|
|
8333
|
+
sub("smoke", "sensor", "sensor", "#ef4444", "smoke", "Smoke");
|
|
8334
|
+
sub("flood", "sensor", "sensor", "#3b82f6", "water", "Water leak");
|
|
8335
|
+
sub("gas", "sensor", "sensor", "#ef4444", "gas", "Gas");
|
|
8336
|
+
sub("carbon-monoxide", "sensor", "sensor", "#dc2626", "smoke", "Carbon monoxide");
|
|
8337
|
+
sub("vibration", "sensor", "sensor", "#eab308", "vibration", "Vibration");
|
|
8338
|
+
sub("tamper", "sensor", "sensor", "#f97316", "tamper", "Tamper");
|
|
8339
|
+
sub("presence", "sensor", "sensor", "#22c55e", "presence", "Presence");
|
|
8340
|
+
sub("enum-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "generic", "Sensor state");
|
|
8341
|
+
sub("device-event", "sensor", "sensor", "#10b981", "button", "Device event");
|
|
8342
|
+
sub("lock", "control", "control", "#0ea5e9", "lock", "Lock");
|
|
8343
|
+
sub("switch", "control", "control", TAXONOMY_COLORS.control, "switch", "Switch");
|
|
8344
|
+
sub("siren", "control", "control", "#dc2626", "siren", "Siren");
|
|
8345
|
+
sub("button", "control", "control", "#10b981", "button", "Button");
|
|
8346
|
+
sub("doorbell", "control", "control", "#a855f7", "doorbell", "Doorbell");
|
|
8347
|
+
for (const l of AUDIO_MACRO_LABELS) {
|
|
8348
|
+
const kind = `audio-${l.id}`;
|
|
8349
|
+
if (entries.has(kind)) continue;
|
|
8350
|
+
sub(kind, "audio", "audio", TAXONOMY_COLORS.audio, kind, l.name);
|
|
8351
|
+
}
|
|
8352
|
+
/** The complete taxonomy dictionary, keyed by kind. */
|
|
8353
|
+
var EVENT_TAXONOMY = Object.freeze(Object.fromEntries(entries));
|
|
8354
|
+
/**
|
|
8026
8355
|
* Error types for the safe expression engine. Two distinct classes so callers
|
|
8027
8356
|
* can tell a compile-time (grammar) failure from a runtime (evaluation)
|
|
8028
8357
|
* failure — both are non-fatal to the host: read paths degrade to "skip link".
|
|
@@ -15082,9 +15411,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
15082
15411
|
* `package` backs the package-drop detector — a package zone is a
|
|
15083
15412
|
* `ZoneRule` on the `'package'` stage referencing drawn polygons
|
|
15084
15413
|
* (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
|
|
15085
|
-
* The orchestrator provider
|
|
15086
|
-
*
|
|
15087
|
-
* consumers read
|
|
15414
|
+
* The orchestrator provider writes this stage as a first-class slice
|
|
15415
|
+
* (Phase 4): every mutation mirrors the full `{motion, detection,
|
|
15416
|
+
* package}` shape, so consumers read the current package rules directly
|
|
15417
|
+
* off `device.state.zoneRules.value.package`.
|
|
15088
15418
|
*/
|
|
15089
15419
|
runtimeState: object({
|
|
15090
15420
|
motion: array(ZoneRuleSchema).readonly(),
|
|
@@ -19071,17 +19401,30 @@ var EventKindCategorySchema = _enum([
|
|
|
19071
19401
|
"audio",
|
|
19072
19402
|
"detection",
|
|
19073
19403
|
"sensor",
|
|
19404
|
+
"control",
|
|
19074
19405
|
"custom",
|
|
19075
19406
|
"package"
|
|
19076
19407
|
]);
|
|
19408
|
+
/** Taxonomy level — macro (timeline lane) vs sub (events-page leaf). */
|
|
19409
|
+
var EventKindLevelSchema = _enum(["macro", "sub"]);
|
|
19077
19410
|
var EventKindDescriptorSchema = object({
|
|
19078
|
-
/** Stable kind id (e.g. 'motion', '
|
|
19411
|
+
/** Stable kind id (e.g. 'motion', 'vehicle', 'car', 'lock'). */
|
|
19079
19412
|
kind: string(),
|
|
19413
|
+
/** i18n key resolved on the UI side; `label` is the English fallback. */
|
|
19414
|
+
labelKey: string(),
|
|
19415
|
+
/** English fallback label (kept for clients that don't translate). */
|
|
19080
19416
|
label: string(),
|
|
19081
19417
|
/** Hex color for timeline/legend rendering. */
|
|
19082
19418
|
color: string(),
|
|
19419
|
+
/** Dictionary id → lucide component on the UI side. */
|
|
19420
|
+
iconId: string(),
|
|
19421
|
+
/** Legacy closed-vocab glyph — fallback for `iconId`. */
|
|
19083
19422
|
icon: EventKindIconSchema,
|
|
19084
19423
|
category: EventKindCategorySchema,
|
|
19424
|
+
/** Macro parent for this kind ('car' → 'vehicle'); null for a macro. */
|
|
19425
|
+
parentKind: string().nullable(),
|
|
19426
|
+
/** Derived from `parentKind`, explicit for the client tree. */
|
|
19427
|
+
level: EventKindLevelSchema,
|
|
19085
19428
|
/** Which cap + device contributes this kind. For built-ins the camera
|
|
19086
19429
|
* itself; for sensor kinds the LINKED source device. */
|
|
19087
19430
|
source: object({
|
|
@@ -19154,11 +19497,21 @@ var TrackAudioLabelSchema = object({
|
|
|
19154
19497
|
firstAt: number(),
|
|
19155
19498
|
lastAt: number()
|
|
19156
19499
|
});
|
|
19500
|
+
/**
|
|
19501
|
+
* How a track was produced. `pipeline` (default / absent) = the spatial
|
|
19502
|
+
* detection+tracking pipeline. `sensor` = a SYNTHETIC track projected from a
|
|
19503
|
+
* linked sensor/control state change (no positions; carries a snapshot). The
|
|
19504
|
+
* spatial subsystems (tracker association, occupancy count, re-id/embedding,
|
|
19505
|
+
* resurrection) MUST skip `sensor` tracks — they have no bbox trajectory.
|
|
19506
|
+
*/
|
|
19507
|
+
var TrackSourceSchema = _enum(["pipeline", "sensor"]);
|
|
19157
19508
|
var TrackSchema = object({
|
|
19158
19509
|
trackId: string(),
|
|
19159
19510
|
deviceId: number(),
|
|
19160
19511
|
className: string(),
|
|
19161
19512
|
label: string().optional(),
|
|
19513
|
+
/** Track provenance. Absent ⇒ `pipeline` (legacy rows). */
|
|
19514
|
+
source: TrackSourceSchema.optional(),
|
|
19162
19515
|
firstSeen: number(),
|
|
19163
19516
|
lastSeen: number(),
|
|
19164
19517
|
/** Frame-rate position history (subject to maxPositionHistory cap). */
|
|
@@ -19413,6 +19766,26 @@ var TrackCascadeCountsSchema = object({
|
|
|
19413
19766
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
19414
19767
|
embeddings: number().int()
|
|
19415
19768
|
});
|
|
19769
|
+
/** Event-store footprint for one camera. */
|
|
19770
|
+
var EventStoreDeviceFootprintSchema = object({
|
|
19771
|
+
deviceId: number(),
|
|
19772
|
+
/** Persisted event rows (motion + object + audio) for the camera. */
|
|
19773
|
+
rows: number().int(),
|
|
19774
|
+
/** Event-owned media bytes on disk for the camera. */
|
|
19775
|
+
bytes: number().int()
|
|
19776
|
+
});
|
|
19777
|
+
/** Aggregate event-store footprint: global totals + per-camera breakdown. */
|
|
19778
|
+
var EventStoreFootprintSchema = object({
|
|
19779
|
+
totalRows: number().int(),
|
|
19780
|
+
totalBytes: number().int(),
|
|
19781
|
+
devices: array(EventStoreDeviceFootprintSchema).readonly()
|
|
19782
|
+
});
|
|
19783
|
+
/** Per-kind counts returned by the event-prune / device-delete mutations. */
|
|
19784
|
+
var EventPruneCountsSchema = object({
|
|
19785
|
+
motion: number().int(),
|
|
19786
|
+
object: number().int(),
|
|
19787
|
+
audio: number().int()
|
|
19788
|
+
});
|
|
19416
19789
|
DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
|
|
19417
19790
|
deviceId: number(),
|
|
19418
19791
|
trackId: string()
|
|
@@ -19476,6 +19849,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19476
19849
|
}), {
|
|
19477
19850
|
kind: "mutation",
|
|
19478
19851
|
auth: "admin"
|
|
19852
|
+
}), method(object({}), EventStoreFootprintSchema, {
|
|
19853
|
+
kind: "query",
|
|
19854
|
+
auth: "admin"
|
|
19855
|
+
}), method(object({
|
|
19856
|
+
olderThanMs: number(),
|
|
19857
|
+
reason: OpsLogReasonSchema.optional()
|
|
19858
|
+
}), EventPruneCountsSchema, {
|
|
19859
|
+
kind: "mutation",
|
|
19860
|
+
auth: "admin"
|
|
19861
|
+
}), method(object({ deviceId: number() }), EventPruneCountsSchema, {
|
|
19862
|
+
kind: "mutation",
|
|
19863
|
+
auth: "admin"
|
|
19864
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
19865
|
+
kind: "query",
|
|
19866
|
+
auth: "admin"
|
|
19479
19867
|
}), method(object({
|
|
19480
19868
|
eventId: string(),
|
|
19481
19869
|
kind: MediaFileKindEnum.optional()
|
|
@@ -19500,6 +19888,76 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19500
19888
|
eventId: string(),
|
|
19501
19889
|
timestamp: number()
|
|
19502
19890
|
});
|
|
19891
|
+
/**
|
|
19892
|
+
* Cap → event-kind mapping for the SENSOR / CONTROL cap families — the table
|
|
19893
|
+
* `pipeline-analytics.listEventKinds` uses to turn a linked device's bound
|
|
19894
|
+
* caps into per-camera event-kind descriptors.
|
|
19895
|
+
*
|
|
19896
|
+
* The descriptor DATA (color / iconId / labelKey / parentKind / category)
|
|
19897
|
+
* is NOT duplicated here — every entry is derived from the single
|
|
19898
|
+
* `EVENT_TAXONOMY` dictionary (`catalogs/event-taxonomy.ts`). This file owns
|
|
19899
|
+
* ONLY the cap-name → taxonomy-kind mapping. Adding a new eventful sensor /
|
|
19900
|
+
* control cap means adding one line here (and a taxonomy entry); the anti-
|
|
19901
|
+
* drift guard `scripts/check-event-kind-coverage.ts` fails the build if an
|
|
19902
|
+
* eventful cap is missing.
|
|
19903
|
+
*/
|
|
19904
|
+
/** Map a taxonomy `iconId` onto the legacy closed `EventKindIcon` enum. */
|
|
19905
|
+
var LEGACY_ICON = {
|
|
19906
|
+
motion: "motion",
|
|
19907
|
+
audio: "audio",
|
|
19908
|
+
person: "person",
|
|
19909
|
+
vehicle: "vehicle",
|
|
19910
|
+
animal: "animal",
|
|
19911
|
+
package: "package",
|
|
19912
|
+
door: "door",
|
|
19913
|
+
pir: "pir",
|
|
19914
|
+
smoke: "smoke",
|
|
19915
|
+
water: "water",
|
|
19916
|
+
button: "button",
|
|
19917
|
+
generic: "generic",
|
|
19918
|
+
gas: "smoke",
|
|
19919
|
+
vibration: "generic",
|
|
19920
|
+
tamper: "generic",
|
|
19921
|
+
presence: "person",
|
|
19922
|
+
lock: "generic",
|
|
19923
|
+
siren: "generic",
|
|
19924
|
+
switch: "generic",
|
|
19925
|
+
doorbell: "button"
|
|
19926
|
+
};
|
|
19927
|
+
function legacyIcon(iconId) {
|
|
19928
|
+
return LEGACY_ICON[iconId] ?? "generic";
|
|
19929
|
+
}
|
|
19930
|
+
/**
|
|
19931
|
+
* Cap name → taxonomy kind id. Covers EVERY eventful sensor / control cap.
|
|
19932
|
+
* The anti-drift guard cross-checks this against the eventful caps declared
|
|
19933
|
+
* in `packages/types/src/capabilities/*.cap.ts`.
|
|
19934
|
+
*/
|
|
19935
|
+
var CAP_TO_KIND = {
|
|
19936
|
+
contact: "contact",
|
|
19937
|
+
motion: "motion-sensor",
|
|
19938
|
+
smoke: "smoke",
|
|
19939
|
+
flood: "flood",
|
|
19940
|
+
gas: "gas",
|
|
19941
|
+
"carbon-monoxide": "carbon-monoxide",
|
|
19942
|
+
vibration: "vibration",
|
|
19943
|
+
tamper: "tamper",
|
|
19944
|
+
presence: "presence",
|
|
19945
|
+
"enum-sensor": "enum-sensor",
|
|
19946
|
+
"event-emitter": "device-event",
|
|
19947
|
+
"lock-control": "lock",
|
|
19948
|
+
switch: "switch",
|
|
19949
|
+
button: "button",
|
|
19950
|
+
doorbell: "doorbell"
|
|
19951
|
+
};
|
|
19952
|
+
function buildDescriptor(capName, kind) {
|
|
19953
|
+
const t = EVENT_TAXONOMY[kind];
|
|
19954
|
+
if (t === void 0) throw new Error(`EVENT_KIND_BY_CAP: cap '${capName}' maps to unknown taxonomy kind '${kind}'`);
|
|
19955
|
+
return {
|
|
19956
|
+
...t,
|
|
19957
|
+
icon: legacyIcon(t.iconId)
|
|
19958
|
+
};
|
|
19959
|
+
}
|
|
19960
|
+
Object.freeze(Object.fromEntries(Object.entries(CAP_TO_KIND).map(([capName, kind]) => [capName, buildDescriptor(capName, kind)])));
|
|
19503
19961
|
var CameraPipelineConfigSchema = object({
|
|
19504
19962
|
engine: PipelineEngineChoiceSchema.optional(),
|
|
19505
19963
|
steps: array(PipelineStepInputSchema).readonly(),
|
|
@@ -22924,13 +23382,29 @@ method(object({
|
|
|
22924
23382
|
}), method(object({ deviceId: number() }), RecordingStatusSchema, {
|
|
22925
23383
|
kind: "mutation",
|
|
22926
23384
|
auth: "admin"
|
|
22927
|
-
}), method(object({
|
|
23385
|
+
}), method(object({
|
|
23386
|
+
deviceId: number(),
|
|
23387
|
+
reason: OpsLogReasonSchema.optional()
|
|
23388
|
+
}), object({
|
|
22928
23389
|
floorMs: number().nullable(),
|
|
22929
23390
|
deletedBuckets: number().int(),
|
|
22930
23391
|
reclaimedBytes: number().int()
|
|
22931
23392
|
}), {
|
|
22932
23393
|
kind: "mutation",
|
|
22933
23394
|
auth: "admin"
|
|
23395
|
+
}), method(object({
|
|
23396
|
+
deviceId: number(),
|
|
23397
|
+
fromMs: number().optional(),
|
|
23398
|
+
toMs: number().optional()
|
|
23399
|
+
}), object({
|
|
23400
|
+
deletedBuckets: number().int(),
|
|
23401
|
+
reclaimedBytes: number().int()
|
|
23402
|
+
}), {
|
|
23403
|
+
kind: "mutation",
|
|
23404
|
+
auth: "admin"
|
|
23405
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
23406
|
+
kind: "query",
|
|
23407
|
+
auth: "admin"
|
|
22934
23408
|
});
|
|
22935
23409
|
/**
|
|
22936
23410
|
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
@@ -26263,6 +26737,12 @@ Object.freeze({
|
|
|
26263
26737
|
addonId: null,
|
|
26264
26738
|
access: "delete"
|
|
26265
26739
|
},
|
|
26740
|
+
"pipelineAnalytics.deleteDeviceEvents": {
|
|
26741
|
+
capName: "pipeline-analytics",
|
|
26742
|
+
capScope: "device",
|
|
26743
|
+
addonId: null,
|
|
26744
|
+
access: "delete"
|
|
26745
|
+
},
|
|
26266
26746
|
"pipelineAnalytics.deleteTracks": {
|
|
26267
26747
|
capName: "pipeline-analytics",
|
|
26268
26748
|
capScope: "device",
|
|
@@ -26293,6 +26773,12 @@ Object.freeze({
|
|
|
26293
26773
|
addonId: null,
|
|
26294
26774
|
access: "view"
|
|
26295
26775
|
},
|
|
26776
|
+
"pipelineAnalytics.getEventStoreFootprint": {
|
|
26777
|
+
capName: "pipeline-analytics",
|
|
26778
|
+
capScope: "device",
|
|
26779
|
+
addonId: null,
|
|
26780
|
+
access: "view"
|
|
26781
|
+
},
|
|
26296
26782
|
"pipelineAnalytics.getKeyEvents": {
|
|
26297
26783
|
capName: "pipeline-analytics",
|
|
26298
26784
|
capScope: "device",
|
|
@@ -26335,6 +26821,12 @@ Object.freeze({
|
|
|
26335
26821
|
addonId: null,
|
|
26336
26822
|
access: "view"
|
|
26337
26823
|
},
|
|
26824
|
+
"pipelineAnalytics.listOpsLog": {
|
|
26825
|
+
capName: "pipeline-analytics",
|
|
26826
|
+
capScope: "device",
|
|
26827
|
+
addonId: null,
|
|
26828
|
+
access: "view"
|
|
26829
|
+
},
|
|
26338
26830
|
"pipelineAnalytics.listRecentTracks": {
|
|
26339
26831
|
capName: "pipeline-analytics",
|
|
26340
26832
|
capScope: "device",
|
|
@@ -26347,6 +26839,12 @@ Object.freeze({
|
|
|
26347
26839
|
addonId: null,
|
|
26348
26840
|
access: "view"
|
|
26349
26841
|
},
|
|
26842
|
+
"pipelineAnalytics.pruneEvents": {
|
|
26843
|
+
capName: "pipeline-analytics",
|
|
26844
|
+
capScope: "device",
|
|
26845
|
+
addonId: null,
|
|
26846
|
+
access: "create"
|
|
26847
|
+
},
|
|
26350
26848
|
"pipelineAnalytics.pruneEventsBefore": {
|
|
26351
26849
|
capName: "pipeline-analytics",
|
|
26352
26850
|
capScope: "device",
|
|
@@ -27109,6 +27607,12 @@ Object.freeze({
|
|
|
27109
27607
|
addonId: null,
|
|
27110
27608
|
access: "create"
|
|
27111
27609
|
},
|
|
27610
|
+
"recording.deleteFootprint": {
|
|
27611
|
+
capName: "recording",
|
|
27612
|
+
capScope: "system",
|
|
27613
|
+
addonId: null,
|
|
27614
|
+
access: "delete"
|
|
27615
|
+
},
|
|
27112
27616
|
"recording.getAvailability": {
|
|
27113
27617
|
capName: "recording",
|
|
27114
27618
|
capScope: "system",
|
|
@@ -27139,6 +27643,12 @@ Object.freeze({
|
|
|
27139
27643
|
addonId: null,
|
|
27140
27644
|
access: "view"
|
|
27141
27645
|
},
|
|
27646
|
+
"recording.listOpsLog": {
|
|
27647
|
+
capName: "recording",
|
|
27648
|
+
capScope: "system",
|
|
27649
|
+
addonId: null,
|
|
27650
|
+
access: "view"
|
|
27651
|
+
},
|
|
27142
27652
|
"recording.locateSegment": {
|
|
27143
27653
|
capName: "recording",
|
|
27144
27654
|
capScope: "system",
|
package/dist/addon.mjs
CHANGED
|
@@ -7515,6 +7515,62 @@ var RecordingConfigSchema = object({
|
|
|
7515
7515
|
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7516
7516
|
});
|
|
7517
7517
|
/**
|
|
7518
|
+
* Ops-log — the durable, append-only operations audit shared by the
|
|
7519
|
+
* recordings and events management surfaces.
|
|
7520
|
+
*
|
|
7521
|
+
* ONE row shape is reused for both domains so a single "Activity" view can
|
|
7522
|
+
* merge the recorder's DurableState ring (recordings ops-log) and the
|
|
7523
|
+
* pipeline-analytics SQLite collection (events ops-log). Each row records a
|
|
7524
|
+
* management operation, WHY it ran (reason), and its measurable effect
|
|
7525
|
+
* (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
|
|
7526
|
+
* never fail the operation it records.
|
|
7527
|
+
*/
|
|
7528
|
+
/** Which management domain the operation belongs to. */
|
|
7529
|
+
var OpsLogDomainSchema = _enum(["recording", "events"]);
|
|
7530
|
+
/** The kind of management operation performed. */
|
|
7531
|
+
var OpsLogOpSchema = _enum([
|
|
7532
|
+
"prune",
|
|
7533
|
+
"manual-delete",
|
|
7534
|
+
"rescan",
|
|
7535
|
+
"retention-run"
|
|
7536
|
+
]);
|
|
7537
|
+
/** Why the operation ran. */
|
|
7538
|
+
var OpsLogReasonSchema = _enum([
|
|
7539
|
+
"retention",
|
|
7540
|
+
"quota",
|
|
7541
|
+
"manual",
|
|
7542
|
+
"operator"
|
|
7543
|
+
]);
|
|
7544
|
+
/** One audit row, shared verbatim by both domains. */
|
|
7545
|
+
var OpsLogEntrySchema = object({
|
|
7546
|
+
/** Unique row id. */
|
|
7547
|
+
id: string(),
|
|
7548
|
+
/** Epoch ms the operation completed. */
|
|
7549
|
+
at: number(),
|
|
7550
|
+
domain: OpsLogDomainSchema,
|
|
7551
|
+
op: OpsLogOpSchema,
|
|
7552
|
+
reason: OpsLogReasonSchema,
|
|
7553
|
+
/** The camera the op targeted; null for a cluster/global op. */
|
|
7554
|
+
deviceId: number().nullable(),
|
|
7555
|
+
/** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
|
|
7556
|
+
nodeId: string(),
|
|
7557
|
+
/** Buckets / rows deleted (op-specific unit). */
|
|
7558
|
+
itemsAffected: number(),
|
|
7559
|
+
/** Bytes reclaimed by the op (0 when not measurable). */
|
|
7560
|
+
bytesReclaimed: number(),
|
|
7561
|
+
/** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
|
|
7562
|
+
detail: string().nullable(),
|
|
7563
|
+
/** Who/what triggered the op. */
|
|
7564
|
+
actor: string()
|
|
7565
|
+
});
|
|
7566
|
+
/** Shared query input for the per-domain `listOpsLog` cap methods. */
|
|
7567
|
+
var OpsLogQueryInputSchema = object({
|
|
7568
|
+
/** Restrict to a single camera; omit for every row. */
|
|
7569
|
+
deviceId: number().optional(),
|
|
7570
|
+
/** Max rows returned, newest-first. */
|
|
7571
|
+
limit: number().int().min(1).max(1e3).optional()
|
|
7572
|
+
});
|
|
7573
|
+
/**
|
|
7518
7574
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
7519
7575
|
* storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
|
|
7520
7576
|
* so the persisted record schema and the consumer-facing cap can both consume it
|
|
@@ -7758,6 +7814,160 @@ var EncodeProfileSchema = object({
|
|
|
7758
7814
|
*/
|
|
7759
7815
|
outputArgs: array(string()).optional()
|
|
7760
7816
|
});
|
|
7817
|
+
var COCO_TO_MACRO = {
|
|
7818
|
+
mapping: {
|
|
7819
|
+
person: "person",
|
|
7820
|
+
bicycle: "vehicle",
|
|
7821
|
+
car: "vehicle",
|
|
7822
|
+
motorcycle: "vehicle",
|
|
7823
|
+
airplane: "vehicle",
|
|
7824
|
+
bus: "vehicle",
|
|
7825
|
+
train: "vehicle",
|
|
7826
|
+
truck: "vehicle",
|
|
7827
|
+
boat: "vehicle",
|
|
7828
|
+
bird: "animal",
|
|
7829
|
+
cat: "animal",
|
|
7830
|
+
dog: "animal",
|
|
7831
|
+
horse: "animal",
|
|
7832
|
+
sheep: "animal",
|
|
7833
|
+
cow: "animal",
|
|
7834
|
+
elephant: "animal",
|
|
7835
|
+
bear: "animal",
|
|
7836
|
+
zebra: "animal",
|
|
7837
|
+
giraffe: "animal",
|
|
7838
|
+
suitcase: "package",
|
|
7839
|
+
backpack: "package",
|
|
7840
|
+
handbag: "package"
|
|
7841
|
+
},
|
|
7842
|
+
preserveOriginal: false
|
|
7843
|
+
};
|
|
7844
|
+
var AUDIO_MACRO_LABELS = [
|
|
7845
|
+
{
|
|
7846
|
+
id: "speech",
|
|
7847
|
+
name: "Speech",
|
|
7848
|
+
icon: "🗣️"
|
|
7849
|
+
},
|
|
7850
|
+
{
|
|
7851
|
+
id: "scream",
|
|
7852
|
+
name: "Scream / Shout",
|
|
7853
|
+
icon: "😱"
|
|
7854
|
+
},
|
|
7855
|
+
{
|
|
7856
|
+
id: "crying",
|
|
7857
|
+
name: "Crying / Baby",
|
|
7858
|
+
icon: "😢"
|
|
7859
|
+
},
|
|
7860
|
+
{
|
|
7861
|
+
id: "laughter",
|
|
7862
|
+
name: "Laughter",
|
|
7863
|
+
icon: "😂"
|
|
7864
|
+
},
|
|
7865
|
+
{
|
|
7866
|
+
id: "music",
|
|
7867
|
+
name: "Music",
|
|
7868
|
+
icon: "🎵"
|
|
7869
|
+
},
|
|
7870
|
+
{
|
|
7871
|
+
id: "dog",
|
|
7872
|
+
name: "Dog",
|
|
7873
|
+
icon: "🐕"
|
|
7874
|
+
},
|
|
7875
|
+
{
|
|
7876
|
+
id: "cat",
|
|
7877
|
+
name: "Cat",
|
|
7878
|
+
icon: "🐈"
|
|
7879
|
+
},
|
|
7880
|
+
{
|
|
7881
|
+
id: "bird",
|
|
7882
|
+
name: "Bird",
|
|
7883
|
+
icon: "🐦"
|
|
7884
|
+
},
|
|
7885
|
+
{
|
|
7886
|
+
id: "animal",
|
|
7887
|
+
name: "Animal (other)",
|
|
7888
|
+
icon: "🐾"
|
|
7889
|
+
},
|
|
7890
|
+
{
|
|
7891
|
+
id: "alarm",
|
|
7892
|
+
name: "Alarm / Siren",
|
|
7893
|
+
icon: "🚨"
|
|
7894
|
+
},
|
|
7895
|
+
{
|
|
7896
|
+
id: "doorbell",
|
|
7897
|
+
name: "Doorbell / Knock",
|
|
7898
|
+
icon: "🔔"
|
|
7899
|
+
},
|
|
7900
|
+
{
|
|
7901
|
+
id: "glass_breaking",
|
|
7902
|
+
name: "Glass Breaking",
|
|
7903
|
+
icon: "💥"
|
|
7904
|
+
},
|
|
7905
|
+
{
|
|
7906
|
+
id: "gunshot",
|
|
7907
|
+
name: "Gunshot / Explosion",
|
|
7908
|
+
icon: "💣"
|
|
7909
|
+
},
|
|
7910
|
+
{
|
|
7911
|
+
id: "vehicle",
|
|
7912
|
+
name: "Vehicle",
|
|
7913
|
+
icon: "🚗"
|
|
7914
|
+
},
|
|
7915
|
+
{
|
|
7916
|
+
id: "siren",
|
|
7917
|
+
name: "Emergency Siren",
|
|
7918
|
+
icon: "🚑"
|
|
7919
|
+
},
|
|
7920
|
+
{
|
|
7921
|
+
id: "fire",
|
|
7922
|
+
name: "Fire / Smoke",
|
|
7923
|
+
icon: "🔥"
|
|
7924
|
+
},
|
|
7925
|
+
{
|
|
7926
|
+
id: "water",
|
|
7927
|
+
name: "Water",
|
|
7928
|
+
icon: "💧"
|
|
7929
|
+
},
|
|
7930
|
+
{
|
|
7931
|
+
id: "wind",
|
|
7932
|
+
name: "Wind / Weather",
|
|
7933
|
+
icon: "🌬️"
|
|
7934
|
+
},
|
|
7935
|
+
{
|
|
7936
|
+
id: "door",
|
|
7937
|
+
name: "Door",
|
|
7938
|
+
icon: "🚪"
|
|
7939
|
+
},
|
|
7940
|
+
{
|
|
7941
|
+
id: "footsteps",
|
|
7942
|
+
name: "Footsteps",
|
|
7943
|
+
icon: "👣"
|
|
7944
|
+
},
|
|
7945
|
+
{
|
|
7946
|
+
id: "crowd",
|
|
7947
|
+
name: "Crowd / Chatter",
|
|
7948
|
+
icon: "👥"
|
|
7949
|
+
},
|
|
7950
|
+
{
|
|
7951
|
+
id: "telephone",
|
|
7952
|
+
name: "Telephone",
|
|
7953
|
+
icon: "📞"
|
|
7954
|
+
},
|
|
7955
|
+
{
|
|
7956
|
+
id: "engine",
|
|
7957
|
+
name: "Engine / Motor",
|
|
7958
|
+
icon: "⚙️"
|
|
7959
|
+
},
|
|
7960
|
+
{
|
|
7961
|
+
id: "tools",
|
|
7962
|
+
name: "Tools / Construction",
|
|
7963
|
+
icon: "🔨"
|
|
7964
|
+
},
|
|
7965
|
+
{
|
|
7966
|
+
id: "silence",
|
|
7967
|
+
name: "Silence",
|
|
7968
|
+
icon: "🤫"
|
|
7969
|
+
}
|
|
7970
|
+
];
|
|
7761
7971
|
var YAMNET_TO_MACRO = {
|
|
7762
7972
|
mapping: {
|
|
7763
7973
|
Speech: "speech",
|
|
@@ -8024,6 +8234,125 @@ var _macroLookup = /* @__PURE__ */ new Map();
|
|
|
8024
8234
|
for (const [k, v] of Object.entries(YAMNET_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
8025
8235
|
for (const [k, v] of Object.entries(APPLE_SA_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
8026
8236
|
/**
|
|
8237
|
+
* Unified event-kind taxonomy — THE single source of truth for
|
|
8238
|
+
* `kind → { parentKind, category, level, color, iconId, labelKey, label,
|
|
8239
|
+
* icon }`.
|
|
8240
|
+
*
|
|
8241
|
+
* This dictionary folds together what used to be scattered across four
|
|
8242
|
+
* copies:
|
|
8243
|
+
* - `capabilities/sensor-event-kinds.ts` (sensor cap colors)
|
|
8244
|
+
* - `addon-post-analysis/.../services/event-kinds.ts`
|
|
8245
|
+
* (MOTION/PERSON/VEHICLE… _COLOR constants)
|
|
8246
|
+
* - `ui-library/composites/detection-colors.ts` (CLASS_COLORS)
|
|
8247
|
+
* - `addon-post-analysis/shared/frame/box-drawer.ts` (DEFAULT_COLOR)
|
|
8248
|
+
* - the COCO / audio class maps (macro ↔ sub relationships)
|
|
8249
|
+
*
|
|
8250
|
+
* The DATA (serializable — color/iconId/labelKey/parentKind) lives here in
|
|
8251
|
+
* `@camstack/types`. The UI-side mapping `iconId → lucide component` and
|
|
8252
|
+
* `labelKey → t()` lives in `@camstack/ui-library`. UIs never hardcode a
|
|
8253
|
+
* color or an icon: they read this dictionary (server descriptors carry the
|
|
8254
|
+
* fields inline; the client resolves color/icon/label from `iconId`/`kind`).
|
|
8255
|
+
*
|
|
8256
|
+
* Two levels only (v1 YAGNI): macro → sub. `person` is a leaf macro.
|
|
8257
|
+
*/
|
|
8258
|
+
var TAXONOMY_COLORS = {
|
|
8259
|
+
motion: "#f59e0b",
|
|
8260
|
+
audio: "#06b6d4",
|
|
8261
|
+
person: "#22c55e",
|
|
8262
|
+
vehicle: "#3b82f6",
|
|
8263
|
+
animal: "#f97316",
|
|
8264
|
+
package: "#a855f7",
|
|
8265
|
+
sensor: "#8b5cf6",
|
|
8266
|
+
control: "#10b981",
|
|
8267
|
+
genericDetection: "#64748b"
|
|
8268
|
+
};
|
|
8269
|
+
var DETECTION_SUB_COLORS = {
|
|
8270
|
+
car: "#f59e0b",
|
|
8271
|
+
truck: "#d97706",
|
|
8272
|
+
bus: "#b45309",
|
|
8273
|
+
motorcycle: "#eab308",
|
|
8274
|
+
bicycle: "#ca8a04",
|
|
8275
|
+
airplane: "#60a5fa",
|
|
8276
|
+
boat: "#2563eb",
|
|
8277
|
+
train: "#1d4ed8",
|
|
8278
|
+
bird: "#14b8a6",
|
|
8279
|
+
dog: "#84cc16",
|
|
8280
|
+
cat: "#f97316",
|
|
8281
|
+
horse: "#a16207",
|
|
8282
|
+
sheep: "#a3a3a3",
|
|
8283
|
+
cow: "#78716c",
|
|
8284
|
+
elephant: "#6b7280",
|
|
8285
|
+
bear: "#7c2d12",
|
|
8286
|
+
zebra: "#404040",
|
|
8287
|
+
giraffe: "#d4a373"
|
|
8288
|
+
};
|
|
8289
|
+
function titleCase(id) {
|
|
8290
|
+
return id.split(/[-_ ]/).filter((p) => p.length > 0).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(" ");
|
|
8291
|
+
}
|
|
8292
|
+
var entries = /* @__PURE__ */ new Map();
|
|
8293
|
+
function macro(kind, category, color, iconId, label) {
|
|
8294
|
+
entries.set(kind, {
|
|
8295
|
+
kind,
|
|
8296
|
+
parentKind: null,
|
|
8297
|
+
level: "macro",
|
|
8298
|
+
category,
|
|
8299
|
+
color,
|
|
8300
|
+
iconId,
|
|
8301
|
+
labelKey: `eventKind.${kind}`,
|
|
8302
|
+
label
|
|
8303
|
+
});
|
|
8304
|
+
}
|
|
8305
|
+
function sub(kind, parentKind, category, color, iconId, label) {
|
|
8306
|
+
entries.set(kind, {
|
|
8307
|
+
kind,
|
|
8308
|
+
parentKind,
|
|
8309
|
+
level: "sub",
|
|
8310
|
+
category,
|
|
8311
|
+
color,
|
|
8312
|
+
iconId,
|
|
8313
|
+
labelKey: `eventKind.${kind}`,
|
|
8314
|
+
label
|
|
8315
|
+
});
|
|
8316
|
+
}
|
|
8317
|
+
macro("motion", "motion", TAXONOMY_COLORS.motion, "motion", "Motion");
|
|
8318
|
+
macro("audio", "audio", TAXONOMY_COLORS.audio, "audio", "Audio");
|
|
8319
|
+
macro("person", "detection", TAXONOMY_COLORS.person, "person", "Person");
|
|
8320
|
+
macro("vehicle", "detection", TAXONOMY_COLORS.vehicle, "vehicle", "Vehicle");
|
|
8321
|
+
macro("animal", "detection", TAXONOMY_COLORS.animal, "animal", "Animal");
|
|
8322
|
+
macro("package", "package", TAXONOMY_COLORS.package, "package", "Package");
|
|
8323
|
+
macro("sensor", "sensor", TAXONOMY_COLORS.sensor, "sensor", "Sensor");
|
|
8324
|
+
macro("control", "control", TAXONOMY_COLORS.control, "control", "Control");
|
|
8325
|
+
for (const [cocoClass, macroClass] of Object.entries(COCO_TO_MACRO.mapping)) {
|
|
8326
|
+
if (macroClass !== "vehicle" && macroClass !== "animal") continue;
|
|
8327
|
+
if (entries.has(cocoClass)) continue;
|
|
8328
|
+
sub(cocoClass, macroClass, "detection", DETECTION_SUB_COLORS[cocoClass] ?? TAXONOMY_COLORS.genericDetection, cocoClass, titleCase(cocoClass));
|
|
8329
|
+
}
|
|
8330
|
+
sub("package-delivered", "package", "package", TAXONOMY_COLORS.package, "package", "Package delivered");
|
|
8331
|
+
sub("package-picked-up", "package", "package", TAXONOMY_COLORS.package, "package", "Package picked up");
|
|
8332
|
+
sub("contact", "sensor", "sensor", "#f59e0b", "door", "Contact");
|
|
8333
|
+
sub("motion-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "pir", "Motion sensor");
|
|
8334
|
+
sub("smoke", "sensor", "sensor", "#ef4444", "smoke", "Smoke");
|
|
8335
|
+
sub("flood", "sensor", "sensor", "#3b82f6", "water", "Water leak");
|
|
8336
|
+
sub("gas", "sensor", "sensor", "#ef4444", "gas", "Gas");
|
|
8337
|
+
sub("carbon-monoxide", "sensor", "sensor", "#dc2626", "smoke", "Carbon monoxide");
|
|
8338
|
+
sub("vibration", "sensor", "sensor", "#eab308", "vibration", "Vibration");
|
|
8339
|
+
sub("tamper", "sensor", "sensor", "#f97316", "tamper", "Tamper");
|
|
8340
|
+
sub("presence", "sensor", "sensor", "#22c55e", "presence", "Presence");
|
|
8341
|
+
sub("enum-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "generic", "Sensor state");
|
|
8342
|
+
sub("device-event", "sensor", "sensor", "#10b981", "button", "Device event");
|
|
8343
|
+
sub("lock", "control", "control", "#0ea5e9", "lock", "Lock");
|
|
8344
|
+
sub("switch", "control", "control", TAXONOMY_COLORS.control, "switch", "Switch");
|
|
8345
|
+
sub("siren", "control", "control", "#dc2626", "siren", "Siren");
|
|
8346
|
+
sub("button", "control", "control", "#10b981", "button", "Button");
|
|
8347
|
+
sub("doorbell", "control", "control", "#a855f7", "doorbell", "Doorbell");
|
|
8348
|
+
for (const l of AUDIO_MACRO_LABELS) {
|
|
8349
|
+
const kind = `audio-${l.id}`;
|
|
8350
|
+
if (entries.has(kind)) continue;
|
|
8351
|
+
sub(kind, "audio", "audio", TAXONOMY_COLORS.audio, kind, l.name);
|
|
8352
|
+
}
|
|
8353
|
+
/** The complete taxonomy dictionary, keyed by kind. */
|
|
8354
|
+
var EVENT_TAXONOMY = Object.freeze(Object.fromEntries(entries));
|
|
8355
|
+
/**
|
|
8027
8356
|
* Error types for the safe expression engine. Two distinct classes so callers
|
|
8028
8357
|
* can tell a compile-time (grammar) failure from a runtime (evaluation)
|
|
8029
8358
|
* failure — both are non-fatal to the host: read paths degrade to "skip link".
|
|
@@ -15083,9 +15412,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
15083
15412
|
* `package` backs the package-drop detector — a package zone is a
|
|
15084
15413
|
* `ZoneRule` on the `'package'` stage referencing drawn polygons
|
|
15085
15414
|
* (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
|
|
15086
|
-
* The orchestrator provider
|
|
15087
|
-
*
|
|
15088
|
-
* consumers read
|
|
15415
|
+
* The orchestrator provider writes this stage as a first-class slice
|
|
15416
|
+
* (Phase 4): every mutation mirrors the full `{motion, detection,
|
|
15417
|
+
* package}` shape, so consumers read the current package rules directly
|
|
15418
|
+
* off `device.state.zoneRules.value.package`.
|
|
15089
15419
|
*/
|
|
15090
15420
|
runtimeState: object({
|
|
15091
15421
|
motion: array(ZoneRuleSchema).readonly(),
|
|
@@ -19072,17 +19402,30 @@ var EventKindCategorySchema = _enum([
|
|
|
19072
19402
|
"audio",
|
|
19073
19403
|
"detection",
|
|
19074
19404
|
"sensor",
|
|
19405
|
+
"control",
|
|
19075
19406
|
"custom",
|
|
19076
19407
|
"package"
|
|
19077
19408
|
]);
|
|
19409
|
+
/** Taxonomy level — macro (timeline lane) vs sub (events-page leaf). */
|
|
19410
|
+
var EventKindLevelSchema = _enum(["macro", "sub"]);
|
|
19078
19411
|
var EventKindDescriptorSchema = object({
|
|
19079
|
-
/** Stable kind id (e.g. 'motion', '
|
|
19412
|
+
/** Stable kind id (e.g. 'motion', 'vehicle', 'car', 'lock'). */
|
|
19080
19413
|
kind: string(),
|
|
19414
|
+
/** i18n key resolved on the UI side; `label` is the English fallback. */
|
|
19415
|
+
labelKey: string(),
|
|
19416
|
+
/** English fallback label (kept for clients that don't translate). */
|
|
19081
19417
|
label: string(),
|
|
19082
19418
|
/** Hex color for timeline/legend rendering. */
|
|
19083
19419
|
color: string(),
|
|
19420
|
+
/** Dictionary id → lucide component on the UI side. */
|
|
19421
|
+
iconId: string(),
|
|
19422
|
+
/** Legacy closed-vocab glyph — fallback for `iconId`. */
|
|
19084
19423
|
icon: EventKindIconSchema,
|
|
19085
19424
|
category: EventKindCategorySchema,
|
|
19425
|
+
/** Macro parent for this kind ('car' → 'vehicle'); null for a macro. */
|
|
19426
|
+
parentKind: string().nullable(),
|
|
19427
|
+
/** Derived from `parentKind`, explicit for the client tree. */
|
|
19428
|
+
level: EventKindLevelSchema,
|
|
19086
19429
|
/** Which cap + device contributes this kind. For built-ins the camera
|
|
19087
19430
|
* itself; for sensor kinds the LINKED source device. */
|
|
19088
19431
|
source: object({
|
|
@@ -19155,11 +19498,21 @@ var TrackAudioLabelSchema = object({
|
|
|
19155
19498
|
firstAt: number(),
|
|
19156
19499
|
lastAt: number()
|
|
19157
19500
|
});
|
|
19501
|
+
/**
|
|
19502
|
+
* How a track was produced. `pipeline` (default / absent) = the spatial
|
|
19503
|
+
* detection+tracking pipeline. `sensor` = a SYNTHETIC track projected from a
|
|
19504
|
+
* linked sensor/control state change (no positions; carries a snapshot). The
|
|
19505
|
+
* spatial subsystems (tracker association, occupancy count, re-id/embedding,
|
|
19506
|
+
* resurrection) MUST skip `sensor` tracks — they have no bbox trajectory.
|
|
19507
|
+
*/
|
|
19508
|
+
var TrackSourceSchema = _enum(["pipeline", "sensor"]);
|
|
19158
19509
|
var TrackSchema = object({
|
|
19159
19510
|
trackId: string(),
|
|
19160
19511
|
deviceId: number(),
|
|
19161
19512
|
className: string(),
|
|
19162
19513
|
label: string().optional(),
|
|
19514
|
+
/** Track provenance. Absent ⇒ `pipeline` (legacy rows). */
|
|
19515
|
+
source: TrackSourceSchema.optional(),
|
|
19163
19516
|
firstSeen: number(),
|
|
19164
19517
|
lastSeen: number(),
|
|
19165
19518
|
/** Frame-rate position history (subject to maxPositionHistory cap). */
|
|
@@ -19414,6 +19767,26 @@ var TrackCascadeCountsSchema = object({
|
|
|
19414
19767
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
19415
19768
|
embeddings: number().int()
|
|
19416
19769
|
});
|
|
19770
|
+
/** Event-store footprint for one camera. */
|
|
19771
|
+
var EventStoreDeviceFootprintSchema = object({
|
|
19772
|
+
deviceId: number(),
|
|
19773
|
+
/** Persisted event rows (motion + object + audio) for the camera. */
|
|
19774
|
+
rows: number().int(),
|
|
19775
|
+
/** Event-owned media bytes on disk for the camera. */
|
|
19776
|
+
bytes: number().int()
|
|
19777
|
+
});
|
|
19778
|
+
/** Aggregate event-store footprint: global totals + per-camera breakdown. */
|
|
19779
|
+
var EventStoreFootprintSchema = object({
|
|
19780
|
+
totalRows: number().int(),
|
|
19781
|
+
totalBytes: number().int(),
|
|
19782
|
+
devices: array(EventStoreDeviceFootprintSchema).readonly()
|
|
19783
|
+
});
|
|
19784
|
+
/** Per-kind counts returned by the event-prune / device-delete mutations. */
|
|
19785
|
+
var EventPruneCountsSchema = object({
|
|
19786
|
+
motion: number().int(),
|
|
19787
|
+
object: number().int(),
|
|
19788
|
+
audio: number().int()
|
|
19789
|
+
});
|
|
19417
19790
|
DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
|
|
19418
19791
|
deviceId: number(),
|
|
19419
19792
|
trackId: string()
|
|
@@ -19477,6 +19850,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19477
19850
|
}), {
|
|
19478
19851
|
kind: "mutation",
|
|
19479
19852
|
auth: "admin"
|
|
19853
|
+
}), method(object({}), EventStoreFootprintSchema, {
|
|
19854
|
+
kind: "query",
|
|
19855
|
+
auth: "admin"
|
|
19856
|
+
}), method(object({
|
|
19857
|
+
olderThanMs: number(),
|
|
19858
|
+
reason: OpsLogReasonSchema.optional()
|
|
19859
|
+
}), EventPruneCountsSchema, {
|
|
19860
|
+
kind: "mutation",
|
|
19861
|
+
auth: "admin"
|
|
19862
|
+
}), method(object({ deviceId: number() }), EventPruneCountsSchema, {
|
|
19863
|
+
kind: "mutation",
|
|
19864
|
+
auth: "admin"
|
|
19865
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
19866
|
+
kind: "query",
|
|
19867
|
+
auth: "admin"
|
|
19480
19868
|
}), method(object({
|
|
19481
19869
|
eventId: string(),
|
|
19482
19870
|
kind: MediaFileKindEnum.optional()
|
|
@@ -19501,6 +19889,76 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19501
19889
|
eventId: string(),
|
|
19502
19890
|
timestamp: number()
|
|
19503
19891
|
});
|
|
19892
|
+
/**
|
|
19893
|
+
* Cap → event-kind mapping for the SENSOR / CONTROL cap families — the table
|
|
19894
|
+
* `pipeline-analytics.listEventKinds` uses to turn a linked device's bound
|
|
19895
|
+
* caps into per-camera event-kind descriptors.
|
|
19896
|
+
*
|
|
19897
|
+
* The descriptor DATA (color / iconId / labelKey / parentKind / category)
|
|
19898
|
+
* is NOT duplicated here — every entry is derived from the single
|
|
19899
|
+
* `EVENT_TAXONOMY` dictionary (`catalogs/event-taxonomy.ts`). This file owns
|
|
19900
|
+
* ONLY the cap-name → taxonomy-kind mapping. Adding a new eventful sensor /
|
|
19901
|
+
* control cap means adding one line here (and a taxonomy entry); the anti-
|
|
19902
|
+
* drift guard `scripts/check-event-kind-coverage.ts` fails the build if an
|
|
19903
|
+
* eventful cap is missing.
|
|
19904
|
+
*/
|
|
19905
|
+
/** Map a taxonomy `iconId` onto the legacy closed `EventKindIcon` enum. */
|
|
19906
|
+
var LEGACY_ICON = {
|
|
19907
|
+
motion: "motion",
|
|
19908
|
+
audio: "audio",
|
|
19909
|
+
person: "person",
|
|
19910
|
+
vehicle: "vehicle",
|
|
19911
|
+
animal: "animal",
|
|
19912
|
+
package: "package",
|
|
19913
|
+
door: "door",
|
|
19914
|
+
pir: "pir",
|
|
19915
|
+
smoke: "smoke",
|
|
19916
|
+
water: "water",
|
|
19917
|
+
button: "button",
|
|
19918
|
+
generic: "generic",
|
|
19919
|
+
gas: "smoke",
|
|
19920
|
+
vibration: "generic",
|
|
19921
|
+
tamper: "generic",
|
|
19922
|
+
presence: "person",
|
|
19923
|
+
lock: "generic",
|
|
19924
|
+
siren: "generic",
|
|
19925
|
+
switch: "generic",
|
|
19926
|
+
doorbell: "button"
|
|
19927
|
+
};
|
|
19928
|
+
function legacyIcon(iconId) {
|
|
19929
|
+
return LEGACY_ICON[iconId] ?? "generic";
|
|
19930
|
+
}
|
|
19931
|
+
/**
|
|
19932
|
+
* Cap name → taxonomy kind id. Covers EVERY eventful sensor / control cap.
|
|
19933
|
+
* The anti-drift guard cross-checks this against the eventful caps declared
|
|
19934
|
+
* in `packages/types/src/capabilities/*.cap.ts`.
|
|
19935
|
+
*/
|
|
19936
|
+
var CAP_TO_KIND = {
|
|
19937
|
+
contact: "contact",
|
|
19938
|
+
motion: "motion-sensor",
|
|
19939
|
+
smoke: "smoke",
|
|
19940
|
+
flood: "flood",
|
|
19941
|
+
gas: "gas",
|
|
19942
|
+
"carbon-monoxide": "carbon-monoxide",
|
|
19943
|
+
vibration: "vibration",
|
|
19944
|
+
tamper: "tamper",
|
|
19945
|
+
presence: "presence",
|
|
19946
|
+
"enum-sensor": "enum-sensor",
|
|
19947
|
+
"event-emitter": "device-event",
|
|
19948
|
+
"lock-control": "lock",
|
|
19949
|
+
switch: "switch",
|
|
19950
|
+
button: "button",
|
|
19951
|
+
doorbell: "doorbell"
|
|
19952
|
+
};
|
|
19953
|
+
function buildDescriptor(capName, kind) {
|
|
19954
|
+
const t = EVENT_TAXONOMY[kind];
|
|
19955
|
+
if (t === void 0) throw new Error(`EVENT_KIND_BY_CAP: cap '${capName}' maps to unknown taxonomy kind '${kind}'`);
|
|
19956
|
+
return {
|
|
19957
|
+
...t,
|
|
19958
|
+
icon: legacyIcon(t.iconId)
|
|
19959
|
+
};
|
|
19960
|
+
}
|
|
19961
|
+
Object.freeze(Object.fromEntries(Object.entries(CAP_TO_KIND).map(([capName, kind]) => [capName, buildDescriptor(capName, kind)])));
|
|
19504
19962
|
var CameraPipelineConfigSchema = object({
|
|
19505
19963
|
engine: PipelineEngineChoiceSchema.optional(),
|
|
19506
19964
|
steps: array(PipelineStepInputSchema).readonly(),
|
|
@@ -22925,13 +23383,29 @@ method(object({
|
|
|
22925
23383
|
}), method(object({ deviceId: number() }), RecordingStatusSchema, {
|
|
22926
23384
|
kind: "mutation",
|
|
22927
23385
|
auth: "admin"
|
|
22928
|
-
}), method(object({
|
|
23386
|
+
}), method(object({
|
|
23387
|
+
deviceId: number(),
|
|
23388
|
+
reason: OpsLogReasonSchema.optional()
|
|
23389
|
+
}), object({
|
|
22929
23390
|
floorMs: number().nullable(),
|
|
22930
23391
|
deletedBuckets: number().int(),
|
|
22931
23392
|
reclaimedBytes: number().int()
|
|
22932
23393
|
}), {
|
|
22933
23394
|
kind: "mutation",
|
|
22934
23395
|
auth: "admin"
|
|
23396
|
+
}), method(object({
|
|
23397
|
+
deviceId: number(),
|
|
23398
|
+
fromMs: number().optional(),
|
|
23399
|
+
toMs: number().optional()
|
|
23400
|
+
}), object({
|
|
23401
|
+
deletedBuckets: number().int(),
|
|
23402
|
+
reclaimedBytes: number().int()
|
|
23403
|
+
}), {
|
|
23404
|
+
kind: "mutation",
|
|
23405
|
+
auth: "admin"
|
|
23406
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
23407
|
+
kind: "query",
|
|
23408
|
+
auth: "admin"
|
|
22935
23409
|
});
|
|
22936
23410
|
/**
|
|
22937
23411
|
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
@@ -26264,6 +26738,12 @@ Object.freeze({
|
|
|
26264
26738
|
addonId: null,
|
|
26265
26739
|
access: "delete"
|
|
26266
26740
|
},
|
|
26741
|
+
"pipelineAnalytics.deleteDeviceEvents": {
|
|
26742
|
+
capName: "pipeline-analytics",
|
|
26743
|
+
capScope: "device",
|
|
26744
|
+
addonId: null,
|
|
26745
|
+
access: "delete"
|
|
26746
|
+
},
|
|
26267
26747
|
"pipelineAnalytics.deleteTracks": {
|
|
26268
26748
|
capName: "pipeline-analytics",
|
|
26269
26749
|
capScope: "device",
|
|
@@ -26294,6 +26774,12 @@ Object.freeze({
|
|
|
26294
26774
|
addonId: null,
|
|
26295
26775
|
access: "view"
|
|
26296
26776
|
},
|
|
26777
|
+
"pipelineAnalytics.getEventStoreFootprint": {
|
|
26778
|
+
capName: "pipeline-analytics",
|
|
26779
|
+
capScope: "device",
|
|
26780
|
+
addonId: null,
|
|
26781
|
+
access: "view"
|
|
26782
|
+
},
|
|
26297
26783
|
"pipelineAnalytics.getKeyEvents": {
|
|
26298
26784
|
capName: "pipeline-analytics",
|
|
26299
26785
|
capScope: "device",
|
|
@@ -26336,6 +26822,12 @@ Object.freeze({
|
|
|
26336
26822
|
addonId: null,
|
|
26337
26823
|
access: "view"
|
|
26338
26824
|
},
|
|
26825
|
+
"pipelineAnalytics.listOpsLog": {
|
|
26826
|
+
capName: "pipeline-analytics",
|
|
26827
|
+
capScope: "device",
|
|
26828
|
+
addonId: null,
|
|
26829
|
+
access: "view"
|
|
26830
|
+
},
|
|
26339
26831
|
"pipelineAnalytics.listRecentTracks": {
|
|
26340
26832
|
capName: "pipeline-analytics",
|
|
26341
26833
|
capScope: "device",
|
|
@@ -26348,6 +26840,12 @@ Object.freeze({
|
|
|
26348
26840
|
addonId: null,
|
|
26349
26841
|
access: "view"
|
|
26350
26842
|
},
|
|
26843
|
+
"pipelineAnalytics.pruneEvents": {
|
|
26844
|
+
capName: "pipeline-analytics",
|
|
26845
|
+
capScope: "device",
|
|
26846
|
+
addonId: null,
|
|
26847
|
+
access: "create"
|
|
26848
|
+
},
|
|
26351
26849
|
"pipelineAnalytics.pruneEventsBefore": {
|
|
26352
26850
|
capName: "pipeline-analytics",
|
|
26353
26851
|
capScope: "device",
|
|
@@ -27110,6 +27608,12 @@ Object.freeze({
|
|
|
27110
27608
|
addonId: null,
|
|
27111
27609
|
access: "create"
|
|
27112
27610
|
},
|
|
27611
|
+
"recording.deleteFootprint": {
|
|
27612
|
+
capName: "recording",
|
|
27613
|
+
capScope: "system",
|
|
27614
|
+
addonId: null,
|
|
27615
|
+
access: "delete"
|
|
27616
|
+
},
|
|
27113
27617
|
"recording.getAvailability": {
|
|
27114
27618
|
capName: "recording",
|
|
27115
27619
|
capScope: "system",
|
|
@@ -27140,6 +27644,12 @@ Object.freeze({
|
|
|
27140
27644
|
addonId: null,
|
|
27141
27645
|
access: "view"
|
|
27142
27646
|
},
|
|
27647
|
+
"recording.listOpsLog": {
|
|
27648
|
+
capName: "recording",
|
|
27649
|
+
capScope: "system",
|
|
27650
|
+
addonId: null,
|
|
27651
|
+
access: "view"
|
|
27652
|
+
},
|
|
27143
27653
|
"recording.locateSegment": {
|
|
27144
27654
|
capName: "recording",
|
|
27145
27655
|
capScope: "system",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-provider-hikvision",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.29",
|
|
4
4
|
"description": "Hikvision camera device provider addon for CamStack — ISAPI over HTTP(S) with digest auth (snapshot, alarm stream, RTSP discovery)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|