@camstack/addon-post-analysis 1.2.201 → 1.2.203
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{dist-1xB8qj2h.mjs → dist-B2bqI0T1.mjs} +17 -7
- package/dist/{dist-DbgfbjZC.js → dist-rqvrMbFv.js} +17 -7
- package/dist/embedding-encoder/index.js +1 -1
- package/dist/embedding-encoder/index.mjs +1 -1
- package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-DwFi68p5.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-BhGMdGiF.mjs} +3 -3
- package/dist/pipeline-analytics/{hostInit-POMJnj4w.mjs → hostInit-1Wpi1AHy.mjs} +3 -3
- package/dist/pipeline-analytics/index.js +97 -7
- package/dist/pipeline-analytics/index.mjs +97 -7
- package/dist/pipeline-analytics/remoteEntry.js +1 -1
- package/package.json +1 -1
|
@@ -12525,6 +12525,9 @@ var QueryFilterSchema = object({
|
|
|
12525
12525
|
whereBetween: record(string(), tuple([unknown(), unknown()])).optional(),
|
|
12526
12526
|
/** NULL-safe exclusion: matches rows whose field is NULL OR != the value. */
|
|
12527
12527
|
whereNot: record(string(), unknown()).optional(),
|
|
12528
|
+
/** NULL-safe exclusion of a SET — `whereNot` for more than one value. An
|
|
12529
|
+
* empty list excludes nothing. See `QueryFilter.whereNotIn`. */
|
|
12530
|
+
whereNotIn: record(string(), array(unknown())).optional(),
|
|
12528
12531
|
orderBy: object({
|
|
12529
12532
|
field: string(),
|
|
12530
12533
|
direction: _enum(["asc", "desc"])
|
|
@@ -12545,7 +12548,8 @@ var MutationFilterSchema = object({
|
|
|
12545
12548
|
where: record(string(), unknown()).optional(),
|
|
12546
12549
|
whereIn: record(string(), array(unknown())).optional(),
|
|
12547
12550
|
whereBetween: record(string(), tuple([unknown(), unknown()])).optional(),
|
|
12548
|
-
whereNot: record(string(), unknown()).optional()
|
|
12551
|
+
whereNot: record(string(), unknown()).optional(),
|
|
12552
|
+
whereNotIn: record(string(), array(unknown())).optional()
|
|
12549
12553
|
});
|
|
12550
12554
|
/**
|
|
12551
12555
|
* One scalar an {@link settingsStoreCapability.methods.aggregate} call asks for.
|
|
@@ -19884,10 +19888,12 @@ var TrackSourceSchema = _enum([
|
|
|
19884
19888
|
* Terminal for the plain `markForTrain` toggle: returning it to `staging` is
|
|
19885
19889
|
* a deliberate action of the retrain page, not a side effect of a checkbox.
|
|
19886
19890
|
*
|
|
19887
|
-
* There is no `null`. The state is stored `TEXT NOT NULL DEFAULT 'none'`
|
|
19888
|
-
*
|
|
19889
|
-
*
|
|
19890
|
-
*
|
|
19891
|
+
* There is no `null`. The state is stored `TEXT NOT NULL DEFAULT 'none'` so that
|
|
19892
|
+
* every row is selectable by a positive predicate. (The filter language has
|
|
19893
|
+
* since grown the NULL-safe `whereNot` / `whereNotIn` and an `IS NULL` reading
|
|
19894
|
+
* of `where: { f: null }`, which is how {@link TrackSourceSchema} can be
|
|
19895
|
+
* filtered on a NULLABLE column — see `excludeSources`. It did not when this
|
|
19896
|
+
* column was designed, and a NOT NULL column is still the better shape.)
|
|
19891
19897
|
*/
|
|
19892
19898
|
var RetrainStatusSchema = _enum([
|
|
19893
19899
|
"none",
|
|
@@ -20623,7 +20629,9 @@ var RecentTracksQueryInput = object({
|
|
|
20623
20629
|
* whose class list is unreadable are kept, and the client's rule stays the
|
|
20624
20630
|
* exact one.
|
|
20625
20631
|
*/
|
|
20626
|
-
classes: array(string()).optional()
|
|
20632
|
+
classes: array(string()).optional(),
|
|
20633
|
+
/** See {@link ExcludeSourcesDoc}. */
|
|
20634
|
+
excludeSources: array(TrackSourceSchema).optional()
|
|
20627
20635
|
});
|
|
20628
20636
|
/**
|
|
20629
20637
|
* A Summary (D359): the per-camera session envelope that references tracks.
|
|
@@ -21065,7 +21073,9 @@ var pipelineAnalyticsCapability = {
|
|
|
21065
21073
|
* selected is an operator who has not narrowed anything, and an empty
|
|
21066
21074
|
* timeline would read as a camera that saw nothing.
|
|
21067
21075
|
*/
|
|
21068
|
-
classes: array(string()).optional()
|
|
21076
|
+
classes: array(string()).optional(),
|
|
21077
|
+
/** See {@link ExcludeSourcesDoc}. */
|
|
21078
|
+
excludeSources: array(TrackSourceSchema).optional()
|
|
21069
21079
|
}), array(TrackSchema).readonly()),
|
|
21070
21080
|
/**
|
|
21071
21081
|
* Batched cluster-wide track listing — ONE call for the events page /
|
|
@@ -12556,6 +12556,9 @@ var QueryFilterSchema = object({
|
|
|
12556
12556
|
whereBetween: record(string(), tuple([unknown(), unknown()])).optional(),
|
|
12557
12557
|
/** NULL-safe exclusion: matches rows whose field is NULL OR != the value. */
|
|
12558
12558
|
whereNot: record(string(), unknown()).optional(),
|
|
12559
|
+
/** NULL-safe exclusion of a SET — `whereNot` for more than one value. An
|
|
12560
|
+
* empty list excludes nothing. See `QueryFilter.whereNotIn`. */
|
|
12561
|
+
whereNotIn: record(string(), array(unknown())).optional(),
|
|
12559
12562
|
orderBy: object({
|
|
12560
12563
|
field: string(),
|
|
12561
12564
|
direction: _enum(["asc", "desc"])
|
|
@@ -12576,7 +12579,8 @@ var MutationFilterSchema = object({
|
|
|
12576
12579
|
where: record(string(), unknown()).optional(),
|
|
12577
12580
|
whereIn: record(string(), array(unknown())).optional(),
|
|
12578
12581
|
whereBetween: record(string(), tuple([unknown(), unknown()])).optional(),
|
|
12579
|
-
whereNot: record(string(), unknown()).optional()
|
|
12582
|
+
whereNot: record(string(), unknown()).optional(),
|
|
12583
|
+
whereNotIn: record(string(), array(unknown())).optional()
|
|
12580
12584
|
});
|
|
12581
12585
|
/**
|
|
12582
12586
|
* One scalar an {@link settingsStoreCapability.methods.aggregate} call asks for.
|
|
@@ -19915,10 +19919,12 @@ var TrackSourceSchema = _enum([
|
|
|
19915
19919
|
* Terminal for the plain `markForTrain` toggle: returning it to `staging` is
|
|
19916
19920
|
* a deliberate action of the retrain page, not a side effect of a checkbox.
|
|
19917
19921
|
*
|
|
19918
|
-
* There is no `null`. The state is stored `TEXT NOT NULL DEFAULT 'none'`
|
|
19919
|
-
*
|
|
19920
|
-
*
|
|
19921
|
-
*
|
|
19922
|
+
* There is no `null`. The state is stored `TEXT NOT NULL DEFAULT 'none'` so that
|
|
19923
|
+
* every row is selectable by a positive predicate. (The filter language has
|
|
19924
|
+
* since grown the NULL-safe `whereNot` / `whereNotIn` and an `IS NULL` reading
|
|
19925
|
+
* of `where: { f: null }`, which is how {@link TrackSourceSchema} can be
|
|
19926
|
+
* filtered on a NULLABLE column — see `excludeSources`. It did not when this
|
|
19927
|
+
* column was designed, and a NOT NULL column is still the better shape.)
|
|
19922
19928
|
*/
|
|
19923
19929
|
var RetrainStatusSchema = _enum([
|
|
19924
19930
|
"none",
|
|
@@ -20654,7 +20660,9 @@ var RecentTracksQueryInput = object({
|
|
|
20654
20660
|
* whose class list is unreadable are kept, and the client's rule stays the
|
|
20655
20661
|
* exact one.
|
|
20656
20662
|
*/
|
|
20657
|
-
classes: array(string()).optional()
|
|
20663
|
+
classes: array(string()).optional(),
|
|
20664
|
+
/** See {@link ExcludeSourcesDoc}. */
|
|
20665
|
+
excludeSources: array(TrackSourceSchema).optional()
|
|
20658
20666
|
});
|
|
20659
20667
|
/**
|
|
20660
20668
|
* A Summary (D359): the per-camera session envelope that references tracks.
|
|
@@ -21096,7 +21104,9 @@ var pipelineAnalyticsCapability = {
|
|
|
21096
21104
|
* selected is an operator who has not narrowed anything, and an empty
|
|
21097
21105
|
* timeline would read as a camera that saw nothing.
|
|
21098
21106
|
*/
|
|
21099
|
-
classes: array(string()).optional()
|
|
21107
|
+
classes: array(string()).optional(),
|
|
21108
|
+
/** See {@link ExcludeSourcesDoc}. */
|
|
21109
|
+
excludeSources: array(TrackSourceSchema).optional()
|
|
21100
21110
|
}), array(TrackSchema).readonly()),
|
|
21101
21111
|
/**
|
|
21102
21112
|
* Batched cluster-wide track listing — ONE call for the events page /
|
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
5
|
+
const require_dist = require("../dist-rqvrMbFv.js");
|
|
6
6
|
let node_fs = require("node:fs");
|
|
7
7
|
node_fs = require_dist.__toESM(node_fs);
|
|
8
8
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { F as PoolMemoryWatchdog, Pt as BaseAddon, Tt as resolvePoolMemoryPolicy, at as embeddingEncoderCapability, dt as hfModelUrl, vt as parseProcStatus } from "../dist-
|
|
1
|
+
import { F as PoolMemoryWatchdog, Pt as BaseAddon, Tt as resolvePoolMemoryPolicy, at as embeddingEncoderCapability, dt as hfModelUrl, vt as parseProcStatus } from "../dist-B2bqI0T1.mjs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -3,7 +3,7 @@ import "./dist-CYZr2fwk.mjs";
|
|
|
3
3
|
var e = {
|
|
4
4
|
"@camstack/sdk": {
|
|
5
5
|
name: "@camstack/sdk",
|
|
6
|
-
version: "1.2.
|
|
6
|
+
version: "1.2.85",
|
|
7
7
|
scope: ["default"],
|
|
8
8
|
loaded: !1,
|
|
9
9
|
from: "addon_pipeline_analytics_widgets",
|
|
@@ -18,7 +18,7 @@ var e = {
|
|
|
18
18
|
},
|
|
19
19
|
"@camstack/types": {
|
|
20
20
|
name: "@camstack/types",
|
|
21
|
-
version: "1.2.
|
|
21
|
+
version: "1.2.165",
|
|
22
22
|
scope: ["default"],
|
|
23
23
|
loaded: !1,
|
|
24
24
|
from: "addon_pipeline_analytics_widgets",
|
|
@@ -33,7 +33,7 @@ var e = {
|
|
|
33
33
|
},
|
|
34
34
|
"@camstack/ui-library": {
|
|
35
35
|
name: "@camstack/ui-library",
|
|
36
|
-
version: "1.2.
|
|
36
|
+
version: "1.2.133",
|
|
37
37
|
scope: ["default"],
|
|
38
38
|
loaded: !1,
|
|
39
39
|
from: "addon_pipeline_analytics_widgets",
|
|
@@ -36,7 +36,7 @@ async function r() {
|
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
"@camstack/types": {
|
|
39
|
-
version: "1.2.
|
|
39
|
+
version: "1.2.165",
|
|
40
40
|
scope: "default",
|
|
41
41
|
shareConfig: {
|
|
42
42
|
singleton: !0,
|
|
@@ -45,7 +45,7 @@ async function r() {
|
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
47
|
"@camstack/sdk": {
|
|
48
|
-
version: "1.2.
|
|
48
|
+
version: "1.2.85",
|
|
49
49
|
scope: "default",
|
|
50
50
|
shareConfig: {
|
|
51
51
|
singleton: !0,
|
|
@@ -81,7 +81,7 @@ async function r() {
|
|
|
81
81
|
}
|
|
82
82
|
},
|
|
83
83
|
"@camstack/ui-library": {
|
|
84
|
-
version: "1.2.
|
|
84
|
+
version: "1.2.133",
|
|
85
85
|
scope: "default",
|
|
86
86
|
shareConfig: {
|
|
87
87
|
singleton: !0,
|
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
5
|
+
const require_dist = require("../dist-rqvrMbFv.js");
|
|
6
6
|
let node_fs = require("node:fs");
|
|
7
7
|
node_fs = require_dist.__toESM(node_fs, 1);
|
|
8
8
|
let node_path = require("node:path");
|
|
@@ -35739,12 +35739,7 @@ var FrameProcessor = class {
|
|
|
35739
35739
|
trackId: e.detection.trackId,
|
|
35740
35740
|
className: e.detection.class,
|
|
35741
35741
|
confidence: e.detection.score,
|
|
35742
|
-
|
|
35743
|
-
x: 0,
|
|
35744
|
-
y: 0,
|
|
35745
|
-
w: 0,
|
|
35746
|
-
h: 0
|
|
35747
|
-
},
|
|
35742
|
+
...td ? { bbox: { ...td.bbox } } : {},
|
|
35748
35743
|
zones,
|
|
35749
35744
|
state,
|
|
35750
35745
|
...crossing !== void 0 ? { zoneCrossing: crossing } : {},
|
|
@@ -39658,6 +39653,58 @@ function isShortMotionlessTrack(lifeMs, movedPx, className) {
|
|
|
39658
39653
|
return lifeMs <= 25e3 && movedPx <= motionlessMaxPxForClass(className);
|
|
39659
39654
|
}
|
|
39660
39655
|
//#endregion
|
|
39656
|
+
//#region src/pipeline-analytics/store/track-source-filter.ts
|
|
39657
|
+
/**
|
|
39658
|
+
* The SQL predicate behind `excludeSources` — track provenance as a real query
|
|
39659
|
+
* filter (see `ExcludeSourcesDoc` in the cap for why the query needs one).
|
|
39660
|
+
*
|
|
39661
|
+
* ## The column is nullable, and that decides everything
|
|
39662
|
+
*
|
|
39663
|
+
* `persistCompleted` writes `source` only when the track carries one, and a
|
|
39664
|
+
* pipeline track does not: on the live hub every pipeline row's `source` is
|
|
39665
|
+
* NULL and only the synthetic rows (`audio`, `sensor`) carry a value. So there
|
|
39666
|
+
* are two exact compilations and the choice between them is purely "is
|
|
39667
|
+
* `pipeline` one of the sources being excluded":
|
|
39668
|
+
*
|
|
39669
|
+
* - **`pipeline` kept** → NULL-safe `whereNotIn`. `(source IS NULL OR source
|
|
39670
|
+
* NOT IN (…))` keeps every pipeline row without naming a value they do not
|
|
39671
|
+
* carry, and keeps any source added after this shipped — an exclusion list
|
|
39672
|
+
* can only hide what it names.
|
|
39673
|
+
* - **`pipeline` excluded** → positive `whereIn` over what survives. NULL is
|
|
39674
|
+
* then exactly the set being dropped, and a NULL-safe exclusion would keep
|
|
39675
|
+
* precisely the rows it was asked to remove. (Excluding EVERY known source
|
|
39676
|
+
* is the degenerate case: `whereIn` with an empty list, which the compiler
|
|
39677
|
+
* reads as "no filter", so it is answered here instead — see below.)
|
|
39678
|
+
*
|
|
39679
|
+
* Both are exact. Neither leaves a row's fate to a default, which is the whole
|
|
39680
|
+
* point: the class filter this replaces was a SUPERSET that kept every row it
|
|
39681
|
+
* could not read, and that is what made "Sensor" and "Audio" select the same
|
|
39682
|
+
* 116 rows on the live hub.
|
|
39683
|
+
*/
|
|
39684
|
+
/** Every source the build knows. Derived from the schema, never restated — a
|
|
39685
|
+
* source added to the enum must not need a second edit here to be filterable. */
|
|
39686
|
+
var KNOWN_SOURCES = require_dist.TrackSourceSchema.options;
|
|
39687
|
+
/**
|
|
39688
|
+
* Compile `excludeSources` into a store filter fragment.
|
|
39689
|
+
*
|
|
39690
|
+
* Pure. Unknown / duplicate entries are normalised away: the input crosses a
|
|
39691
|
+
* wire from a client whose enum may be older or newer than this one.
|
|
39692
|
+
*/
|
|
39693
|
+
function trackSourceFilter(excludeSources) {
|
|
39694
|
+
const excluded = new Set((excludeSources ?? []).filter((s) => KNOWN_SOURCES.includes(s)));
|
|
39695
|
+
if (excluded.size === 0) return { kind: "none" };
|
|
39696
|
+
const kept = KNOWN_SOURCES.filter((s) => !excluded.has(s));
|
|
39697
|
+
if (kept.length === 0) return { kind: "impossible" };
|
|
39698
|
+
if (!excluded.has("pipeline")) return {
|
|
39699
|
+
kind: "filter",
|
|
39700
|
+
filter: { whereNotIn: { source: [...excluded] } }
|
|
39701
|
+
};
|
|
39702
|
+
return {
|
|
39703
|
+
kind: "filter",
|
|
39704
|
+
filter: { whereIn: { source: kept } }
|
|
39705
|
+
};
|
|
39706
|
+
}
|
|
39707
|
+
//#endregion
|
|
39661
39708
|
//#region src/pipeline-analytics/store/track-store.ts
|
|
39662
39709
|
/**
|
|
39663
39710
|
* WHY a track's row was written EARLY — i.e. by {@link TrackStore.closeActive}
|
|
@@ -41227,6 +41274,9 @@ var TrackStore = class {
|
|
|
41227
41274
|
const timeBetween = params.since !== void 0 || params.until !== void 0 ? { firstSeen: [params.since ?? 0, params.until ?? Date.now()] } : {};
|
|
41228
41275
|
const stationaryExclusion = params.excludeStationaryPromotions === true ? { whereNot: { closedReason: "stationary-promotion" } } : {};
|
|
41229
41276
|
const classFilter = params.classes !== void 0 && params.classes.length > 0 ? { whereJsonArrayAny: { classes: [...params.classes] } } : {};
|
|
41277
|
+
const source = trackSourceFilter(params.excludeSources);
|
|
41278
|
+
if (source.kind === "impossible") return [];
|
|
41279
|
+
const sourceFilter = source.kind === "filter" ? source.filter : {};
|
|
41230
41280
|
if (params.zone === void 0) return (await this.store.query.query({
|
|
41231
41281
|
collection: TRACKS_COLLECTION,
|
|
41232
41282
|
filter: {
|
|
@@ -41234,6 +41284,7 @@ var TrackStore = class {
|
|
|
41234
41284
|
...Object.keys(timeBetween).length > 0 ? { whereBetween: timeBetween } : {},
|
|
41235
41285
|
...stationaryExclusion,
|
|
41236
41286
|
...classFilter,
|
|
41287
|
+
...sourceFilter,
|
|
41237
41288
|
orderBy: {
|
|
41238
41289
|
field: "firstSeen",
|
|
41239
41290
|
direction: "desc"
|
|
@@ -41250,6 +41301,7 @@ var TrackStore = class {
|
|
|
41250
41301
|
where: { deviceId: params.deviceId },
|
|
41251
41302
|
...stationaryExclusion,
|
|
41252
41303
|
...classFilter,
|
|
41304
|
+
...sourceFilter,
|
|
41253
41305
|
whereBetween: {
|
|
41254
41306
|
...timeBetween,
|
|
41255
41307
|
envMinX: [-1e6, bounds.maxX],
|
|
@@ -41271,6 +41323,7 @@ var TrackStore = class {
|
|
|
41271
41323
|
where: { deviceId: params.deviceId },
|
|
41272
41324
|
...stationaryExclusion,
|
|
41273
41325
|
...classFilter,
|
|
41326
|
+
...sourceFilter,
|
|
41274
41327
|
...Object.keys(timeBetween).length > 0 ? { whereBetween: timeBetween } : {},
|
|
41275
41328
|
orderBy: {
|
|
41276
41329
|
field: "firstSeen",
|
|
@@ -41368,6 +41421,12 @@ var TrackStore = class {
|
|
|
41368
41421
|
page: [],
|
|
41369
41422
|
nextCursor: null
|
|
41370
41423
|
};
|
|
41424
|
+
const source = trackSourceFilter(params.excludeSources);
|
|
41425
|
+
if (source.kind === "impossible") return {
|
|
41426
|
+
page: [],
|
|
41427
|
+
nextCursor: null
|
|
41428
|
+
};
|
|
41429
|
+
const sourceFilter = source.kind === "filter" ? source.filter : {};
|
|
41371
41430
|
const requested = Math.min(Math.max(params.limit ?? RECENT_DEFAULT_LIMIT, 1), RECENT_MAX_LIMIT);
|
|
41372
41431
|
/**
|
|
41373
41432
|
* The bound is on `deviceCount x limit`, because that — not `limit` — is
|
|
@@ -41400,6 +41459,7 @@ var TrackStore = class {
|
|
|
41400
41459
|
where: { deviceId },
|
|
41401
41460
|
...stationaryExclusion,
|
|
41402
41461
|
...classFilter,
|
|
41462
|
+
...sourceFilter,
|
|
41403
41463
|
whereBetween: { lastSeen: range },
|
|
41404
41464
|
orderBy: {
|
|
41405
41465
|
field: "lastSeen",
|
|
@@ -63607,6 +63667,27 @@ var SyntheticTrackMaterializer = class {
|
|
|
63607
63667
|
trackId,
|
|
63608
63668
|
deviceId: input.cameraId,
|
|
63609
63669
|
className: input.kind,
|
|
63670
|
+
/**
|
|
63671
|
+
* The accumulated-class column, seeded with the one class this row will
|
|
63672
|
+
* ever have. A pipeline track gets `classes: [className]` on its first
|
|
63673
|
+
* observation; a synthetic row was left with the column NULL, and
|
|
63674
|
+
* `whereJsonArrayAny` — the operator `classes` compiles to — is a
|
|
63675
|
+
* deliberate SUPERSET that KEEPS a row whose column it cannot read.
|
|
63676
|
+
*
|
|
63677
|
+
* So every class selection returned every synthetic row and no class
|
|
63678
|
+
* selection ever SELECTED one: measured on the live hub, `classes:
|
|
63679
|
+
* ['person']` came back with 66 contact markers and 29 audio markers
|
|
63680
|
+
* attached, `classes: ['contact']` returned no contact row by its class
|
|
63681
|
+
* (only the 116 rows the escape hatch keeps), and a class that exists
|
|
63682
|
+
* nowhere answered those same 116. That is the "the sensor and control
|
|
63683
|
+
* filters do nothing" report, exactly.
|
|
63684
|
+
*
|
|
63685
|
+
* Writing it here makes a synthetic row selectable BY ITS KIND like any
|
|
63686
|
+
* other. Rows already on disk keep a NULL column and stay in the
|
|
63687
|
+
* superset — which is what `excludeSources` is for: provenance is not a
|
|
63688
|
+
* class, and the source filter is exact for the whole history.
|
|
63689
|
+
*/
|
|
63690
|
+
classes: [input.kind],
|
|
63610
63691
|
source: input.source,
|
|
63611
63692
|
...input.producingDeviceName !== void 0 ? { producingDeviceName: input.producingDeviceName } : {},
|
|
63612
63693
|
...input.audioLabels !== void 0 && input.audioLabels.length > 0 ? { audioLabels: input.audioLabels } : {},
|
|
@@ -71693,6 +71774,15 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends require_dist.B
|
|
|
71693
71774
|
if (this.eventMediaDispatcher && frameHandle) {
|
|
71694
71775
|
const mediaEvents = [...result.objectEvents, ...result.appearanceEvents];
|
|
71695
71776
|
const childCropsByEvent = buildEventChildCrops(mediaEvents, frame.detections);
|
|
71777
|
+
const uncroppable = mediaEvents.filter((e) => e.bbox === void 0 || e.bbox.w <= 0 || e.bbox.h <= 0);
|
|
71778
|
+
if (uncroppable.length > 0) this.ctx.logger.debug("event media: no crop for events with no box in this frame (a departed track has nothing to cut)", {
|
|
71779
|
+
tags: { deviceId },
|
|
71780
|
+
meta: {
|
|
71781
|
+
events: uncroppable.length,
|
|
71782
|
+
states: [...new Set(uncroppable.map((e) => e.state ?? "unknown"))],
|
|
71783
|
+
zeroArea: uncroppable.filter((e) => e.bbox !== void 0).length
|
|
71784
|
+
}
|
|
71785
|
+
});
|
|
71696
71786
|
const eventTargets = mediaEvents.filter((e) => e.bbox !== void 0 && e.bbox.w > 0 && e.bbox.h > 0).map((e) => {
|
|
71697
71787
|
const childCrops = childCropsByEvent.get(e.id);
|
|
71698
71788
|
return {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as audioModeOf, $t as EventCategory, A as NcSnoozeSchema, At as vectorDimFromBase64, B as SCENE_DEFAULT_UNCOVERED_POLICY, Bt as nodePin, C as NcConditionDescriptorSchema, Ct as readTimelapseGeneratedAt, D as NcRuleTargetSchema, Dt as storageOccupancyCapability, E as NcRuleSchema, Et as sceneMonitorCapability, Ft as CamProfileSchema, G as TimelapseRulePatchSchema, Gt as discriminatedUnion, H as SceneMonitorSchema, Ht as _enum, I as RECORDING_EXPORT_MAX_READ_BYTES, It as DeviceType, J as VISIT_MERGE_GAP_MS, Jt as object, K as TimelapseRuleSchema, Kt as literal, L as RetrainStatusSchema, Lt as createEvent, M as NcSystemEventKindSchema, Mt as zoneAnalyticsCapability, N as NcTaxonomySchema, Nt as errMsg$1, O as NcScheduleSchema, Ot as subKindsOf, P as OpsLogEntrySchema, Pt as BaseAddon, Q as audioMetricsCapability, Qt as unknown, Rt as hydrateSchema, S as NC_TAXONOMY, St as readDeviceStateFrom, T as NcRulePatchSchema, U as TIMELAPSE_DENSE_FLOOR_SEC, Ut as array, V as SCENE_DIVERGED, Vt as sleep$1, W as TimelapseRuleInputSchema, Wt as boolean, X as alarmPanelCapability, Xt as record, Y as addonWidgetsSourceCapability, Yt as partialRecord, Z as assertTimelapseCadences, Zt as string, _ as MediaFileKindEnum, _t as notificationRulesCapability, a as DEFAULT_EVENT_COLOR, b as NC_DEFAULT_SNOOZE_MINUTES, bt as pipelineAnalyticsCapability, c as DETECTION_MACRO_CLASSES, ct as evictionPolicyOfLocation, d as EVENT_KIND_BY_CAP, et as buildEventKindDescriptor, f as EVENT_PAD_MS, ft as isDetectionMacroClass, g as MACRO_LABELS, gt as mayWriteToLocation, h as LabelAttributionSchema, ht as kebabToCamel, i as COCO_TO_MACRO, it as deriveRecordingMode, j as NcSnoozeSuppressedSchema, jt as videoclipsCapability, k as NcSnoozeInputSchema, kt as systemEventFilterApplies, lt as faceGalleryCapability, m as FailureCounters, mt as isSourceCap, n as BaseDevice, nt as customAction, ot as encodeVectorBase64, p as FULL_IMAGE_BBOX, pt as isScheduleActive, q as TrackSourceSchema, qt as number, r as CLUSTER_MODEL_SCOPED_STEPS, rt as defineCustomActions, st as evaluateSensorEdge, t as AUDIO_MACRO_LABELS, tt as cosineSimilarity$1, u as DeclaredDevices, ut as failureContributionCapability, v as NC_ALARM_SYSTEM_EVENT_KINDS, w as NcRuleInputSchema, wt as resolveLocationMode, xt as plateGalleryCapability, y as NC_CONDITION_CATALOG, yt as pickClusterStepModels, z as SCENE_DEFAULT_ANCHOR_THRESHOLD, zt as isDeviceScopedCap } from "../dist-
|
|
1
|
+
import { $ as audioModeOf, $t as EventCategory, A as NcSnoozeSchema, At as vectorDimFromBase64, B as SCENE_DEFAULT_UNCOVERED_POLICY, Bt as nodePin, C as NcConditionDescriptorSchema, Ct as readTimelapseGeneratedAt, D as NcRuleTargetSchema, Dt as storageOccupancyCapability, E as NcRuleSchema, Et as sceneMonitorCapability, Ft as CamProfileSchema, G as TimelapseRulePatchSchema, Gt as discriminatedUnion, H as SceneMonitorSchema, Ht as _enum, I as RECORDING_EXPORT_MAX_READ_BYTES, It as DeviceType, J as VISIT_MERGE_GAP_MS, Jt as object, K as TimelapseRuleSchema, Kt as literal, L as RetrainStatusSchema, Lt as createEvent, M as NcSystemEventKindSchema, Mt as zoneAnalyticsCapability, N as NcTaxonomySchema, Nt as errMsg$1, O as NcScheduleSchema, Ot as subKindsOf, P as OpsLogEntrySchema, Pt as BaseAddon, Q as audioMetricsCapability, Qt as unknown, Rt as hydrateSchema, S as NC_TAXONOMY, St as readDeviceStateFrom, T as NcRulePatchSchema, U as TIMELAPSE_DENSE_FLOOR_SEC, Ut as array, V as SCENE_DIVERGED, Vt as sleep$1, W as TimelapseRuleInputSchema, Wt as boolean, X as alarmPanelCapability, Xt as record, Y as addonWidgetsSourceCapability, Yt as partialRecord, Z as assertTimelapseCadences, Zt as string, _ as MediaFileKindEnum, _t as notificationRulesCapability, a as DEFAULT_EVENT_COLOR, b as NC_DEFAULT_SNOOZE_MINUTES, bt as pipelineAnalyticsCapability, c as DETECTION_MACRO_CLASSES, ct as evictionPolicyOfLocation, d as EVENT_KIND_BY_CAP, et as buildEventKindDescriptor, f as EVENT_PAD_MS, ft as isDetectionMacroClass, g as MACRO_LABELS, gt as mayWriteToLocation, h as LabelAttributionSchema, ht as kebabToCamel, i as COCO_TO_MACRO, it as deriveRecordingMode, j as NcSnoozeSuppressedSchema, jt as videoclipsCapability, k as NcSnoozeInputSchema, kt as systemEventFilterApplies, lt as faceGalleryCapability, m as FailureCounters, mt as isSourceCap, n as BaseDevice, nt as customAction, ot as encodeVectorBase64, p as FULL_IMAGE_BBOX, pt as isScheduleActive, q as TrackSourceSchema, qt as number, r as CLUSTER_MODEL_SCOPED_STEPS, rt as defineCustomActions, st as evaluateSensorEdge, t as AUDIO_MACRO_LABELS, tt as cosineSimilarity$1, u as DeclaredDevices, ut as failureContributionCapability, v as NC_ALARM_SYSTEM_EVENT_KINDS, w as NcRuleInputSchema, wt as resolveLocationMode, xt as plateGalleryCapability, y as NC_CONDITION_CATALOG, yt as pickClusterStepModels, z as SCENE_DEFAULT_ANCHOR_THRESHOLD, zt as isDeviceScopedCap } from "../dist-B2bqI0T1.mjs";
|
|
2
2
|
import { t as __exportAll } from "../embedding-encoder/index.mjs";
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
4
|
import { promises } from "node:fs";
|
|
@@ -35714,12 +35714,7 @@ var FrameProcessor = class {
|
|
|
35714
35714
|
trackId: e.detection.trackId,
|
|
35715
35715
|
className: e.detection.class,
|
|
35716
35716
|
confidence: e.detection.score,
|
|
35717
|
-
|
|
35718
|
-
x: 0,
|
|
35719
|
-
y: 0,
|
|
35720
|
-
w: 0,
|
|
35721
|
-
h: 0
|
|
35722
|
-
},
|
|
35717
|
+
...td ? { bbox: { ...td.bbox } } : {},
|
|
35723
35718
|
zones,
|
|
35724
35719
|
state,
|
|
35725
35720
|
...crossing !== void 0 ? { zoneCrossing: crossing } : {},
|
|
@@ -39633,6 +39628,58 @@ function isShortMotionlessTrack(lifeMs, movedPx, className) {
|
|
|
39633
39628
|
return lifeMs <= 25e3 && movedPx <= motionlessMaxPxForClass(className);
|
|
39634
39629
|
}
|
|
39635
39630
|
//#endregion
|
|
39631
|
+
//#region src/pipeline-analytics/store/track-source-filter.ts
|
|
39632
|
+
/**
|
|
39633
|
+
* The SQL predicate behind `excludeSources` — track provenance as a real query
|
|
39634
|
+
* filter (see `ExcludeSourcesDoc` in the cap for why the query needs one).
|
|
39635
|
+
*
|
|
39636
|
+
* ## The column is nullable, and that decides everything
|
|
39637
|
+
*
|
|
39638
|
+
* `persistCompleted` writes `source` only when the track carries one, and a
|
|
39639
|
+
* pipeline track does not: on the live hub every pipeline row's `source` is
|
|
39640
|
+
* NULL and only the synthetic rows (`audio`, `sensor`) carry a value. So there
|
|
39641
|
+
* are two exact compilations and the choice between them is purely "is
|
|
39642
|
+
* `pipeline` one of the sources being excluded":
|
|
39643
|
+
*
|
|
39644
|
+
* - **`pipeline` kept** → NULL-safe `whereNotIn`. `(source IS NULL OR source
|
|
39645
|
+
* NOT IN (…))` keeps every pipeline row without naming a value they do not
|
|
39646
|
+
* carry, and keeps any source added after this shipped — an exclusion list
|
|
39647
|
+
* can only hide what it names.
|
|
39648
|
+
* - **`pipeline` excluded** → positive `whereIn` over what survives. NULL is
|
|
39649
|
+
* then exactly the set being dropped, and a NULL-safe exclusion would keep
|
|
39650
|
+
* precisely the rows it was asked to remove. (Excluding EVERY known source
|
|
39651
|
+
* is the degenerate case: `whereIn` with an empty list, which the compiler
|
|
39652
|
+
* reads as "no filter", so it is answered here instead — see below.)
|
|
39653
|
+
*
|
|
39654
|
+
* Both are exact. Neither leaves a row's fate to a default, which is the whole
|
|
39655
|
+
* point: the class filter this replaces was a SUPERSET that kept every row it
|
|
39656
|
+
* could not read, and that is what made "Sensor" and "Audio" select the same
|
|
39657
|
+
* 116 rows on the live hub.
|
|
39658
|
+
*/
|
|
39659
|
+
/** Every source the build knows. Derived from the schema, never restated — a
|
|
39660
|
+
* source added to the enum must not need a second edit here to be filterable. */
|
|
39661
|
+
var KNOWN_SOURCES = TrackSourceSchema.options;
|
|
39662
|
+
/**
|
|
39663
|
+
* Compile `excludeSources` into a store filter fragment.
|
|
39664
|
+
*
|
|
39665
|
+
* Pure. Unknown / duplicate entries are normalised away: the input crosses a
|
|
39666
|
+
* wire from a client whose enum may be older or newer than this one.
|
|
39667
|
+
*/
|
|
39668
|
+
function trackSourceFilter(excludeSources) {
|
|
39669
|
+
const excluded = new Set((excludeSources ?? []).filter((s) => KNOWN_SOURCES.includes(s)));
|
|
39670
|
+
if (excluded.size === 0) return { kind: "none" };
|
|
39671
|
+
const kept = KNOWN_SOURCES.filter((s) => !excluded.has(s));
|
|
39672
|
+
if (kept.length === 0) return { kind: "impossible" };
|
|
39673
|
+
if (!excluded.has("pipeline")) return {
|
|
39674
|
+
kind: "filter",
|
|
39675
|
+
filter: { whereNotIn: { source: [...excluded] } }
|
|
39676
|
+
};
|
|
39677
|
+
return {
|
|
39678
|
+
kind: "filter",
|
|
39679
|
+
filter: { whereIn: { source: kept } }
|
|
39680
|
+
};
|
|
39681
|
+
}
|
|
39682
|
+
//#endregion
|
|
39636
39683
|
//#region src/pipeline-analytics/store/track-store.ts
|
|
39637
39684
|
/**
|
|
39638
39685
|
* WHY a track's row was written EARLY — i.e. by {@link TrackStore.closeActive}
|
|
@@ -41202,6 +41249,9 @@ var TrackStore = class {
|
|
|
41202
41249
|
const timeBetween = params.since !== void 0 || params.until !== void 0 ? { firstSeen: [params.since ?? 0, params.until ?? Date.now()] } : {};
|
|
41203
41250
|
const stationaryExclusion = params.excludeStationaryPromotions === true ? { whereNot: { closedReason: "stationary-promotion" } } : {};
|
|
41204
41251
|
const classFilter = params.classes !== void 0 && params.classes.length > 0 ? { whereJsonArrayAny: { classes: [...params.classes] } } : {};
|
|
41252
|
+
const source = trackSourceFilter(params.excludeSources);
|
|
41253
|
+
if (source.kind === "impossible") return [];
|
|
41254
|
+
const sourceFilter = source.kind === "filter" ? source.filter : {};
|
|
41205
41255
|
if (params.zone === void 0) return (await this.store.query.query({
|
|
41206
41256
|
collection: TRACKS_COLLECTION,
|
|
41207
41257
|
filter: {
|
|
@@ -41209,6 +41259,7 @@ var TrackStore = class {
|
|
|
41209
41259
|
...Object.keys(timeBetween).length > 0 ? { whereBetween: timeBetween } : {},
|
|
41210
41260
|
...stationaryExclusion,
|
|
41211
41261
|
...classFilter,
|
|
41262
|
+
...sourceFilter,
|
|
41212
41263
|
orderBy: {
|
|
41213
41264
|
field: "firstSeen",
|
|
41214
41265
|
direction: "desc"
|
|
@@ -41225,6 +41276,7 @@ var TrackStore = class {
|
|
|
41225
41276
|
where: { deviceId: params.deviceId },
|
|
41226
41277
|
...stationaryExclusion,
|
|
41227
41278
|
...classFilter,
|
|
41279
|
+
...sourceFilter,
|
|
41228
41280
|
whereBetween: {
|
|
41229
41281
|
...timeBetween,
|
|
41230
41282
|
envMinX: [-1e6, bounds.maxX],
|
|
@@ -41246,6 +41298,7 @@ var TrackStore = class {
|
|
|
41246
41298
|
where: { deviceId: params.deviceId },
|
|
41247
41299
|
...stationaryExclusion,
|
|
41248
41300
|
...classFilter,
|
|
41301
|
+
...sourceFilter,
|
|
41249
41302
|
...Object.keys(timeBetween).length > 0 ? { whereBetween: timeBetween } : {},
|
|
41250
41303
|
orderBy: {
|
|
41251
41304
|
field: "firstSeen",
|
|
@@ -41343,6 +41396,12 @@ var TrackStore = class {
|
|
|
41343
41396
|
page: [],
|
|
41344
41397
|
nextCursor: null
|
|
41345
41398
|
};
|
|
41399
|
+
const source = trackSourceFilter(params.excludeSources);
|
|
41400
|
+
if (source.kind === "impossible") return {
|
|
41401
|
+
page: [],
|
|
41402
|
+
nextCursor: null
|
|
41403
|
+
};
|
|
41404
|
+
const sourceFilter = source.kind === "filter" ? source.filter : {};
|
|
41346
41405
|
const requested = Math.min(Math.max(params.limit ?? RECENT_DEFAULT_LIMIT, 1), RECENT_MAX_LIMIT);
|
|
41347
41406
|
/**
|
|
41348
41407
|
* The bound is on `deviceCount x limit`, because that — not `limit` — is
|
|
@@ -41375,6 +41434,7 @@ var TrackStore = class {
|
|
|
41375
41434
|
where: { deviceId },
|
|
41376
41435
|
...stationaryExclusion,
|
|
41377
41436
|
...classFilter,
|
|
41437
|
+
...sourceFilter,
|
|
41378
41438
|
whereBetween: { lastSeen: range },
|
|
41379
41439
|
orderBy: {
|
|
41380
41440
|
field: "lastSeen",
|
|
@@ -63533,6 +63593,27 @@ var SyntheticTrackMaterializer = class {
|
|
|
63533
63593
|
trackId,
|
|
63534
63594
|
deviceId: input.cameraId,
|
|
63535
63595
|
className: input.kind,
|
|
63596
|
+
/**
|
|
63597
|
+
* The accumulated-class column, seeded with the one class this row will
|
|
63598
|
+
* ever have. A pipeline track gets `classes: [className]` on its first
|
|
63599
|
+
* observation; a synthetic row was left with the column NULL, and
|
|
63600
|
+
* `whereJsonArrayAny` — the operator `classes` compiles to — is a
|
|
63601
|
+
* deliberate SUPERSET that KEEPS a row whose column it cannot read.
|
|
63602
|
+
*
|
|
63603
|
+
* So every class selection returned every synthetic row and no class
|
|
63604
|
+
* selection ever SELECTED one: measured on the live hub, `classes:
|
|
63605
|
+
* ['person']` came back with 66 contact markers and 29 audio markers
|
|
63606
|
+
* attached, `classes: ['contact']` returned no contact row by its class
|
|
63607
|
+
* (only the 116 rows the escape hatch keeps), and a class that exists
|
|
63608
|
+
* nowhere answered those same 116. That is the "the sensor and control
|
|
63609
|
+
* filters do nothing" report, exactly.
|
|
63610
|
+
*
|
|
63611
|
+
* Writing it here makes a synthetic row selectable BY ITS KIND like any
|
|
63612
|
+
* other. Rows already on disk keep a NULL column and stay in the
|
|
63613
|
+
* superset — which is what `excludeSources` is for: provenance is not a
|
|
63614
|
+
* class, and the source filter is exact for the whole history.
|
|
63615
|
+
*/
|
|
63616
|
+
classes: [input.kind],
|
|
63536
63617
|
source: input.source,
|
|
63537
63618
|
...input.producingDeviceName !== void 0 ? { producingDeviceName: input.producingDeviceName } : {},
|
|
63538
63619
|
...input.audioLabels !== void 0 && input.audioLabels.length > 0 ? { audioLabels: input.audioLabels } : {},
|
|
@@ -71619,6 +71700,15 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
71619
71700
|
if (this.eventMediaDispatcher && frameHandle) {
|
|
71620
71701
|
const mediaEvents = [...result.objectEvents, ...result.appearanceEvents];
|
|
71621
71702
|
const childCropsByEvent = buildEventChildCrops(mediaEvents, frame.detections);
|
|
71703
|
+
const uncroppable = mediaEvents.filter((e) => e.bbox === void 0 || e.bbox.w <= 0 || e.bbox.h <= 0);
|
|
71704
|
+
if (uncroppable.length > 0) this.ctx.logger.debug("event media: no crop for events with no box in this frame (a departed track has nothing to cut)", {
|
|
71705
|
+
tags: { deviceId },
|
|
71706
|
+
meta: {
|
|
71707
|
+
events: uncroppable.length,
|
|
71708
|
+
states: [...new Set(uncroppable.map((e) => e.state ?? "unknown"))],
|
|
71709
|
+
zeroArea: uncroppable.filter((e) => e.bbox !== void 0).length
|
|
71710
|
+
}
|
|
71711
|
+
});
|
|
71622
71712
|
const eventTargets = mediaEvents.filter((e) => e.bbox !== void 0 && e.bbox.w > 0 && e.bbox.h > 0).map((e) => {
|
|
71623
71713
|
const childCrops = childCropsByEvent.get(e.id);
|
|
71624
71714
|
return {
|
|
@@ -30,7 +30,7 @@ async function d(e) {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
async function f() {
|
|
33
|
-
return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-
|
|
33
|
+
return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-BhGMdGiF.mjs")).catch((e) => {
|
|
34
34
|
throw l = void 0, e;
|
|
35
35
|
}), l;
|
|
36
36
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-post-analysis",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.203",
|
|
4
4
|
"description": "Post-Analysis bundle — enrichment, embedding-encoder, pipeline-analytics. Multi-entry npm package shipping addons that consume pipeline output.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|