@camstack/addon-post-analysis 1.2.248 → 1.2.249
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-KRjxHIQ4.mjs → dist-C7xHFnGJ.mjs} +47 -8
- package/dist/{dist-DmB50uQ-.js → dist-CdLfCStM.js} +47 -8
- 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-DaT9RhCO.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-DJ9dpbgD.mjs} +3 -3
- package/dist/pipeline-analytics/{hostInit-B2MVHHLi.mjs → hostInit-gS_O2jp5.mjs} +3 -3
- package/dist/pipeline-analytics/index.js +78 -18
- package/dist/pipeline-analytics/index.mjs +78 -18
- package/dist/pipeline-analytics/remoteEntry.js +1 -1
- package/package.json +1 -1
|
@@ -20663,13 +20663,26 @@ var TrackAudioLabelSchema = object({
|
|
|
20663
20663
|
* - `audio` — an audio event on the camera itself that was anomalous for
|
|
20664
20664
|
* THAT camera, loud, and heard while nothing visual was happening (D62).
|
|
20665
20665
|
*
|
|
20666
|
+
* - `onboard` — the CAMERA's own firmware, paired with a decoded frame in
|
|
20667
|
+
* that frame's pixel space. A real root detector and a SPATIAL one: its
|
|
20668
|
+
* boxes are the same kind of fact `pipeline`'s are, produced by a different
|
|
20669
|
+
* detector.
|
|
20670
|
+
*
|
|
20671
|
+
* `onboard` was missing here while `DetectionSourceSchema` already had it, so
|
|
20672
|
+
* a persisted onboard track failed `safeParse` on read and came back with NO
|
|
20673
|
+
* source at all — which `isSpatialTrack` then admitted by accident, through the
|
|
20674
|
+
* `undefined` arm rather than by anybody's decision, and which `excludeSources`
|
|
20675
|
+
* could not name.
|
|
20676
|
+
*
|
|
20666
20677
|
* The spatial subsystems (tracker association, occupancy count, re-id /
|
|
20667
20678
|
* embedding, resurrection) MUST skip every synthetic source. Test for that
|
|
20668
|
-
* with `isSpatialTrack`, which allow-lists
|
|
20669
|
-
* check silently readmits every source added after it was
|
|
20679
|
+
* with `isSpatialTrack`, which allow-lists the spatial sources explicitly — a
|
|
20680
|
+
* `!== 'sensor'` check silently readmits every source added after it was
|
|
20681
|
+
* written.
|
|
20670
20682
|
*/
|
|
20671
20683
|
var TrackSourceSchema = _enum([
|
|
20672
20684
|
"pipeline",
|
|
20685
|
+
"onboard",
|
|
20673
20686
|
"sensor",
|
|
20674
20687
|
"audio"
|
|
20675
20688
|
]);
|
|
@@ -23402,13 +23415,39 @@ var MotionSourceEnum = _enum([
|
|
|
23402
23415
|
*/
|
|
23403
23416
|
var MotionSourcesSchema = array(MotionSourceEnum);
|
|
23404
23417
|
/**
|
|
23405
|
-
* Which root
|
|
23406
|
-
*
|
|
23407
|
-
*
|
|
23408
|
-
*
|
|
23409
|
-
*
|
|
23418
|
+
* Which root detector a camera runs — EXACTLY ONE.
|
|
23419
|
+
*
|
|
23420
|
+
* Deliberately the SAME vocabulary post-analysis already tags every detection
|
|
23421
|
+
* with (`DetectionSource`) rather than a second spelling of the same two
|
|
23422
|
+
* ideas: the value an operator picks here is the value that comes back on the
|
|
23423
|
+
* track, the overlay and the debug row.
|
|
23424
|
+
*
|
|
23425
|
+
* ## Why one, and why it is still an array
|
|
23426
|
+
*
|
|
23427
|
+
* Two roots on one camera is a capability nobody asked for and the operator has
|
|
23428
|
+
* since ruled out. It was never free: both planes feed the SAME per-device
|
|
23429
|
+
* stationary registry, both can promote the same parked object, and the two
|
|
23430
|
+
* detectors disagree about the same box by construction — which is the
|
|
23431
|
+
* disagreement D505 had to arbitrate. Removing the case removes the arbitration.
|
|
23432
|
+
*
|
|
23433
|
+
* The ARRAY shape survives because the stored settings and the attach payload
|
|
23434
|
+
* already speak it on every camera of every fleet, and a cap input that
|
|
23435
|
+
* suddenly refuses a stored value makes the camera un-attachable — a fail-closed
|
|
23436
|
+
* in the one direction that costs an operator their cameras. So the wire stays
|
|
23437
|
+
* tolerant and the TYPE is exact: a longer list is truncated to its first
|
|
23438
|
+
* element rather than refused, and `max(1)` is what every consumer can then
|
|
23439
|
+
* rely on.
|
|
23440
|
+
*
|
|
23441
|
+
* AT MOST one, not exactly one. The EMPTY list is a legal, deliberate pick —
|
|
23442
|
+
* a camera an operator left with no root detector — and `planDetectionSources`
|
|
23443
|
+
* has always said so: inventing a root for them is how a default acts without
|
|
23444
|
+
* anybody choosing it. Tightening this to `length(1)` broke that, and the
|
|
23445
|
+
* suite caught it.
|
|
23446
|
+
*
|
|
23447
|
+
* Measured before tightening (2026-09-15, this fleet, 6 h of attaches): 3327
|
|
23448
|
+
* `["pipeline"]` and 2 `["onboard"]`. Not one camera had two.
|
|
23410
23449
|
*/
|
|
23411
|
-
var DetectionSourcesSchema = array(DetectionSourceSchema);
|
|
23450
|
+
var DetectionSourcesSchema = preprocess((value) => Array.isArray(value) && value.length > 1 ? value.slice(0, 1) : value, array(DetectionSourceSchema).max(1));
|
|
23412
23451
|
/**
|
|
23413
23452
|
* Input shape for `pipeline-runner.reportMotion` cap method. Exported
|
|
23414
23453
|
* so cap-side consumers (the orchestrator forward, the runner addon's
|
|
@@ -20694,13 +20694,26 @@ var TrackAudioLabelSchema = object({
|
|
|
20694
20694
|
* - `audio` — an audio event on the camera itself that was anomalous for
|
|
20695
20695
|
* THAT camera, loud, and heard while nothing visual was happening (D62).
|
|
20696
20696
|
*
|
|
20697
|
+
* - `onboard` — the CAMERA's own firmware, paired with a decoded frame in
|
|
20698
|
+
* that frame's pixel space. A real root detector and a SPATIAL one: its
|
|
20699
|
+
* boxes are the same kind of fact `pipeline`'s are, produced by a different
|
|
20700
|
+
* detector.
|
|
20701
|
+
*
|
|
20702
|
+
* `onboard` was missing here while `DetectionSourceSchema` already had it, so
|
|
20703
|
+
* a persisted onboard track failed `safeParse` on read and came back with NO
|
|
20704
|
+
* source at all — which `isSpatialTrack` then admitted by accident, through the
|
|
20705
|
+
* `undefined` arm rather than by anybody's decision, and which `excludeSources`
|
|
20706
|
+
* could not name.
|
|
20707
|
+
*
|
|
20697
20708
|
* The spatial subsystems (tracker association, occupancy count, re-id /
|
|
20698
20709
|
* embedding, resurrection) MUST skip every synthetic source. Test for that
|
|
20699
|
-
* with `isSpatialTrack`, which allow-lists
|
|
20700
|
-
* check silently readmits every source added after it was
|
|
20710
|
+
* with `isSpatialTrack`, which allow-lists the spatial sources explicitly — a
|
|
20711
|
+
* `!== 'sensor'` check silently readmits every source added after it was
|
|
20712
|
+
* written.
|
|
20701
20713
|
*/
|
|
20702
20714
|
var TrackSourceSchema = _enum([
|
|
20703
20715
|
"pipeline",
|
|
20716
|
+
"onboard",
|
|
20704
20717
|
"sensor",
|
|
20705
20718
|
"audio"
|
|
20706
20719
|
]);
|
|
@@ -23433,13 +23446,39 @@ var MotionSourceEnum = _enum([
|
|
|
23433
23446
|
*/
|
|
23434
23447
|
var MotionSourcesSchema = array(MotionSourceEnum);
|
|
23435
23448
|
/**
|
|
23436
|
-
* Which root
|
|
23437
|
-
*
|
|
23438
|
-
*
|
|
23439
|
-
*
|
|
23440
|
-
*
|
|
23449
|
+
* Which root detector a camera runs — EXACTLY ONE.
|
|
23450
|
+
*
|
|
23451
|
+
* Deliberately the SAME vocabulary post-analysis already tags every detection
|
|
23452
|
+
* with (`DetectionSource`) rather than a second spelling of the same two
|
|
23453
|
+
* ideas: the value an operator picks here is the value that comes back on the
|
|
23454
|
+
* track, the overlay and the debug row.
|
|
23455
|
+
*
|
|
23456
|
+
* ## Why one, and why it is still an array
|
|
23457
|
+
*
|
|
23458
|
+
* Two roots on one camera is a capability nobody asked for and the operator has
|
|
23459
|
+
* since ruled out. It was never free: both planes feed the SAME per-device
|
|
23460
|
+
* stationary registry, both can promote the same parked object, and the two
|
|
23461
|
+
* detectors disagree about the same box by construction — which is the
|
|
23462
|
+
* disagreement D505 had to arbitrate. Removing the case removes the arbitration.
|
|
23463
|
+
*
|
|
23464
|
+
* The ARRAY shape survives because the stored settings and the attach payload
|
|
23465
|
+
* already speak it on every camera of every fleet, and a cap input that
|
|
23466
|
+
* suddenly refuses a stored value makes the camera un-attachable — a fail-closed
|
|
23467
|
+
* in the one direction that costs an operator their cameras. So the wire stays
|
|
23468
|
+
* tolerant and the TYPE is exact: a longer list is truncated to its first
|
|
23469
|
+
* element rather than refused, and `max(1)` is what every consumer can then
|
|
23470
|
+
* rely on.
|
|
23471
|
+
*
|
|
23472
|
+
* AT MOST one, not exactly one. The EMPTY list is a legal, deliberate pick —
|
|
23473
|
+
* a camera an operator left with no root detector — and `planDetectionSources`
|
|
23474
|
+
* has always said so: inventing a root for them is how a default acts without
|
|
23475
|
+
* anybody choosing it. Tightening this to `length(1)` broke that, and the
|
|
23476
|
+
* suite caught it.
|
|
23477
|
+
*
|
|
23478
|
+
* Measured before tightening (2026-09-15, this fleet, 6 h of attaches): 3327
|
|
23479
|
+
* `["pipeline"]` and 2 `["onboard"]`. Not one camera had two.
|
|
23441
23480
|
*/
|
|
23442
|
-
var DetectionSourcesSchema = array(DetectionSourceSchema);
|
|
23481
|
+
var DetectionSourcesSchema = preprocess((value) => Array.isArray(value) && value.length > 1 ? value.slice(0, 1) : value, array(DetectionSourceSchema).max(1));
|
|
23443
23482
|
/**
|
|
23444
23483
|
* Input shape for `pipeline-runner.reportMotion` cap method. Exported
|
|
23445
23484
|
* so cap-side consumers (the orchestrator forward, the runner addon's
|
|
@@ -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-CdLfCStM.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 { Et as parseProcStatus, H as PoolMemoryWatchdog, Ht as BaseAddon, Nt as resolvePoolMemoryPolicy, gt as hfModelUrl, ut as embeddingEncoderCapability } from "../dist-
|
|
1
|
+
import { Et as parseProcStatus, H as PoolMemoryWatchdog, Ht as BaseAddon, Nt as resolvePoolMemoryPolicy, gt as hfModelUrl, ut as embeddingEncoderCapability } from "../dist-C7xHFnGJ.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.107",
|
|
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.201",
|
|
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.166",
|
|
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.201",
|
|
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.107",
|
|
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.166",
|
|
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-CdLfCStM.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");
|
|
@@ -15088,20 +15088,23 @@ var OccupancyWatcher = class {
|
|
|
15088
15088
|
* this tick (usually none). Every watched key is evaluated for `deviceId`;
|
|
15089
15089
|
* fail-closed keys (absent zone) are skipped and hold no state.
|
|
15090
15090
|
*/
|
|
15091
|
-
observe(deviceId, snapshot, now) {
|
|
15091
|
+
observe(deviceId, snapshot, now, evidence = "scene") {
|
|
15092
15092
|
const edges = [];
|
|
15093
15093
|
for (const spec of this.watched.values()) {
|
|
15094
15094
|
const resolved = resolveOccupancyScope(snapshot, spec);
|
|
15095
15095
|
if (resolved === null) continue;
|
|
15096
15096
|
const key = occupancyKey(deviceId, spec.zoneId, spec.className, spec.threshold);
|
|
15097
15097
|
this.reportImpossibleScope(deviceId, key, spec);
|
|
15098
|
+
const blindCensus = evidence === "census" && resolved.count < spec.threshold;
|
|
15098
15099
|
const existing = this.states.get(key);
|
|
15099
15100
|
if (existing === void 0) {
|
|
15101
|
+
if (blindCensus) continue;
|
|
15100
15102
|
const state = seedState(deviceId, spec, resolved, now);
|
|
15101
15103
|
this.states.set(key, state);
|
|
15102
15104
|
this.seeded.set(key, stateToRow(key, state, now));
|
|
15103
15105
|
continue;
|
|
15104
15106
|
}
|
|
15107
|
+
if (blindCensus) continue;
|
|
15105
15108
|
const edge = step(existing, spec, resolved, now);
|
|
15106
15109
|
if (edge !== null) edges.push(edge);
|
|
15107
15110
|
}
|
|
@@ -24730,12 +24733,12 @@ var NotificationCenter = class NotificationCenter {
|
|
|
24730
24733
|
* COMMITTED edge is persisted (rare — only on a confirmed flip, never
|
|
24731
24734
|
* per-frame) and routed to {@link onOccupancyEdge}.
|
|
24732
24735
|
*/
|
|
24733
|
-
observeOccupancy(deviceId, snapshot) {
|
|
24736
|
+
observeOccupancy(deviceId, snapshot, evidence = "scene") {
|
|
24734
24737
|
if (!this.evaluationActive || !this.occupancyEnabled) return;
|
|
24735
24738
|
const now = this.now();
|
|
24736
24739
|
let edges;
|
|
24737
24740
|
try {
|
|
24738
|
-
edges = this.occupancyWatcher.observe(deviceId, snapshot, now);
|
|
24741
|
+
edges = this.occupancyWatcher.observe(deviceId, snapshot, now, evidence);
|
|
24739
24742
|
} catch (err) {
|
|
24740
24743
|
this.logger.debug("occupancy observe failed", {
|
|
24741
24744
|
tags: { deviceId },
|
|
@@ -24756,7 +24759,8 @@ var NotificationCenter = class NotificationCenter {
|
|
|
24756
24759
|
previousCount: edge.previousCount,
|
|
24757
24760
|
occupied: edge.occupied,
|
|
24758
24761
|
observedAt: edge.observedAt ?? -1,
|
|
24759
|
-
observedLagMs: edge.observedAt !== void 0 ? edge.timestamp - edge.observedAt : -1
|
|
24762
|
+
observedLagMs: edge.observedAt !== void 0 ? edge.timestamp - edge.observedAt : -1,
|
|
24763
|
+
committedBy: evidence
|
|
24760
24764
|
}
|
|
24761
24765
|
});
|
|
24762
24766
|
this.persistOccupancyEdge(edge, now);
|
|
@@ -61830,6 +61834,49 @@ function hasKeyFrame(source) {
|
|
|
61830
61834
|
return source.keyFrame !== null && source.bbox !== null;
|
|
61831
61835
|
}
|
|
61832
61836
|
//#endregion
|
|
61837
|
+
//#region src/pipeline-analytics/pipeline/stationary-planes.ts
|
|
61838
|
+
/**
|
|
61839
|
+
* WHICH detection planes carry the stationary machinery.
|
|
61840
|
+
*
|
|
61841
|
+
* A plane qualifies when it produces OBJECT BOXES on decoded frames — because
|
|
61842
|
+
* that is what the registry needs to decide an object is parked: a box, a
|
|
61843
|
+
* class, and an observed clock that only advances while frames flow.
|
|
61844
|
+
*
|
|
61845
|
+
* Both root detectors qualify. `pipeline` is the ML tree; `onboard` is the
|
|
61846
|
+
* camera's own firmware, and the boxes it produces are paired with a decoded
|
|
61847
|
+
* frame in that frame's pixel space — the same plane, entered by a different
|
|
61848
|
+
* door. `sensor` and `audio` do not: they carry no geometry to park.
|
|
61849
|
+
*
|
|
61850
|
+
* It used to be `source === 'pipeline'`, in five places, each explaining that
|
|
61851
|
+
* the gate "runs on that plane". The reason given was WHERE the flood it was
|
|
61852
|
+
* written for had been measured (617, the ML plane), never an argument that the
|
|
61853
|
+
* firmware's boxes were unfit. The cost of the accident, on device 640: a still
|
|
61854
|
+
* object is never promoted, so it holds `hasLiveTrack` true for as long as it
|
|
61855
|
+
* sits there, and every detection session runs to its 120 s cap instead of
|
|
61856
|
+
* closing on cooldown — `closed at the max-hold cap with a subject still
|
|
61857
|
+
* present`. The camera's lazy stream is then torn down and rebuilt on the next
|
|
61858
|
+
* detection, on a battery camera.
|
|
61859
|
+
*
|
|
61860
|
+
* One predicate and not five comparisons, because five copies of a rule drift:
|
|
61861
|
+
* this repo has already paid for that with two authorities on one function
|
|
61862
|
+
* (D62).
|
|
61863
|
+
*/
|
|
61864
|
+
/** Does this detection plane run the stationary registry, gate and promotion? */
|
|
61865
|
+
function planeRunsStationary(source) {
|
|
61866
|
+
return source === "pipeline" || source === "onboard";
|
|
61867
|
+
}
|
|
61868
|
+
//#endregion
|
|
61869
|
+
//#region src/pipeline-analytics/pipeline/onboard-birth-authority.ts
|
|
61870
|
+
/**
|
|
61871
|
+
* May a suppression verdict RETRACT this birth?
|
|
61872
|
+
*
|
|
61873
|
+
* `false` means hold: keep the track, log the held verdict, and let the
|
|
61874
|
+
* ordinary lifetime decide. It never means "confirmed".
|
|
61875
|
+
*/
|
|
61876
|
+
function suppressionMayRetract(source) {
|
|
61877
|
+
return source !== "onboard";
|
|
61878
|
+
}
|
|
61879
|
+
//#endregion
|
|
61833
61880
|
//#region src/pipeline-analytics/rebuild-source-loader.ts
|
|
61834
61881
|
/**
|
|
61835
61882
|
* Assemble one track's rebuild inputs, reading at most ONE blob.
|
|
@@ -65600,9 +65647,10 @@ var PlateStore = class {
|
|
|
65600
65647
|
* `PlateColumnPatch` widens the nullable media columns to accept `null`,
|
|
65601
65648
|
* which is how a caller CLEARS one (`assignPlate` nulls a crop whose blob it
|
|
65602
65649
|
* just deleted, so the reown that follows cannot try to move a resource that
|
|
65603
|
-
* is gone). It used to be expressed
|
|
65604
|
-
*
|
|
65605
|
-
* became a number (D482), and which the type can simply
|
|
65650
|
+
* is gone). It used to be expressed at the call site as a `null` double-cast
|
|
65651
|
+
* through `unknown` to `string` — a cast that stopped being even nominally
|
|
65652
|
+
* true when the column became a number (D482), and which the type can simply
|
|
65653
|
+
* say instead.
|
|
65606
65654
|
*/
|
|
65607
65655
|
async update(plateId, data) {
|
|
65608
65656
|
try {
|
|
@@ -74803,7 +74851,7 @@ var ZoneAnalyticsProvider = class {
|
|
|
74803
74851
|
this.snapshots.set(input.deviceId, snapshot);
|
|
74804
74852
|
this.noteLtsSamples(input.deviceId, snapshot, input.timestamp);
|
|
74805
74853
|
this.appendHistory(input.deviceId, snapshot);
|
|
74806
|
-
this.emitSnapshot(input.deviceId, snapshot);
|
|
74854
|
+
this.emitSnapshot(input.deviceId, snapshot, "scene");
|
|
74807
74855
|
this.sliceThrottle.push(input.deviceId, snapshot);
|
|
74808
74856
|
}
|
|
74809
74857
|
/** Drop a device's snapshot + history. Called on device removal. */
|
|
@@ -74869,7 +74917,7 @@ var ZoneAnalyticsProvider = class {
|
|
|
74869
74917
|
if (snapshot) {
|
|
74870
74918
|
this.appendHistory(deviceId, snapshot);
|
|
74871
74919
|
this.noteLtsSamples(deviceId, snapshot, now);
|
|
74872
|
-
this.emitSnapshot(deviceId, snapshot);
|
|
74920
|
+
this.emitSnapshot(deviceId, snapshot, "census");
|
|
74873
74921
|
this.sliceThrottle.push(deviceId, snapshot);
|
|
74874
74922
|
}
|
|
74875
74923
|
}
|
|
@@ -74898,10 +74946,10 @@ var ZoneAnalyticsProvider = class {
|
|
|
74898
74946
|
}
|
|
74899
74947
|
/** Push one snapshot to the occupancy tap, isolating any consumer throw from
|
|
74900
74948
|
* the frame path (occupancy notifications must never break analytics). */
|
|
74901
|
-
emitSnapshot(deviceId, snapshot) {
|
|
74949
|
+
emitSnapshot(deviceId, snapshot, evidence) {
|
|
74902
74950
|
if (!this.ctx.onSnapshot) return;
|
|
74903
74951
|
try {
|
|
74904
|
-
this.ctx.onSnapshot(deviceId, snapshot);
|
|
74952
|
+
this.ctx.onSnapshot(deviceId, snapshot, evidence);
|
|
74905
74953
|
} catch (err) {
|
|
74906
74954
|
this.ctx.logger.debug("zone-analytics occupancy tap failed", {
|
|
74907
74955
|
tags: { deviceId },
|
|
@@ -77521,7 +77569,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends require_dist.B
|
|
|
77521
77569
|
listStationaryObjects: (deviceId) => this.stationaryRegistry?.listViews(deviceId) ?? [],
|
|
77522
77570
|
listStationaryDeviceIds: () => this.stationaryRegistry?.deviceIds() ?? [],
|
|
77523
77571
|
resolveZones: (deviceId) => this.resolveDeviceZones(deviceId),
|
|
77524
|
-
onSnapshot: (deviceId, snapshot) => this.notificationCenter?.observeOccupancy(deviceId, snapshot)
|
|
77572
|
+
onSnapshot: (deviceId, snapshot, evidence) => this.notificationCenter?.observeOccupancy(deviceId, snapshot, evidence)
|
|
77525
77573
|
});
|
|
77526
77574
|
this.zoneAnalytics = zoneAnalytics;
|
|
77527
77575
|
const audioMetrics = new AudioMetricsProvider({
|
|
@@ -79362,7 +79410,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends require_dist.B
|
|
|
79362
79410
|
return;
|
|
79363
79411
|
}
|
|
79364
79412
|
this.dropoutSkipsByKey.set(key, 0);
|
|
79365
|
-
if (source
|
|
79413
|
+
if (planeRunsStationary(source) && this.stationaryRegistry) {
|
|
79366
79414
|
await this.resolveDeviceStationarySettings(deviceId);
|
|
79367
79415
|
await this.resolveDevicePackageDropSettings(deviceId);
|
|
79368
79416
|
await this.resolveDeviceSummarySettings(deviceId);
|
|
@@ -79422,7 +79470,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends require_dist.B
|
|
|
79422
79470
|
});
|
|
79423
79471
|
this.trackStore?.markRiderFolded(fold.trackId);
|
|
79424
79472
|
}
|
|
79425
|
-
if (source
|
|
79473
|
+
if (planeRunsStationary(source)) this.stationaryRegistry?.noteFrame(deviceId, result.timestamp);
|
|
79426
79474
|
if (this.stationaryRegistry && (result.stationaryConfirmed.length > 0 || result.stationaryWoken.length > 0)) this.stationaryRegistry.applyFrameOutcome({
|
|
79427
79475
|
deviceId,
|
|
79428
79476
|
confirmed: result.stationaryConfirmed,
|
|
@@ -79596,8 +79644,20 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends require_dist.B
|
|
|
79596
79644
|
firstSeen: this.trackStore?.peekActive(id)?.firstSeen ?? null
|
|
79597
79645
|
});
|
|
79598
79646
|
if (!outcome.confirmed.has(id)) {
|
|
79647
|
+
if (!suppressionMayRetract(source)) {
|
|
79648
|
+
log.info("birth suppression held — the gate is not this root detector", {
|
|
79649
|
+
tags: { deviceId },
|
|
79650
|
+
meta: {
|
|
79651
|
+
trackId: id,
|
|
79652
|
+
className: t.className,
|
|
79653
|
+
source
|
|
79654
|
+
}
|
|
79655
|
+
});
|
|
79656
|
+
continue;
|
|
79657
|
+
}
|
|
79599
79658
|
this.suppressedBirths.reject(key, id);
|
|
79600
79659
|
this.trackStore?.dropActive(id);
|
|
79660
|
+
this.clearLiveTrackState(deviceId, id);
|
|
79601
79661
|
log.info("birth suppressed — track record retracted", { meta: {
|
|
79602
79662
|
trackId: id,
|
|
79603
79663
|
className: t.className,
|
|
@@ -79727,7 +79787,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends require_dist.B
|
|
|
79727
79787
|
const stationarySettings = this.stationarySettingsFromCache(deviceId);
|
|
79728
79788
|
const packageSettings = this.packageDropSettingsFromCache(deviceId);
|
|
79729
79789
|
const packageClasses = new Set(packageSettings.packageDropClassFilter);
|
|
79730
|
-
if (source
|
|
79790
|
+
if (planeRunsStationary(source) && this.stationaryRegistry && this.stationaryEvidence && stationarySettings.enabled) {
|
|
79731
79791
|
const evidence = this.stationaryEvidence;
|
|
79732
79792
|
for (const t of result.tracked) {
|
|
79733
79793
|
if (packageClasses.has(t.className)) continue;
|
|
@@ -79761,7 +79821,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends require_dist.B
|
|
|
79761
79821
|
}
|
|
79762
79822
|
evidence.retainTracks(deviceId, currentTrackIds);
|
|
79763
79823
|
}
|
|
79764
|
-
if (source
|
|
79824
|
+
if (planeRunsStationary(source)) this.runPackageStillness({
|
|
79765
79825
|
deviceId,
|
|
79766
79826
|
tracked: result.tracked,
|
|
79767
79827
|
packageClasses,
|
|
@@ -83019,7 +83079,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends require_dist.B
|
|
|
83019
83079
|
...active.subLabelMeta !== void 0 ? { subLabelMeta: active.subLabelMeta } : {}
|
|
83020
83080
|
} : void 0;
|
|
83021
83081
|
});
|
|
83022
|
-
if (source
|
|
83082
|
+
if (planeRunsStationary(source) && this.stationaryRegistry) {
|
|
83023
83083
|
const registry = this.stationaryRegistry;
|
|
83024
83084
|
p.setStationaryGate({ filter: (input) => {
|
|
83025
83085
|
const s = this.stationarySettingsFromCache(deviceId);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as TimelapseRuleSchema, $t as array, A as NcConditionDescriptorSchema, At as readDeviceStateFrom, B as NcTaxonomySchema, Bt as zoneAnalyticsCapability, C as MOTION_CLOSE_AFTER_MS, Ct as mayWriteToLocation, D as NC_DEFAULT_SNOOZE_MINUTES, Dt as pickClusterStepModels, E as NC_CONDITION_CATALOG, F as NcScheduleSchema, Ft as storageOccupancyCapability, Gt as createEvent, Ht as BaseAddon, I as NcSnoozeInputSchema, It as subKindsOf, J as SCENE_DIVERGED, Jt as hydrateSchema, K as SCENE_DEFAULT_ANCHOR_THRESHOLD, Kt as customAction, L as NcSnoozeSchema, Lt as systemEventFilterApplies, M as NcRulePatchSchema, Mt as resolveLocationMode, N as NcRuleSchema, Ot as pipelineAnalyticsCapability, P as NcRuleTargetSchema, Pt as sceneMonitorCapability, Q as TimelapseRulePatchSchema, Qt as _enum, R as NcSnoozeSuppressedSchema, Rt as vectorDimFromBase64, St as kebabToCamel, T as NC_ALARM_SYSTEM_EVENT_KINDS, Tt as occupancyScope, U as RECORDING_EXPORT_MAX_READ_BYTES, Ut as CamProfileSchema, V as OpsLogEntrySchema, Vt as errMsg$1, W as RetrainStatusSchema, Wt as DeviceType, X as TIMELAPSE_DENSE_FLOOR_SEC, Xt as nodePin, Y as SceneMonitorSchema, Yt as isDeviceScopedCap, Z as TimelapseRuleInputSchema, Zt as sleep$1, _ as FULL_IMAGE_BBOX, _t as isDetectionMacroClass, a as CLUSTER_MODEL_SCOPED_STEPS, an as partialRecord, at as audioMetricsCapability, b as MAX_ARCHIVED_DEBUG_NOTES, bt as isScheduleActive, cn as unknown, ct as cosineSimilarity$1, dt as encodeVectorBase64, en as boolean, et as TrackSourceSchema, f as DeclaredDevices, ft as evaluateSensorEdge, g as FIRST_LEVEL_MACRO_CLASSES, h as EVENT_PAD_MS, ht as failureContributionCapability, i as BirthDecisionRecordSchema, in as object, it as assertTimelapseCadences, j as NcRuleInputSchema, jt as readTimelapseGeneratedAt, k as NC_TAXONOMY, kt as plateGalleryCapability, ln as EventCategory, lt as deriveRecordingMode, m as EVENT_OWNER_TYPES, mt as faceGalleryCapability, n as ArchivedDebugNoteSchema, nn as literal, nt as addonWidgetsSourceCapability, o as COCO_TO_MACRO, on as record, ot as audioModeOf, p as EVENT_KIND_BY_CAP, pt as evictionPolicyOfLocation, q as SCENE_DEFAULT_UNCOVERED_POLICY, qt as defineCustomActions, r as BaseDevice, rn as number, rt as alarmPanelCapability, s as DEFAULT_EVENT_COLOR, sn as string, st as buildEventKindDescriptor, t as AUDIO_MACRO_LABELS, tn as discriminatedUnion, tt as VISIT_MERGE_GAP_MS, u as DETECTION_MACRO_CLASSES, v as FailureCounters, vt as isEventOwnerType, w as MediaFileKindEnum, wt as notificationRulesCapability, x as MAX_BIRTH_DECISION_RECORDS, xt as isSourceCap, y as LabelAttributionSchema, yt as isMediaOwnerType, z as NcSystemEventKindSchema, zt as videoclipsCapability } from "../dist-
|
|
1
|
+
import { $ as TimelapseRuleSchema, $t as array, A as NcConditionDescriptorSchema, At as readDeviceStateFrom, B as NcTaxonomySchema, Bt as zoneAnalyticsCapability, C as MOTION_CLOSE_AFTER_MS, Ct as mayWriteToLocation, D as NC_DEFAULT_SNOOZE_MINUTES, Dt as pickClusterStepModels, E as NC_CONDITION_CATALOG, F as NcScheduleSchema, Ft as storageOccupancyCapability, Gt as createEvent, Ht as BaseAddon, I as NcSnoozeInputSchema, It as subKindsOf, J as SCENE_DIVERGED, Jt as hydrateSchema, K as SCENE_DEFAULT_ANCHOR_THRESHOLD, Kt as customAction, L as NcSnoozeSchema, Lt as systemEventFilterApplies, M as NcRulePatchSchema, Mt as resolveLocationMode, N as NcRuleSchema, Ot as pipelineAnalyticsCapability, P as NcRuleTargetSchema, Pt as sceneMonitorCapability, Q as TimelapseRulePatchSchema, Qt as _enum, R as NcSnoozeSuppressedSchema, Rt as vectorDimFromBase64, St as kebabToCamel, T as NC_ALARM_SYSTEM_EVENT_KINDS, Tt as occupancyScope, U as RECORDING_EXPORT_MAX_READ_BYTES, Ut as CamProfileSchema, V as OpsLogEntrySchema, Vt as errMsg$1, W as RetrainStatusSchema, Wt as DeviceType, X as TIMELAPSE_DENSE_FLOOR_SEC, Xt as nodePin, Y as SceneMonitorSchema, Yt as isDeviceScopedCap, Z as TimelapseRuleInputSchema, Zt as sleep$1, _ as FULL_IMAGE_BBOX, _t as isDetectionMacroClass, a as CLUSTER_MODEL_SCOPED_STEPS, an as partialRecord, at as audioMetricsCapability, b as MAX_ARCHIVED_DEBUG_NOTES, bt as isScheduleActive, cn as unknown, ct as cosineSimilarity$1, dt as encodeVectorBase64, en as boolean, et as TrackSourceSchema, f as DeclaredDevices, ft as evaluateSensorEdge, g as FIRST_LEVEL_MACRO_CLASSES, h as EVENT_PAD_MS, ht as failureContributionCapability, i as BirthDecisionRecordSchema, in as object, it as assertTimelapseCadences, j as NcRuleInputSchema, jt as readTimelapseGeneratedAt, k as NC_TAXONOMY, kt as plateGalleryCapability, ln as EventCategory, lt as deriveRecordingMode, m as EVENT_OWNER_TYPES, mt as faceGalleryCapability, n as ArchivedDebugNoteSchema, nn as literal, nt as addonWidgetsSourceCapability, o as COCO_TO_MACRO, on as record, ot as audioModeOf, p as EVENT_KIND_BY_CAP, pt as evictionPolicyOfLocation, q as SCENE_DEFAULT_UNCOVERED_POLICY, qt as defineCustomActions, r as BaseDevice, rn as number, rt as alarmPanelCapability, s as DEFAULT_EVENT_COLOR, sn as string, st as buildEventKindDescriptor, t as AUDIO_MACRO_LABELS, tn as discriminatedUnion, tt as VISIT_MERGE_GAP_MS, u as DETECTION_MACRO_CLASSES, v as FailureCounters, vt as isEventOwnerType, w as MediaFileKindEnum, wt as notificationRulesCapability, x as MAX_BIRTH_DECISION_RECORDS, xt as isSourceCap, y as LabelAttributionSchema, yt as isMediaOwnerType, z as NcSystemEventKindSchema, zt as videoclipsCapability } from "../dist-C7xHFnGJ.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";
|
|
@@ -15081,20 +15081,23 @@ var OccupancyWatcher = class {
|
|
|
15081
15081
|
* this tick (usually none). Every watched key is evaluated for `deviceId`;
|
|
15082
15082
|
* fail-closed keys (absent zone) are skipped and hold no state.
|
|
15083
15083
|
*/
|
|
15084
|
-
observe(deviceId, snapshot, now) {
|
|
15084
|
+
observe(deviceId, snapshot, now, evidence = "scene") {
|
|
15085
15085
|
const edges = [];
|
|
15086
15086
|
for (const spec of this.watched.values()) {
|
|
15087
15087
|
const resolved = resolveOccupancyScope(snapshot, spec);
|
|
15088
15088
|
if (resolved === null) continue;
|
|
15089
15089
|
const key = occupancyKey(deviceId, spec.zoneId, spec.className, spec.threshold);
|
|
15090
15090
|
this.reportImpossibleScope(deviceId, key, spec);
|
|
15091
|
+
const blindCensus = evidence === "census" && resolved.count < spec.threshold;
|
|
15091
15092
|
const existing = this.states.get(key);
|
|
15092
15093
|
if (existing === void 0) {
|
|
15094
|
+
if (blindCensus) continue;
|
|
15093
15095
|
const state = seedState(deviceId, spec, resolved, now);
|
|
15094
15096
|
this.states.set(key, state);
|
|
15095
15097
|
this.seeded.set(key, stateToRow(key, state, now));
|
|
15096
15098
|
continue;
|
|
15097
15099
|
}
|
|
15100
|
+
if (blindCensus) continue;
|
|
15098
15101
|
const edge = step(existing, spec, resolved, now);
|
|
15099
15102
|
if (edge !== null) edges.push(edge);
|
|
15100
15103
|
}
|
|
@@ -24708,12 +24711,12 @@ var NotificationCenter = class NotificationCenter {
|
|
|
24708
24711
|
* COMMITTED edge is persisted (rare — only on a confirmed flip, never
|
|
24709
24712
|
* per-frame) and routed to {@link onOccupancyEdge}.
|
|
24710
24713
|
*/
|
|
24711
|
-
observeOccupancy(deviceId, snapshot) {
|
|
24714
|
+
observeOccupancy(deviceId, snapshot, evidence = "scene") {
|
|
24712
24715
|
if (!this.evaluationActive || !this.occupancyEnabled) return;
|
|
24713
24716
|
const now = this.now();
|
|
24714
24717
|
let edges;
|
|
24715
24718
|
try {
|
|
24716
|
-
edges = this.occupancyWatcher.observe(deviceId, snapshot, now);
|
|
24719
|
+
edges = this.occupancyWatcher.observe(deviceId, snapshot, now, evidence);
|
|
24717
24720
|
} catch (err) {
|
|
24718
24721
|
this.logger.debug("occupancy observe failed", {
|
|
24719
24722
|
tags: { deviceId },
|
|
@@ -24734,7 +24737,8 @@ var NotificationCenter = class NotificationCenter {
|
|
|
24734
24737
|
previousCount: edge.previousCount,
|
|
24735
24738
|
occupied: edge.occupied,
|
|
24736
24739
|
observedAt: edge.observedAt ?? -1,
|
|
24737
|
-
observedLagMs: edge.observedAt !== void 0 ? edge.timestamp - edge.observedAt : -1
|
|
24740
|
+
observedLagMs: edge.observedAt !== void 0 ? edge.timestamp - edge.observedAt : -1,
|
|
24741
|
+
committedBy: evidence
|
|
24738
24742
|
}
|
|
24739
24743
|
});
|
|
24740
24744
|
this.persistOccupancyEdge(edge, now);
|
|
@@ -61756,6 +61760,49 @@ function hasKeyFrame(source) {
|
|
|
61756
61760
|
return source.keyFrame !== null && source.bbox !== null;
|
|
61757
61761
|
}
|
|
61758
61762
|
//#endregion
|
|
61763
|
+
//#region src/pipeline-analytics/pipeline/stationary-planes.ts
|
|
61764
|
+
/**
|
|
61765
|
+
* WHICH detection planes carry the stationary machinery.
|
|
61766
|
+
*
|
|
61767
|
+
* A plane qualifies when it produces OBJECT BOXES on decoded frames — because
|
|
61768
|
+
* that is what the registry needs to decide an object is parked: a box, a
|
|
61769
|
+
* class, and an observed clock that only advances while frames flow.
|
|
61770
|
+
*
|
|
61771
|
+
* Both root detectors qualify. `pipeline` is the ML tree; `onboard` is the
|
|
61772
|
+
* camera's own firmware, and the boxes it produces are paired with a decoded
|
|
61773
|
+
* frame in that frame's pixel space — the same plane, entered by a different
|
|
61774
|
+
* door. `sensor` and `audio` do not: they carry no geometry to park.
|
|
61775
|
+
*
|
|
61776
|
+
* It used to be `source === 'pipeline'`, in five places, each explaining that
|
|
61777
|
+
* the gate "runs on that plane". The reason given was WHERE the flood it was
|
|
61778
|
+
* written for had been measured (617, the ML plane), never an argument that the
|
|
61779
|
+
* firmware's boxes were unfit. The cost of the accident, on device 640: a still
|
|
61780
|
+
* object is never promoted, so it holds `hasLiveTrack` true for as long as it
|
|
61781
|
+
* sits there, and every detection session runs to its 120 s cap instead of
|
|
61782
|
+
* closing on cooldown — `closed at the max-hold cap with a subject still
|
|
61783
|
+
* present`. The camera's lazy stream is then torn down and rebuilt on the next
|
|
61784
|
+
* detection, on a battery camera.
|
|
61785
|
+
*
|
|
61786
|
+
* One predicate and not five comparisons, because five copies of a rule drift:
|
|
61787
|
+
* this repo has already paid for that with two authorities on one function
|
|
61788
|
+
* (D62).
|
|
61789
|
+
*/
|
|
61790
|
+
/** Does this detection plane run the stationary registry, gate and promotion? */
|
|
61791
|
+
function planeRunsStationary(source) {
|
|
61792
|
+
return source === "pipeline" || source === "onboard";
|
|
61793
|
+
}
|
|
61794
|
+
//#endregion
|
|
61795
|
+
//#region src/pipeline-analytics/pipeline/onboard-birth-authority.ts
|
|
61796
|
+
/**
|
|
61797
|
+
* May a suppression verdict RETRACT this birth?
|
|
61798
|
+
*
|
|
61799
|
+
* `false` means hold: keep the track, log the held verdict, and let the
|
|
61800
|
+
* ordinary lifetime decide. It never means "confirmed".
|
|
61801
|
+
*/
|
|
61802
|
+
function suppressionMayRetract(source) {
|
|
61803
|
+
return source !== "onboard";
|
|
61804
|
+
}
|
|
61805
|
+
//#endregion
|
|
61759
61806
|
//#region src/pipeline-analytics/rebuild-source-loader.ts
|
|
61760
61807
|
/**
|
|
61761
61808
|
* Assemble one track's rebuild inputs, reading at most ONE blob.
|
|
@@ -65526,9 +65573,10 @@ var PlateStore = class {
|
|
|
65526
65573
|
* `PlateColumnPatch` widens the nullable media columns to accept `null`,
|
|
65527
65574
|
* which is how a caller CLEARS one (`assignPlate` nulls a crop whose blob it
|
|
65528
65575
|
* just deleted, so the reown that follows cannot try to move a resource that
|
|
65529
|
-
* is gone). It used to be expressed
|
|
65530
|
-
*
|
|
65531
|
-
* became a number (D482), and which the type can simply
|
|
65576
|
+
* is gone). It used to be expressed at the call site as a `null` double-cast
|
|
65577
|
+
* through `unknown` to `string` — a cast that stopped being even nominally
|
|
65578
|
+
* true when the column became a number (D482), and which the type can simply
|
|
65579
|
+
* say instead.
|
|
65532
65580
|
*/
|
|
65533
65581
|
async update(plateId, data) {
|
|
65534
65582
|
try {
|
|
@@ -74729,7 +74777,7 @@ var ZoneAnalyticsProvider = class {
|
|
|
74729
74777
|
this.snapshots.set(input.deviceId, snapshot);
|
|
74730
74778
|
this.noteLtsSamples(input.deviceId, snapshot, input.timestamp);
|
|
74731
74779
|
this.appendHistory(input.deviceId, snapshot);
|
|
74732
|
-
this.emitSnapshot(input.deviceId, snapshot);
|
|
74780
|
+
this.emitSnapshot(input.deviceId, snapshot, "scene");
|
|
74733
74781
|
this.sliceThrottle.push(input.deviceId, snapshot);
|
|
74734
74782
|
}
|
|
74735
74783
|
/** Drop a device's snapshot + history. Called on device removal. */
|
|
@@ -74795,7 +74843,7 @@ var ZoneAnalyticsProvider = class {
|
|
|
74795
74843
|
if (snapshot) {
|
|
74796
74844
|
this.appendHistory(deviceId, snapshot);
|
|
74797
74845
|
this.noteLtsSamples(deviceId, snapshot, now);
|
|
74798
|
-
this.emitSnapshot(deviceId, snapshot);
|
|
74846
|
+
this.emitSnapshot(deviceId, snapshot, "census");
|
|
74799
74847
|
this.sliceThrottle.push(deviceId, snapshot);
|
|
74800
74848
|
}
|
|
74801
74849
|
}
|
|
@@ -74824,10 +74872,10 @@ var ZoneAnalyticsProvider = class {
|
|
|
74824
74872
|
}
|
|
74825
74873
|
/** Push one snapshot to the occupancy tap, isolating any consumer throw from
|
|
74826
74874
|
* the frame path (occupancy notifications must never break analytics). */
|
|
74827
|
-
emitSnapshot(deviceId, snapshot) {
|
|
74875
|
+
emitSnapshot(deviceId, snapshot, evidence) {
|
|
74828
74876
|
if (!this.ctx.onSnapshot) return;
|
|
74829
74877
|
try {
|
|
74830
|
-
this.ctx.onSnapshot(deviceId, snapshot);
|
|
74878
|
+
this.ctx.onSnapshot(deviceId, snapshot, evidence);
|
|
74831
74879
|
} catch (err) {
|
|
74832
74880
|
this.ctx.logger.debug("zone-analytics occupancy tap failed", {
|
|
74833
74881
|
tags: { deviceId },
|
|
@@ -77447,7 +77495,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
77447
77495
|
listStationaryObjects: (deviceId) => this.stationaryRegistry?.listViews(deviceId) ?? [],
|
|
77448
77496
|
listStationaryDeviceIds: () => this.stationaryRegistry?.deviceIds() ?? [],
|
|
77449
77497
|
resolveZones: (deviceId) => this.resolveDeviceZones(deviceId),
|
|
77450
|
-
onSnapshot: (deviceId, snapshot) => this.notificationCenter?.observeOccupancy(deviceId, snapshot)
|
|
77498
|
+
onSnapshot: (deviceId, snapshot, evidence) => this.notificationCenter?.observeOccupancy(deviceId, snapshot, evidence)
|
|
77451
77499
|
});
|
|
77452
77500
|
this.zoneAnalytics = zoneAnalytics;
|
|
77453
77501
|
const audioMetrics = new AudioMetricsProvider({
|
|
@@ -79288,7 +79336,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
79288
79336
|
return;
|
|
79289
79337
|
}
|
|
79290
79338
|
this.dropoutSkipsByKey.set(key, 0);
|
|
79291
|
-
if (source
|
|
79339
|
+
if (planeRunsStationary(source) && this.stationaryRegistry) {
|
|
79292
79340
|
await this.resolveDeviceStationarySettings(deviceId);
|
|
79293
79341
|
await this.resolveDevicePackageDropSettings(deviceId);
|
|
79294
79342
|
await this.resolveDeviceSummarySettings(deviceId);
|
|
@@ -79348,7 +79396,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
79348
79396
|
});
|
|
79349
79397
|
this.trackStore?.markRiderFolded(fold.trackId);
|
|
79350
79398
|
}
|
|
79351
|
-
if (source
|
|
79399
|
+
if (planeRunsStationary(source)) this.stationaryRegistry?.noteFrame(deviceId, result.timestamp);
|
|
79352
79400
|
if (this.stationaryRegistry && (result.stationaryConfirmed.length > 0 || result.stationaryWoken.length > 0)) this.stationaryRegistry.applyFrameOutcome({
|
|
79353
79401
|
deviceId,
|
|
79354
79402
|
confirmed: result.stationaryConfirmed,
|
|
@@ -79522,8 +79570,20 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
79522
79570
|
firstSeen: this.trackStore?.peekActive(id)?.firstSeen ?? null
|
|
79523
79571
|
});
|
|
79524
79572
|
if (!outcome.confirmed.has(id)) {
|
|
79573
|
+
if (!suppressionMayRetract(source)) {
|
|
79574
|
+
log.info("birth suppression held — the gate is not this root detector", {
|
|
79575
|
+
tags: { deviceId },
|
|
79576
|
+
meta: {
|
|
79577
|
+
trackId: id,
|
|
79578
|
+
className: t.className,
|
|
79579
|
+
source
|
|
79580
|
+
}
|
|
79581
|
+
});
|
|
79582
|
+
continue;
|
|
79583
|
+
}
|
|
79525
79584
|
this.suppressedBirths.reject(key, id);
|
|
79526
79585
|
this.trackStore?.dropActive(id);
|
|
79586
|
+
this.clearLiveTrackState(deviceId, id);
|
|
79527
79587
|
log.info("birth suppressed — track record retracted", { meta: {
|
|
79528
79588
|
trackId: id,
|
|
79529
79589
|
className: t.className,
|
|
@@ -79653,7 +79713,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
79653
79713
|
const stationarySettings = this.stationarySettingsFromCache(deviceId);
|
|
79654
79714
|
const packageSettings = this.packageDropSettingsFromCache(deviceId);
|
|
79655
79715
|
const packageClasses = new Set(packageSettings.packageDropClassFilter);
|
|
79656
|
-
if (source
|
|
79716
|
+
if (planeRunsStationary(source) && this.stationaryRegistry && this.stationaryEvidence && stationarySettings.enabled) {
|
|
79657
79717
|
const evidence = this.stationaryEvidence;
|
|
79658
79718
|
for (const t of result.tracked) {
|
|
79659
79719
|
if (packageClasses.has(t.className)) continue;
|
|
@@ -79687,7 +79747,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
79687
79747
|
}
|
|
79688
79748
|
evidence.retainTracks(deviceId, currentTrackIds);
|
|
79689
79749
|
}
|
|
79690
|
-
if (source
|
|
79750
|
+
if (planeRunsStationary(source)) this.runPackageStillness({
|
|
79691
79751
|
deviceId,
|
|
79692
79752
|
tracked: result.tracked,
|
|
79693
79753
|
packageClasses,
|
|
@@ -82945,7 +83005,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
82945
83005
|
...active.subLabelMeta !== void 0 ? { subLabelMeta: active.subLabelMeta } : {}
|
|
82946
83006
|
} : void 0;
|
|
82947
83007
|
});
|
|
82948
|
-
if (source
|
|
83008
|
+
if (planeRunsStationary(source) && this.stationaryRegistry) {
|
|
82949
83009
|
const registry = this.stationaryRegistry;
|
|
82950
83010
|
p.setStationaryGate({ filter: (input) => {
|
|
82951
83011
|
const s = this.stationarySettingsFromCache(deviceId);
|
|
@@ -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-DJ9dpbgD.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.249",
|
|
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",
|