@camstack/addon-post-analysis 1.2.220 → 1.2.222

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.
@@ -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-Bw4aTXFP.js");
5
+ const require_dist = require("../dist-iJA2F7_d.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");
@@ -45876,8 +45876,13 @@ async function encodeRgbCropToJpeg(bytes, width, height) {
45876
45876
  * same-node (raw) or cross-node (JPEG). The decode happens IN-PROCESS on the
45877
45877
  * post-processing node — no raw pixels ever cross a process boundary.
45878
45878
  */
45879
- async function decodeJpegToRgb(base64Jpeg) {
45880
- const { data, info } = await (0, sharp.default)(Buffer.from(base64Jpeg, "base64")).raw().toBuffer({ resolveWithObject: true });
45879
+ /**
45880
+ * Decode a JPEG to raw RGB. Takes the BYTES, or the base64 a pre-D462 runner
45881
+ * still answers with — sharp wants bytes either way, so accepting both here is
45882
+ * what lets the caller stop base64-ing purely to be understood.
45883
+ */
45884
+ async function decodeJpegToRgb(jpeg) {
45885
+ const { data, info } = await (0, sharp.default)(typeof jpeg === "string" ? Buffer.from(jpeg, "base64") : Buffer.from(jpeg)).raw().toBuffer({ resolveWithObject: true });
45881
45886
  return {
45882
45887
  bytes: data,
45883
45888
  width: info.width,
@@ -46579,6 +46584,17 @@ var AudioDetectionSettingsSchema = require_dist.object({
46579
46584
  audioConfirmHits: require_dist.number().int().min(1).default(2),
46580
46585
  /** Width of the corroboration window. Ignored when `audioConfirmHits` is 1. */
46581
46586
  audioConfirmWindowSec: require_dist.number().positive().default(10),
46587
+ /**
46588
+ * How far above the camera's own 10 s mean a sample must sit to be a peak.
46589
+ *
46590
+ * A DIFFERENCE between two readings on the same camera, so a uniform scale
46591
+ * offset cancels exactly and the D459 correction did not touch it. Proved,
46592
+ * not assumed — D459 enumerates this alongside `audioMarkerMinDeviationDb`,
46593
+ * `audioMarkerMinDeviations` and the EWMA/MAD pair. "Correcting" it by
46594
+ * 12 dB would be introducing the very error the epoch removed.
46595
+ *
46596
+ * @dbfs-era relative
46597
+ */
46582
46598
  levelDeviationDb: require_dist.number().positive().default(10),
46583
46599
  levelWindowSec: require_dist.number().positive().default(10),
46584
46600
  levelMaxWaitSec: require_dist.number().positive().default(20),
@@ -46588,14 +46604,44 @@ var AudioDetectionSettingsSchema = require_dist.object({
46588
46604
  /** EWMA time constant for the camera's "normal" loudness, in seconds. Also
46589
46605
  * the warm-up: no marker until one time constant of audio has been heard. */
46590
46606
  audioMarkerBaselineSec: require_dist.number().positive().default(300),
46591
- /** "High volume", absolute. A sample quieter than this is never a marker
46592
- * however surprising it is for the camera. */
46607
+ /**
46608
+ * "High volume", absolute. A sample quieter than this is never a marker
46609
+ * however surprising it is for the camera.
46610
+ *
46611
+ * NOT shifted at the D459 epoch, for the same reason as `SILENCE_FLOOR_DBFS`
46612
+ * and with one extra argument of its own. `-25 dBFS is loud` is a statement
46613
+ * about the scale, not a measurement taken through the old decoder: nobody
46614
+ * read it off a meter, it is what "loud" means on a 16-bit full-scale range.
46615
+ *
46616
+ * The extra argument is that on the old scale this default was effectively
46617
+ * DEAD on the 19 mis-decoded cameras — a reading of -25 there required a
46618
+ * true level of -13 dBFS, which is a sound close to clipping. Bar 1 almost
46619
+ * never bound on them, so the feature has been running on two of its three
46620
+ * bars. At the epoch it starts working as designed rather than becoming too
46621
+ * permissive.
46622
+ *
46623
+ * That it also ships OFF by default (`audioMarkerEnabled`) is what makes
46624
+ * this safe to leave alone: the operator sizes the rate from the `wouldFire`
46625
+ * counter before paying for it, and that counter is now measuring the real
46626
+ * thing for the first time.
46627
+ *
46628
+ * @dbfs-era itu
46629
+ */
46593
46630
  audioMarkerMinDbfs: require_dist.number().max(0).default(-25),
46594
46631
  /** "Out of the ordinary": how many mean-absolute-deviations of the camera's
46595
46632
  * OWN jitter the sample must sit above its own mean. */
46596
46633
  audioMarkerMinDeviations: require_dist.number().positive().default(4),
46597
- /** Floor in dB on the distance above the camera's own mean — what holds
46598
- * when a dead-steady camera's deviation unit collapses toward zero. */
46634
+ /**
46635
+ * Floor in dB on the distance above the camera's own mean what holds when
46636
+ * a dead-steady camera's deviation unit collapses toward zero.
46637
+ *
46638
+ * A distance between two readings on the same camera: scale-invariant, and
46639
+ * untouched by D459. The numerical coincidence with the PCMU correction
46640
+ * (12 dB) is exactly that — a coincidence, and the reason this note exists
46641
+ * is so nobody reads it as one of the shifted numbers.
46642
+ *
46643
+ * @dbfs-era relative
46644
+ */
46599
46645
  audioMarkerMinDeviationDb: require_dist.number().positive().default(12),
46600
46646
  /** Audio matters most when nothing visual is happening. A marker is
46601
46647
  * suppressed while a track is alive on the camera, or motion was reported,
@@ -64321,6 +64367,15 @@ function createNativeFrameTransport(deps) {
64321
64367
  const wantJpeg = (_handle) => true;
64322
64368
  const cropReplyToRgb = async (reply) => {
64323
64369
  const tier = reply.tier;
64370
+ if (reply.jpegBytes !== void 0) {
64371
+ const rgb = await decodeJpegToRgb(reply.jpegBytes);
64372
+ return {
64373
+ bytes: rgb.bytes,
64374
+ width: rgb.width,
64375
+ height: rgb.height,
64376
+ ...tier !== void 0 ? { tier } : {}
64377
+ };
64378
+ }
64324
64379
  if (reply.jpeg !== void 0) {
64325
64380
  const rgb = await decodeJpegToRgb(reply.jpeg);
64326
64381
  return {
@@ -64340,6 +64395,12 @@ function createNativeFrameTransport(deps) {
64340
64395
  };
64341
64396
  const cropReplyToJpeg = async (reply) => {
64342
64397
  const tier = reply.tier;
64398
+ if (reply.jpegBytes !== void 0) return {
64399
+ jpeg: Buffer.from(reply.jpegBytes),
64400
+ width: reply.width,
64401
+ height: reply.height,
64402
+ ...tier !== void 0 ? { tier } : {}
64403
+ };
64343
64404
  if (reply.jpeg !== void 0) return {
64344
64405
  jpeg: Buffer.from(reply.jpeg, "base64"),
64345
64406
  width: reply.width,
@@ -64401,7 +64462,8 @@ function createNativeFrameTransport(deps) {
64401
64462
  handle: frameHandle,
64402
64463
  bbox,
64403
64464
  ...maxWidth !== void 0 ? { maxWidth } : {},
64404
- encodeJpeg: wantJpeg(frameHandle)
64465
+ encodeJpeg: wantJpeg(frameHandle),
64466
+ acceptJpegBytes: true
64405
64467
  }, require_dist.nodePin(frameHandle.nodeId));
64406
64468
  if (!native || native.width <= 0 || native.height <= 0) return null;
64407
64469
  return await normalize(native);
@@ -64722,7 +64784,8 @@ function createParkedFrameClient(deps) {
64722
64784
  const parcel = await api.getParkedTrackFrame.query({
64723
64785
  deviceId: known.deviceId,
64724
64786
  trackId,
64725
- kind
64787
+ kind,
64788
+ acceptJpegBytes: true
64726
64789
  }, require_dist.nodePin(known.nodeId));
64727
64790
  if (parcel === null) {
64728
64791
  logger.warn("parked frame gone at retrieval — the node no longer holds it", {
@@ -64736,8 +64799,20 @@ function createParkedFrameClient(deps) {
64736
64799
  });
64737
64800
  return null;
64738
64801
  }
64802
+ const jpeg = parcel.jpegBytes !== void 0 ? Buffer.from(parcel.jpegBytes) : parcel.jpeg !== void 0 ? Buffer.from(parcel.jpeg, "base64") : null;
64803
+ if (jpeg === null) {
64804
+ logger.warn("parked frame arrived with neither jpegBytes nor jpeg", {
64805
+ tags: { deviceId: known.deviceId },
64806
+ meta: {
64807
+ trackId,
64808
+ kind,
64809
+ nodeId: known.nodeId
64810
+ }
64811
+ });
64812
+ return null;
64813
+ }
64739
64814
  return {
64740
- jpeg: Buffer.from(parcel.jpeg, "base64"),
64815
+ jpeg,
64741
64816
  width: parcel.width,
64742
64817
  height: parcel.height,
64743
64818
  timestamp: parcel.timestamp,
@@ -65109,6 +65184,10 @@ var STALE_BASELINE_FACTOR = 5;
65109
65184
  * has MAD 0 and would make every deviation infinite. 1 dB is below the
65110
65185
  * quantisation of any real level meter, so it only ever binds on a synthetic
65111
65186
  * or a genuinely dead-steady signal — where bar 2 is what should decide.
65187
+ *
65188
+ * A floor on a DEVIATION, not on a level: scale-invariant, untouched by D459.
65189
+ *
65190
+ * @dbfs-era relative
65112
65191
  */
65113
65192
  var MIN_MAD_DB = 1;
65114
65193
  function emptyAudioBaseline() {
@@ -1,4 +1,4 @@
1
- import { $ as VISIT_MERGE_GAP_MS, $t as object, A as NcRulePatchSchema, Bt as CamProfileSchema, C as NC_ALARM_SYSTEM_EVENT_KINDS, D as NC_TAXONOMY, Dt as readDeviceStateFrom, Et as plateGalleryCapability, F as NcSnoozeSchema, Ft as vectorDimFromBase64, G as SCENE_DEFAULT_UNCOVERED_POLICY, Gt as nodePin, H as RetrainStatusSchema, Ht as createEvent, I as NcSnoozeSuppressedSchema, It as videoclipsCapability, J as TIMELAPSE_DENSE_FLOOR_SEC, Jt as array, K as SCENE_DIVERGED, Kt as sleep$1, L as NcSystemEventKindSchema, Lt as zoneAnalyticsCapability, M as NcRuleTargetSchema, Mt as storageOccupancyCapability, N as NcScheduleSchema, Nt as subKindsOf, O as NcConditionDescriptorSchema, Ot as readTimelapseGeneratedAt, P as NcSnoozeInputSchema, Pt as systemEventFilterApplies, Q as TrackSourceSchema, Qt as number, R as NcTaxonomySchema, Rt as errMsg$1, S as MediaFileKindEnum, St as notificationRulesCapability, T as NC_DEFAULT_SNOOZE_MINUTES, Tt as pipelineAnalyticsCapability, Ut as hydrateSchema, V as RECORDING_EXPORT_MAX_READ_BYTES, Vt as DeviceType, W as SCENE_DEFAULT_ANCHOR_THRESHOLD, Wt as isDeviceScopedCap, X as TimelapseRulePatchSchema, Xt as discriminatedUnion, Y as TimelapseRuleInputSchema, Yt as boolean, Z as TimelapseRuleSchema, Zt as literal, _ as FailureCounters, _t as isDetectionMacroClass, a as CLUSTER_MODEL_SCOPED_STEPS, at as buildEventKindDescriptor, b as MAX_BIRTH_DECISION_RECORDS, bt as kebabToCamel, ct as defineCustomActions, dt as encodeVectorBase64, en as partialRecord, et as addonWidgetsSourceCapability, f as DeclaredDevices, ft as evaluateSensorEdge, g as FULL_IMAGE_BBOX, h as FIRST_LEVEL_MACRO_CLASSES, ht as failureContributionCapability, i as BirthDecisionRecordSchema, in as EventCategory, it as audioModeOf, j as NcRuleSchema, jt as sceneMonitorCapability, k as NcRuleInputSchema, kt as resolveLocationMode, lt as deriveRecordingMode, m as EVENT_PAD_MS, mt as faceGalleryCapability, n as ArchivedDebugNoteSchema, nn as string, nt as assertTimelapseCadences, o as COCO_TO_MACRO, ot as cosineSimilarity$1, p as EVENT_KIND_BY_CAP, pt as evictionPolicyOfLocation, q as SceneMonitorSchema, qt as _enum, r as BaseDevice, rn as unknown, rt as audioMetricsCapability, s as DEFAULT_EVENT_COLOR, st as customAction, t as AUDIO_MACRO_LABELS, tn as record, tt as alarmPanelCapability, u as DETECTION_MACRO_CLASSES, v as LabelAttributionSchema, vt as isScheduleActive, w as NC_CONDITION_CATALOG, wt as pickClusterStepModels, xt as mayWriteToLocation, y as MAX_ARCHIVED_DEBUG_NOTES, yt as isSourceCap, z as OpsLogEntrySchema, zt as BaseAddon } from "../dist-DWXR9KNe.mjs";
1
+ import { $ as VISIT_MERGE_GAP_MS, $t as object, A as NcRulePatchSchema, Bt as CamProfileSchema, C as NC_ALARM_SYSTEM_EVENT_KINDS, D as NC_TAXONOMY, Dt as readDeviceStateFrom, Et as plateGalleryCapability, F as NcSnoozeSchema, Ft as vectorDimFromBase64, G as SCENE_DEFAULT_UNCOVERED_POLICY, Gt as nodePin, H as RetrainStatusSchema, Ht as createEvent, I as NcSnoozeSuppressedSchema, It as videoclipsCapability, J as TIMELAPSE_DENSE_FLOOR_SEC, Jt as array, K as SCENE_DIVERGED, Kt as sleep$1, L as NcSystemEventKindSchema, Lt as zoneAnalyticsCapability, M as NcRuleTargetSchema, Mt as storageOccupancyCapability, N as NcScheduleSchema, Nt as subKindsOf, O as NcConditionDescriptorSchema, Ot as readTimelapseGeneratedAt, P as NcSnoozeInputSchema, Pt as systemEventFilterApplies, Q as TrackSourceSchema, Qt as number, R as NcTaxonomySchema, Rt as errMsg$1, S as MediaFileKindEnum, St as notificationRulesCapability, T as NC_DEFAULT_SNOOZE_MINUTES, Tt as pipelineAnalyticsCapability, Ut as hydrateSchema, V as RECORDING_EXPORT_MAX_READ_BYTES, Vt as DeviceType, W as SCENE_DEFAULT_ANCHOR_THRESHOLD, Wt as isDeviceScopedCap, X as TimelapseRulePatchSchema, Xt as discriminatedUnion, Y as TimelapseRuleInputSchema, Yt as boolean, Z as TimelapseRuleSchema, Zt as literal, _ as FailureCounters, _t as isDetectionMacroClass, a as CLUSTER_MODEL_SCOPED_STEPS, at as buildEventKindDescriptor, b as MAX_BIRTH_DECISION_RECORDS, bt as kebabToCamel, ct as defineCustomActions, dt as encodeVectorBase64, en as partialRecord, et as addonWidgetsSourceCapability, f as DeclaredDevices, ft as evaluateSensorEdge, g as FULL_IMAGE_BBOX, h as FIRST_LEVEL_MACRO_CLASSES, ht as failureContributionCapability, i as BirthDecisionRecordSchema, in as EventCategory, it as audioModeOf, j as NcRuleSchema, jt as sceneMonitorCapability, k as NcRuleInputSchema, kt as resolveLocationMode, lt as deriveRecordingMode, m as EVENT_PAD_MS, mt as faceGalleryCapability, n as ArchivedDebugNoteSchema, nn as string, nt as assertTimelapseCadences, o as COCO_TO_MACRO, ot as cosineSimilarity$1, p as EVENT_KIND_BY_CAP, pt as evictionPolicyOfLocation, q as SceneMonitorSchema, qt as _enum, r as BaseDevice, rn as unknown, rt as audioMetricsCapability, s as DEFAULT_EVENT_COLOR, st as customAction, t as AUDIO_MACRO_LABELS, tn as record, tt as alarmPanelCapability, u as DETECTION_MACRO_CLASSES, v as LabelAttributionSchema, vt as isScheduleActive, w as NC_CONDITION_CATALOG, wt as pickClusterStepModels, xt as mayWriteToLocation, y as MAX_ARCHIVED_DEBUG_NOTES, yt as isSourceCap, z as OpsLogEntrySchema, zt as BaseAddon } from "../dist-CxPGPwcy.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";
@@ -45802,8 +45802,13 @@ async function encodeRgbCropToJpeg(bytes, width, height) {
45802
45802
  * same-node (raw) or cross-node (JPEG). The decode happens IN-PROCESS on the
45803
45803
  * post-processing node — no raw pixels ever cross a process boundary.
45804
45804
  */
45805
- async function decodeJpegToRgb(base64Jpeg) {
45806
- const { data, info } = await sharp(Buffer.from(base64Jpeg, "base64")).raw().toBuffer({ resolveWithObject: true });
45805
+ /**
45806
+ * Decode a JPEG to raw RGB. Takes the BYTES, or the base64 a pre-D462 runner
45807
+ * still answers with — sharp wants bytes either way, so accepting both here is
45808
+ * what lets the caller stop base64-ing purely to be understood.
45809
+ */
45810
+ async function decodeJpegToRgb(jpeg) {
45811
+ const { data, info } = await sharp(typeof jpeg === "string" ? Buffer.from(jpeg, "base64") : Buffer.from(jpeg)).raw().toBuffer({ resolveWithObject: true });
45807
45812
  return {
45808
45813
  bytes: data,
45809
45814
  width: info.width,
@@ -46505,6 +46510,17 @@ var AudioDetectionSettingsSchema = object({
46505
46510
  audioConfirmHits: number().int().min(1).default(2),
46506
46511
  /** Width of the corroboration window. Ignored when `audioConfirmHits` is 1. */
46507
46512
  audioConfirmWindowSec: number().positive().default(10),
46513
+ /**
46514
+ * How far above the camera's own 10 s mean a sample must sit to be a peak.
46515
+ *
46516
+ * A DIFFERENCE between two readings on the same camera, so a uniform scale
46517
+ * offset cancels exactly and the D459 correction did not touch it. Proved,
46518
+ * not assumed — D459 enumerates this alongside `audioMarkerMinDeviationDb`,
46519
+ * `audioMarkerMinDeviations` and the EWMA/MAD pair. "Correcting" it by
46520
+ * 12 dB would be introducing the very error the epoch removed.
46521
+ *
46522
+ * @dbfs-era relative
46523
+ */
46508
46524
  levelDeviationDb: number().positive().default(10),
46509
46525
  levelWindowSec: number().positive().default(10),
46510
46526
  levelMaxWaitSec: number().positive().default(20),
@@ -46514,14 +46530,44 @@ var AudioDetectionSettingsSchema = object({
46514
46530
  /** EWMA time constant for the camera's "normal" loudness, in seconds. Also
46515
46531
  * the warm-up: no marker until one time constant of audio has been heard. */
46516
46532
  audioMarkerBaselineSec: number().positive().default(300),
46517
- /** "High volume", absolute. A sample quieter than this is never a marker
46518
- * however surprising it is for the camera. */
46533
+ /**
46534
+ * "High volume", absolute. A sample quieter than this is never a marker
46535
+ * however surprising it is for the camera.
46536
+ *
46537
+ * NOT shifted at the D459 epoch, for the same reason as `SILENCE_FLOOR_DBFS`
46538
+ * and with one extra argument of its own. `-25 dBFS is loud` is a statement
46539
+ * about the scale, not a measurement taken through the old decoder: nobody
46540
+ * read it off a meter, it is what "loud" means on a 16-bit full-scale range.
46541
+ *
46542
+ * The extra argument is that on the old scale this default was effectively
46543
+ * DEAD on the 19 mis-decoded cameras — a reading of -25 there required a
46544
+ * true level of -13 dBFS, which is a sound close to clipping. Bar 1 almost
46545
+ * never bound on them, so the feature has been running on two of its three
46546
+ * bars. At the epoch it starts working as designed rather than becoming too
46547
+ * permissive.
46548
+ *
46549
+ * That it also ships OFF by default (`audioMarkerEnabled`) is what makes
46550
+ * this safe to leave alone: the operator sizes the rate from the `wouldFire`
46551
+ * counter before paying for it, and that counter is now measuring the real
46552
+ * thing for the first time.
46553
+ *
46554
+ * @dbfs-era itu
46555
+ */
46519
46556
  audioMarkerMinDbfs: number().max(0).default(-25),
46520
46557
  /** "Out of the ordinary": how many mean-absolute-deviations of the camera's
46521
46558
  * OWN jitter the sample must sit above its own mean. */
46522
46559
  audioMarkerMinDeviations: number().positive().default(4),
46523
- /** Floor in dB on the distance above the camera's own mean — what holds
46524
- * when a dead-steady camera's deviation unit collapses toward zero. */
46560
+ /**
46561
+ * Floor in dB on the distance above the camera's own mean what holds when
46562
+ * a dead-steady camera's deviation unit collapses toward zero.
46563
+ *
46564
+ * A distance between two readings on the same camera: scale-invariant, and
46565
+ * untouched by D459. The numerical coincidence with the PCMU correction
46566
+ * (12 dB) is exactly that — a coincidence, and the reason this note exists
46567
+ * is so nobody reads it as one of the shifted numbers.
46568
+ *
46569
+ * @dbfs-era relative
46570
+ */
46525
46571
  audioMarkerMinDeviationDb: number().positive().default(12),
46526
46572
  /** Audio matters most when nothing visual is happening. A marker is
46527
46573
  * suppressed while a track is alive on the camera, or motion was reported,
@@ -64247,6 +64293,15 @@ function createNativeFrameTransport(deps) {
64247
64293
  const wantJpeg = (_handle) => true;
64248
64294
  const cropReplyToRgb = async (reply) => {
64249
64295
  const tier = reply.tier;
64296
+ if (reply.jpegBytes !== void 0) {
64297
+ const rgb = await decodeJpegToRgb(reply.jpegBytes);
64298
+ return {
64299
+ bytes: rgb.bytes,
64300
+ width: rgb.width,
64301
+ height: rgb.height,
64302
+ ...tier !== void 0 ? { tier } : {}
64303
+ };
64304
+ }
64250
64305
  if (reply.jpeg !== void 0) {
64251
64306
  const rgb = await decodeJpegToRgb(reply.jpeg);
64252
64307
  return {
@@ -64266,6 +64321,12 @@ function createNativeFrameTransport(deps) {
64266
64321
  };
64267
64322
  const cropReplyToJpeg = async (reply) => {
64268
64323
  const tier = reply.tier;
64324
+ if (reply.jpegBytes !== void 0) return {
64325
+ jpeg: Buffer.from(reply.jpegBytes),
64326
+ width: reply.width,
64327
+ height: reply.height,
64328
+ ...tier !== void 0 ? { tier } : {}
64329
+ };
64269
64330
  if (reply.jpeg !== void 0) return {
64270
64331
  jpeg: Buffer.from(reply.jpeg, "base64"),
64271
64332
  width: reply.width,
@@ -64327,7 +64388,8 @@ function createNativeFrameTransport(deps) {
64327
64388
  handle: frameHandle,
64328
64389
  bbox,
64329
64390
  ...maxWidth !== void 0 ? { maxWidth } : {},
64330
- encodeJpeg: wantJpeg(frameHandle)
64391
+ encodeJpeg: wantJpeg(frameHandle),
64392
+ acceptJpegBytes: true
64331
64393
  }, nodePin(frameHandle.nodeId));
64332
64394
  if (!native || native.width <= 0 || native.height <= 0) return null;
64333
64395
  return await normalize(native);
@@ -64648,7 +64710,8 @@ function createParkedFrameClient(deps) {
64648
64710
  const parcel = await api.getParkedTrackFrame.query({
64649
64711
  deviceId: known.deviceId,
64650
64712
  trackId,
64651
- kind
64713
+ kind,
64714
+ acceptJpegBytes: true
64652
64715
  }, nodePin(known.nodeId));
64653
64716
  if (parcel === null) {
64654
64717
  logger.warn("parked frame gone at retrieval — the node no longer holds it", {
@@ -64662,8 +64725,20 @@ function createParkedFrameClient(deps) {
64662
64725
  });
64663
64726
  return null;
64664
64727
  }
64728
+ const jpeg = parcel.jpegBytes !== void 0 ? Buffer.from(parcel.jpegBytes) : parcel.jpeg !== void 0 ? Buffer.from(parcel.jpeg, "base64") : null;
64729
+ if (jpeg === null) {
64730
+ logger.warn("parked frame arrived with neither jpegBytes nor jpeg", {
64731
+ tags: { deviceId: known.deviceId },
64732
+ meta: {
64733
+ trackId,
64734
+ kind,
64735
+ nodeId: known.nodeId
64736
+ }
64737
+ });
64738
+ return null;
64739
+ }
64665
64740
  return {
64666
- jpeg: Buffer.from(parcel.jpeg, "base64"),
64741
+ jpeg,
64667
64742
  width: parcel.width,
64668
64743
  height: parcel.height,
64669
64744
  timestamp: parcel.timestamp,
@@ -65035,6 +65110,10 @@ var STALE_BASELINE_FACTOR = 5;
65035
65110
  * has MAD 0 and would make every deviation infinite. 1 dB is below the
65036
65111
  * quantisation of any real level meter, so it only ever binds on a synthetic
65037
65112
  * or a genuinely dead-steady signal — where bar 2 is what should decide.
65113
+ *
65114
+ * A floor on a DEVIATION, not on a level: scale-invariant, untouched by D459.
65115
+ *
65116
+ * @dbfs-era relative
65038
65117
  */
65039
65118
  var MIN_MAD_DB = 1;
65040
65119
  function emptyAudioBaseline() {
@@ -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-Bfm6wOeY.mjs")).catch((e) => {
33
+ return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-B3K65b9h.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.220",
3
+ "version": "1.2.222",
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",