@camstack/addon-osd-manager 0.1.124 → 0.1.126
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/MotionZonesSettings-k6Zzbfy9.mjs +310 -0
- package/dist/{PrivacyMaskSettings-9rCXAZlR.mjs → PrivacyMaskSettings-DwhFoc16.mjs} +26 -26
- package/dist/{SceneMonitorEditor-D2ATIIZD.mjs → SceneMonitorEditor-DAqbVCgr.mjs} +295 -295
- package/dist/_stub.js +354 -354
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_osd_manager_page-B2cBM7jE.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_osd_manager_page-Dy_PTg0V.mjs} +3 -3
- package/dist/_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Ds-WCEP6.mjs +26 -0
- package/dist/addon-osd-manager.css +1 -1
- package/dist/{responsive-CC0j2h-d.mjs → cap-error-hton7JwR.mjs} +8 -8
- package/dist/{hostInit-Du2Me1GR.mjs → hostInit-D_FWYfaI.mjs} +2 -2
- package/dist/index.js +133 -85
- package/dist/index.mjs +133 -85
- package/dist/{player-overlays-CMeXfcep.mjs → player-overlays-CEidmNyu.mjs} +1 -1
- package/dist/remoteEntry.js +1 -1
- package/dist/{scene-monitor-copy-CjiHJ4pT.mjs → scene-monitor-copy-CLKtgPk1.mjs} +1 -1
- package/dist/{square-hvOcBhdH.mjs → square-Dq8X76sM.mjs} +1 -1
- package/dist/{trash-2-rb-x3jwf.mjs → trash-2-BYTSgKQu.mjs} +1 -1
- package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_osd_manager_page__remoteEntry_js-D8j_yb3G.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_osd_manager_page__remoteEntry_js-B9gGFib0.mjs} +1 -1
- package/package.json +1 -1
- package/dist/MotionZonesSettings-DOFOB5MX.mjs +0 -310
- package/dist/_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BK-eslgm.mjs +0 -26
|
@@ -36,7 +36,7 @@ async function r() {
|
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
"@camstack/types": {
|
|
39
|
-
version: "1.2.
|
|
39
|
+
version: "1.2.236",
|
|
40
40
|
scope: "default",
|
|
41
41
|
shareConfig: {
|
|
42
42
|
singleton: !0,
|
|
@@ -81,7 +81,7 @@ async function r() {
|
|
|
81
81
|
}
|
|
82
82
|
},
|
|
83
83
|
"@camstack/ui-library": {
|
|
84
|
-
version: "1.2.
|
|
84
|
+
version: "1.2.192",
|
|
85
85
|
scope: "default",
|
|
86
86
|
shareConfig: {
|
|
87
87
|
singleton: !0,
|
package/dist/index.js
CHANGED
|
@@ -5363,7 +5363,7 @@ var ZodIssueCode = {
|
|
|
5363
5363
|
var ZodFirstPartyTypeKind;
|
|
5364
5364
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5365
5365
|
//#endregion
|
|
5366
|
-
//#region ../types/dist/sleep-
|
|
5366
|
+
//#region ../types/dist/sleep-CaB_hL5g.mjs
|
|
5367
5367
|
/**
|
|
5368
5368
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5369
5369
|
* window to float samples (D455).
|
|
@@ -5563,12 +5563,6 @@ Object.fromEntries([
|
|
|
5563
5563
|
icon: "circle-dot",
|
|
5564
5564
|
order: 40
|
|
5565
5565
|
},
|
|
5566
|
-
{
|
|
5567
|
-
id: "clips",
|
|
5568
|
-
label: "Clips",
|
|
5569
|
-
icon: "clapperboard",
|
|
5570
|
-
order: 41
|
|
5571
|
-
},
|
|
5572
5566
|
{
|
|
5573
5567
|
id: "engine",
|
|
5574
5568
|
label: "Inference Engine",
|
|
@@ -7466,6 +7460,8 @@ var EVENT_OWNER_TYPES = [
|
|
|
7466
7460
|
* nothing failing until a caller asked.
|
|
7467
7461
|
*/
|
|
7468
7462
|
var EventOwnerTypeSchema = _enum(EVENT_OWNER_TYPES);
|
|
7463
|
+
/** The same list as a Zod enum, for the cap input that carries it. */
|
|
7464
|
+
var MediaPresenceOwnerKindSchema = _enum([...EVENT_OWNER_TYPES, "track"]);
|
|
7469
7465
|
new Set(EVENT_OWNER_TYPES);
|
|
7470
7466
|
var EncodeProfileSchema = object({
|
|
7471
7467
|
video: object({
|
|
@@ -15946,30 +15942,30 @@ var deviceManagerCapability = {
|
|
|
15946
15942
|
*/
|
|
15947
15943
|
getAllBindings: method(object({}), array(DeviceBindingsForDeviceSchema)),
|
|
15948
15944
|
/**
|
|
15949
|
-
* Activate (or deactivate) a wrapper addon
|
|
15950
|
-
* (
|
|
15951
|
-
*
|
|
15952
|
-
* Persists the binding via ctx.settings;
|
|
15953
|
-
* clears the wrapper (falling back to native if one is
|
|
15954
|
-
*
|
|
15955
|
-
*
|
|
15956
|
-
*
|
|
15957
|
-
*
|
|
15958
|
-
* `sourceId`
|
|
15959
|
-
*
|
|
15960
|
-
*
|
|
15961
|
-
*
|
|
15962
|
-
*
|
|
15963
|
-
*
|
|
15964
|
-
*
|
|
15965
|
-
*
|
|
15945
|
+
* Activate (or deactivate) a wrapper addon for a (device, cap) pair — the
|
|
15946
|
+
* per-camera function switch's ONE authority (D62).
|
|
15947
|
+
*
|
|
15948
|
+
* SINGLETON capabilities only. Persists the binding via ctx.settings;
|
|
15949
|
+
* `active: false` clears the wrapper (falling back to native if one is
|
|
15950
|
+
* registered) by persisting the explicit `{ wrapperAddonId: null }` marker,
|
|
15951
|
+
* which is what stops `getBindings` re-binding a `defaultActive` wrapper.
|
|
15952
|
+
*
|
|
15953
|
+
* **A COLLECTION capability is REFUSED by name.** It briefly took a
|
|
15954
|
+
* `sourceId` and wrote a per-device DENY set, so one of an addon's several
|
|
15955
|
+
* sources could be switched off without switching off the rest (D556, then
|
|
15956
|
+
* D555's re-key by source). The operator removed the whole idea the same
|
|
15957
|
+
* day: *"tutti i providers funzionano sempre, non serve
|
|
15958
|
+
* disattivarli/attivarli … loro vivono lì"* (D557 amended, third). A
|
|
15959
|
+
* collection cap's providers are a DERIVED set — every addon that provides
|
|
15960
|
+
* the cap for this device type, computed on every read and persisted
|
|
15961
|
+
* nowhere — so there is nothing here to activate, and a verb that accepted
|
|
15962
|
+
* the call could only write a field the enumeration does not read. That is
|
|
15963
|
+
* the D62 shape, and this repo has shipped it four times.
|
|
15966
15964
|
*/
|
|
15967
15965
|
setWrapperActive: method(object({
|
|
15968
15966
|
deviceId: number(),
|
|
15969
15967
|
capName: string(),
|
|
15970
15968
|
wrapperAddonId: string(),
|
|
15971
|
-
/** The `ClipSource.source` id to toggle. Absent = all of the addon's. */
|
|
15972
|
-
sourceId: string().optional(),
|
|
15973
15969
|
active: boolean()
|
|
15974
15970
|
}), _void(), {
|
|
15975
15971
|
kind: "mutation",
|
|
@@ -24913,6 +24909,35 @@ var pipelineAnalyticsCapability = {
|
|
|
24913
24909
|
deviceId: number()
|
|
24914
24910
|
}), array(MediaFileInfoSchema).readonly()),
|
|
24915
24911
|
/**
|
|
24912
|
+
* Which of `ownerIds` hold at least ONE media row — an INDEX read, never a
|
|
24913
|
+
* blob read, and the LICENCE `videoclips` needs to publish a `thumbnail`.
|
|
24914
|
+
*
|
|
24915
|
+
* The event-media URL is stamped from a template for every event in the
|
|
24916
|
+
* system, so "the plane is up" was being served as "there are bytes": 64 of
|
|
24917
|
+
* one camera's 179 clips pointed at a 404 (device 3836, 2026-08-17). This
|
|
24918
|
+
* is the question that turns the stamp into a claim.
|
|
24919
|
+
*
|
|
24920
|
+
* It is on the WIRE because the clip source is registered by the addon that
|
|
24921
|
+
* owns the FOOTAGE, not by this one (D560) — the probe used to be an
|
|
24922
|
+
* in-process `MediaStore` read. One call per OWNER KIND, never one per
|
|
24923
|
+
* owner: that N+1 is what `MediaStore.ownersWithMedia` was written to
|
|
24924
|
+
* prevent, and crossing a process boundary makes it worse, not better.
|
|
24925
|
+
* `ownerIds` is bounded at the same 5 000 the annotation fetch is bounded
|
|
24926
|
+
* at, so one pathological camera-day cannot mint an unbounded request.
|
|
24927
|
+
*
|
|
24928
|
+
* THROWS rather than answering partially. A probe that quietly
|
|
24929
|
+
* under-reports reads as "these owners have nothing" and the caller drops
|
|
24930
|
+
* thumbnails that exist — the opposite failure to the one above, and
|
|
24931
|
+
* equally invisible.
|
|
24932
|
+
*
|
|
24933
|
+
* `deviceId` is the authorization subject, exactly as on `getEventMedia`.
|
|
24934
|
+
*/
|
|
24935
|
+
ownersWithMedia: method(object({
|
|
24936
|
+
deviceId: number(),
|
|
24937
|
+
ownerKind: MediaPresenceOwnerKindSchema,
|
|
24938
|
+
ownerIds: array(string()).max(5e3)
|
|
24939
|
+
}), array(string()).readonly()),
|
|
24940
|
+
/**
|
|
24916
24941
|
* Search object events by text query using CLIP cosine similarity.
|
|
24917
24942
|
* Encodes `text` via the `embedding-encoder` cap, queries the
|
|
24918
24943
|
* `ObjectEmbeddingStore` with optional prefilters, ranks all matching
|
|
@@ -28966,6 +28991,18 @@ var vectorStoreCapability = {
|
|
|
28966
28991
|
stats: method(VectorStatsInputSchema, VectorStatsResultSchema, { auth: "admin" })
|
|
28967
28992
|
}
|
|
28968
28993
|
};
|
|
28994
|
+
_enum([
|
|
28995
|
+
"queue-full",
|
|
28996
|
+
"camera-backoff",
|
|
28997
|
+
"sleeping",
|
|
28998
|
+
"camera-refused",
|
|
28999
|
+
"no-keyframe",
|
|
29000
|
+
"no-catalog-row",
|
|
29001
|
+
"unsupported",
|
|
29002
|
+
"unknown-device",
|
|
29003
|
+
"uid-missing"
|
|
29004
|
+
]);
|
|
29005
|
+
_enum(["deferred", "final"]);
|
|
28969
29006
|
var ClipSchema = object({
|
|
28970
29007
|
/** Opaque, provider-namespaced id. The default provider encodes the time
|
|
28971
29008
|
* window so `getClipPlayback` is self-contained (no event re-query). */
|
|
@@ -29116,7 +29153,25 @@ var ClipSchema = object({
|
|
|
29116
29153
|
*/
|
|
29117
29154
|
playable: boolean().optional(),
|
|
29118
29155
|
/** Why {@link playable} is false, verbatim (`no-file-for-window`). */
|
|
29119
|
-
unplayableReason: string().optional()
|
|
29156
|
+
unplayableReason: string().optional(),
|
|
29157
|
+
/**
|
|
29158
|
+
* This clip is STILL BEING WRITTEN, so {@link ClipSchema.timeRange}`.endMs`
|
|
29159
|
+
* is not its end.
|
|
29160
|
+
*
|
|
29161
|
+
* Absent — the common case — means the row is closed and its `endMs` is the
|
|
29162
|
+
* end of the recording. Present and `true` means the source told us the file
|
|
29163
|
+
* has no end yet, and the `endMs` we carry is whatever the camera's index
|
|
29164
|
+
* entry happened to hold: on a Reolink E1 Outdoor PoE (592, measured
|
|
29165
|
+
* 2026-09-20) the newest file `…_192927_000000_…_0.mp4` reported an `endTime`
|
|
29166
|
+
* of 19:29:56 and STILL reported it eight minutes later, while the file went
|
|
29167
|
+
* on growing. A surface that drew 29 s there was lying about a clip that
|
|
29168
|
+
* plays for minutes, on the one row the operator looks at first.
|
|
29169
|
+
*
|
|
29170
|
+
* `endMs` is deliberately still a number: it is the best bound anything has
|
|
29171
|
+
* for a mint window or a byte fetch, and every consumer already requires it.
|
|
29172
|
+
* This flag says what it is WORTH, and a duration is not drawn from it.
|
|
29173
|
+
*/
|
|
29174
|
+
inProgress: boolean().optional()
|
|
29120
29175
|
});
|
|
29121
29176
|
var ClipPlaybackSchema = object({
|
|
29122
29177
|
/**
|
|
@@ -29199,59 +29254,17 @@ var ClipSourceSchema = object({
|
|
|
29199
29254
|
* alternative — a `native:reolink:* → provider-reolink` table inside the
|
|
29200
29255
|
* widget — is a second authority on provider identity living in the one
|
|
29201
29256
|
* package with no business knowing it, wrong the day a third source appears
|
|
29202
|
-
* (D557). One addon may serve SEVERAL sources
|
|
29203
|
-
*
|
|
29204
|
-
*
|
|
29205
|
-
*
|
|
29257
|
+
* (D557). One addon may serve SEVERAL sources, which is why the per-device
|
|
29258
|
+
* switch is keyed by SOURCE and not by this (D555) — `addon-provider-reolink`
|
|
29259
|
+
* served a hub child two of them until the two views were measured to be one
|
|
29260
|
+
* store read twice (D555) and then read ONE way (D565).
|
|
29206
29261
|
*
|
|
29207
29262
|
* Optional for version skew only. The collection dispatcher stamps it from
|
|
29208
29263
|
* the registry, so a row that travelled through the fan-out carries the
|
|
29209
29264
|
* authoritative id whatever the provider filled in.
|
|
29210
29265
|
*/
|
|
29211
29266
|
addonId: string().optional(),
|
|
29212
|
-
|
|
29213
|
-
* Which API this source resolved to FOR THIS CAMERA, when it has a choice.
|
|
29214
|
-
*
|
|
29215
|
-
* A source may cover one store through more than one surface — the Reolink
|
|
29216
|
-
* provider reads a hub child through the parent's event log and a standalone
|
|
29217
|
-
* through its own file list, because that is what each camera answers. The
|
|
29218
|
-
* CHOICE is the provider's, made from what the camera is, and is never a row
|
|
29219
|
-
* the operator has to understand; but it is REPORTED, because a source that
|
|
29220
|
-
* silently reads a different API on two cameras and then behaves differently
|
|
29221
|
-
* is the thing nobody can debug later. Absent when the source has only one
|
|
29222
|
-
* way to read its store.
|
|
29223
|
-
*/
|
|
29224
|
-
via: string().optional(),
|
|
29225
|
-
availability: ClipSourceAvailabilitySchema,
|
|
29226
|
-
/**
|
|
29227
|
-
* The operator switched this source OFF for this camera.
|
|
29228
|
-
*
|
|
29229
|
-
* Deliberately NOT a member of {@link ClipSourceAvailabilitySchema}'s
|
|
29230
|
-
* vocabulary. That enum models what the source CAN do — a sleeping camera, an
|
|
29231
|
-
* unmounted card, an index that disagrees with its own calendar — and a
|
|
29232
|
-
* switched-off source could answer perfectly well; the operator decided it
|
|
29233
|
-
* should not. Folding the choice in is how `disabled` and `broken` stop being
|
|
29234
|
-
* distinguishable, which is the D62 rule this repo has already paid for twice:
|
|
29235
|
-
* an off switch is REPORTED off (`CameraStatus.switchedOff`, the same word),
|
|
29236
|
-
* and disabled must never look like broken. It is also what lets every
|
|
29237
|
-
* exhaustive consumer of the availability enum keep compiling.
|
|
29238
|
-
*
|
|
29239
|
-
* A switched-off source contributes NO clips (`listClips` never calls it) and
|
|
29240
|
-
* its row carries no `catalogAsOf`: nothing confirms a catalog it is not
|
|
29241
|
-
* allowed to serve, and a frozen age that can only grow draws a stalling
|
|
29242
|
-
* source rather than an off switch.
|
|
29243
|
-
*
|
|
29244
|
-
* The row survives BECAUSE it is the control the operator switches the source
|
|
29245
|
-
* back on from — D554 decision 4's rule ("a source that cannot answer
|
|
29246
|
-
* produces a ROW, not an absence") applied to the one case D556 carved out of
|
|
29247
|
-
* it, and D557's own kept property ("a source is never hidden, only its
|
|
29248
|
-
* rows"). Absent means on.
|
|
29249
|
-
*
|
|
29250
|
-
* A provider never sets this — like {@link ClipSourceSchema.addonId} it is
|
|
29251
|
-
* stamped by the collection dispatcher, which holds the registry's projection
|
|
29252
|
-
* of the persisted authority (D556) and is the only place that knows it.
|
|
29253
|
-
*/
|
|
29254
|
-
switchedOff: boolean().optional()
|
|
29267
|
+
availability: ClipSourceAvailabilitySchema
|
|
29255
29268
|
});
|
|
29256
29269
|
var videoclipsCapability = {
|
|
29257
29270
|
name: "videoclips",
|
|
@@ -29271,17 +29284,31 @@ var videoclipsCapability = {
|
|
|
29271
29284
|
* `device-config-widget-wrapped-binding.spec.ts` pins that a `kind:'wrapped'`
|
|
29272
29285
|
* binding entry derives the same section a native one does.
|
|
29273
29286
|
*
|
|
29274
|
-
*
|
|
29275
|
-
*
|
|
29276
|
-
*
|
|
29287
|
+
* **It is a SECTION of the Recording tab, at the end of it — not a tab of
|
|
29288
|
+
* its own.** It shipped as a `clips` top-tab and the operator rejected the
|
|
29289
|
+
* placement: *"utilizzerei la stessa tab recordings, lì abbiamo già tutto il
|
|
29290
|
+
* necessario, una nuova sezione alla fine per le clips"*. The Recording tab
|
|
29291
|
+
* already holds the recorder's panel, the schedule bands and the unified
|
|
29292
|
+
* retention policy; footage the camera itself holds is the same question,
|
|
29293
|
+
* asked of a different store. `order: 100` puts it after all of them with
|
|
29294
|
+
* room left in front. The `clips` entry in `WELL_KNOWN_TABS` went with it —
|
|
29295
|
+
* a well-known id nobody declares is an invitation to mint the tab again.
|
|
29296
|
+
*
|
|
29297
|
+
* `topTab` stays: the browser owns a pane (a day's tiles, a source list and
|
|
29298
|
+
* a player) and the Config tab's inner bar has no room for one. The widget
|
|
29299
|
+
* itself is `host/clips-browser` in ui-library's `HOST_WIDGETS`, and because
|
|
29300
|
+
* the admin Recordings page renders every `location:'top-tab'` +
|
|
29301
|
+
* `tab:'recording'` section behind its camera picker
|
|
29302
|
+
* (`CameraRecordingSettingsSection`), this declaration lands the section on
|
|
29303
|
+
* BOTH surfaces with no second wiring.
|
|
29277
29304
|
*/
|
|
29278
29305
|
deviceConfig: { ui: {
|
|
29279
29306
|
kind: "widget",
|
|
29280
29307
|
widgetId: "host/clips-browser",
|
|
29281
|
-
tab: "
|
|
29308
|
+
tab: "recording",
|
|
29282
29309
|
topTab: true,
|
|
29283
29310
|
label: "Clips",
|
|
29284
|
-
order:
|
|
29311
|
+
order: 100
|
|
29285
29312
|
} },
|
|
29286
29313
|
methods: {
|
|
29287
29314
|
listClips: method(object({
|
|
@@ -29290,13 +29317,23 @@ var videoclipsCapability = {
|
|
|
29290
29317
|
until: number(),
|
|
29291
29318
|
limit: number().int().positive().optional(),
|
|
29292
29319
|
/**
|
|
29293
|
-
*
|
|
29294
|
-
*
|
|
29295
|
-
*
|
|
29296
|
-
*
|
|
29297
|
-
*
|
|
29320
|
+
* WHICH provider to ask — the `addonId` a {@link ClipSourceSchema} row
|
|
29321
|
+
* carries, never a source id and never a list.
|
|
29322
|
+
*
|
|
29323
|
+
* Absent means the device's BOUND provider, which is CamStack on every
|
|
29324
|
+
* camera today because that is what `deviceManager.getBindings`
|
|
29325
|
+
* answers with. A provider the device is not bound to is refused by
|
|
29326
|
+
* name rather than answered by another one (D552's
|
|
29327
|
+
* `rejectUnresolvedAddonPin` rule).
|
|
29328
|
+
*
|
|
29329
|
+
* It replaced `sources?: string[]`, a VIEW filter over source ids that
|
|
29330
|
+
* assumed the answer was a fan-out over everything a camera has. The
|
|
29331
|
+
* operator settled otherwise on 2026-09-20 — *"il get videoclips
|
|
29332
|
+
* prendere un provider opzionale, di default va su camstack"*,
|
|
29333
|
+
* *"l'utilizzatore è uno solo"* — so the list is asked of one provider
|
|
29334
|
+
* at a time and there is nothing to filter out of it.
|
|
29298
29335
|
*/
|
|
29299
|
-
|
|
29336
|
+
provider: string().optional()
|
|
29300
29337
|
}), array(ClipSchema).readonly(), {
|
|
29301
29338
|
kind: "query",
|
|
29302
29339
|
auth: "protected"
|
|
@@ -44834,6 +44871,12 @@ Object.freeze({
|
|
|
44834
44871
|
addonId: null,
|
|
44835
44872
|
access: "view"
|
|
44836
44873
|
},
|
|
44874
|
+
"pipelineAnalytics.ownersWithMedia": {
|
|
44875
|
+
capName: "pipeline-analytics",
|
|
44876
|
+
capScope: "device",
|
|
44877
|
+
addonId: null,
|
|
44878
|
+
access: "view"
|
|
44879
|
+
},
|
|
44837
44880
|
"pipelineAnalytics.pauseForStorageMigration": {
|
|
44838
44881
|
capName: "pipeline-analytics",
|
|
44839
44882
|
capScope: "device",
|
|
@@ -48734,6 +48777,11 @@ Object.freeze({
|
|
|
48734
48777
|
form: "single",
|
|
48735
48778
|
optional: false
|
|
48736
48779
|
}],
|
|
48780
|
+
"pipelineAnalytics.ownersWithMedia": [{
|
|
48781
|
+
name: "deviceId",
|
|
48782
|
+
form: "single",
|
|
48783
|
+
optional: false
|
|
48784
|
+
}],
|
|
48737
48785
|
"pipelineAnalytics.proposeRetrainAnnotations": [{
|
|
48738
48786
|
name: "deviceId",
|
|
48739
48787
|
form: "single",
|
package/dist/index.mjs
CHANGED
|
@@ -5359,7 +5359,7 @@ var ZodIssueCode = {
|
|
|
5359
5359
|
var ZodFirstPartyTypeKind;
|
|
5360
5360
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5361
5361
|
//#endregion
|
|
5362
|
-
//#region ../types/dist/sleep-
|
|
5362
|
+
//#region ../types/dist/sleep-CaB_hL5g.mjs
|
|
5363
5363
|
/**
|
|
5364
5364
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5365
5365
|
* window to float samples (D455).
|
|
@@ -5559,12 +5559,6 @@ Object.fromEntries([
|
|
|
5559
5559
|
icon: "circle-dot",
|
|
5560
5560
|
order: 40
|
|
5561
5561
|
},
|
|
5562
|
-
{
|
|
5563
|
-
id: "clips",
|
|
5564
|
-
label: "Clips",
|
|
5565
|
-
icon: "clapperboard",
|
|
5566
|
-
order: 41
|
|
5567
|
-
},
|
|
5568
5562
|
{
|
|
5569
5563
|
id: "engine",
|
|
5570
5564
|
label: "Inference Engine",
|
|
@@ -7462,6 +7456,8 @@ var EVENT_OWNER_TYPES = [
|
|
|
7462
7456
|
* nothing failing until a caller asked.
|
|
7463
7457
|
*/
|
|
7464
7458
|
var EventOwnerTypeSchema = _enum(EVENT_OWNER_TYPES);
|
|
7459
|
+
/** The same list as a Zod enum, for the cap input that carries it. */
|
|
7460
|
+
var MediaPresenceOwnerKindSchema = _enum([...EVENT_OWNER_TYPES, "track"]);
|
|
7465
7461
|
new Set(EVENT_OWNER_TYPES);
|
|
7466
7462
|
var EncodeProfileSchema = object({
|
|
7467
7463
|
video: object({
|
|
@@ -15942,30 +15938,30 @@ var deviceManagerCapability = {
|
|
|
15942
15938
|
*/
|
|
15943
15939
|
getAllBindings: method(object({}), array(DeviceBindingsForDeviceSchema)),
|
|
15944
15940
|
/**
|
|
15945
|
-
* Activate (or deactivate) a wrapper addon
|
|
15946
|
-
* (
|
|
15947
|
-
*
|
|
15948
|
-
* Persists the binding via ctx.settings;
|
|
15949
|
-
* clears the wrapper (falling back to native if one is
|
|
15950
|
-
*
|
|
15951
|
-
*
|
|
15952
|
-
*
|
|
15953
|
-
*
|
|
15954
|
-
* `sourceId`
|
|
15955
|
-
*
|
|
15956
|
-
*
|
|
15957
|
-
*
|
|
15958
|
-
*
|
|
15959
|
-
*
|
|
15960
|
-
*
|
|
15961
|
-
*
|
|
15941
|
+
* Activate (or deactivate) a wrapper addon for a (device, cap) pair — the
|
|
15942
|
+
* per-camera function switch's ONE authority (D62).
|
|
15943
|
+
*
|
|
15944
|
+
* SINGLETON capabilities only. Persists the binding via ctx.settings;
|
|
15945
|
+
* `active: false` clears the wrapper (falling back to native if one is
|
|
15946
|
+
* registered) by persisting the explicit `{ wrapperAddonId: null }` marker,
|
|
15947
|
+
* which is what stops `getBindings` re-binding a `defaultActive` wrapper.
|
|
15948
|
+
*
|
|
15949
|
+
* **A COLLECTION capability is REFUSED by name.** It briefly took a
|
|
15950
|
+
* `sourceId` and wrote a per-device DENY set, so one of an addon's several
|
|
15951
|
+
* sources could be switched off without switching off the rest (D556, then
|
|
15952
|
+
* D555's re-key by source). The operator removed the whole idea the same
|
|
15953
|
+
* day: *"tutti i providers funzionano sempre, non serve
|
|
15954
|
+
* disattivarli/attivarli … loro vivono lì"* (D557 amended, third). A
|
|
15955
|
+
* collection cap's providers are a DERIVED set — every addon that provides
|
|
15956
|
+
* the cap for this device type, computed on every read and persisted
|
|
15957
|
+
* nowhere — so there is nothing here to activate, and a verb that accepted
|
|
15958
|
+
* the call could only write a field the enumeration does not read. That is
|
|
15959
|
+
* the D62 shape, and this repo has shipped it four times.
|
|
15962
15960
|
*/
|
|
15963
15961
|
setWrapperActive: method(object({
|
|
15964
15962
|
deviceId: number(),
|
|
15965
15963
|
capName: string(),
|
|
15966
15964
|
wrapperAddonId: string(),
|
|
15967
|
-
/** The `ClipSource.source` id to toggle. Absent = all of the addon's. */
|
|
15968
|
-
sourceId: string().optional(),
|
|
15969
15965
|
active: boolean()
|
|
15970
15966
|
}), _void(), {
|
|
15971
15967
|
kind: "mutation",
|
|
@@ -24909,6 +24905,35 @@ var pipelineAnalyticsCapability = {
|
|
|
24909
24905
|
deviceId: number()
|
|
24910
24906
|
}), array(MediaFileInfoSchema).readonly()),
|
|
24911
24907
|
/**
|
|
24908
|
+
* Which of `ownerIds` hold at least ONE media row — an INDEX read, never a
|
|
24909
|
+
* blob read, and the LICENCE `videoclips` needs to publish a `thumbnail`.
|
|
24910
|
+
*
|
|
24911
|
+
* The event-media URL is stamped from a template for every event in the
|
|
24912
|
+
* system, so "the plane is up" was being served as "there are bytes": 64 of
|
|
24913
|
+
* one camera's 179 clips pointed at a 404 (device 3836, 2026-08-17). This
|
|
24914
|
+
* is the question that turns the stamp into a claim.
|
|
24915
|
+
*
|
|
24916
|
+
* It is on the WIRE because the clip source is registered by the addon that
|
|
24917
|
+
* owns the FOOTAGE, not by this one (D560) — the probe used to be an
|
|
24918
|
+
* in-process `MediaStore` read. One call per OWNER KIND, never one per
|
|
24919
|
+
* owner: that N+1 is what `MediaStore.ownersWithMedia` was written to
|
|
24920
|
+
* prevent, and crossing a process boundary makes it worse, not better.
|
|
24921
|
+
* `ownerIds` is bounded at the same 5 000 the annotation fetch is bounded
|
|
24922
|
+
* at, so one pathological camera-day cannot mint an unbounded request.
|
|
24923
|
+
*
|
|
24924
|
+
* THROWS rather than answering partially. A probe that quietly
|
|
24925
|
+
* under-reports reads as "these owners have nothing" and the caller drops
|
|
24926
|
+
* thumbnails that exist — the opposite failure to the one above, and
|
|
24927
|
+
* equally invisible.
|
|
24928
|
+
*
|
|
24929
|
+
* `deviceId` is the authorization subject, exactly as on `getEventMedia`.
|
|
24930
|
+
*/
|
|
24931
|
+
ownersWithMedia: method(object({
|
|
24932
|
+
deviceId: number(),
|
|
24933
|
+
ownerKind: MediaPresenceOwnerKindSchema,
|
|
24934
|
+
ownerIds: array(string()).max(5e3)
|
|
24935
|
+
}), array(string()).readonly()),
|
|
24936
|
+
/**
|
|
24912
24937
|
* Search object events by text query using CLIP cosine similarity.
|
|
24913
24938
|
* Encodes `text` via the `embedding-encoder` cap, queries the
|
|
24914
24939
|
* `ObjectEmbeddingStore` with optional prefilters, ranks all matching
|
|
@@ -28962,6 +28987,18 @@ var vectorStoreCapability = {
|
|
|
28962
28987
|
stats: method(VectorStatsInputSchema, VectorStatsResultSchema, { auth: "admin" })
|
|
28963
28988
|
}
|
|
28964
28989
|
};
|
|
28990
|
+
_enum([
|
|
28991
|
+
"queue-full",
|
|
28992
|
+
"camera-backoff",
|
|
28993
|
+
"sleeping",
|
|
28994
|
+
"camera-refused",
|
|
28995
|
+
"no-keyframe",
|
|
28996
|
+
"no-catalog-row",
|
|
28997
|
+
"unsupported",
|
|
28998
|
+
"unknown-device",
|
|
28999
|
+
"uid-missing"
|
|
29000
|
+
]);
|
|
29001
|
+
_enum(["deferred", "final"]);
|
|
28965
29002
|
var ClipSchema = object({
|
|
28966
29003
|
/** Opaque, provider-namespaced id. The default provider encodes the time
|
|
28967
29004
|
* window so `getClipPlayback` is self-contained (no event re-query). */
|
|
@@ -29112,7 +29149,25 @@ var ClipSchema = object({
|
|
|
29112
29149
|
*/
|
|
29113
29150
|
playable: boolean().optional(),
|
|
29114
29151
|
/** Why {@link playable} is false, verbatim (`no-file-for-window`). */
|
|
29115
|
-
unplayableReason: string().optional()
|
|
29152
|
+
unplayableReason: string().optional(),
|
|
29153
|
+
/**
|
|
29154
|
+
* This clip is STILL BEING WRITTEN, so {@link ClipSchema.timeRange}`.endMs`
|
|
29155
|
+
* is not its end.
|
|
29156
|
+
*
|
|
29157
|
+
* Absent — the common case — means the row is closed and its `endMs` is the
|
|
29158
|
+
* end of the recording. Present and `true` means the source told us the file
|
|
29159
|
+
* has no end yet, and the `endMs` we carry is whatever the camera's index
|
|
29160
|
+
* entry happened to hold: on a Reolink E1 Outdoor PoE (592, measured
|
|
29161
|
+
* 2026-09-20) the newest file `…_192927_000000_…_0.mp4` reported an `endTime`
|
|
29162
|
+
* of 19:29:56 and STILL reported it eight minutes later, while the file went
|
|
29163
|
+
* on growing. A surface that drew 29 s there was lying about a clip that
|
|
29164
|
+
* plays for minutes, on the one row the operator looks at first.
|
|
29165
|
+
*
|
|
29166
|
+
* `endMs` is deliberately still a number: it is the best bound anything has
|
|
29167
|
+
* for a mint window or a byte fetch, and every consumer already requires it.
|
|
29168
|
+
* This flag says what it is WORTH, and a duration is not drawn from it.
|
|
29169
|
+
*/
|
|
29170
|
+
inProgress: boolean().optional()
|
|
29116
29171
|
});
|
|
29117
29172
|
var ClipPlaybackSchema = object({
|
|
29118
29173
|
/**
|
|
@@ -29195,59 +29250,17 @@ var ClipSourceSchema = object({
|
|
|
29195
29250
|
* alternative — a `native:reolink:* → provider-reolink` table inside the
|
|
29196
29251
|
* widget — is a second authority on provider identity living in the one
|
|
29197
29252
|
* package with no business knowing it, wrong the day a third source appears
|
|
29198
|
-
* (D557). One addon may serve SEVERAL sources
|
|
29199
|
-
*
|
|
29200
|
-
*
|
|
29201
|
-
*
|
|
29253
|
+
* (D557). One addon may serve SEVERAL sources, which is why the per-device
|
|
29254
|
+
* switch is keyed by SOURCE and not by this (D555) — `addon-provider-reolink`
|
|
29255
|
+
* served a hub child two of them until the two views were measured to be one
|
|
29256
|
+
* store read twice (D555) and then read ONE way (D565).
|
|
29202
29257
|
*
|
|
29203
29258
|
* Optional for version skew only. The collection dispatcher stamps it from
|
|
29204
29259
|
* the registry, so a row that travelled through the fan-out carries the
|
|
29205
29260
|
* authoritative id whatever the provider filled in.
|
|
29206
29261
|
*/
|
|
29207
29262
|
addonId: string().optional(),
|
|
29208
|
-
|
|
29209
|
-
* Which API this source resolved to FOR THIS CAMERA, when it has a choice.
|
|
29210
|
-
*
|
|
29211
|
-
* A source may cover one store through more than one surface — the Reolink
|
|
29212
|
-
* provider reads a hub child through the parent's event log and a standalone
|
|
29213
|
-
* through its own file list, because that is what each camera answers. The
|
|
29214
|
-
* CHOICE is the provider's, made from what the camera is, and is never a row
|
|
29215
|
-
* the operator has to understand; but it is REPORTED, because a source that
|
|
29216
|
-
* silently reads a different API on two cameras and then behaves differently
|
|
29217
|
-
* is the thing nobody can debug later. Absent when the source has only one
|
|
29218
|
-
* way to read its store.
|
|
29219
|
-
*/
|
|
29220
|
-
via: string().optional(),
|
|
29221
|
-
availability: ClipSourceAvailabilitySchema,
|
|
29222
|
-
/**
|
|
29223
|
-
* The operator switched this source OFF for this camera.
|
|
29224
|
-
*
|
|
29225
|
-
* Deliberately NOT a member of {@link ClipSourceAvailabilitySchema}'s
|
|
29226
|
-
* vocabulary. That enum models what the source CAN do — a sleeping camera, an
|
|
29227
|
-
* unmounted card, an index that disagrees with its own calendar — and a
|
|
29228
|
-
* switched-off source could answer perfectly well; the operator decided it
|
|
29229
|
-
* should not. Folding the choice in is how `disabled` and `broken` stop being
|
|
29230
|
-
* distinguishable, which is the D62 rule this repo has already paid for twice:
|
|
29231
|
-
* an off switch is REPORTED off (`CameraStatus.switchedOff`, the same word),
|
|
29232
|
-
* and disabled must never look like broken. It is also what lets every
|
|
29233
|
-
* exhaustive consumer of the availability enum keep compiling.
|
|
29234
|
-
*
|
|
29235
|
-
* A switched-off source contributes NO clips (`listClips` never calls it) and
|
|
29236
|
-
* its row carries no `catalogAsOf`: nothing confirms a catalog it is not
|
|
29237
|
-
* allowed to serve, and a frozen age that can only grow draws a stalling
|
|
29238
|
-
* source rather than an off switch.
|
|
29239
|
-
*
|
|
29240
|
-
* The row survives BECAUSE it is the control the operator switches the source
|
|
29241
|
-
* back on from — D554 decision 4's rule ("a source that cannot answer
|
|
29242
|
-
* produces a ROW, not an absence") applied to the one case D556 carved out of
|
|
29243
|
-
* it, and D557's own kept property ("a source is never hidden, only its
|
|
29244
|
-
* rows"). Absent means on.
|
|
29245
|
-
*
|
|
29246
|
-
* A provider never sets this — like {@link ClipSourceSchema.addonId} it is
|
|
29247
|
-
* stamped by the collection dispatcher, which holds the registry's projection
|
|
29248
|
-
* of the persisted authority (D556) and is the only place that knows it.
|
|
29249
|
-
*/
|
|
29250
|
-
switchedOff: boolean().optional()
|
|
29263
|
+
availability: ClipSourceAvailabilitySchema
|
|
29251
29264
|
});
|
|
29252
29265
|
var videoclipsCapability = {
|
|
29253
29266
|
name: "videoclips",
|
|
@@ -29267,17 +29280,31 @@ var videoclipsCapability = {
|
|
|
29267
29280
|
* `device-config-widget-wrapped-binding.spec.ts` pins that a `kind:'wrapped'`
|
|
29268
29281
|
* binding entry derives the same section a native one does.
|
|
29269
29282
|
*
|
|
29270
|
-
*
|
|
29271
|
-
*
|
|
29272
|
-
*
|
|
29283
|
+
* **It is a SECTION of the Recording tab, at the end of it — not a tab of
|
|
29284
|
+
* its own.** It shipped as a `clips` top-tab and the operator rejected the
|
|
29285
|
+
* placement: *"utilizzerei la stessa tab recordings, lì abbiamo già tutto il
|
|
29286
|
+
* necessario, una nuova sezione alla fine per le clips"*. The Recording tab
|
|
29287
|
+
* already holds the recorder's panel, the schedule bands and the unified
|
|
29288
|
+
* retention policy; footage the camera itself holds is the same question,
|
|
29289
|
+
* asked of a different store. `order: 100` puts it after all of them with
|
|
29290
|
+
* room left in front. The `clips` entry in `WELL_KNOWN_TABS` went with it —
|
|
29291
|
+
* a well-known id nobody declares is an invitation to mint the tab again.
|
|
29292
|
+
*
|
|
29293
|
+
* `topTab` stays: the browser owns a pane (a day's tiles, a source list and
|
|
29294
|
+
* a player) and the Config tab's inner bar has no room for one. The widget
|
|
29295
|
+
* itself is `host/clips-browser` in ui-library's `HOST_WIDGETS`, and because
|
|
29296
|
+
* the admin Recordings page renders every `location:'top-tab'` +
|
|
29297
|
+
* `tab:'recording'` section behind its camera picker
|
|
29298
|
+
* (`CameraRecordingSettingsSection`), this declaration lands the section on
|
|
29299
|
+
* BOTH surfaces with no second wiring.
|
|
29273
29300
|
*/
|
|
29274
29301
|
deviceConfig: { ui: {
|
|
29275
29302
|
kind: "widget",
|
|
29276
29303
|
widgetId: "host/clips-browser",
|
|
29277
|
-
tab: "
|
|
29304
|
+
tab: "recording",
|
|
29278
29305
|
topTab: true,
|
|
29279
29306
|
label: "Clips",
|
|
29280
|
-
order:
|
|
29307
|
+
order: 100
|
|
29281
29308
|
} },
|
|
29282
29309
|
methods: {
|
|
29283
29310
|
listClips: method(object({
|
|
@@ -29286,13 +29313,23 @@ var videoclipsCapability = {
|
|
|
29286
29313
|
until: number(),
|
|
29287
29314
|
limit: number().int().positive().optional(),
|
|
29288
29315
|
/**
|
|
29289
|
-
*
|
|
29290
|
-
*
|
|
29291
|
-
*
|
|
29292
|
-
*
|
|
29293
|
-
*
|
|
29316
|
+
* WHICH provider to ask — the `addonId` a {@link ClipSourceSchema} row
|
|
29317
|
+
* carries, never a source id and never a list.
|
|
29318
|
+
*
|
|
29319
|
+
* Absent means the device's BOUND provider, which is CamStack on every
|
|
29320
|
+
* camera today because that is what `deviceManager.getBindings`
|
|
29321
|
+
* answers with. A provider the device is not bound to is refused by
|
|
29322
|
+
* name rather than answered by another one (D552's
|
|
29323
|
+
* `rejectUnresolvedAddonPin` rule).
|
|
29324
|
+
*
|
|
29325
|
+
* It replaced `sources?: string[]`, a VIEW filter over source ids that
|
|
29326
|
+
* assumed the answer was a fan-out over everything a camera has. The
|
|
29327
|
+
* operator settled otherwise on 2026-09-20 — *"il get videoclips
|
|
29328
|
+
* prendere un provider opzionale, di default va su camstack"*,
|
|
29329
|
+
* *"l'utilizzatore è uno solo"* — so the list is asked of one provider
|
|
29330
|
+
* at a time and there is nothing to filter out of it.
|
|
29294
29331
|
*/
|
|
29295
|
-
|
|
29332
|
+
provider: string().optional()
|
|
29296
29333
|
}), array(ClipSchema).readonly(), {
|
|
29297
29334
|
kind: "query",
|
|
29298
29335
|
auth: "protected"
|
|
@@ -44830,6 +44867,12 @@ Object.freeze({
|
|
|
44830
44867
|
addonId: null,
|
|
44831
44868
|
access: "view"
|
|
44832
44869
|
},
|
|
44870
|
+
"pipelineAnalytics.ownersWithMedia": {
|
|
44871
|
+
capName: "pipeline-analytics",
|
|
44872
|
+
capScope: "device",
|
|
44873
|
+
addonId: null,
|
|
44874
|
+
access: "view"
|
|
44875
|
+
},
|
|
44833
44876
|
"pipelineAnalytics.pauseForStorageMigration": {
|
|
44834
44877
|
capName: "pipeline-analytics",
|
|
44835
44878
|
capScope: "device",
|
|
@@ -48730,6 +48773,11 @@ Object.freeze({
|
|
|
48730
48773
|
form: "single",
|
|
48731
48774
|
optional: false
|
|
48732
48775
|
}],
|
|
48776
|
+
"pipelineAnalytics.ownersWithMedia": [{
|
|
48777
|
+
name: "deviceId",
|
|
48778
|
+
form: "single",
|
|
48779
|
+
optional: false
|
|
48780
|
+
}],
|
|
48733
48781
|
"pipelineAnalytics.proposeRetrainAnnotations": [{
|
|
48734
48782
|
name: "deviceId",
|
|
48735
48783
|
form: "single",
|