@camstack/addon-post-analysis 1.2.626 → 1.2.628
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/{clip-model-registry-FGmg0uYz.js → clip-model-registry-CK0QHBLo.js} +6823 -1590
- package/dist/{clip-model-registry-DAWGt4j9.mjs → clip-model-registry-CXp8hOtz.mjs} +6818 -1591
- package/dist/embedding-encoder/index.js +1 -1
- package/dist/embedding-encoder/index.mjs +1 -1
- package/dist/pipeline-analytics/_stub.js +2 -2
- package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-Biy-u2yt.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-BSMQI14W.mjs} +2 -2
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CC5fsXdm.mjs +26 -0
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DdDfkgWU.mjs +26 -0
- package/dist/pipeline-analytics/{hostInit-4lybsFX0.mjs → hostInit-DZur54eI.mjs} +2 -2
- package/dist/pipeline-analytics/index.js +259 -136
- package/dist/pipeline-analytics/index.mjs +259 -136
- package/dist/pipeline-analytics/remoteEntry.js +1 -1
- package/package.json +1 -1
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-yap5surJ.mjs +0 -26
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-_Ip2ZGVX.mjs +0 -26
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as MediaFileKindEnum, $i as
|
|
1
|
+
import { $ as MediaFileKindEnum, $i as customAction, $n as coreBlockIdFromAddonId, $r as pipelineAnalyticsCapability, $t as OpsLogEntrySchema, A as DeclaredDevices, Ai as systemEventDeliveryProblems, An as TrackSourceSchema, Ar as isDrawableSubjectPath, At as NcAlarmSensorsInputSchema, B as FULL_IMAGE_BBOX, Bi as zoneAnalyticsCapability, Bn as applyNonBlockingEdit, Br as isSystemEventSummaryRule, Bt as NcRuleUpdateInputSchema, C as ClearTrackRelationResultSchema, Ca as unknown, Ci as startMoverUnderClearance, Cn as TimelapseRulePatchSchema, Cr as isAlarmControllableCap, Ct as NC_SNOOZE_MAX_MINUTES, D as DEFAULT_TIMELAPSE_PREVIEW_TEXT, Di as subjectPathSvgPoints, Dn as TrackRelationKindSchema, Dr as isAudioClassName, Dt as NC_TEMPLATE_VARS, E as DEFAULT_EVENT_COLOR, Ei as subjectPathSampleFromBox, En as TrackPuritySchema, Er as isAppLinkBase, Et as NC_TAXONOMY, F as EVENT_DENSITY_BATCH_MAX, Fi as templateCarriesSummary, Fn as alertEpisodeId, Fr as isMediaOwnerType, Ft as NcRuleActionSchema, G as ListTrackRelationsResultSchema, Gi as DeviceType, Gn as audioModeOf, Gr as memoizePinnedFfmpeg, Gt as NcSnoozeSuppressedSchema, H as LABEL_SUPPLY_MACRO, Hi as canonicalHash, Hn as armRemovalReconcile, Hr as kebabToCamel, Ht as NcSharedSequenceSchema, I as EVENT_KIND_BY_CAP, Ii as templateVarsFor, In as alertEpisodeKind, Ir as isRetiredClearKey, It as NcRuleInputSchema, J as MAX_BIRTH_DECISION_RECORDS, Ji as CamProfileSchema, Jn as buildViewerLink, Jr as notificationRulesCapability, Jt as NcTaxonomySchema, K as LockStateSchema, Ki as errMsg, Kn as buildEventKindDescriptor, Kr as ncMediaPolicyError, Kt as NcStateSummarySectionIdSchema, L as EVENT_OWNER_TYPES, Li as vectorDimFromBase64, Ln as alertEpisodePayload, Lr as isRootSuppliableStepId, Lt as NcRulePatchSchema, M as EMBEDDING_MODEL_FAILED, Mi as systemEventFilterApplies, Mn as addonWidgetsSourceCapability, Mr as isEventOwnerType, Mt as NcAlarmSettingsPatchSchema, N as EMBEDDING_REQUIREMENTS_FAILED, Ni as systemEventSummaryScheduleOf, Nn as alarmDeviceSecureOnArm, Nr as isKnownTemplateVar, Nt as NcConditionDescriptorSchema, O as DETECTION_MACRO_CLASSES, Oi as summarizeReview, On as TrackRelationSchema, Or as isDefaultAlarmProfileId, Ot as NcAlarmConfigSchema, P as EMBEDDING_REQUIREMENTS_UNAVAILABLE, Pi as systemEventSummarySplitOf, Pn as alarmPanelCapability, Pr as isLabelSupplyStepId, Pt as NcConditionsSchema, Q as MOTION_CLOSE_AFTER_MS, Qi as createEvent, Qn as consumableLowPercentOf, Qr as pickFaceRescoreIntervalMinutes, Qt as OPS_LOG_DEFAULT_LIMIT, R as EXPORT_DENSE_MAX_RANGES, Ri as viewerLinkBaseOf, Rn as applyBlockingEdit, Rr as isScheduleActive, Rt as NcRuleSchema, S as ClearTrackRelationInputSchema, Sa as union, Si as servedTemplateVars, Sn as TimelapseRuleInputSchema, Sr as gifFromMp4Args, St as NC_SENSOR_TRANSITION_KINDS, T as DEFAULT_DETAIL_CROP_CONVENTION, Ti as subKindsOf, Tn as TrackPlacementSchema, Tr as isAlertEpisodeSeverity, Tt as NC_TANK_SYSTEM_EVENT_KINDS, U as LabelAttributionSchema, Ui as evaluateSensorEdge, Un as assertTimelapseCadences, Ur as linkedStepOf, Ut as NcSnoozeInputSchema, V as FailureCounters, Vi as DEFAULT_FIRST_SIGHTING_FRESHNESS_MS, Vn as applySecureOnArmEdit, Vr as isVectorIndexDimConflict, Vt as NcScheduleSchema, W as ListTrackRelationsInputSchema, Wi as isSourceCap, Wn as audioMetricsCapability, Wr as mayWriteToLocation, Wt as NcSnoozeSchema, X as MAX_TRACK_PURITIES, Xi as RECORD_MAX_DATA_BYTES, Xn as classifyRetrainReview, Xr as parseAlertEpisodePayload, Xt as NcTemplatePreviewSchema, Y as MAX_BIRTH_LATENCY_PROXY_MS, Yi as InvalidRecordError, Yn as calendarEventLocalSpan, Yr as occupancyScope, Yt as NcTemplatePreviewInputSchema, Z as MAX_TRACK_RELATIONS, Zi as RECORD_QUERY_MAX, Zn as cloneAlarmSettings, Zt as NcTemplateVarDescriptorSchema, _ as BIRTH_DECISION_DEFAULT_LIMIT, _a as record, _i as ruleGroupingApplies, _n as SetTrackPurityInputSchema, _r as eventKindLabel, _t as NC_CONSUMABLE_SYSTEM_EVENT_KINDS, a as CLIP_EMBEDDING_STEP_ID, ai as renameAlarmProfile, an as RetrainOriginSchema, ar as deriveRecordingMode, at as NC_ALARM_NOTIFY_FIELDS, b as BucketAccumulator, ba as templateLiteral, bi as secureActuationFor, bn as TIMELAPSE_DENSE_FLOOR_SEC, br as failureContributionCapability, bt as NC_GROUPING_MAX_SEC, c as readClusterModelPinStrict, ca as _enum, ci as resolveModeDelays, cn as SCENE_CONFIRM_DEFAULT_TIMEOUT_MS, cr as deviceAttentionKind, ct as NC_AUDIO_CONFIRM_HITS_DEFAULT, d as APPEARANCE_BLOCKS, da as discriminatedUnion, dn as SCENE_DEFAULT_OBSERVATION_SPACING_SEC, dt as NC_CLIP_PRE_ROLL_DEFAULT_SEC, ea as defineCustomActions, ei as plateGalleryCapability, er as cosineSimilarity$1, et as MotionTriggeredBySchema, f as APPEARANCE_RESOLVES_AMBIGUITY_DEFAULT, fa as literal, fi as retrainRevisionConflictMessage, fn as SCENE_DEFAULT_QUIET_SECONDS, fr as embeddingRefusalOf, ft as NC_CLIP_RETENTION_MAX_SEC, g as ArchivedDebugNoteSchema, ga as partialRecord, gi as ruleDeviceCompatCapQueries, gn as SceneMonitorSchema, gr as ensureAlarmProfiles, gt as NC_CONSUMABLE_LOW_PERCENT_DEFAULT, h as AlarmArmModeSchema, ha as object, hi as ruleBelongsToAlarm$1, hn as SCENE_RESET_RECAPTURES, hr as encodeVectorBase64, ht as NC_CONFIRM_DEFAULT_TIMEOUT_MS, ia as nodePin, ii as readTimelapseGeneratedAt, in as RetrainDismissedSchema, ir as derivePostTriggeredAction, it as NC_ALARM_DELAY_MAX_SEC, j as DetectionSourceSchema, ji as systemEventFamilyProblems, jn as activateAlarmProfile, jr as isEventKindLabelKey, jt as NcAlarmSensorsSchema, k as DETECTION_PIPELINE_CAP_NAME, ki as syncActiveAlarmProfileSettings, kn as TrackSideSchema, kr as isDetectionMacroClass, kt as NcAlarmPostTriggeredActionSchema, l as resolveClusterModelPin, la as array, li as resolveModeNotifyPolicy, ln as SCENE_DEFAULT_ANCHOR_THRESHOLD, lr as deviceRemovalHookCapability, lt as NC_AUDIO_CONFIRM_WINDOW_SEC_DEFAULT, m as AUDIO_MACRO_LABELS, ma as number, mi as ruleAutoTriggersAlarm, mn as SCENE_DIVERGED, mt as NC_CONFIRM_DEFAULT_MAX_IMAGE_PX, na as hydrateSchema, ni as readDeviceStateFrom, nn as RECORDING_SOURCE_CAMSTACK_ADDON, nr as deleteAlarmProfile, nt as NC_ALARM_DEFAULT_TRIGGERED_DURATION_SEC, o as CLUSTER_MODEL_OWNER_ADDON_ID, oa as sleep$1, oi as resolveClipSearchMinScore, on as RetrainStatusSchema, or as describeSystemEventDeliveryProblem, ot as NC_ALARM_SYSTEM_EVENT_KINDS, p as ARCHIVED_DEBUG_NOTES_DEFAULT_LIMIT, pa as looseObject, pi as rootSupplyServes, pn as SCENE_DEFAULT_UNCOVERED_POLICY, pt as NC_CONDITION_CATALOG, q as MAX_ARCHIVED_DEBUG_NOTES, qi as BaseAddon, qn as buildSubjectPath, qr as normalizeNcMediaPolicy, qt as NcSystemEventKindSchema, ra as isDeviceScopedCap, ri as readMotionTriggeredBy, rn as RebuildObjectEmbeddingsRefusalSchema, rr as deriveDetailCropRect, rt as NC_ALARM_DELAY_FIELDS, s as FACE_EMBEDDING_STEP_ID, sa as ZodObject, si as resolveLocationMode, sn as SCENE_CONFIRM_DEFAULT_MAX_IMAGE_PX, sr as describeSystemEventFamilyProblem, st as NC_ALARM_TRIGGERED_MAX_SEC, t as BUILTIN_CLIP_MODELS, ta as defineRecordKinds, ti as projectSubjectPath, tn as RECORDING_EXPORT_MAX_READ_BYTES, tr as createAlarmProfile, tt as NC_ALARM_DEFAULT_PROFILE_ID, u as APPEARANCE_BIN_COUNT, ua as boolean, ui as resolveNcMediaImage, un as SCENE_DEFAULT_CHECK_INTERVAL_SEC, ut as NC_CLIP_POST_ROLL_DEFAULT_SEC, v as BaseDevice, va as strictObject, vi as ruleKindOf, vn as SetTrackPurityResultSchema, vr as evictionPolicyOfLocation, vt as NC_DEFAULT_SNOOZE_MINUTES, w as CoverStateSchema, wa as EventCategory, wi as storageOccupancyCapability, wn as TimelapseRuleSchema, wr as isAlertEpisodeOpen, wt as NC_SYSTEM_EVENT_KIND_GROUP_SPECS, x as COCO_TO_MACRO, xa as tuple, xi as sensorRaisedOf, xn as TRACK_RELATIONS_DEFAULT_LIMIT, xr as gifDeriveSpeed, xt as NC_GROUPING_MIN_SEC, y as BirthDecisionRecordSchema, ya as string, yi as sceneMonitorCapability, yn as SetTrackRelationInputSchema, yr as faceGalleryCapability, yt as NC_GROUPING_DEFAULT_SEC, z as FIRST_LEVEL_MACRO_CLASSES, zi as withSystemEventClasses, zn as applyModeDelaysEdits, zr as isSystemDelivery, zt as NcRuleTargetSchema } from "../clip-model-registry-CXp8hOtz.mjs";
|
|
2
2
|
import { t as __exportAll } from "../embedding-encoder/index.mjs";
|
|
3
3
|
import * as fs$1 from "node:fs";
|
|
4
4
|
import { createWriteStream, promises } from "node:fs";
|
|
@@ -9905,7 +9905,6 @@ var SCENE_LATCH_SPEC = {
|
|
|
9905
9905
|
fromRecord: latchFromRecord,
|
|
9906
9906
|
deviceIdOf: (row) => row.deviceId
|
|
9907
9907
|
};
|
|
9908
|
-
SCENE_LATCH_SPEC.fromRecord, SCENE_LATCH_SPEC.toValue, SCENE_LATCH_SPEC.deviceIdOf;
|
|
9909
9908
|
/**
|
|
9910
9909
|
* The two ledgers behind one façade. Callers never see the split, but they can
|
|
9911
9910
|
* never accidentally write one when they meant the other either: the config
|
|
@@ -16396,6 +16395,18 @@ function gapDistance(a, b) {
|
|
|
16396
16395
|
if (last === void 0 || first === void 0 || first.timestamp < last.timestamp) return 0;
|
|
16397
16396
|
return Math.sqrt((first.x - last.x) ** 2 + (first.y - last.y) ** 2);
|
|
16398
16397
|
}
|
|
16398
|
+
/**
|
|
16399
|
+
* WHERE a fused track was detected (D683 L2 fusion): it OPENED where its
|
|
16400
|
+
* earliest-born piece opened and CLOSED where its latest-seen piece was last
|
|
16401
|
+
* sighted — the same span `firstSeen` / `lastSeen` take, decided by the times
|
|
16402
|
+
* rather than by which piece survived (an absorbed piece can overlap and end
|
|
16403
|
+
* first). The placements of the pieces in between are not kept: the row
|
|
16404
|
+
* answers "where did this subject start and end", and a hop in the middle is
|
|
16405
|
+
* the `inference device selection` log's to tell. A piece with no placement
|
|
16406
|
+
* never erases the other's.
|
|
16407
|
+
*/
|
|
16408
|
+
var earlierOpened = (a, b) => b.firstSeen < a.firstSeen ? b.openedPlacement ?? a.openedPlacement : a.openedPlacement ?? b.openedPlacement;
|
|
16409
|
+
var laterClosed = (a, b) => b.lastSeen >= a.lastSeen ? b.closedPlacement ?? a.closedPlacement : a.closedPlacement ?? b.closedPlacement;
|
|
16399
16410
|
var TRACK_MERGE_RULES = {
|
|
16400
16411
|
trackId: survivor$1("trackId"),
|
|
16401
16412
|
deviceId: survivor$1("deviceId"),
|
|
@@ -16436,6 +16447,8 @@ var TRACK_MERGE_RULES = {
|
|
|
16436
16447
|
hasRider: either$1("hasRider"),
|
|
16437
16448
|
closedReason: survivor$1("closedReason"),
|
|
16438
16449
|
provenance: survivor$1("provenance"),
|
|
16450
|
+
openedPlacement: earlierOpened,
|
|
16451
|
+
closedPlacement: laterClosed,
|
|
16439
16452
|
movedProbe: mergedMovedProbe,
|
|
16440
16453
|
keptAtPromotion: (a, b) => a.keptAtPromotion === true || b.keptAtPromotion === true ? true : void 0
|
|
16441
16454
|
};
|
|
@@ -16477,6 +16490,8 @@ var TRACK_MERGE_KEYS = [
|
|
|
16477
16490
|
"hasRider",
|
|
16478
16491
|
"closedReason",
|
|
16479
16492
|
"provenance",
|
|
16493
|
+
"openedPlacement",
|
|
16494
|
+
"closedPlacement",
|
|
16480
16495
|
"movedProbe",
|
|
16481
16496
|
"keptAtPromotion"
|
|
16482
16497
|
];
|
|
@@ -16813,7 +16828,15 @@ var TRACKS_COLUMNS = [
|
|
|
16813
16828
|
{
|
|
16814
16829
|
name: "observations",
|
|
16815
16830
|
type: "INTEGER"
|
|
16816
|
-
})
|
|
16831
|
+
}),
|
|
16832
|
+
{
|
|
16833
|
+
name: "openedPlacement",
|
|
16834
|
+
type: "JSON"
|
|
16835
|
+
},
|
|
16836
|
+
{
|
|
16837
|
+
name: "closedPlacement",
|
|
16838
|
+
type: "JSON"
|
|
16839
|
+
}
|
|
16817
16840
|
];
|
|
16818
16841
|
/**
|
|
16819
16842
|
* The columns `rowToTrack` reads, per projection — the SELECT list the store
|
|
@@ -16960,7 +16983,9 @@ function cloneTrack(t) {
|
|
|
16960
16983
|
...t.provenance !== void 0 ? {
|
|
16961
16984
|
frameWidth: t.provenance.frameWidth,
|
|
16962
16985
|
frameHeight: t.provenance.frameHeight
|
|
16963
|
-
} : {}
|
|
16986
|
+
} : {},
|
|
16987
|
+
...t.openedPlacement !== void 0 ? { openedPlacement: { ...t.openedPlacement } } : {},
|
|
16988
|
+
...t.closedPlacement !== void 0 ? { closedPlacement: { ...t.closedPlacement } } : {}
|
|
16964
16989
|
};
|
|
16965
16990
|
}
|
|
16966
16991
|
/** Ids per set-based `benchPinned` statement — well under SQLite's bound
|
|
@@ -17108,7 +17133,11 @@ var TrackStore = class {
|
|
|
17108
17133
|
active: true,
|
|
17109
17134
|
lastSnapshotAt: 0,
|
|
17110
17135
|
movedProbe: stepMovedProbe(EMPTY_MOVED_PROBE, params.position.bbox),
|
|
17111
|
-
...params.provenance !== void 0 ? { provenance: params.provenance } : {}
|
|
17136
|
+
...params.provenance !== void 0 ? { provenance: params.provenance } : {},
|
|
17137
|
+
...params.placement !== void 0 ? {
|
|
17138
|
+
openedPlacement: params.placement,
|
|
17139
|
+
closedPlacement: params.placement
|
|
17140
|
+
} : {}
|
|
17112
17141
|
};
|
|
17113
17142
|
}
|
|
17114
17143
|
const existing = this.active.get(params.trackId);
|
|
@@ -17122,6 +17151,7 @@ var TrackStore = class {
|
|
|
17122
17151
|
const last = existing.positions[existing.positions.length - 1];
|
|
17123
17152
|
const dist = last ? Math.sqrt((params.position.x - last.x) ** 2 + (params.position.y - last.y) ** 2) : 0;
|
|
17124
17153
|
existing.lastSeen = params.timestamp;
|
|
17154
|
+
if (params.placement !== void 0) existing.closedPlacement = params.placement;
|
|
17125
17155
|
existing.totalDistance += dist;
|
|
17126
17156
|
existing.state = params.state;
|
|
17127
17157
|
existing.movedProbe = stepMovedProbe(existing.movedProbe, params.position.bbox);
|
|
@@ -17147,7 +17177,11 @@ var TrackStore = class {
|
|
|
17147
17177
|
active: true,
|
|
17148
17178
|
lastSnapshotAt: 0,
|
|
17149
17179
|
movedProbe: stepMovedProbe(EMPTY_MOVED_PROBE, params.position.bbox),
|
|
17150
|
-
...params.provenance !== void 0 ? { provenance: params.provenance } : {}
|
|
17180
|
+
...params.provenance !== void 0 ? { provenance: params.provenance } : {},
|
|
17181
|
+
...params.placement !== void 0 ? {
|
|
17182
|
+
openedPlacement: params.placement,
|
|
17183
|
+
closedPlacement: params.placement
|
|
17184
|
+
} : {}
|
|
17151
17185
|
};
|
|
17152
17186
|
this.active.set(params.trackId, fresh);
|
|
17153
17187
|
return fresh;
|
|
@@ -18898,7 +18932,9 @@ var TrackStore = class {
|
|
|
18898
18932
|
frameWidth: dims.w,
|
|
18899
18933
|
frameHeight: dims.h
|
|
18900
18934
|
} : {},
|
|
18901
|
-
...t.modelId !== void 0 ? { modelId: t.modelId } : {}
|
|
18935
|
+
...t.modelId !== void 0 ? { modelId: t.modelId } : {},
|
|
18936
|
+
...t.openedPlacement !== void 0 ? { openedPlacement: t.openedPlacement } : {},
|
|
18937
|
+
...t.closedPlacement !== void 0 ? { closedPlacement: t.closedPlacement } : {}
|
|
18902
18938
|
}
|
|
18903
18939
|
});
|
|
18904
18940
|
}
|
|
@@ -18963,6 +18999,8 @@ var TrackStore = class {
|
|
|
18963
18999
|
* string read, absent stays absent. */
|
|
18964
19000
|
const previewMissReason = data["previewMissReason"];
|
|
18965
19001
|
const modelId = data["modelId"];
|
|
19002
|
+
const openedPlacement = TrackPlacementSchema.safeParse(data["openedPlacement"]);
|
|
19003
|
+
const closedPlacement = TrackPlacementSchema.safeParse(data["closedPlacement"]);
|
|
18966
19004
|
const frameWidth = data["frameWidth"];
|
|
18967
19005
|
const frameHeight = data["frameHeight"];
|
|
18968
19006
|
const envMinX = data["envMinX"];
|
|
@@ -19015,7 +19053,9 @@ var TrackStore = class {
|
|
|
19015
19053
|
...typeof frameWidth === "number" && typeof frameHeight === "number" ? {
|
|
19016
19054
|
frameWidth,
|
|
19017
19055
|
frameHeight
|
|
19018
|
-
} : {}
|
|
19056
|
+
} : {},
|
|
19057
|
+
...openedPlacement.success ? { openedPlacement: openedPlacement.data } : {},
|
|
19058
|
+
...closedPlacement.success ? { closedPlacement: closedPlacement.data } : {}
|
|
19019
19059
|
});
|
|
19020
19060
|
}
|
|
19021
19061
|
};
|
|
@@ -22279,6 +22319,8 @@ function proposalOrigin(source, index, facts) {
|
|
|
22279
22319
|
...facts.modelId !== void 0 ? { modelId: facts.modelId } : {}
|
|
22280
22320
|
};
|
|
22281
22321
|
}
|
|
22322
|
+
//#endregion
|
|
22323
|
+
//#region src/pipeline-analytics/retrain/retrain-taxonomy.ts
|
|
22282
22324
|
var MACRO_SET = new Set([
|
|
22283
22325
|
"person",
|
|
22284
22326
|
"vehicle",
|
|
@@ -25841,7 +25883,6 @@ var NC_ALERTS_SPEC = {
|
|
|
25841
25883
|
equalFact: (held, incoming) => held.alerting === incoming.alerting,
|
|
25842
25884
|
deviceIdOf: (row) => deviceIdOf(row.subject)
|
|
25843
25885
|
};
|
|
25844
|
-
NC_ALERTS_SPEC.fromRecord, NC_ALERTS_SPEC.toValue, NC_ALERTS_SPEC.deviceIdOf;
|
|
25845
25886
|
/**
|
|
25846
25887
|
* Which row the boot settle keeps for one subject observed inside the window
|
|
25847
25888
|
* (D698's rule, applied to the alert ledger).
|
|
@@ -30574,7 +30615,6 @@ var NC_DEVICE_PRUNES_SPEC = {
|
|
|
30574
30615
|
deviceIdOf: (row) => row.subjectKind === "device" ? Number(row.subject) : void 0,
|
|
30575
30616
|
loadLimit: LOAD_LIMIT$1
|
|
30576
30617
|
};
|
|
30577
|
-
NC_DEVICE_PRUNES_SPEC.fromRecord, NC_DEVICE_PRUNES_SPEC.toValue, NC_DEVICE_PRUNES_SPEC.deviceIdOf;
|
|
30578
30618
|
/** The outcomes that mean "this last reference was already dealt with". */
|
|
30579
30619
|
var KEPT_OUTCOMES = new Set(["kept-disabled", "kept"]);
|
|
30580
30620
|
var NcPruneLedger = class {
|
|
@@ -45566,7 +45606,6 @@ var NC_ALERT_EPISODES_SPEC = {
|
|
|
45566
45606
|
};
|
|
45567
45607
|
}
|
|
45568
45608
|
};
|
|
45569
|
-
NC_ALERT_EPISODES_SPEC.fromRecord, NC_ALERT_EPISODES_SPEC.toValue;
|
|
45570
45609
|
var NcAlertEpisodeLedger = class {
|
|
45571
45610
|
ledger;
|
|
45572
45611
|
constructor(deps) {
|
|
@@ -45724,6 +45763,8 @@ function occupancyClassWarning(className) {
|
|
|
45724
45763
|
if (className === void 0 || isDetectionMacroClass(className)) return null;
|
|
45725
45764
|
return `⚠ “${className}” is a sub-type, not a macro class: this counter is always 0 (use ${[...DETECTION_MACRO_CLASSES].join(" / ")})`;
|
|
45726
45765
|
}
|
|
45766
|
+
//#endregion
|
|
45767
|
+
//#region src/notification-center/occupancy-store.ts
|
|
45727
45768
|
/**
|
|
45728
45769
|
* The mechanics, declared once.
|
|
45729
45770
|
*
|
|
@@ -45875,7 +45916,6 @@ function recordToRow(key, data) {
|
|
|
45875
45916
|
updatedAt
|
|
45876
45917
|
};
|
|
45877
45918
|
}
|
|
45878
|
-
NC_OCCUPANCY_SPEC.fromRecord, NC_OCCUPANCY_SPEC.toValue, NC_OCCUPANCY_SPEC.deviceIdOf;
|
|
45879
45919
|
//#endregion
|
|
45880
45920
|
//#region src/notification-center/outbox.ts
|
|
45881
45921
|
/**
|
|
@@ -48346,7 +48386,6 @@ var NC_SNOOZES_SPEC = {
|
|
|
48346
48386
|
},
|
|
48347
48387
|
loadLimit: 1e3
|
|
48348
48388
|
};
|
|
48349
|
-
NC_SNOOZES_SPEC.fromRecord, NC_SNOOZES_SPEC.toValue;
|
|
48350
48389
|
var NcSnoozeStore = class {
|
|
48351
48390
|
windows;
|
|
48352
48391
|
/** The `snooze-suppressed` records kind (events.db): the counters. */
|
|
@@ -52444,7 +52483,6 @@ var NC_SYSTEM_STATE_SPEC = {
|
|
|
52444
52483
|
},
|
|
52445
52484
|
deviceIdOf: (row) => row.deviceId
|
|
52446
52485
|
};
|
|
52447
|
-
NC_SYSTEM_STATE_SPEC.fromRecord, NC_SYSTEM_STATE_SPEC.toValue, NC_SYSTEM_STATE_SPEC.deviceIdOf;
|
|
52448
52486
|
/** The hub's own node id when an update row names none. */
|
|
52449
52487
|
var HUB_NODE = "hub";
|
|
52450
52488
|
function isUpdateTarget(value) {
|
|
@@ -53530,6 +53568,8 @@ var NcStateSummaryScheduler = class {
|
|
|
53530
53568
|
}
|
|
53531
53569
|
}
|
|
53532
53570
|
};
|
|
53571
|
+
//#endregion
|
|
53572
|
+
//#region src/notification-center/state-summary/state-summary-stamps.ts
|
|
53533
53573
|
var SPEC = {
|
|
53534
53574
|
collection: "notification-center:state-summary-stamps",
|
|
53535
53575
|
columns: [
|
|
@@ -53577,7 +53617,6 @@ var SPEC = {
|
|
|
53577
53617
|
},
|
|
53578
53618
|
loadLimit: 1e4
|
|
53579
53619
|
};
|
|
53580
|
-
SPEC.fromRecord, SPEC.toValue;
|
|
53581
53620
|
var NcStateSummaryStampStore = class {
|
|
53582
53621
|
ledger;
|
|
53583
53622
|
constructor(deps) {
|
|
@@ -74803,8 +74842,8 @@ var TrackCloser = class {
|
|
|
74803
74842
|
}
|
|
74804
74843
|
});
|
|
74805
74844
|
}
|
|
74806
|
-
/** Emit the
|
|
74807
|
-
*
|
|
74845
|
+
/** Emit the thin `TrackEnded` event + the unified lifecycle `end` event
|
|
74846
|
+
* (the FULL final summary — fires ONCE per real track). */
|
|
74808
74847
|
emitEndEvents(t, duration, trackerPeakConfidence, keyFrameMediaId, summary) {
|
|
74809
74848
|
this.deps.emitTrackEnded({
|
|
74810
74849
|
deviceId: t.deviceId,
|
|
@@ -74845,6 +74884,16 @@ function trackProvenanceOf(frame) {
|
|
|
74845
74884
|
};
|
|
74846
74885
|
}
|
|
74847
74886
|
//#endregion
|
|
74887
|
+
//#region src/pipeline-analytics/pipeline/track-placement.ts
|
|
74888
|
+
function trackPlacementOf(frame, nodeId) {
|
|
74889
|
+
if (nodeId.length === 0) return void 0;
|
|
74890
|
+
return {
|
|
74891
|
+
nodeId,
|
|
74892
|
+
...frame.rootDeviceKey !== void 0 && frame.rootDeviceKey.length > 0 ? { deviceKey: frame.rootDeviceKey } : {},
|
|
74893
|
+
...frame.rootModelId !== void 0 && frame.rootModelId.length > 0 ? { modelId: frame.rootModelId } : {}
|
|
74894
|
+
};
|
|
74895
|
+
}
|
|
74896
|
+
//#endregion
|
|
74848
74897
|
//#region src/pipeline-analytics/pipeline/best-detection-tracker.ts
|
|
74849
74898
|
/**
|
|
74850
74899
|
* `BestDetectionTracker` — the SINGLE canonical policy for "the best detection
|
|
@@ -79069,22 +79118,22 @@ function buildTapeDeleteDeps(src) {
|
|
|
79069
79118
|
removeFile: src.removeFile
|
|
79070
79119
|
};
|
|
79071
79120
|
}
|
|
79072
|
-
function unavailable(reason) {
|
|
79121
|
+
function unavailable$1(reason) {
|
|
79073
79122
|
return {
|
|
79074
79123
|
status: "unavailable",
|
|
79075
79124
|
reason
|
|
79076
79125
|
};
|
|
79077
79126
|
}
|
|
79078
79127
|
async function releaseOrUnavailable(deps, tapeId, queue) {
|
|
79079
|
-
if (typeof deps === "string") return unavailable(deps);
|
|
79128
|
+
if (typeof deps === "string") return unavailable$1(deps);
|
|
79080
79129
|
return queue.run((signal) => releaseTape(deps, tapeId, signal), { name: "release" });
|
|
79081
79130
|
}
|
|
79082
79131
|
async function deleteOrUnavailable(deps, tapeId, queue) {
|
|
79083
|
-
if (typeof deps === "string") return unavailable(deps);
|
|
79132
|
+
if (typeof deps === "string") return unavailable$1(deps);
|
|
79084
79133
|
return queue.run((signal) => deleteTape(deps, tapeId, signal), { name: "delete" });
|
|
79085
79134
|
}
|
|
79086
79135
|
async function reconcileOrUnavailable(deps, queue) {
|
|
79087
|
-
if (typeof deps === "string") return unavailable(deps);
|
|
79136
|
+
if (typeof deps === "string") return unavailable$1(deps);
|
|
79088
79137
|
return queue.run((signal) => reconcileTapePins(deps, signal), { name: "reconcile" });
|
|
79089
79138
|
}
|
|
79090
79139
|
/**
|
|
@@ -83648,6 +83697,9 @@ function isConfirmationCompatible(trackClassName, detectionMacroClass) {
|
|
|
83648
83697
|
if (track === "other" || det === "other") return true;
|
|
83649
83698
|
return track === det;
|
|
83650
83699
|
}
|
|
83700
|
+
function isSessionDetectorUnavailable(answer) {
|
|
83701
|
+
return answer !== null && "unavailable" in answer;
|
|
83702
|
+
}
|
|
83651
83703
|
var undecided = (candidate, reason) => ({
|
|
83652
83704
|
trackId: candidate.trackId,
|
|
83653
83705
|
verdict: "undecided",
|
|
@@ -83670,7 +83722,7 @@ async function runConfirmation(candidate, config, deps, exhausted) {
|
|
|
83670
83722
|
const carried = candidate.evidenceCrop ?? null;
|
|
83671
83723
|
if (carried) {
|
|
83672
83724
|
const verdict = await measure(candidate, carried, config, deps, "carried");
|
|
83673
|
-
if (verdict.verdict === "confirmed" || verdict.reason === "redetect-error") return verdict;
|
|
83725
|
+
if (verdict.verdict === "confirmed" || verdict.reason === "redetect-error" || verdict.reason === "session-device-unavailable") return verdict;
|
|
83674
83726
|
}
|
|
83675
83727
|
let crop = await deps.fetchCrop(candidate);
|
|
83676
83728
|
let cropSource = "native";
|
|
@@ -83692,11 +83744,14 @@ async function measure(candidate, crop, config, deps, cropSource) {
|
|
|
83692
83744
|
deps.keepCrop?.(candidate, crop, cropSource);
|
|
83693
83745
|
const detections = await deps.redetect(crop);
|
|
83694
83746
|
if (detections === null) return undecided(candidate, "redetect-error");
|
|
83747
|
+
if (isSessionDetectorUnavailable(detections)) return undecided(candidate, "session-device-unavailable");
|
|
83695
83748
|
let best;
|
|
83696
83749
|
let bestIncompatible;
|
|
83697
83750
|
for (const d of detections) if (isConfirmationCompatible(candidate.className, d.macroClass)) {
|
|
83698
83751
|
if (!best || d.score > best.score) best = d;
|
|
83699
|
-
} else if (
|
|
83752
|
+
} else if (d.refusedByDetectorFloor !== true) {
|
|
83753
|
+
if (!bestIncompatible || d.score > bestIncompatible.score) bestIncompatible = d;
|
|
83754
|
+
}
|
|
83700
83755
|
const bar = barFor(candidate, config, deps);
|
|
83701
83756
|
const confirmed = best !== void 0 && best.score >= bar;
|
|
83702
83757
|
if (!confirmed && cropSource !== "native") return undecided(candidate, cropSource === "fallback" ? "fallback-inconclusive" : "carried-inconclusive");
|
|
@@ -83704,7 +83759,7 @@ async function measure(candidate, crop, config, deps, cropSource) {
|
|
|
83704
83759
|
return {
|
|
83705
83760
|
trackId: candidate.trackId,
|
|
83706
83761
|
verdict: confirmed ? "confirmed" : "suppressed",
|
|
83707
|
-
reason: confirmed ? "confirmed" :
|
|
83762
|
+
reason: confirmed ? "confirmed" : suppressionReason(best, bestIncompatible),
|
|
83708
83763
|
className: candidate.className,
|
|
83709
83764
|
appliedMinConfidence: bar,
|
|
83710
83765
|
cropSource,
|
|
@@ -83717,6 +83772,16 @@ async function measure(candidate, crop, config, deps, cropSource) {
|
|
|
83717
83772
|
};
|
|
83718
83773
|
}
|
|
83719
83774
|
/**
|
|
83775
|
+
* Why a measured native crop said no — first matching rule wins (D922). The
|
|
83776
|
+
* best compatible box is under the gate's bar either way; `below-detector-floor`
|
|
83777
|
+
* says the detector's own floor had refused it too (D925).
|
|
83778
|
+
*/
|
|
83779
|
+
function suppressionReason(best, bestIncompatible) {
|
|
83780
|
+
if (best !== void 0) return best.refusedByDetectorFloor === true ? "below-detector-floor" : "scored-below-threshold";
|
|
83781
|
+
if (bestIncompatible !== void 0) return "incompatible-class";
|
|
83782
|
+
return "no-detection";
|
|
83783
|
+
}
|
|
83784
|
+
/**
|
|
83720
83785
|
* The incompatible best becomes a secondary subject when it clears the SAME
|
|
83721
83786
|
* bar the candidate faced and can be placed in the frame. The crop-normalised
|
|
83722
83787
|
* box is scaled into the crop's frame rectangle — the one derivation the
|
|
@@ -86462,11 +86527,9 @@ function faceSizeScore(detectionFrameShortSidePx) {
|
|
|
86462
86527
|
return detectionFrameShortSidePx / FACE_SIZE_SCORE_REFERENCE_PX;
|
|
86463
86528
|
}
|
|
86464
86529
|
//#endregion
|
|
86465
|
-
//#region src/pipeline-analytics/face-
|
|
86530
|
+
//#region src/pipeline-analytics/face-recognizer.ts
|
|
86466
86531
|
/** The recognizer's step id — the attribution a face identity label carries. */
|
|
86467
86532
|
var FACE_RECOGNIZER_STEP_ID = "face-recognizer";
|
|
86468
|
-
//#endregion
|
|
86469
|
-
//#region src/pipeline-analytics/face-recognizer.ts
|
|
86470
86533
|
/** At most one "dropping imageless track" log per this interval, per recognizer. */
|
|
86471
86534
|
var FACE_IMAGELESS_LOG_THROTTLE_MS = 6e4;
|
|
86472
86535
|
/** At most one 'embedding magnitude' sample line per device per this interval. */
|
|
@@ -92905,11 +92968,119 @@ function buildBirthDecisionRecord(input) {
|
|
|
92905
92968
|
decidedByBirthEvidence: input.decidedByBirthEvidence,
|
|
92906
92969
|
bestScore: input.bestScore ?? null,
|
|
92907
92970
|
appliedMinConfidence: input.appliedMinConfidence ?? null,
|
|
92971
|
+
cropSource: input.cropSource ?? null,
|
|
92972
|
+
detectorModelId: input.detector?.modelId ?? null,
|
|
92973
|
+
detectorDeviceKey: input.detector?.deviceKey ?? null,
|
|
92974
|
+
detectorNodeId: input.detector?.nodeId ?? null,
|
|
92908
92975
|
firstSeen,
|
|
92909
92976
|
...latency
|
|
92910
92977
|
};
|
|
92911
92978
|
}
|
|
92912
92979
|
//#endregion
|
|
92980
|
+
//#region src/pipeline-analytics/confirmation-redetect-result.ts
|
|
92981
|
+
/** Map a re-detect result to the gate's input; `null` when it carried no detections array. */
|
|
92982
|
+
function toConfirmationDetections(result) {
|
|
92983
|
+
const detections = result?.detections;
|
|
92984
|
+
if (!result || !detections) return null;
|
|
92985
|
+
const cropWidth = result.width ?? 0;
|
|
92986
|
+
const cropHeight = result.height ?? 0;
|
|
92987
|
+
const kept = detections.map((d) => ({
|
|
92988
|
+
macroClass: d.macroClass,
|
|
92989
|
+
score: d.score,
|
|
92990
|
+
...d.bbox !== void 0 && cropWidth > 0 && cropHeight > 0 ? { bbox: {
|
|
92991
|
+
x: d.bbox.x / cropWidth,
|
|
92992
|
+
y: d.bbox.y / cropHeight,
|
|
92993
|
+
w: d.bbox.width / cropWidth,
|
|
92994
|
+
h: d.bbox.height / cropHeight
|
|
92995
|
+
} } : {}
|
|
92996
|
+
}));
|
|
92997
|
+
const refused = (result.discarded ?? []).filter((d) => d.reason === "below-threshold").map((d) => ({
|
|
92998
|
+
macroClass: d.macroClass,
|
|
92999
|
+
score: d.score,
|
|
93000
|
+
refusedByDetectorFloor: true
|
|
93001
|
+
}));
|
|
93002
|
+
return [...kept, ...refused];
|
|
93003
|
+
}
|
|
93004
|
+
//#endregion
|
|
93005
|
+
//#region src/pipeline-analytics/confirmation-session-detector.ts
|
|
93006
|
+
/**
|
|
93007
|
+
* The detector the birth confirmation gate re-judges a birth WITH: the
|
|
93008
|
+
* session's own (D925).
|
|
93009
|
+
*
|
|
93010
|
+
* A birth is a claim made by one detector — the root model of the session that
|
|
93011
|
+
* produced the frame, on the inference-device pool it ran on. The gate asks
|
|
93012
|
+
* whether that claim holds on better pixels, so it must ask the SAME detector:
|
|
93013
|
+
* a different model has a different score scale and a different floor, and its
|
|
93014
|
+
* "no" says nothing about the claim. It used to ask the node's global default
|
|
93015
|
+
* (`getGlobalSteps`), which on a Coral node meant a CPU `yolov9t` re-judging an
|
|
93016
|
+
* `edgetpu` model's births.
|
|
93017
|
+
*
|
|
93018
|
+
* The identity rides the frame result (`rootStepId` / `rootModelId` /
|
|
93019
|
+
* `rootDeviceKey`, stamped by the executor with what it RAN), and the node is
|
|
93020
|
+
* the frame handle's — the same node the crop is cut on, so no new bytes cross
|
|
93021
|
+
* anywhere.
|
|
93022
|
+
*
|
|
93023
|
+
* When that detector cannot answer — no identity on the frame (an onboard
|
|
93024
|
+
* detector), the device in backoff or failed, or the executor running anything
|
|
93025
|
+
* other than exactly that model on exactly that pool — the answer is
|
|
93026
|
+
* `session-device-unavailable`: NO measurement. The gate defers the birth and
|
|
93027
|
+
* admits it once the deferral is exhausted. Another model is never asked.
|
|
93028
|
+
*
|
|
93029
|
+
* PURE apart from the injected `run`, so the matrix is testable without an
|
|
93030
|
+
* executor.
|
|
93031
|
+
*/
|
|
93032
|
+
/** The session detector named by a frame, or `null` when the frame names none in full. */
|
|
93033
|
+
function sessionDetectorOf(frame, nodeId) {
|
|
93034
|
+
const { rootStepId, rootModelId, rootDeviceKey } = frame;
|
|
93035
|
+
if (!rootStepId || !rootModelId || !rootDeviceKey || !nodeId) return null;
|
|
93036
|
+
return {
|
|
93037
|
+
stepId: rootStepId,
|
|
93038
|
+
modelId: rootModelId,
|
|
93039
|
+
deviceKey: rootDeviceKey,
|
|
93040
|
+
nodeId
|
|
93041
|
+
};
|
|
93042
|
+
}
|
|
93043
|
+
/**
|
|
93044
|
+
* The executor's refusal of a device it will not dispatch to: the liveness
|
|
93045
|
+
* refusal (`InferenceDeviceUnusableError`), a device key whose backend this
|
|
93046
|
+
* node does not know, or a pinned pool that cannot serve. Read from the
|
|
93047
|
+
* message because the error crosses a process boundary without its class.
|
|
93048
|
+
*/
|
|
93049
|
+
var DEVICE_REFUSAL = /inference device ".+" is (failed|backoff)|unknown backend|device-not-servable|model-not-servable/;
|
|
93050
|
+
/** Re-detect a crop with the session detector, or say why it could not. */
|
|
93051
|
+
async function redetectWithSessionDetector(detector, cropJpeg, deviceId, run) {
|
|
93052
|
+
if (detector === null) return unavailable("the frame names no session detector");
|
|
93053
|
+
let result;
|
|
93054
|
+
try {
|
|
93055
|
+
result = await run({
|
|
93056
|
+
steps: [{
|
|
93057
|
+
addonId: detector.stepId,
|
|
93058
|
+
modelId: detector.modelId,
|
|
93059
|
+
enabled: true
|
|
93060
|
+
}],
|
|
93061
|
+
image: new Uint8Array(cropJpeg),
|
|
93062
|
+
deviceId,
|
|
93063
|
+
plane: "frame",
|
|
93064
|
+
deviceKey: detector.deviceKey
|
|
93065
|
+
}, detector.nodeId);
|
|
93066
|
+
} catch (err) {
|
|
93067
|
+
const message = errMsg(err);
|
|
93068
|
+
if (DEVICE_REFUSAL.test(message)) return unavailable(message);
|
|
93069
|
+
return {
|
|
93070
|
+
answer: null,
|
|
93071
|
+
error: message
|
|
93072
|
+
};
|
|
93073
|
+
}
|
|
93074
|
+
if (result !== null && (result.rootModelId !== detector.modelId || result.rootDeviceKey !== detector.deviceKey)) return unavailable(`ran ${result.rootModelId ?? "an unnamed model"} on ${result.rootDeviceKey ?? "an unnamed pool"}, not ${detector.modelId} on ${detector.deviceKey}`);
|
|
93075
|
+
return { answer: toConfirmationDetections(result) };
|
|
93076
|
+
}
|
|
93077
|
+
function unavailable(detail) {
|
|
93078
|
+
return { answer: {
|
|
93079
|
+
unavailable: "session-device-unavailable",
|
|
93080
|
+
detail
|
|
93081
|
+
} };
|
|
93082
|
+
}
|
|
93083
|
+
//#endregion
|
|
92913
93084
|
//#region src/pipeline-analytics/pipeline/birth-evidence-store.ts
|
|
92914
93085
|
/**
|
|
92915
93086
|
* The pixels a birth arrived with, held for as long as its deferral can last —
|
|
@@ -93819,7 +93990,6 @@ var PHANTOM_CELLS_SPEC = {
|
|
|
93819
93990
|
},
|
|
93820
93991
|
deviceIdOf: (row) => row.deviceId
|
|
93821
93992
|
};
|
|
93822
|
-
PHANTOM_CELLS_SPEC.fromRecord, PHANTOM_CELLS_SPEC.toValue, PHANTOM_CELLS_SPEC.deviceIdOf;
|
|
93823
93993
|
/**
|
|
93824
93994
|
* The durable cell memory. Reads answer from RAM only (D49) — a gate that
|
|
93825
93995
|
* consulted SQLite would be a gate that fails when SQLite is slow.
|
|
@@ -94019,7 +94189,6 @@ var PACKAGE_BACKGROUND_SPEC = {
|
|
|
94019
94189
|
},
|
|
94020
94190
|
deviceIdOf: (row) => row.deviceId
|
|
94021
94191
|
};
|
|
94022
|
-
PACKAGE_BACKGROUND_SPEC.fromRecord, PACKAGE_BACKGROUND_SPEC.toValue, PACKAGE_BACKGROUND_SPEC.deviceIdOf;
|
|
94023
94192
|
/**
|
|
94024
94193
|
* The durable ghost-cycle memory. Reads answer from RAM only (D49); writes go
|
|
94025
94194
|
* write-behind — a lost write costs one under-counted cycle, which is the
|
|
@@ -96584,7 +96753,6 @@ var STATIONARY_EVIDENCE_SPEC = {
|
|
|
96584
96753
|
},
|
|
96585
96754
|
deviceIdOf: (row) => row.deviceId
|
|
96586
96755
|
};
|
|
96587
|
-
STATIONARY_EVIDENCE_SPEC.fromRecord, STATIONARY_EVIDENCE_SPEC.toValue, STATIONARY_EVIDENCE_SPEC.deviceIdOf;
|
|
96588
96756
|
var StationaryEvidenceLedger = class {
|
|
96589
96757
|
ledger;
|
|
96590
96758
|
spec = STATIONARY_EVIDENCE_SPEC;
|
|
@@ -97119,7 +97287,6 @@ var STATIONARY_SPEC = {
|
|
|
97119
97287
|
fromRecord: rowToEntry,
|
|
97120
97288
|
deviceIdOf: (entry) => entry.deviceId
|
|
97121
97289
|
};
|
|
97122
|
-
STATIONARY_SPEC.fromRecord, STATIONARY_SPEC.toValue, STATIONARY_SPEC.deviceIdOf;
|
|
97123
97290
|
var StationaryObjectRegistry = class {
|
|
97124
97291
|
/** Entry ids per device — an INDEX over the ledger's mirror, not a second
|
|
97125
97292
|
* copy of it. The entries themselves live in exactly one place. */
|
|
@@ -113200,9 +113367,6 @@ var KEYFRAME_CROP_MIN_SUBJECT_IOU = .5;
|
|
|
113200
113367
|
* evidence" and the temporal bound takes over. */
|
|
113201
113368
|
var KEYFRAME_CROP_MAX_SAMPLE_GAP_MS = 1e3;
|
|
113202
113369
|
var SETTINGS_CACHE_TTL_MS = 5e3;
|
|
113203
|
-
/** TTL for the per-node confirmation-gate detector-step cache (the node's
|
|
113204
|
-
* default object-detector step rarely changes). */
|
|
113205
|
-
var CONFIRMATION_DETECTOR_CACHE_TTL_MS = 6e4;
|
|
113206
113370
|
/** Padding applied to a birth box before re-detecting it — a little context
|
|
113207
113371
|
* around the subject improves the confirmation detector's recall. */
|
|
113208
113372
|
var CONFIRMATION_CROP_PADDING = .15;
|
|
@@ -113990,11 +114154,6 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
113990
114154
|
trackingSettingsCache = this.settingsCaches.registerDeviceCache("tracking", SETTINGS_CACHE_TTL_MS);
|
|
113991
114155
|
/** Per-device confirmation-gate settings cache (default off), TTL-mirrored. */
|
|
113992
114156
|
confirmationGateSettingsCache = this.settingsCaches.registerDeviceCache("confirmation-gate", SETTINGS_CACHE_TTL_MS);
|
|
113993
|
-
/** Per-node detector-step cache for the confirmation gate's re-detection —
|
|
113994
|
-
* the node's default root object-detector reduced to a single childless
|
|
113995
|
-
* step, resolved lazily from `pipelineExecutor.getGlobalSteps` and reused.
|
|
113996
|
-
* NOT part of the settings-cache hub: node-keyed, not device-keyed. */
|
|
113997
|
-
confirmationDetectorStepByNode = /* @__PURE__ */ new Map();
|
|
113998
114157
|
faceSettingsCache = this.settingsCaches.registerDeviceCache("face", SETTINGS_CACHE_TTL_MS);
|
|
113999
114158
|
/** GLOBAL face-recognition master switch (addon store), TTL-cached. */
|
|
114000
114159
|
faceGlobalEnabledCache = this.settingsCaches.registerGlobalCache("face-global-enabled", SETTINGS_CACHE_TTL_MS);
|
|
@@ -118264,7 +118423,6 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
118264
118423
|
this.settingsCaches.clearAll();
|
|
118265
118424
|
this.rawDeviceBlobMirror.invalidateAll();
|
|
118266
118425
|
this.rawGlobalStoreMirror.invalidate();
|
|
118267
|
-
this.confirmationDetectorStepByNode.clear();
|
|
118268
118426
|
this.trackStore?.clearAll();
|
|
118269
118427
|
this.stationaryRegistry = null;
|
|
118270
118428
|
this.bindingCache?.clearAll();
|
|
@@ -118370,7 +118528,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
118370
118528
|
}
|
|
118371
118529
|
});
|
|
118372
118530
|
}
|
|
118373
|
-
await this.processFrame(deviceId, frame, data.source ?? "pipeline", data.frameHandle, data.detailSteps, data.occasion ?? "session");
|
|
118531
|
+
await this.processFrame(deviceId, frame, data.source ?? "pipeline", data.frameHandle, data.detailSteps, data.occasion ?? "session", data.nodeId);
|
|
118374
118532
|
}
|
|
118375
118533
|
/**
|
|
118376
118534
|
* Run one detection frame through the analysis layers for a given
|
|
@@ -118644,7 +118802,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
118644
118802
|
}
|
|
118645
118803
|
});
|
|
118646
118804
|
}
|
|
118647
|
-
async processFrame(deviceId, frame, source, rawFrameHandle, detailSteps, occasion = "session") {
|
|
118805
|
+
async processFrame(deviceId, frame, source, rawFrameHandle, detailSteps, occasion = "session", producerNodeId = "") {
|
|
118648
118806
|
if (this.shuttingDown) return;
|
|
118649
118807
|
if (detailSteps !== void 0) this.detailStepsByDevice.set(deviceId, detailSteps);
|
|
118650
118808
|
if (!await this.bindingCache.isActive(deviceId)) {
|
|
@@ -118831,6 +118989,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
118831
118989
|
const currentTrackIds = /* @__PURE__ */ new Set();
|
|
118832
118990
|
const positionsCountById = /* @__PURE__ */ new Map();
|
|
118833
118991
|
const provenance = trackProvenanceOf(frame);
|
|
118992
|
+
const placement = trackPlacementOf(frame, producerNodeId);
|
|
118834
118993
|
for (const t of result.tracked) {
|
|
118835
118994
|
currentTrackIds.add(t.trackId);
|
|
118836
118995
|
if (this.suppressedBirths.isRejected(key, t.trackId)) continue;
|
|
@@ -118855,7 +119014,8 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
118855
119014
|
},
|
|
118856
119015
|
zones: t.zones,
|
|
118857
119016
|
state: t.state,
|
|
118858
|
-
...provenance !== void 0 ? { provenance } : {}
|
|
119017
|
+
...provenance !== void 0 ? { provenance } : {},
|
|
119018
|
+
...placement !== void 0 ? { placement } : {}
|
|
118859
119019
|
});
|
|
118860
119020
|
positionsCountById.set(t.trackId, upserted.positions.length);
|
|
118861
119021
|
}
|
|
@@ -118920,6 +119080,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
118920
119080
|
this.birthEvidence.remember(key, id, Buffer.from(t.birthEvidence.jpegBase64, "base64"), exhaustionNowMs);
|
|
118921
119081
|
}
|
|
118922
119082
|
const withBirthEvidence = /* @__PURE__ */ new Set();
|
|
119083
|
+
const sessionDetector = frameHandle ? sessionDetectorOf(frame, frameHandle.nodeId) : null;
|
|
118923
119084
|
const run = await this.confirmTrackBirths(bornCandidates.map(({ id, t }) => {
|
|
118924
119085
|
const evidenceCrop = this.birthEvidence.get(key, id, exhaustionNowMs);
|
|
118925
119086
|
if (evidenceCrop !== null) withBirthEvidence.add(id);
|
|
@@ -118935,7 +119096,9 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
118935
119096
|
source,
|
|
118936
119097
|
frameHandle,
|
|
118937
119098
|
frameWidth: result.frameWidth,
|
|
118938
|
-
frameHeight: result.frameHeight
|
|
119099
|
+
frameHeight: result.frameHeight,
|
|
119100
|
+
sessionDetector,
|
|
119101
|
+
attemptsFor: (trackId) => this.deferredBirths.attemptsFor(key, trackId)
|
|
118939
119102
|
}, exhaustedIds);
|
|
118940
119103
|
const outcome = run.outcome;
|
|
118941
119104
|
const gateNowMs = Date.now();
|
|
@@ -118990,6 +119153,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
118990
119153
|
matchedThisFrame: t.matchedThisFrame,
|
|
118991
119154
|
birthEvidenceAvailable: withBirthEvidence.has(id),
|
|
118992
119155
|
decision: run.decisions.get(id),
|
|
119156
|
+
sessionDetector,
|
|
118993
119157
|
decidedAtMs: gateNowMs,
|
|
118994
119158
|
firstSeen: this.trackStore?.peekActive(id)?.firstSeen ?? null
|
|
118995
119159
|
});
|
|
@@ -119049,16 +119213,25 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
119049
119213
|
processor.markSuppressed(id);
|
|
119050
119214
|
this.trackStore?.dropActive(id);
|
|
119051
119215
|
this.clearLiveTrackState(deviceId, id);
|
|
119052
|
-
|
|
119053
|
-
|
|
119054
|
-
|
|
119055
|
-
|
|
119056
|
-
|
|
119057
|
-
|
|
119058
|
-
|
|
119059
|
-
|
|
119060
|
-
|
|
119061
|
-
|
|
119216
|
+
const suppression = run.decisions.get(id);
|
|
119217
|
+
log.info("birth suppressed — track record retracted", {
|
|
119218
|
+
tags: { deviceId },
|
|
119219
|
+
meta: {
|
|
119220
|
+
trackId: id,
|
|
119221
|
+
className: t.className,
|
|
119222
|
+
source,
|
|
119223
|
+
reason: suppression?.reason ?? null,
|
|
119224
|
+
bestScore: suppression?.bestScore ?? null,
|
|
119225
|
+
appliedMinConfidence: suppression?.appliedMinConfidence ?? null,
|
|
119226
|
+
cropSource: suppression?.cropSource ?? null,
|
|
119227
|
+
attempts: deferredAttempts,
|
|
119228
|
+
...wasDeferred ? {
|
|
119229
|
+
wasDeferred,
|
|
119230
|
+
deferredForMs,
|
|
119231
|
+
deferredAttempts
|
|
119232
|
+
} : {}
|
|
119233
|
+
}
|
|
119234
|
+
});
|
|
119062
119235
|
continue;
|
|
119063
119236
|
}
|
|
119064
119237
|
if (wasDeferred && exhaustedIds.has(id)) log.warn("birth allowed unmeasured — deferral exhausted, no crop available", { meta: {
|
|
@@ -119750,88 +119923,30 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
119750
119923
|
return this.confirmationGateSettingsCache.get(deviceId, (id) => this.readDeviceSettings(id, resolveConfirmationGateSettings));
|
|
119751
119924
|
}
|
|
119752
119925
|
/**
|
|
119753
|
-
*
|
|
119754
|
-
*
|
|
119755
|
-
*
|
|
119756
|
-
*
|
|
119926
|
+
* Re-run object detection on a confirmation crop JPEG with the SESSION'S
|
|
119927
|
+
* detector (D925): the root model the birth's frame ran, on the device pool
|
|
119928
|
+
* it ran on, pinned to that frame's node — the node the crop is cut on, so
|
|
119929
|
+
* no new bytes cross anywhere. A session detector that cannot answer is
|
|
119930
|
+
* `session-device-unavailable` (no measurement, the birth defers); another
|
|
119931
|
+
* model is never asked. An inference failure is `null` (`redetect-error`).
|
|
119757
119932
|
*/
|
|
119758
|
-
|
|
119759
|
-
const
|
|
119760
|
-
|
|
119761
|
-
|
|
119762
|
-
|
|
119763
|
-
|
|
119764
|
-
|
|
119765
|
-
|
|
119766
|
-
|
|
119767
|
-
|
|
119768
|
-
|
|
119769
|
-
|
|
119770
|
-
|
|
119771
|
-
|
|
119772
|
-
|
|
119773
|
-
if (cached && now < cached.expiresAt) return cached.step;
|
|
119774
|
-
let step = null;
|
|
119775
|
-
const executor = this.pipelineExecutorApi();
|
|
119776
|
-
if (executor?.getGlobalSteps) try {
|
|
119777
|
-
const steps = await executor.getGlobalSteps.query(void 0, nodePin(nodeId));
|
|
119778
|
-
const detector = steps?.find((s) => s.slot === "detector" && s.enabled) ?? steps?.find((s) => s.slot === "detector");
|
|
119779
|
-
if (detector) step = {
|
|
119780
|
-
addonId: detector.addonId,
|
|
119781
|
-
...detector.modelId ? { modelId: detector.modelId } : {},
|
|
119782
|
-
enabled: true
|
|
119783
|
-
};
|
|
119784
|
-
} catch (err) {
|
|
119785
|
-
this.ctx.logger.debug("confirmation gate: getGlobalSteps failed", { meta: {
|
|
119786
|
-
nodeId,
|
|
119787
|
-
error: errMsg(err)
|
|
119788
|
-
} });
|
|
119789
|
-
}
|
|
119790
|
-
this.confirmationDetectorStepByNode.set(nodeId, {
|
|
119791
|
-
step,
|
|
119792
|
-
expiresAt: now + CONFIRMATION_DETECTOR_CACHE_TTL_MS
|
|
119933
|
+
async redetectCropForConfirmation(detector, deviceId, cropJpeg) {
|
|
119934
|
+
const outcome = await redetectWithSessionDetector(detector, cropJpeg, deviceId, (request, nodeId) => this.ctx.api.pipelineExecutor.runPipeline.mutate({
|
|
119935
|
+
...request,
|
|
119936
|
+
steps: [...request.steps]
|
|
119937
|
+
}, nodePin(nodeId)));
|
|
119938
|
+
if (outcome.error !== void 0) this.ctx.logger.warn("confirmation gate: re-detection failed — birth deferred", {
|
|
119939
|
+
tags: { deviceId },
|
|
119940
|
+
meta: {
|
|
119941
|
+
error: outcome.error,
|
|
119942
|
+
...detector !== null ? {
|
|
119943
|
+
modelId: detector.modelId,
|
|
119944
|
+
deviceKey: detector.deviceKey,
|
|
119945
|
+
node: detector.nodeId
|
|
119946
|
+
} : {}
|
|
119947
|
+
}
|
|
119793
119948
|
});
|
|
119794
|
-
return
|
|
119795
|
-
}
|
|
119796
|
-
/**
|
|
119797
|
-
* Re-run object detection on a confirmation crop JPEG via the frame-owning
|
|
119798
|
-
* node's `pipelineExecutor` (pinned by `nodeId`, matching the native-crop
|
|
119799
|
-
* fetch). Returns the crop's detections, or `null` on any unavailability /
|
|
119800
|
-
* error so the gate fails open.
|
|
119801
|
-
*/
|
|
119802
|
-
async redetectCropForConfirmation(nodeId, deviceId, cropJpeg) {
|
|
119803
|
-
const step = await this.resolveConfirmationDetectorStep(nodeId);
|
|
119804
|
-
if (!step) return null;
|
|
119805
|
-
const executor = this.pipelineExecutorApi();
|
|
119806
|
-
if (!executor?.runPipeline) return null;
|
|
119807
|
-
try {
|
|
119808
|
-
const result = await executor.runPipeline.mutate({
|
|
119809
|
-
steps: [step],
|
|
119810
|
-
image: new Uint8Array(cropJpeg),
|
|
119811
|
-
deviceId,
|
|
119812
|
-
plane: "frame"
|
|
119813
|
-
}, nodePin(nodeId));
|
|
119814
|
-
const detections = result?.detections;
|
|
119815
|
-
if (!detections) return null;
|
|
119816
|
-
const cropWidth = result.width ?? 0;
|
|
119817
|
-
const cropHeight = result.height ?? 0;
|
|
119818
|
-
return detections.map((d) => ({
|
|
119819
|
-
macroClass: d.macroClass,
|
|
119820
|
-
score: d.score,
|
|
119821
|
-
...d.bbox !== void 0 && cropWidth > 0 && cropHeight > 0 ? { bbox: {
|
|
119822
|
-
x: d.bbox.x / cropWidth,
|
|
119823
|
-
y: d.bbox.y / cropHeight,
|
|
119824
|
-
w: d.bbox.width / cropWidth,
|
|
119825
|
-
h: d.bbox.height / cropHeight
|
|
119826
|
-
} } : {}
|
|
119827
|
-
}));
|
|
119828
|
-
} catch (err) {
|
|
119829
|
-
this.ctx.logger.debug("confirmation gate: re-detection failed — fail-open", {
|
|
119830
|
-
tags: { deviceId },
|
|
119831
|
-
meta: { error: errMsg(err) }
|
|
119832
|
-
});
|
|
119833
|
-
return null;
|
|
119834
|
-
}
|
|
119949
|
+
return outcome.answer;
|
|
119835
119950
|
}
|
|
119836
119951
|
/**
|
|
119837
119952
|
* Confirm a batch of track-birth candidates before they are created. Returns
|
|
@@ -119885,6 +120000,8 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
119885
120000
|
reason: decision?.reason ?? null,
|
|
119886
120001
|
bestScore: decision?.bestScore ?? null,
|
|
119887
120002
|
appliedMinConfidence: decision?.appliedMinConfidence ?? null,
|
|
120003
|
+
cropSource: decision?.cropSource ?? null,
|
|
120004
|
+
detector: decision !== void 0 && (decision.cropSource !== void 0 || decision.reason === "session-device-unavailable") ? input.sessionDetector ?? null : null,
|
|
119888
120005
|
decidedAtMs: input.decidedAtMs,
|
|
119889
120006
|
firstSeen: input.firstSeen,
|
|
119890
120007
|
motionOnsetAtMs,
|
|
@@ -119922,7 +120039,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
119922
120039
|
});
|
|
119923
120040
|
return allConfirmed();
|
|
119924
120041
|
}
|
|
119925
|
-
const
|
|
120042
|
+
const { sessionDetector } = params;
|
|
119926
120043
|
const candidateNativeRecovery = /* @__PURE__ */ new Map();
|
|
119927
120044
|
for (const c of candidates) if (c.nativeRecovery !== void 0) candidateNativeRecovery.set(c.trackId, c.nativeRecovery);
|
|
119928
120045
|
return {
|
|
@@ -119949,7 +120066,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
119949
120066
|
h: candidate.bbox.h
|
|
119950
120067
|
}, frameWidth, frameHeight, CONFIRMATION_CROP_PADDING, candidate.trackId, CONFIRMATION_CROP_MAX_WIDTH);
|
|
119951
120068
|
},
|
|
119952
|
-
redetect: (cropJpeg) => this.redetectCropForConfirmation(
|
|
120069
|
+
redetect: (cropJpeg) => this.redetectCropForConfirmation(sessionDetector, deviceId, cropJpeg),
|
|
119953
120070
|
keepCrop: (candidate, cropJpeg) => {
|
|
119954
120071
|
offeredCrops.set(candidate.trackId, cropJpeg);
|
|
119955
120072
|
},
|
|
@@ -119974,6 +120091,12 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
119974
120091
|
reason: decision.reason,
|
|
119975
120092
|
className: decision.className,
|
|
119976
120093
|
...decision.bestScore !== void 0 ? { bestScore: decision.bestScore } : {},
|
|
120094
|
+
...sessionDetector !== null ? {
|
|
120095
|
+
modelId: sessionDetector.modelId,
|
|
120096
|
+
deviceKey: sessionDetector.deviceKey,
|
|
120097
|
+
node: sessionDetector.nodeId
|
|
120098
|
+
} : {},
|
|
120099
|
+
attempts: params.attemptsFor(decision.trackId),
|
|
119977
120100
|
...decision.bestIncompatibleClass !== void 0 ? {
|
|
119978
120101
|
bestIncompatibleClass: decision.bestIncompatibleClass,
|
|
119979
120102
|
bestIncompatibleScore: decision.bestIncompatibleScore
|