@camstack/addon-pipeline 1.2.272 → 1.2.274
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/audio-analyzer/index.js +2 -2
- package/dist/audio-analyzer/index.mjs +2 -2
- package/dist/{default-detection-model-DqrqHCuw.mjs → default-detection-model-BXwE-Dvo.mjs} +1 -1
- package/dist/{default-detection-model-kQnvoRyv.js → default-detection-model-CAWhHQo2.js} +1 -1
- package/dist/detection-pipeline/index.js +4 -4
- package/dist/detection-pipeline/index.mjs +4 -4
- package/dist/{dist-DBHsAlUE.mjs → dist-g5MfpiBh.mjs} +363 -20
- package/dist/{dist-DygcLvgG.js → dist-k6Vu-AhZ.js} +386 -19
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/{node-CACCuE7t.js → node--u_jUObS.js} +1 -1
- package/dist/{node-j_3VvNQJ.mjs → node-BXsHQH5h.mjs} +1 -1
- package/dist/pipeline-runner/index.js +3 -3
- package/dist/pipeline-runner/index.mjs +3 -3
- package/dist/{process-memory-fse8NnRi.js → process-memory-DN7opum2.js} +1 -1
- package/dist/{process-memory-DcoIQGG5.mjs → process-memory-Gl3EowL-.mjs} +1 -1
- package/dist/recorder/index.js +572 -3
- package/dist/recorder/index.mjs +572 -3
- package/dist/{segment-demux-js-Ce24Y2G0.js → segment-demux-js-DHX8o8pI.js} +1 -1
- package/dist/{segment-demux-js-DSgNEMf6.mjs → segment-demux-js-sYP_jndp.mjs} +1 -1
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BSZUBMBY.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CEy8IryH.mjs} +2 -2
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BlXyfeXU.mjs +26 -0
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-MU3_q1MX.mjs +26 -0
- package/dist/stream-broker/demux-worker-child.js +1 -1
- package/dist/stream-broker/demux-worker-child.mjs +1 -1
- package/dist/stream-broker/{hostInit-lVR0hopj.mjs → hostInit-UKNN4qes.mjs} +2 -2
- package/dist/stream-broker/index.js +3 -3
- package/dist/stream-broker/index.mjs +3 -3
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/package.json +5 -1
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-_bHa4uUp.mjs +0 -26
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CeR_IxxU.mjs +0 -26
|
@@ -5360,7 +5360,7 @@ var ZodIssueCode = {
|
|
|
5360
5360
|
var ZodFirstPartyTypeKind;
|
|
5361
5361
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5362
5362
|
//#endregion
|
|
5363
|
-
//#region ../types/dist/sleep-
|
|
5363
|
+
//#region ../types/dist/sleep-CaB_hL5g.mjs
|
|
5364
5364
|
/**
|
|
5365
5365
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5366
5366
|
* window to float samples (D455).
|
|
@@ -8341,6 +8341,8 @@ var EVENT_OWNER_TYPES = [
|
|
|
8341
8341
|
* nothing failing until a caller asked.
|
|
8342
8342
|
*/
|
|
8343
8343
|
var EventOwnerTypeSchema = _enum(EVENT_OWNER_TYPES);
|
|
8344
|
+
/** The same list as a Zod enum, for the cap input that carries it. */
|
|
8345
|
+
var MediaPresenceOwnerKindSchema = _enum([...EVENT_OWNER_TYPES, "track"]);
|
|
8344
8346
|
new Set(EVENT_OWNER_TYPES);
|
|
8345
8347
|
var EncodeProfileSchema = object({
|
|
8346
8348
|
video: object({
|
|
@@ -9321,6 +9323,24 @@ var DetectionCatalogClassMapSchema = object({
|
|
|
9321
9323
|
preserveOriginal: boolean()
|
|
9322
9324
|
});
|
|
9323
9325
|
/**
|
|
9326
|
+
* THE canonical event-clip pad: the time window a single-timestamp analytics
|
|
9327
|
+
* event expands to when joined with footage (clip window = `[timestamp - preMs,
|
|
9328
|
+
* timestamp + postMs]`). Matches the admin-ui clip window (−5s/+10s).
|
|
9329
|
+
*
|
|
9330
|
+
* Every consumer derives from this ONE constant so event↔footage boundaries
|
|
9331
|
+
* agree everywhere (C1): today that is the `videoclips` default provider
|
|
9332
|
+
* (addon-post-analysis), which pads its clip windows with it. The recorder used
|
|
9333
|
+
* to pad in-RAM playback markers with it too; those markers had no reader
|
|
9334
|
+
* anywhere in the repo and were deleted on 2026-08-29.
|
|
9335
|
+
*
|
|
9336
|
+
* NOTE: this is a UI/JOIN convention, NOT the `events`-band keep/discard gate —
|
|
9337
|
+
* that uses the per-device `preBufferSec`/`postBufferSec` config.
|
|
9338
|
+
*/
|
|
9339
|
+
var EVENT_PAD_MS = {
|
|
9340
|
+
preMs: 5e3,
|
|
9341
|
+
postMs: 1e4
|
|
9342
|
+
};
|
|
9343
|
+
/**
|
|
9324
9344
|
* Numeric day-of-week: 0 = Sunday … 6 = Saturday (matches `Date.getDay`).
|
|
9325
9345
|
* Named `RecordingWeekday` to avoid collision with the string-union
|
|
9326
9346
|
* `Weekday` exported from `interfaces/timezones.ts`.
|
|
@@ -9537,7 +9557,20 @@ function stripRetiredBandPreBufferSec(config) {
|
|
|
9537
9557
|
strippedBands
|
|
9538
9558
|
};
|
|
9539
9559
|
}
|
|
9540
|
-
|
|
9560
|
+
/**
|
|
9561
|
+
* Adjacent recorded ranges closer than this belong to the SAME videoclip visit.
|
|
9562
|
+
*
|
|
9563
|
+
* This is NOT the recorder calendar merge (`RANGE_MERGE_GAP_MS = 5s`). That
|
|
9564
|
+
* threshold is for the timeline bar, which must show exact holes — including
|
|
9565
|
+
* the ~8s GOP/keyframe rolls measured on events-mode cameras (dispensa 1438,
|
|
9566
|
+
* 2026-08-16). A videoclip is the events-mode keep-window (writer session),
|
|
9567
|
+
* whose idle bound is `postBufferSec`. Using that default (30s) glues those
|
|
9568
|
+
* intra-visit holes without joining visits hours apart.
|
|
9569
|
+
*
|
|
9570
|
+
* Segments stay the source of truth on disk (`startMs-durMs-bytes.m4s`); a
|
|
9571
|
+
* visit is derived, not a second copy of the files.
|
|
9572
|
+
*/
|
|
9573
|
+
var VISIT_MERGE_GAP_MS = DEFAULT_EVENTS_BAND_BUFFER_SEC.postBufferSec * 1e3;
|
|
9541
9574
|
/**
|
|
9542
9575
|
* Per-device retention overrides. Every field is optional; an unset or `0`
|
|
9543
9576
|
* value inherits the node-wide recorder default. Only footage-lifetime limits
|
|
@@ -23927,7 +23960,11 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
23927
23960
|
ownerType: EventOwnerTypeSchema,
|
|
23928
23961
|
eventId: number().int(),
|
|
23929
23962
|
deviceId: number()
|
|
23930
|
-
}), array(MediaFileInfoSchema).readonly()), method(
|
|
23963
|
+
}), array(MediaFileInfoSchema).readonly()), method(object({
|
|
23964
|
+
deviceId: number(),
|
|
23965
|
+
ownerKind: MediaPresenceOwnerKindSchema,
|
|
23966
|
+
ownerIds: array(string()).max(5e3)
|
|
23967
|
+
}), array(string()).readonly()), method(SearchObjectEventsInput, array(ScoredObjectEventSchema).readonly()), method(object({}), WipeObjectEmbeddingsResultSchema, {
|
|
23931
23968
|
kind: "mutation",
|
|
23932
23969
|
auth: "admin"
|
|
23933
23970
|
}), method(RebuildObjectEmbeddingsInput, RebuildObjectEmbeddingsResultSchema, {
|
|
@@ -27155,6 +27192,18 @@ method(VectorDeclareIndexInputSchema, _void(), {
|
|
|
27155
27192
|
kind: "mutation",
|
|
27156
27193
|
auth: "admin"
|
|
27157
27194
|
}), method(VectorStatsInputSchema, VectorStatsResultSchema, { auth: "admin" });
|
|
27195
|
+
_enum([
|
|
27196
|
+
"queue-full",
|
|
27197
|
+
"camera-backoff",
|
|
27198
|
+
"sleeping",
|
|
27199
|
+
"camera-refused",
|
|
27200
|
+
"no-keyframe",
|
|
27201
|
+
"no-catalog-row",
|
|
27202
|
+
"unsupported",
|
|
27203
|
+
"unknown-device",
|
|
27204
|
+
"uid-missing"
|
|
27205
|
+
]);
|
|
27206
|
+
_enum(["deferred", "final"]);
|
|
27158
27207
|
var ClipSchema = object({
|
|
27159
27208
|
/** Opaque, provider-namespaced id. The default provider encodes the time
|
|
27160
27209
|
* window so `getClipPlayback` is self-contained (no event re-query). */
|
|
@@ -27229,30 +27278,302 @@ var ClipSchema = object({
|
|
|
27229
27278
|
holes: array(object({
|
|
27230
27279
|
startMs: number(),
|
|
27231
27280
|
endMs: number()
|
|
27232
|
-
})).optional()
|
|
27281
|
+
})).optional(),
|
|
27282
|
+
/**
|
|
27283
|
+
* A URL that MAY produce this clip's still, asked only for rows actually on
|
|
27284
|
+
* screen. The opposite of {@link ClipSchema.thumbnail}: that one is VOUCHED
|
|
27285
|
+
* (a JPEG is already on disk), this one is an offer. The route answers 200
|
|
27286
|
+
* with the image, or 204 with `x-camstack-reason` when it could not mint one
|
|
27287
|
+
* — a surface latches that refusal to the instant rather than retrying.
|
|
27288
|
+
*
|
|
27289
|
+
* Never both: a clip with a vouched `thumbnail` needs no mint.
|
|
27290
|
+
*/
|
|
27291
|
+
thumbnailMint: string().optional(),
|
|
27292
|
+
/**
|
|
27293
|
+
* Why no still will be produced for this clip RIGHT NOW — set when the
|
|
27294
|
+
* provider already knows, so the surface draws the glyph and the reason
|
|
27295
|
+
* instead of firing a mint that cannot succeed.
|
|
27296
|
+
*
|
|
27297
|
+
* `sleeping` — a standalone battery camera; a read would be a wake (D549 4).
|
|
27298
|
+
* `camera-refused` — the camera answered the CoverPreview with a refusal.
|
|
27299
|
+
* `no-keyframe` — the window holds no decodable I-frame (an event that sits
|
|
27300
|
+
* inside no file is the measured case).
|
|
27301
|
+
* `unsupported` — this source cannot mint stills at all.
|
|
27302
|
+
*/
|
|
27303
|
+
thumbnailUnavailable: object({ reason: _enum([
|
|
27304
|
+
"sleeping",
|
|
27305
|
+
"camera-refused",
|
|
27306
|
+
"no-keyframe",
|
|
27307
|
+
"unsupported"
|
|
27308
|
+
]) }).optional(),
|
|
27309
|
+
/**
|
|
27310
|
+
* When the catalog this row came from was last CONFIRMED against the device.
|
|
27311
|
+
* Absent means "this row was read live". A persisted catalog served while a
|
|
27312
|
+
* camera sleeps carries the age it really has — a cached list is never drawn
|
|
27313
|
+
* as current (D549 13).
|
|
27314
|
+
*/
|
|
27315
|
+
catalogAsOf: number().optional(),
|
|
27316
|
+
/**
|
|
27317
|
+
* The camera's OWN type strings for this clip, all of them, unmapped
|
|
27318
|
+
* (`md`, `people`, `dog_cat`, `sched`, …). Kept beside {@link labels}
|
|
27319
|
+
* because a firmware inventing a type must not vanish: the mapping into our
|
|
27320
|
+
* filter vocabulary is lossy on purpose and this is the lossless copy
|
|
27321
|
+
* (D549 20).
|
|
27322
|
+
*/
|
|
27323
|
+
nativeTypes: array(string()).optional(),
|
|
27324
|
+
/**
|
|
27325
|
+
* What the subject DID — `crossline`, `intrude`, `loitering`. A behaviour
|
|
27326
|
+
* travels BESIDE a class, never instead of one, and the class filter ignores
|
|
27327
|
+
* it: "a person crossed a line" is still a person (D549 20).
|
|
27328
|
+
*/
|
|
27329
|
+
behaviours: array(string()).optional(),
|
|
27330
|
+
/**
|
|
27331
|
+
* The same recording as two files — the sub twin (what the row and its
|
|
27332
|
+
* thumbnail are) and its main twin, matched at listing time so a quality
|
|
27333
|
+
* change never re-searches the camera (D549 15). `getClipPlayback`'s
|
|
27334
|
+
* `profile` picks between them: `low | mid` → sub, `high` → main.
|
|
27335
|
+
*/
|
|
27336
|
+
streams: object({
|
|
27337
|
+
sub: object({
|
|
27338
|
+
id: string(),
|
|
27339
|
+
bytes: number().optional()
|
|
27340
|
+
}).optional(),
|
|
27341
|
+
main: object({
|
|
27342
|
+
id: string(),
|
|
27343
|
+
bytes: number().optional()
|
|
27344
|
+
}).optional()
|
|
27345
|
+
}).optional(),
|
|
27346
|
+
/** The camera says it holds a sub-stream copy of this recording. */
|
|
27347
|
+
supportSub: boolean().optional(),
|
|
27348
|
+
/**
|
|
27349
|
+
* Whether this row has bytes behind it. ABSENT means yes — every clip that
|
|
27350
|
+
* IS a file is playable, and only a source that lists EVENTS can produce a
|
|
27351
|
+
* row with nothing to play (the measured case: 1 of 29 hub events on 3628
|
|
27352
|
+
* fell inside no file). Such a row is shown, never dropped and never offered
|
|
27353
|
+
* as playable-then-failing (D549 19).
|
|
27354
|
+
*/
|
|
27355
|
+
playable: boolean().optional(),
|
|
27356
|
+
/** Why {@link playable} is false, verbatim (`no-file-for-window`). */
|
|
27357
|
+
unplayableReason: string().optional(),
|
|
27358
|
+
/**
|
|
27359
|
+
* This clip is STILL BEING WRITTEN, so {@link ClipSchema.timeRange}`.endMs`
|
|
27360
|
+
* is not its end.
|
|
27361
|
+
*
|
|
27362
|
+
* Absent — the common case — means the row is closed and its `endMs` is the
|
|
27363
|
+
* end of the recording. Present and `true` means the source told us the file
|
|
27364
|
+
* has no end yet, and the `endMs` we carry is whatever the camera's index
|
|
27365
|
+
* entry happened to hold: on a Reolink E1 Outdoor PoE (592, measured
|
|
27366
|
+
* 2026-09-20) the newest file `…_192927_000000_…_0.mp4` reported an `endTime`
|
|
27367
|
+
* of 19:29:56 and STILL reported it eight minutes later, while the file went
|
|
27368
|
+
* on growing. A surface that drew 29 s there was lying about a clip that
|
|
27369
|
+
* plays for minutes, on the one row the operator looks at first.
|
|
27370
|
+
*
|
|
27371
|
+
* `endMs` is deliberately still a number: it is the best bound anything has
|
|
27372
|
+
* for a mint window or a byte fetch, and every consumer already requires it.
|
|
27373
|
+
* This flag says what it is WORTH, and a duration is not drawn from it.
|
|
27374
|
+
*/
|
|
27375
|
+
inProgress: boolean().optional()
|
|
27233
27376
|
});
|
|
27234
27377
|
var ClipPlaybackSchema = object({
|
|
27235
|
-
/**
|
|
27378
|
+
/**
|
|
27379
|
+
* A media URL through the hub data-plane. {@link ClipPlaybackSchema.format}
|
|
27380
|
+
* says what kind — an HLS master playlist for a recording-derived clip, a
|
|
27381
|
+
* progressive MP4 for a native file the vendor addon muxed and serves with
|
|
27382
|
+
* `Range`. The URL is NOT a credential: both planes are registered
|
|
27383
|
+
* `access: 'authenticated'` and the hub's `/addon/<id>/<prefix>` proxy takes
|
|
27384
|
+
* the session cookie, so nothing is appended to it (D549 22).
|
|
27385
|
+
*/
|
|
27236
27386
|
playbackUrl: string(),
|
|
27387
|
+
/**
|
|
27388
|
+
* How to play {@link playbackUrl}. Absent means `hls` — the shape every
|
|
27389
|
+
* existing consumer already assumes. A player that branches on this is the
|
|
27390
|
+
* one change a native clip needs; a player that ignores it will hand an MP4
|
|
27391
|
+
* to hls.js and fail parsing it as a manifest.
|
|
27392
|
+
*/
|
|
27393
|
+
format: _enum(["hls", "mp4"]).optional(),
|
|
27394
|
+
/**
|
|
27395
|
+
* Which twin was actually served. A clip that holds only one stream answers
|
|
27396
|
+
* with the one it has, and the surface SAYS so — a missing main twin is
|
|
27397
|
+
* never served silently as if it were the asked-for quality (D549 15).
|
|
27398
|
+
*/
|
|
27399
|
+
served: CamProfileSchema.optional(),
|
|
27237
27400
|
/** Optional LAN/remote alternates for the same clip. */
|
|
27238
27401
|
playbackEndpoints: array(string()).optional(),
|
|
27239
27402
|
token: string().optional()
|
|
27240
27403
|
});
|
|
27241
|
-
|
|
27242
|
-
|
|
27243
|
-
|
|
27244
|
-
|
|
27245
|
-
|
|
27246
|
-
|
|
27247
|
-
|
|
27248
|
-
|
|
27249
|
-
|
|
27250
|
-
|
|
27251
|
-
|
|
27252
|
-
|
|
27253
|
-
|
|
27254
|
-
|
|
27404
|
+
/**
|
|
27405
|
+
* Why a source cannot answer right now — per SOURCE, never fleet-wide.
|
|
27406
|
+
*
|
|
27407
|
+
* `ok` is the only state whose clip list may be read as complete. The other
|
|
27408
|
+
* three exist because an empty list from a sleeping camera reads as "this
|
|
27409
|
+
* camera has no recordings", which is the defect this whole line of work is
|
|
27410
|
+
* about: a battery camera nobody woke (`sleeping`), a camera that could not be
|
|
27411
|
+
* reached at all (`unreachable`, also what a provider that THREW reports), a
|
|
27412
|
+
* camera whose SD card is not mounted (`no-storage`, measured on 640 —
|
|
27413
|
+
* `HddInfo mount 0`, honestly nothing to list rather than "no clips"), and a
|
|
27414
|
+
* camera whose OWN index disagrees with its OWN calendar (`index-empty`,
|
|
27415
|
+
* measured on 618: the calendar marks 3–20 September, days 6–20 list zero
|
|
27416
|
+
* files on both streams and both filters, with 177 GB free). That last one is
|
|
27417
|
+
* a defect ON THE CAMERA, and the only honest thing a provider can do is say
|
|
27418
|
+
* which days it asked for and got nothing — "no clips" would be a lie about a
|
|
27419
|
+
* card that is full of them.
|
|
27420
|
+
*/
|
|
27421
|
+
var ClipSourceAvailabilitySchema = object({
|
|
27422
|
+
state: _enum([
|
|
27423
|
+
"ok",
|
|
27424
|
+
"sleeping",
|
|
27425
|
+
"unreachable",
|
|
27426
|
+
"no-storage",
|
|
27427
|
+
"index-empty"
|
|
27428
|
+
]),
|
|
27429
|
+
/** Free text, shown verbatim. Names the camera's own refusal when there is one. */
|
|
27430
|
+
reason: string().optional(),
|
|
27431
|
+
/** When this source's catalog was last CONFIRMED. A cached list is never
|
|
27432
|
+
* drawn as current: the surface shows the age whenever it is older than the
|
|
27433
|
+
* refresh interval. */
|
|
27434
|
+
catalogAsOf: number().optional()
|
|
27435
|
+
});
|
|
27436
|
+
/**
|
|
27437
|
+
* One SOURCE of clips for a camera — a row of the picker, and the namespace
|
|
27438
|
+
* every clip id from it is prefixed with (`analytics`,
|
|
27439
|
+
* `native:reolink:onboard`, `hksv`, …).
|
|
27440
|
+
*
|
|
27441
|
+
* A provider lists the sources IT serves for that device, and answers for each
|
|
27442
|
+
* of them whether it can answer at all. A provider with nothing to offer on a
|
|
27443
|
+
* camera returns `[]` — it is not that camera's business.
|
|
27444
|
+
*/
|
|
27445
|
+
var ClipSourceSchema = object({
|
|
27446
|
+
/** The value this source stamps on {@link ClipSchema.source}, and the prefix
|
|
27447
|
+
* of every clip id it mints. `getClipPlayback` routes on it. */
|
|
27448
|
+
source: string(),
|
|
27449
|
+
/** Operator-facing name of the source ("CamStack recordings", "SD card"). */
|
|
27450
|
+
label: string(),
|
|
27451
|
+
/**
|
|
27452
|
+
* The addon that SERVES this row.
|
|
27453
|
+
*
|
|
27454
|
+
* A surface cannot otherwise resolve a source to who answers it, and the
|
|
27455
|
+
* alternative — a `native:reolink:* → provider-reolink` table inside the
|
|
27456
|
+
* widget — is a second authority on provider identity living in the one
|
|
27457
|
+
* package with no business knowing it, wrong the day a third source appears
|
|
27458
|
+
* (D557). One addon may serve SEVERAL sources, which is why the per-device
|
|
27459
|
+
* switch is keyed by SOURCE and not by this (D555) — `addon-provider-reolink`
|
|
27460
|
+
* served a hub child two of them until the two views were measured to be one
|
|
27461
|
+
* store read twice (D555) and then read ONE way (D565).
|
|
27462
|
+
*
|
|
27463
|
+
* Optional for version skew only. The collection dispatcher stamps it from
|
|
27464
|
+
* the registry, so a row that travelled through the fan-out carries the
|
|
27465
|
+
* authoritative id whatever the provider filled in.
|
|
27466
|
+
*/
|
|
27467
|
+
addonId: string().optional(),
|
|
27468
|
+
availability: ClipSourceAvailabilitySchema
|
|
27255
27469
|
});
|
|
27470
|
+
var videoclipsCapability = {
|
|
27471
|
+
name: "videoclips",
|
|
27472
|
+
scope: "device",
|
|
27473
|
+
mode: "collection",
|
|
27474
|
+
kind: "wrapper",
|
|
27475
|
+
defaultActive: true,
|
|
27476
|
+
/** A clip is a window over a camera's footage — the cap is meaningless on a
|
|
27477
|
+
* sensor, a button or an event emitter, and the `defaultActive` auto-bind
|
|
27478
|
+
* reads this to decide which devices it may claim. */
|
|
27479
|
+
deviceTypes: [DeviceType.Camera],
|
|
27480
|
+
/**
|
|
27481
|
+
* The Clips section of a camera's device details is FRAMEWORK-DERIVED (D14):
|
|
27482
|
+
* the aggregator turns this declaration into the `type:'widget'` section and
|
|
27483
|
+
* `DeviceDetail.tsx` is never edited. `videoclips` is the first WRAPPER cap
|
|
27484
|
+
* to declare one — every previous `host/` widget cap is `deviceNative` — so
|
|
27485
|
+
* `device-config-widget-wrapped-binding.spec.ts` pins that a `kind:'wrapped'`
|
|
27486
|
+
* binding entry derives the same section a native one does.
|
|
27487
|
+
*
|
|
27488
|
+
* **It is a SECTION of the Recording tab, at the end of it — not a tab of
|
|
27489
|
+
* its own.** It shipped as a `clips` top-tab and the operator rejected the
|
|
27490
|
+
* placement: *"utilizzerei la stessa tab recordings, lì abbiamo già tutto il
|
|
27491
|
+
* necessario, una nuova sezione alla fine per le clips"*. The Recording tab
|
|
27492
|
+
* already holds the recorder's panel, the schedule bands and the unified
|
|
27493
|
+
* retention policy; footage the camera itself holds is the same question,
|
|
27494
|
+
* asked of a different store. `order: 100` puts it after all of them with
|
|
27495
|
+
* room left in front. The `clips` entry in `WELL_KNOWN_TABS` went with it —
|
|
27496
|
+
* a well-known id nobody declares is an invitation to mint the tab again.
|
|
27497
|
+
*
|
|
27498
|
+
* `topTab` stays: the browser owns a pane (a day's tiles, a source list and
|
|
27499
|
+
* a player) and the Config tab's inner bar has no room for one. The widget
|
|
27500
|
+
* itself is `host/clips-browser` in ui-library's `HOST_WIDGETS`, and because
|
|
27501
|
+
* the admin Recordings page renders every `location:'top-tab'` +
|
|
27502
|
+
* `tab:'recording'` section behind its camera picker
|
|
27503
|
+
* (`CameraRecordingSettingsSection`), this declaration lands the section on
|
|
27504
|
+
* BOTH surfaces with no second wiring.
|
|
27505
|
+
*/
|
|
27506
|
+
deviceConfig: { ui: {
|
|
27507
|
+
kind: "widget",
|
|
27508
|
+
widgetId: "host/clips-browser",
|
|
27509
|
+
tab: "recording",
|
|
27510
|
+
topTab: true,
|
|
27511
|
+
label: "Clips",
|
|
27512
|
+
order: 100
|
|
27513
|
+
} },
|
|
27514
|
+
methods: {
|
|
27515
|
+
listClips: method(object({
|
|
27516
|
+
deviceId: number(),
|
|
27517
|
+
since: number(),
|
|
27518
|
+
until: number(),
|
|
27519
|
+
limit: number().int().positive().optional(),
|
|
27520
|
+
/**
|
|
27521
|
+
* WHICH provider to ask — the `addonId` a {@link ClipSourceSchema} row
|
|
27522
|
+
* carries, never a source id and never a list.
|
|
27523
|
+
*
|
|
27524
|
+
* Absent means the device's BOUND provider, which is CamStack on every
|
|
27525
|
+
* camera today because that is what `deviceManager.getBindings`
|
|
27526
|
+
* answers with. A provider the device is not bound to is refused by
|
|
27527
|
+
* name rather than answered by another one (D552's
|
|
27528
|
+
* `rejectUnresolvedAddonPin` rule).
|
|
27529
|
+
*
|
|
27530
|
+
* It replaced `sources?: string[]`, a VIEW filter over source ids that
|
|
27531
|
+
* assumed the answer was a fan-out over everything a camera has. The
|
|
27532
|
+
* operator settled otherwise on 2026-09-20 — *"il get videoclips
|
|
27533
|
+
* prendere un provider opzionale, di default va su camstack"*,
|
|
27534
|
+
* *"l'utilizzatore è uno solo"* — so the list is asked of one provider
|
|
27535
|
+
* at a time and there is nothing to filter out of it.
|
|
27536
|
+
*/
|
|
27537
|
+
provider: string().optional()
|
|
27538
|
+
}), array(ClipSchema).readonly(), {
|
|
27539
|
+
kind: "query",
|
|
27540
|
+
auth: "protected"
|
|
27541
|
+
}),
|
|
27542
|
+
/**
|
|
27543
|
+
* The sources this camera has, WITH the reason any of them cannot answer.
|
|
27544
|
+
*
|
|
27545
|
+
* Asked separately from `listClips` because an empty clip list is
|
|
27546
|
+
* ambiguous and this is the only place the ambiguity is resolved: every
|
|
27547
|
+
* bound provider contributes its own rows, and a provider that could not
|
|
27548
|
+
* be reached at all still produces one row saying so. A surface that draws
|
|
27549
|
+
* "no clips" without reading this is drawing a guess.
|
|
27550
|
+
*/
|
|
27551
|
+
listSources: method(object({ deviceId: number() }), array(ClipSourceSchema).readonly(), {
|
|
27552
|
+
kind: "query",
|
|
27553
|
+
auth: "protected"
|
|
27554
|
+
}),
|
|
27555
|
+
getClipPlayback: method(object({
|
|
27556
|
+
deviceId: number(),
|
|
27557
|
+
clipId: string(),
|
|
27558
|
+
/**
|
|
27559
|
+
* Which twin to serve, on the ONE quality scale the system already has
|
|
27560
|
+
* (`CamProfileSchema`). `low | mid` → the sub file, `high` → the main
|
|
27561
|
+
* twin; both ids are already on the row so this never re-searches the
|
|
27562
|
+
* camera. Absent means the provider's own default (the sub file, which
|
|
27563
|
+
* every source is measured to hold).
|
|
27564
|
+
*
|
|
27565
|
+
* `auto` is deliberately NOT accepted here: a stored file has no
|
|
27566
|
+
* broker session, so the adaptive tier cannot be resolved for it. The
|
|
27567
|
+
* viewer resolves `auto` to a profile the same way live does, before
|
|
27568
|
+
* it calls (D549 15).
|
|
27569
|
+
*/
|
|
27570
|
+
profile: CamProfileSchema.optional()
|
|
27571
|
+
}), ClipPlaybackSchema, {
|
|
27572
|
+
kind: "query",
|
|
27573
|
+
auth: "protected"
|
|
27574
|
+
})
|
|
27575
|
+
}
|
|
27576
|
+
};
|
|
27256
27577
|
/**
|
|
27257
27578
|
* Optional client-side hints sent at session creation to help the provider
|
|
27258
27579
|
* pick the best native source. All fields optional — a viewer that knows
|
|
@@ -39233,6 +39554,12 @@ Object.freeze({
|
|
|
39233
39554
|
addonId: null,
|
|
39234
39555
|
access: "view"
|
|
39235
39556
|
},
|
|
39557
|
+
"pipelineAnalytics.ownersWithMedia": {
|
|
39558
|
+
capName: "pipeline-analytics",
|
|
39559
|
+
capScope: "device",
|
|
39560
|
+
addonId: null,
|
|
39561
|
+
access: "view"
|
|
39562
|
+
},
|
|
39236
39563
|
"pipelineAnalytics.pauseForStorageMigration": {
|
|
39237
39564
|
capName: "pipeline-analytics",
|
|
39238
39565
|
capScope: "device",
|
|
@@ -41825,6 +42152,12 @@ Object.freeze({
|
|
|
41825
42152
|
addonId: null,
|
|
41826
42153
|
access: "view"
|
|
41827
42154
|
},
|
|
42155
|
+
"videoclips.listSources": {
|
|
42156
|
+
capName: "videoclips",
|
|
42157
|
+
capScope: "device",
|
|
42158
|
+
addonId: null,
|
|
42159
|
+
access: "view"
|
|
42160
|
+
},
|
|
41828
42161
|
"viewerUi.getStaticDir": {
|
|
41829
42162
|
capName: "viewer-ui",
|
|
41830
42163
|
capScope: "system",
|
|
@@ -43127,6 +43460,11 @@ Object.freeze({
|
|
|
43127
43460
|
form: "single",
|
|
43128
43461
|
optional: false
|
|
43129
43462
|
}],
|
|
43463
|
+
"pipelineAnalytics.ownersWithMedia": [{
|
|
43464
|
+
name: "deviceId",
|
|
43465
|
+
form: "single",
|
|
43466
|
+
optional: false
|
|
43467
|
+
}],
|
|
43130
43468
|
"pipelineAnalytics.proposeRetrainAnnotations": [{
|
|
43131
43469
|
name: "deviceId",
|
|
43132
43470
|
form: "single",
|
|
@@ -43833,6 +44171,11 @@ Object.freeze({
|
|
|
43833
44171
|
form: "single",
|
|
43834
44172
|
optional: false
|
|
43835
44173
|
}],
|
|
44174
|
+
"videoclips.listSources": [{
|
|
44175
|
+
name: "deviceId",
|
|
44176
|
+
form: "single",
|
|
44177
|
+
optional: false
|
|
44178
|
+
}],
|
|
43836
44179
|
"waterHeater.setAway": [{
|
|
43837
44180
|
name: "deviceId",
|
|
43838
44181
|
form: "single",
|
|
@@ -45712,6 +46055,18 @@ Object.defineProperty(exports, "DeviceType", {
|
|
|
45712
46055
|
return DeviceType;
|
|
45713
46056
|
}
|
|
45714
46057
|
});
|
|
46058
|
+
Object.defineProperty(exports, "EVENT_OWNER_TYPES", {
|
|
46059
|
+
enumerable: true,
|
|
46060
|
+
get: function() {
|
|
46061
|
+
return EVENT_OWNER_TYPES;
|
|
46062
|
+
}
|
|
46063
|
+
});
|
|
46064
|
+
Object.defineProperty(exports, "EVENT_PAD_MS", {
|
|
46065
|
+
enumerable: true,
|
|
46066
|
+
get: function() {
|
|
46067
|
+
return EVENT_PAD_MS;
|
|
46068
|
+
}
|
|
46069
|
+
});
|
|
45715
46070
|
Object.defineProperty(exports, "EncodeProfileSchema", {
|
|
45716
46071
|
enumerable: true,
|
|
45717
46072
|
get: function() {
|
|
@@ -45820,6 +46175,12 @@ Object.defineProperty(exports, "RingBuffer", {
|
|
|
45820
46175
|
return RingBuffer;
|
|
45821
46176
|
}
|
|
45822
46177
|
});
|
|
46178
|
+
Object.defineProperty(exports, "VISIT_MERGE_GAP_MS", {
|
|
46179
|
+
enumerable: true,
|
|
46180
|
+
get: function() {
|
|
46181
|
+
return VISIT_MERGE_GAP_MS;
|
|
46182
|
+
}
|
|
46183
|
+
});
|
|
45823
46184
|
Object.defineProperty(exports, "YAMNET_TO_MACRO", {
|
|
45824
46185
|
enumerable: true,
|
|
45825
46186
|
get: function() {
|
|
@@ -46354,6 +46715,12 @@ Object.defineProperty(exports, "union", {
|
|
|
46354
46715
|
return union;
|
|
46355
46716
|
}
|
|
46356
46717
|
});
|
|
46718
|
+
Object.defineProperty(exports, "videoclipsCapability", {
|
|
46719
|
+
enumerable: true,
|
|
46720
|
+
get: function() {
|
|
46721
|
+
return videoclipsCapability;
|
|
46722
|
+
}
|
|
46723
|
+
});
|
|
46357
46724
|
Object.defineProperty(exports, "webrtcSessionCapability", {
|
|
46358
46725
|
enumerable: true,
|
|
46359
46726
|
get: function() {
|
|
@@ -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-k6Vu-AhZ.js");
|
|
6
6
|
const require_lazy_sharp = require("../lazy-sharp-BuwKlQLR.js");
|
|
7
7
|
let node_fs = require("node:fs");
|
|
8
8
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $
|
|
1
|
+
import { $ as evaluateZoneRules, Jt as BaseAddon, Zt as DeviceType, ht as motionDetectionCapability, rn as hydrateSchema } from "../dist-g5MfpiBh.mjs";
|
|
2
2
|
import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-emK7D4bc.js");
|
|
2
|
-
const require_dist = require("./dist-
|
|
2
|
+
const require_dist = require("./dist-k6Vu-AhZ.js");
|
|
3
3
|
let node_crypto = require("node:crypto");
|
|
4
4
|
let node_fs = require("node:fs");
|
|
5
5
|
node_fs = require_chunk.__toESM(node_fs, 1);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Kt as isSoftwareDecode, Ut as Fmp4BoxSplitter, Vt as errMsg, Wt as buildFfmpegArgs } from "./dist-g5MfpiBh.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { realpathSync } from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
@@ -3,9 +3,9 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../chunk-emK7D4bc.js");
|
|
6
|
-
const require_dist = require("../dist-
|
|
7
|
-
const require_node = require("../node
|
|
8
|
-
const require_default_detection_model = require("../default-detection-model-
|
|
6
|
+
const require_dist = require("../dist-k6Vu-AhZ.js");
|
|
7
|
+
const require_node = require("../node--u_jUObS.js");
|
|
8
|
+
const require_default_detection_model = require("../default-detection-model-CAWhHQo2.js");
|
|
9
9
|
const require_worker_protocol = require("../worker-protocol-B2MfQLlu.js");
|
|
10
10
|
const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
|
|
11
11
|
const require_lazy_sharp = require("../lazy-sharp-BuwKlQLR.js");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { $ as
|
|
2
|
-
import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-
|
|
3
|
-
import { a as localFrameRegistry, d as getStepDefinition, i as rootObjectGate, o as resolveFrameViewGeometry, r as macroGateVerdict } from "../default-detection-model-
|
|
1
|
+
import { $t as createEvent, C as NativeLeaseAdmissionSchema, Ct as pipelineRunnerCapability, Jt as BaseAddon, K as deriveDetailCropRect, S as MOTION_CLOSE_AFTER_MS, Sn as string, Vt as errMsg, _n as literal, bt as pickDetailCropConvention, en as customAction, fn as _enum, gn as lazy, m as DEVICE_BACKEND_TO_FORMAT, mn as boolean, nt as failureContributionCapability, p as DEFAULT_NATIVE_LEASE_SETTINGS, pn as array, sn as nodePin, st as loadContributionCapability, tn as defineCustomActions, u as DEFAULT_DETAIL_CROP_CONVENTION, vn as number, w as NativeLeaseSettingsSchema, wn as EventCategory, xt as pickNativeLeaseOverride, y as FailureCounters, yn as object } from "../dist-g5MfpiBh.mjs";
|
|
2
|
+
import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-BXsHQH5h.mjs";
|
|
3
|
+
import { a as localFrameRegistry, d as getStepDefinition, i as rootObjectGate, o as resolveFrameViewGeometry, r as macroGateVerdict } from "../default-detection-model-BXwE-Dvo.mjs";
|
|
4
4
|
import { t as isWorkerReply } from "../worker-protocol-C_W-P_g-.mjs";
|
|
5
5
|
import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
|
|
6
6
|
import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-emK7D4bc.js");
|
|
2
|
-
const require_dist = require("./dist-
|
|
2
|
+
const require_dist = require("./dist-k6Vu-AhZ.js");
|
|
3
3
|
let node_fs = require("node:fs");
|
|
4
4
|
node_fs = require_chunk.__toESM(node_fs);
|
|
5
5
|
let node_child_process = require("node:child_process");
|