@camstack/addon-pipeline 0.1.17 → 0.1.19
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 +8 -3
- package/dist/audio-analyzer/index.js.map +1 -1
- package/dist/audio-analyzer/index.mjs +8 -3
- package/dist/audio-analyzer/index.mjs.map +1 -1
- package/dist/audio-codec-nodeav/index.js +1 -1
- package/dist/audio-codec-nodeav/index.mjs +1 -1
- package/dist/decoder-nodeav/index.js +1 -1
- package/dist/decoder-nodeav/index.mjs +1 -1
- package/dist/detection-pipeline/index.js +23 -20
- package/dist/detection-pipeline/index.js.map +1 -1
- package/dist/detection-pipeline/index.mjs +23 -20
- package/dist/detection-pipeline/index.mjs.map +1 -1
- package/dist/{index-p-6GfKOg.js → index-BbPPvoCx.js} +469 -57
- package/dist/index-BbPPvoCx.js.map +1 -0
- package/dist/{index-CVzLrojg.mjs → index-Bmlkm0Fd.mjs} +469 -57
- package/dist/index-Bmlkm0Fd.mjs.map +1 -0
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/pipeline-runner/index.js +132 -14
- package/dist/pipeline-runner/index.js.map +1 -1
- package/dist/pipeline-runner/index.mjs +133 -15
- package/dist/pipeline-runner/index.mjs.map +1 -1
- package/dist/stream-broker/@mf-types.zip +0 -0
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.mjs-NjF4kxzW.mjs +19 -0
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-BAv_5ISf.mjs +20 -0
- package/dist/stream-broker/{__mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs-DAssX3h0.mjs → __mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs-BsB2G7oY.mjs} +2 -1
- package/dist/stream-broker/{__mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs_commonjs-proxy-DFoJJhpt.mjs → __mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs_commonjs-proxy-xrRiPUpA.mjs} +1 -1
- package/dist/stream-broker/{__mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_2_dom__loadShare__.mjs_commonjs-proxy-x7XMEeuJ.mjs → __mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_2_dom__loadShare__.mjs_commonjs-proxy-C0E2yCzO.mjs} +1 -1
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-Sx8tgpFZ.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CupRlwqG.mjs} +6 -6
- package/dist/stream-broker/{client-CZXrddDR.mjs → client-NPZqorv9.mjs} +2 -2
- package/dist/stream-broker/{hostInit-D0jPgChu.mjs → hostInit-Bh4w7o5_.mjs} +12 -12
- package/dist/stream-broker/{index-C0BzaWmB.mjs → index-2Qp8vT3w.mjs} +1 -1
- package/dist/stream-broker/{index-CZNxa0ad.mjs → index-BBcZvb5t.mjs} +1 -1
- package/dist/stream-broker/index-CIJue-4t.mjs +37880 -0
- package/dist/stream-broker/{index-BvV3RVTZ.mjs → index-Cc6QBqMk.mjs} +2 -2
- package/dist/stream-broker/{index-cYW01SNH.mjs → index-D_1p2K9B.mjs} +1 -1
- package/dist/stream-broker/{index-BCEx31Mh.mjs → index-Dy2V7VOm.mjs} +3808 -3277
- package/dist/stream-broker/{index-KtR7Pp0O.mjs → index-mX3Kgiv1.mjs} +1 -1
- package/dist/stream-broker/index.js +1565 -280
- package/dist/stream-broker/index.js.map +1 -1
- package/dist/stream-broker/index.mjs +1567 -281
- package/dist/stream-broker/index.mjs.map +1 -1
- package/dist/stream-broker/{jsx-runtime-B_evVsXl.mjs → jsx-runtime-lb0mH5st.mjs} +1 -1
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/dist/stream-broker/{schemas-ChN4Ih0h.mjs → schemas-ClCuS4qa.mjs} +151 -141
- package/package.json +1 -1
- package/dist/index-CVzLrojg.mjs.map +0 -1
- package/dist/index-p-6GfKOg.js.map +0 -1
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.mjs-d8PmLbO2.mjs +0 -19
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-B4l8Nb2y.mjs +0 -20
- package/dist/stream-broker/index-Kb4xa8FX.mjs +0 -36403
|
@@ -4778,6 +4778,16 @@ function record(keyType, valueType, params) {
|
|
|
4778
4778
|
...normalizeParams(params)
|
|
4779
4779
|
});
|
|
4780
4780
|
}
|
|
4781
|
+
function partialRecord(keyType, valueType, params) {
|
|
4782
|
+
const k = clone(keyType);
|
|
4783
|
+
k._zod.values = void 0;
|
|
4784
|
+
return new ZodRecord({
|
|
4785
|
+
type: "record",
|
|
4786
|
+
keyType: k,
|
|
4787
|
+
valueType,
|
|
4788
|
+
...normalizeParams(params)
|
|
4789
|
+
});
|
|
4790
|
+
}
|
|
4781
4791
|
const ZodEnum = /* @__PURE__ */ $constructor("ZodEnum", (inst, def) => {
|
|
4782
4792
|
$ZodEnum.init(inst, def);
|
|
4783
4793
|
ZodType.init(inst, def);
|
|
@@ -5054,6 +5064,37 @@ function _instanceof(cls, params = {}) {
|
|
|
5054
5064
|
};
|
|
5055
5065
|
return inst;
|
|
5056
5066
|
}
|
|
5067
|
+
const wiringProbeKindSchema = _enum(["singleton", "device", "widget"]);
|
|
5068
|
+
const wiringProbeResultSchema = object({
|
|
5069
|
+
capName: string(),
|
|
5070
|
+
kind: wiringProbeKindSchema,
|
|
5071
|
+
deviceId: number().optional(),
|
|
5072
|
+
reachable: boolean(),
|
|
5073
|
+
latencyMs: number(),
|
|
5074
|
+
error: string().optional()
|
|
5075
|
+
});
|
|
5076
|
+
const wiringAddonHealthSchema = object({
|
|
5077
|
+
addonId: string(),
|
|
5078
|
+
caps: array(wiringProbeResultSchema).readonly(),
|
|
5079
|
+
widgets: array(wiringProbeResultSchema).readonly()
|
|
5080
|
+
});
|
|
5081
|
+
const wiringNodeHealthSchema = object({
|
|
5082
|
+
nodeId: string(),
|
|
5083
|
+
addons: array(wiringAddonHealthSchema).readonly()
|
|
5084
|
+
});
|
|
5085
|
+
object({
|
|
5086
|
+
/** True only when every probed target is reachable. */
|
|
5087
|
+
ok: boolean(),
|
|
5088
|
+
/** True when at least one target is unreachable. */
|
|
5089
|
+
degraded: boolean(),
|
|
5090
|
+
checkedAt: string(),
|
|
5091
|
+
nodes: array(wiringNodeHealthSchema).readonly(),
|
|
5092
|
+
summary: object({
|
|
5093
|
+
total: number(),
|
|
5094
|
+
reachable: number(),
|
|
5095
|
+
unreachable: number()
|
|
5096
|
+
})
|
|
5097
|
+
});
|
|
5057
5098
|
const MODEL_FORMATS = ["onnx", "coreml", "openvino", "tflite", "pt"];
|
|
5058
5099
|
const WELL_KNOWN_TABS = [
|
|
5059
5100
|
{ id: "overview", label: "Overview", icon: "layout-dashboard", order: -10 },
|
|
@@ -6618,7 +6659,7 @@ const SpatialDetectionSchema = object({
|
|
|
6618
6659
|
bbox: BoundingBoxSchema
|
|
6619
6660
|
});
|
|
6620
6661
|
const AudioChunkInputSchema = object({
|
|
6621
|
-
data: _instanceof(
|
|
6662
|
+
data: _instanceof(Uint8Array),
|
|
6622
6663
|
sampleRate: number(),
|
|
6623
6664
|
channels: number(),
|
|
6624
6665
|
timestamp: number(),
|
|
@@ -7298,7 +7339,23 @@ const RunnerCameraConfigSchema = object({
|
|
|
7298
7339
|
* whenever its `zones` device-state slice changes, so the runner's
|
|
7299
7340
|
* copy stays in sync. Empty array → no zone filtering.
|
|
7300
7341
|
*/
|
|
7301
|
-
zones: array(ZoneSchema).readonly().default([])
|
|
7342
|
+
zones: array(ZoneSchema).readonly().default([]),
|
|
7343
|
+
/**
|
|
7344
|
+
* When true (default) and the camera's `motionSources` contains only
|
|
7345
|
+
* `'onboard'`, the runner dynamically opens the same WASM frame-diff
|
|
7346
|
+
* motion-frames subscription on each `MotionOnMotionChanged
|
|
7347
|
+
* source:'onboard'` event and tears it down after `motionCooldownMs`.
|
|
7348
|
+
* This causes `runMotionAnalysis` to emit `MotionZonesRaw` /
|
|
7349
|
+
* `MotionAnalysis` during active-motion windows without the
|
|
7350
|
+
* substream being held open continuously.
|
|
7351
|
+
*
|
|
7352
|
+
* Set to `false` to disable the dynamic analyzer for this camera
|
|
7353
|
+
* (e.g. very low-bandwidth links where the extra substream is
|
|
7354
|
+
* undesirable). Has no effect when `motionSources` already includes
|
|
7355
|
+
* `'analyzer'` — the analyzer runs continuously in that case and
|
|
7356
|
+
* this gate is bypassed.
|
|
7357
|
+
*/
|
|
7358
|
+
onboardMotionDrivesAnalyzer: boolean().default(true)
|
|
7302
7359
|
});
|
|
7303
7360
|
const RunnerLocalLoadSchema = object({
|
|
7304
7361
|
/** Moleculer node id of this runner instance. */
|
|
@@ -7438,22 +7495,68 @@ MotionTriggerStatusSchema.extend({
|
|
|
7438
7495
|
}) }
|
|
7439
7496
|
}
|
|
7440
7497
|
});
|
|
7498
|
+
const MaskPointSchema = object({
|
|
7499
|
+
x: number(),
|
|
7500
|
+
y: number()
|
|
7501
|
+
});
|
|
7502
|
+
const MaskRectShapeSchema = object({
|
|
7503
|
+
kind: literal("rect"),
|
|
7504
|
+
x: number(),
|
|
7505
|
+
y: number(),
|
|
7506
|
+
width: number(),
|
|
7507
|
+
height: number()
|
|
7508
|
+
});
|
|
7509
|
+
const MaskPolygonShapeSchema = object({
|
|
7510
|
+
kind: literal("polygon"),
|
|
7511
|
+
points: array(MaskPointSchema)
|
|
7512
|
+
});
|
|
7513
|
+
const MaskGridShapeSchema = object({
|
|
7514
|
+
kind: literal("grid"),
|
|
7515
|
+
gridWidth: number(),
|
|
7516
|
+
gridHeight: number(),
|
|
7517
|
+
cells: array(boolean())
|
|
7518
|
+
});
|
|
7519
|
+
const MaskLineShapeSchema = object({
|
|
7520
|
+
kind: literal("line"),
|
|
7521
|
+
points: array(MaskPointSchema)
|
|
7522
|
+
});
|
|
7523
|
+
discriminatedUnion("kind", [
|
|
7524
|
+
MaskRectShapeSchema,
|
|
7525
|
+
MaskPolygonShapeSchema,
|
|
7526
|
+
MaskGridShapeSchema,
|
|
7527
|
+
MaskLineShapeSchema
|
|
7528
|
+
]);
|
|
7529
|
+
const MaskShapeKindSchema = _enum(["rect", "polygon", "grid", "line"]);
|
|
7530
|
+
const MaskPolygonVerticesSchema = object({
|
|
7531
|
+
min: number(),
|
|
7532
|
+
max: number()
|
|
7533
|
+
});
|
|
7534
|
+
const MaskGridDimsSchema = object({
|
|
7535
|
+
width: number(),
|
|
7536
|
+
height: number()
|
|
7537
|
+
});
|
|
7538
|
+
const MotionZoneRegionSchema = object({
|
|
7539
|
+
id: number(),
|
|
7540
|
+
enabled: boolean(),
|
|
7541
|
+
shape: MaskGridShapeSchema
|
|
7542
|
+
});
|
|
7441
7543
|
object({
|
|
7442
7544
|
enabled: boolean(),
|
|
7443
7545
|
sensitivity: number(),
|
|
7444
|
-
/**
|
|
7445
|
-
|
|
7546
|
+
/** Grid region(s). Today exactly one `grid` shape. */
|
|
7547
|
+
regions: array(MotionZoneRegionSchema),
|
|
7446
7548
|
lastFetchedAt: number()
|
|
7447
7549
|
});
|
|
7448
7550
|
const MotionZoneOptionsSchema = object({
|
|
7449
|
-
|
|
7450
|
-
|
|
7551
|
+
maxRegions: number(),
|
|
7552
|
+
supportedShapes: array(MaskShapeKindSchema),
|
|
7553
|
+
grid: MaskGridDimsSchema,
|
|
7451
7554
|
sensitivity: object({ min: number(), max: number(), step: number() })
|
|
7452
7555
|
});
|
|
7453
7556
|
const MotionZonePatchSchema = object({
|
|
7454
7557
|
enabled: boolean().optional(),
|
|
7455
7558
|
sensitivity: number().optional(),
|
|
7456
|
-
|
|
7559
|
+
regions: array(MotionZoneRegionSchema).optional()
|
|
7457
7560
|
});
|
|
7458
7561
|
({
|
|
7459
7562
|
deviceTypes: [DeviceType.Camera],
|
|
@@ -7466,6 +7569,102 @@ const MotionZonePatchSchema = object({
|
|
|
7466
7569
|
)
|
|
7467
7570
|
}
|
|
7468
7571
|
});
|
|
7572
|
+
const NativeObjectClassEnum = _enum([
|
|
7573
|
+
"person",
|
|
7574
|
+
"vehicle",
|
|
7575
|
+
"animal",
|
|
7576
|
+
"face",
|
|
7577
|
+
"package",
|
|
7578
|
+
"other"
|
|
7579
|
+
]);
|
|
7580
|
+
const NativeDetectionSchema = object({
|
|
7581
|
+
class: NativeObjectClassEnum,
|
|
7582
|
+
timestamp: number(),
|
|
7583
|
+
/** Firmware-provided confidence [0..1]. Reolink pushes don't carry it → undefined. */
|
|
7584
|
+
confidence: number().min(0).max(1).optional()
|
|
7585
|
+
});
|
|
7586
|
+
const NativeObjectDetectionStatusSchema = object({
|
|
7587
|
+
/**
|
|
7588
|
+
* Last observed instance per class. Missing entries mean the class
|
|
7589
|
+
* is supported but nothing has been seen since the provider started.
|
|
7590
|
+
*
|
|
7591
|
+
* MUST be a partial record: providers seed an empty `{}` on cold-start
|
|
7592
|
+
* and write one class at a time as detections arrive. In Zod 4
|
|
7593
|
+
* `z.record(enum, …)` is EXHAUSTIVE (requires every enum key), so a
|
|
7594
|
+
* partial write throws "expected object, received undefined" for every
|
|
7595
|
+
* unseen class. `z.partialRecord` keeps the enum-key narrowing while
|
|
7596
|
+
* allowing the sparse shape the providers actually write.
|
|
7597
|
+
*/
|
|
7598
|
+
lastByClass: partialRecord(NativeObjectClassEnum, NativeDetectionSchema.nullable()),
|
|
7599
|
+
/** Classes the firmware is capable of detecting — enumerated at device register. */
|
|
7600
|
+
supportedClasses: array(NativeObjectClassEnum).readonly(),
|
|
7601
|
+
/**
|
|
7602
|
+
* Whether forwarding of onboard AI detections is enabled for this device.
|
|
7603
|
+
* Default true (on cold-start) — detections flow unconditionally before
|
|
7604
|
+
* the toggle is saved, so defaulting true preserves existing behaviour.
|
|
7605
|
+
*/
|
|
7606
|
+
enabled: boolean()
|
|
7607
|
+
});
|
|
7608
|
+
NativeObjectDetectionStatusSchema.extend({
|
|
7609
|
+
/** Required by createRuntimeStateBridge — epoch ms of last refresh. */
|
|
7610
|
+
lastFetchedAt: number()
|
|
7611
|
+
});
|
|
7612
|
+
({
|
|
7613
|
+
deviceTypes: [DeviceType.Camera],
|
|
7614
|
+
methods: {
|
|
7615
|
+
setEnabled: method(
|
|
7616
|
+
object({ deviceId: number(), enabled: boolean() }),
|
|
7617
|
+
_void(),
|
|
7618
|
+
{ kind: "mutation", auth: "admin" }
|
|
7619
|
+
)
|
|
7620
|
+
},
|
|
7621
|
+
events: {
|
|
7622
|
+
onDetected: { data: object({
|
|
7623
|
+
deviceId: number(),
|
|
7624
|
+
detection: NativeDetectionSchema
|
|
7625
|
+
}) }
|
|
7626
|
+
}
|
|
7627
|
+
});
|
|
7628
|
+
const PrivacyMaskShapeSchema = discriminatedUnion("kind", [
|
|
7629
|
+
MaskRectShapeSchema,
|
|
7630
|
+
MaskPolygonShapeSchema
|
|
7631
|
+
]);
|
|
7632
|
+
const PrivacyMaskRegionSchema = object({
|
|
7633
|
+
/** Slot id, 0-based. Stable across read/write. */
|
|
7634
|
+
id: number(),
|
|
7635
|
+
/** Whether this zone is active (blanked out by the camera). */
|
|
7636
|
+
enabled: boolean(),
|
|
7637
|
+
shape: PrivacyMaskShapeSchema
|
|
7638
|
+
});
|
|
7639
|
+
object({
|
|
7640
|
+
enabled: boolean(),
|
|
7641
|
+
/** Active zones (normalized 0..1). Length ≤ maxRegions. */
|
|
7642
|
+
regions: array(PrivacyMaskRegionSchema),
|
|
7643
|
+
lastFetchedAt: number()
|
|
7644
|
+
});
|
|
7645
|
+
const PrivacyMaskOptionsSchema = object({
|
|
7646
|
+
/** Maximum number of supported zones. */
|
|
7647
|
+
maxRegions: number(),
|
|
7648
|
+
/** Shape kinds this camera accepts — Reolink: ['rect']; Hikvision: ['rect','polygon']. */
|
|
7649
|
+
supportedShapes: array(MaskShapeKindSchema),
|
|
7650
|
+
/** Polygon vertex bounds when 'polygon' is supported (Hikvision: {min:4,max:4}). */
|
|
7651
|
+
polygonVertices: MaskPolygonVerticesSchema.optional()
|
|
7652
|
+
});
|
|
7653
|
+
const PrivacyMaskPatchSchema = object({
|
|
7654
|
+
enabled: boolean().optional(),
|
|
7655
|
+
regions: array(PrivacyMaskRegionSchema).optional()
|
|
7656
|
+
});
|
|
7657
|
+
({
|
|
7658
|
+
deviceTypes: [DeviceType.Camera],
|
|
7659
|
+
methods: {
|
|
7660
|
+
getOptions: method(object({ deviceId: number() }), PrivacyMaskOptionsSchema),
|
|
7661
|
+
setMask: method(
|
|
7662
|
+
object({ deviceId: number(), patch: PrivacyMaskPatchSchema }),
|
|
7663
|
+
_void(),
|
|
7664
|
+
{ kind: "mutation", auth: "admin" }
|
|
7665
|
+
)
|
|
7666
|
+
}
|
|
7667
|
+
});
|
|
7469
7668
|
const AutotrackTargetTypeSchema = string().describe("Vendor target string (people/vehicle/pet); empty = camera default");
|
|
7470
7669
|
const PtzAutotrackSettingsSchema = object({
|
|
7471
7670
|
targetType: AutotrackTargetTypeSchema,
|
|
@@ -7984,7 +8183,8 @@ const SettingsUpdateResultSchema = object({
|
|
|
7984
8183
|
object({
|
|
7985
8184
|
addonId: string(),
|
|
7986
8185
|
nodeId: string().optional(),
|
|
7987
|
-
overlay: record(string(), unknown()).optional()
|
|
8186
|
+
overlay: record(string(), unknown()).optional(),
|
|
8187
|
+
cap: string().optional()
|
|
7988
8188
|
}),
|
|
7989
8189
|
SettingsSchemaWithValuesSchema.nullable()
|
|
7990
8190
|
),
|
|
@@ -8715,7 +8915,14 @@ const OauthIntegrationDescriptorSchema = object({
|
|
|
8715
8915
|
/** Allowed redirect_uri prefixes. /api/oauth2/authorize rejects any
|
|
8716
8916
|
* redirect_uri that does not start with one of these. Required —
|
|
8717
8917
|
* an empty list means the integration can never complete linking. */
|
|
8718
|
-
allowedRedirectPrefixes: array(string()).min(1)
|
|
8918
|
+
allowedRedirectPrefixes: array(string()).min(1),
|
|
8919
|
+
/** Optional public origin (no trailing slash) that this integration's
|
|
8920
|
+
* issued codes/tokens should carry as the `hubUrl` claim — typically the
|
|
8921
|
+
* operator-selected external-access endpoint resolved by the addon. When
|
|
8922
|
+
* present, /api/oauth2/authorize bakes THIS into the code instead of the
|
|
8923
|
+
* hub-global `publicHubUrl()`, so a forked exporter addon (which can't set
|
|
8924
|
+
* the hub's env) drives the claim that its cloud Lambda routes back on. */
|
|
8925
|
+
hubUrl: string().optional()
|
|
8719
8926
|
});
|
|
8720
8927
|
({
|
|
8721
8928
|
methods: {
|
|
@@ -9365,7 +9572,20 @@ const webrtcSessionCapability = {
|
|
|
9365
9572
|
object({
|
|
9366
9573
|
deviceId: number().int().nonnegative(),
|
|
9367
9574
|
target: WebrtcStreamTargetSchema,
|
|
9368
|
-
hints: webrtcClientHintsSchema.optional()
|
|
9575
|
+
hints: webrtcClientHintsSchema.optional(),
|
|
9576
|
+
/**
|
|
9577
|
+
* SERVER-INJECTED — NOT a client hint. The hub layer that holds
|
|
9578
|
+
* the tRPC request context (and therefore the client IP) sets
|
|
9579
|
+
* this to `true` when the viewer's source IP is non-LAN
|
|
9580
|
+
* (4G/CGNAT/internet). The broker then forces TURN-relay-only
|
|
9581
|
+
* ICE for the session so a CGNAT client (which can only offer a
|
|
9582
|
+
* relay candidate) gets a clean relay↔relay media path instead
|
|
9583
|
+
* of werift nominating a dead host/hairpin-srflx pair. LAN
|
|
9584
|
+
* clients leave this absent/false and keep the low-latency
|
|
9585
|
+
* direct (host/srflx) path. Clients MUST NOT send this — the
|
|
9586
|
+
* server overwrites it from the request context.
|
|
9587
|
+
*/
|
|
9588
|
+
relayOnly: boolean().optional()
|
|
9369
9589
|
}),
|
|
9370
9590
|
object({ sessionId: string(), sdpOffer: string() }),
|
|
9371
9591
|
{ kind: "mutation" }
|
|
@@ -9388,7 +9608,22 @@ const webrtcSessionCapability = {
|
|
|
9388
9608
|
deviceId: number().int().nonnegative(),
|
|
9389
9609
|
target: WebrtcStreamTargetSchema.optional(),
|
|
9390
9610
|
sdpOffer: string(),
|
|
9391
|
-
sessionId: string().optional()
|
|
9611
|
+
sessionId: string().optional(),
|
|
9612
|
+
/**
|
|
9613
|
+
* Force TURN-relay-only ICE for this session. Two kinds of caller
|
|
9614
|
+
* set it:
|
|
9615
|
+
* - A cloud peer like Alexa's RTCSessionController (reachable
|
|
9616
|
+
* only via TURN, never our host/srflx behind NAT) passes
|
|
9617
|
+
* `true` from its own trusted addon context.
|
|
9618
|
+
* - The hub injects it for browser client-offer viewers from the
|
|
9619
|
+
* request's source IP (non-LAN ⇒ true), exactly as it does for
|
|
9620
|
+
* `createSession`.
|
|
9621
|
+
* A LAN/Tailscale browser doing client-offer passthrough leaves it
|
|
9622
|
+
* absent/false so a direct host pair carries full native quality.
|
|
9623
|
+
* Untrusted browser clients MUST NOT send it — the hub overwrites
|
|
9624
|
+
* it from the request context.
|
|
9625
|
+
*/
|
|
9626
|
+
relayOnly: boolean().optional()
|
|
9392
9627
|
}),
|
|
9393
9628
|
object({ sessionId: string(), sdpAnswer: string() }),
|
|
9394
9629
|
{ kind: "mutation" }
|
|
@@ -9402,6 +9637,46 @@ const webrtcSessionCapability = {
|
|
|
9402
9637
|
_void(),
|
|
9403
9638
|
{ kind: "mutation" }
|
|
9404
9639
|
),
|
|
9640
|
+
/**
|
|
9641
|
+
* Trickle ICE — add a remote (client) ICE candidate to a live session.
|
|
9642
|
+
* Lets the client send its SDP offer/answer IMMEDIATELY (before ICE
|
|
9643
|
+
* gathering finishes) and deliver candidates as they arrive, so the
|
|
9644
|
+
* connection establishes in ~0s instead of waiting for full gathering.
|
|
9645
|
+
* The dual of `getIceCandidates`. Mirrors Scrypted's signaling.
|
|
9646
|
+
*/
|
|
9647
|
+
addIceCandidate: method(
|
|
9648
|
+
object({
|
|
9649
|
+
deviceId: number().int().nonnegative(),
|
|
9650
|
+
sessionId: string(),
|
|
9651
|
+
candidate: string(),
|
|
9652
|
+
sdpMid: string().nullable().optional(),
|
|
9653
|
+
sdpMLineIndex: number().int().nullable().optional()
|
|
9654
|
+
}),
|
|
9655
|
+
_void(),
|
|
9656
|
+
{ kind: "mutation" }
|
|
9657
|
+
),
|
|
9658
|
+
/**
|
|
9659
|
+
* Trickle ICE — poll the server's gathered ICE candidates for a session.
|
|
9660
|
+
* The server answers immediately (no gathering wait) and the client polls
|
|
9661
|
+
* this to receive host/srflx/relay candidates as werift gathers them,
|
|
9662
|
+
* adding each to its PeerConnection. Returns all candidates gathered so
|
|
9663
|
+
* far; the client dedupes. `done` flips true once gathering completes.
|
|
9664
|
+
*/
|
|
9665
|
+
getIceCandidates: method(
|
|
9666
|
+
object({
|
|
9667
|
+
deviceId: number().int().nonnegative(),
|
|
9668
|
+
sessionId: string()
|
|
9669
|
+
}),
|
|
9670
|
+
object({
|
|
9671
|
+
candidates: array(object({
|
|
9672
|
+
candidate: string(),
|
|
9673
|
+
sdpMid: string().nullable(),
|
|
9674
|
+
sdpMLineIndex: number().int().nullable()
|
|
9675
|
+
})),
|
|
9676
|
+
done: boolean()
|
|
9677
|
+
}),
|
|
9678
|
+
{ kind: "query" }
|
|
9679
|
+
),
|
|
9405
9680
|
closeSession: method(
|
|
9406
9681
|
object({
|
|
9407
9682
|
deviceId: number().int().nonnegative(),
|
|
@@ -11102,6 +11377,9 @@ const detectionPipelineCapability = {
|
|
|
11102
11377
|
exposesDeviceSettings: true,
|
|
11103
11378
|
methods: {}
|
|
11104
11379
|
};
|
|
11380
|
+
({
|
|
11381
|
+
deviceTypes: [DeviceType.Camera]
|
|
11382
|
+
});
|
|
11105
11383
|
const TrackStateSchema = _enum(["new", "entered", "left", "moving", "idle"]);
|
|
11106
11384
|
const EventKindSchema = _enum(["motion", "object", "audio"]);
|
|
11107
11385
|
const TrackPositionSchema = object({
|
|
@@ -11929,36 +12207,28 @@ const IntercomStatusSchema = object({
|
|
|
11929
12207
|
}) }
|
|
11930
12208
|
}
|
|
11931
12209
|
});
|
|
11932
|
-
const
|
|
11933
|
-
|
|
11934
|
-
|
|
11935
|
-
|
|
11936
|
-
|
|
11937
|
-
|
|
11938
|
-
|
|
11939
|
-
|
|
11940
|
-
|
|
11941
|
-
|
|
11942
|
-
|
|
11943
|
-
|
|
11944
|
-
|
|
11945
|
-
|
|
11946
|
-
object({
|
|
11947
|
-
/**
|
|
11948
|
-
* Last observed instance per class. Undefined entries mean the class
|
|
11949
|
-
* is supported but nothing has been seen since the provider started.
|
|
11950
|
-
*/
|
|
11951
|
-
lastByClass: record(NativeObjectClassEnum, NativeDetectionSchema.nullable()),
|
|
11952
|
-
/** Classes the firmware is capable of detecting — enumerated at device register. */
|
|
11953
|
-
supportedClasses: array(NativeObjectClassEnum).readonly()
|
|
12210
|
+
const CamStreamDescriptorSchema = object({
|
|
12211
|
+
camStreamId: string().min(1),
|
|
12212
|
+
kind: CamStreamKindSchema,
|
|
12213
|
+
url: string().optional(),
|
|
12214
|
+
codec: string().optional(),
|
|
12215
|
+
resolution: CamStreamResolutionSchema.optional(),
|
|
12216
|
+
fps: number().positive().optional(),
|
|
12217
|
+
label: string().optional(),
|
|
12218
|
+
/** Device-level features (e.g. `battery-operated`) — drives broker policy. */
|
|
12219
|
+
deviceFeatures: array(string()).optional(),
|
|
12220
|
+
/** Eligible for automatic profile assignment. Absent = `true`. */
|
|
12221
|
+
autoEligible: boolean().optional(),
|
|
12222
|
+
/** Transport-specific opaque metadata (e.g. rfc4571 SDP). */
|
|
12223
|
+
metadata: record(string(), unknown()).optional()
|
|
11954
12224
|
});
|
|
11955
12225
|
({
|
|
11956
12226
|
deviceTypes: [DeviceType.Camera],
|
|
11957
|
-
|
|
11958
|
-
|
|
11959
|
-
deviceId: number(),
|
|
11960
|
-
|
|
11961
|
-
|
|
12227
|
+
methods: {
|
|
12228
|
+
getCatalog: method(
|
|
12229
|
+
object({ deviceId: number().int().nonnegative() }),
|
|
12230
|
+
array(CamStreamDescriptorSchema).readonly()
|
|
12231
|
+
)
|
|
11962
12232
|
}
|
|
11963
12233
|
});
|
|
11964
12234
|
const ModelFormatSchema = _enum(MODEL_FORMATS);
|
|
@@ -12826,6 +13096,18 @@ const TopologyProcessSchema = object({
|
|
|
12826
13096
|
services: array(TopologyServiceSchema).readonly(),
|
|
12827
13097
|
groupId: string().optional()
|
|
12828
13098
|
});
|
|
13099
|
+
const TopologyCategoryAddonSchema = object({
|
|
13100
|
+
id: string(),
|
|
13101
|
+
status: string(),
|
|
13102
|
+
cpuPercent: number(),
|
|
13103
|
+
memoryRss: number()
|
|
13104
|
+
});
|
|
13105
|
+
const TopologyCategorySchema = object({
|
|
13106
|
+
category: string(),
|
|
13107
|
+
total: number(),
|
|
13108
|
+
healthy: number(),
|
|
13109
|
+
addons: array(TopologyCategoryAddonSchema).readonly()
|
|
13110
|
+
});
|
|
12829
13111
|
const TopologyNodeSchema = object({
|
|
12830
13112
|
id: string(),
|
|
12831
13113
|
name: string(),
|
|
@@ -12850,7 +13132,15 @@ const TopologyNodeSchema = object({
|
|
|
12850
13132
|
status: string()
|
|
12851
13133
|
})
|
|
12852
13134
|
).readonly(),
|
|
12853
|
-
processes: array(TopologyProcessSchema).readonly()
|
|
13135
|
+
processes: array(TopologyProcessSchema).readonly(),
|
|
13136
|
+
categories: array(TopologyCategorySchema).readonly()
|
|
13137
|
+
});
|
|
13138
|
+
const CapUsageEdgeSchema = object({
|
|
13139
|
+
callerAddonId: string(),
|
|
13140
|
+
providerAddonId: string(),
|
|
13141
|
+
capName: string(),
|
|
13142
|
+
callsPerMin: number(),
|
|
13143
|
+
lastCallAtMs: number()
|
|
12854
13144
|
});
|
|
12855
13145
|
const ClusterAddonNodeDeploymentSchema = object({
|
|
12856
13146
|
nodeId: string(),
|
|
@@ -12934,13 +13224,7 @@ const RenameNodeResultSchema = object({
|
|
|
12934
13224
|
object({
|
|
12935
13225
|
windowSeconds: number().int().positive().max(300).default(60)
|
|
12936
13226
|
}),
|
|
12937
|
-
array(
|
|
12938
|
-
callerAddonId: string(),
|
|
12939
|
-
providerAddonId: string(),
|
|
12940
|
-
capName: string(),
|
|
12941
|
-
callsPerMin: number(),
|
|
12942
|
-
lastCallAtMs: number()
|
|
12943
|
-
})).readonly(),
|
|
13227
|
+
array(CapUsageEdgeSchema).readonly(),
|
|
12944
13228
|
{ auth: "admin" }
|
|
12945
13229
|
),
|
|
12946
13230
|
/**
|
|
@@ -13152,7 +13436,8 @@ const PackageUpdateSchema = object({
|
|
|
13152
13436
|
currentVersion: string(),
|
|
13153
13437
|
latestVersion: string(),
|
|
13154
13438
|
category: _enum(["addon", "core"]),
|
|
13155
|
-
requiresRestart: boolean()
|
|
13439
|
+
requiresRestart: boolean(),
|
|
13440
|
+
isSystem: boolean()
|
|
13156
13441
|
});
|
|
13157
13442
|
const PackageVersionInfoSchema = object({
|
|
13158
13443
|
version: string(),
|
|
@@ -13185,6 +13470,42 @@ const UpdateFrameworkPackageResultSchema = object({
|
|
|
13185
13470
|
/** Ms-epoch the server scheduled its self-restart. */
|
|
13186
13471
|
restartingAt: number()
|
|
13187
13472
|
});
|
|
13473
|
+
const BulkUpdateItemStatusSchema = _enum([
|
|
13474
|
+
"queued",
|
|
13475
|
+
"updating",
|
|
13476
|
+
"done",
|
|
13477
|
+
"done-pending-restart",
|
|
13478
|
+
"failed"
|
|
13479
|
+
]);
|
|
13480
|
+
const BulkUpdateItemSchema = object({
|
|
13481
|
+
name: string(),
|
|
13482
|
+
isSystem: boolean(),
|
|
13483
|
+
fromVersion: string(),
|
|
13484
|
+
toVersion: string(),
|
|
13485
|
+
status: BulkUpdateItemStatusSchema,
|
|
13486
|
+
error: string().optional(),
|
|
13487
|
+
startedAtMs: number().optional(),
|
|
13488
|
+
completedAtMs: number().optional()
|
|
13489
|
+
});
|
|
13490
|
+
const BulkUpdatePhaseSchema = _enum([
|
|
13491
|
+
"regular",
|
|
13492
|
+
"system",
|
|
13493
|
+
"restarting",
|
|
13494
|
+
"finalizing"
|
|
13495
|
+
]);
|
|
13496
|
+
const BulkUpdateStateSchema = object({
|
|
13497
|
+
id: string(),
|
|
13498
|
+
nodeId: string(),
|
|
13499
|
+
startedAtMs: number(),
|
|
13500
|
+
completedAtMs: number().optional(),
|
|
13501
|
+
total: number(),
|
|
13502
|
+
completed: number(),
|
|
13503
|
+
failed: number(),
|
|
13504
|
+
current: string().nullable(),
|
|
13505
|
+
phase: BulkUpdatePhaseSchema,
|
|
13506
|
+
cancelled: boolean(),
|
|
13507
|
+
items: array(BulkUpdateItemSchema).readonly()
|
|
13508
|
+
});
|
|
13188
13509
|
const FrameworkPackageStatusSchema = object({
|
|
13189
13510
|
packageName: string(),
|
|
13190
13511
|
currentVersion: string(),
|
|
@@ -13322,7 +13643,7 @@ const CustomActionInputSchema = object({
|
|
|
13322
13643
|
getLastRestart: method(
|
|
13323
13644
|
_void(),
|
|
13324
13645
|
object({
|
|
13325
|
-
kind: _enum(["framework-update", "manual", "system"]),
|
|
13646
|
+
kind: _enum(["framework-update", "manual", "system", "framework-bulk-update"]),
|
|
13326
13647
|
packageName: string().optional(),
|
|
13327
13648
|
fromVersion: string().optional(),
|
|
13328
13649
|
toVersion: string().optional(),
|
|
@@ -13412,11 +13733,70 @@ const CustomActionInputSchema = object({
|
|
|
13412
13733
|
updateFrameworkPackage: method(
|
|
13413
13734
|
object({
|
|
13414
13735
|
packageName: string().min(1),
|
|
13415
|
-
version: string().optional()
|
|
13736
|
+
version: string().optional(),
|
|
13737
|
+
deferRestart: boolean().optional()
|
|
13416
13738
|
}),
|
|
13417
13739
|
UpdateFrameworkPackageResultSchema,
|
|
13418
13740
|
{ kind: "mutation", auth: "admin" }
|
|
13419
13741
|
),
|
|
13742
|
+
/**
|
|
13743
|
+
* Kicks off a server-side bulk update operation and returns the bulk
|
|
13744
|
+
* id immediately. The operation runs asynchronously; observe progress
|
|
13745
|
+
* via the `AddonsBulkUpdateProgress` event or `getBulkUpdateState`.
|
|
13746
|
+
* Items with `isSystem: true` use `deferRestart` — the hub restarts
|
|
13747
|
+
* ONCE at the end of the system phase, after all system packages are
|
|
13748
|
+
* installed.
|
|
13749
|
+
*
|
|
13750
|
+
* `items[].version` is REQUIRED — callers must pass the resolved
|
|
13751
|
+
* version from `listUpdates`. There is no `'latest'` default here
|
|
13752
|
+
* (unlike `updatePackage`) to guarantee deterministic bulk rolls.
|
|
13753
|
+
*/
|
|
13754
|
+
startBulkUpdate: method(
|
|
13755
|
+
object({
|
|
13756
|
+
nodeId: string(),
|
|
13757
|
+
items: array(object({
|
|
13758
|
+
name: string(),
|
|
13759
|
+
version: string(),
|
|
13760
|
+
isSystem: boolean()
|
|
13761
|
+
})).readonly()
|
|
13762
|
+
}),
|
|
13763
|
+
object({ id: string() }),
|
|
13764
|
+
{ kind: "mutation", auth: "admin" }
|
|
13765
|
+
),
|
|
13766
|
+
/**
|
|
13767
|
+
* Returns the current state of a bulk update by id.
|
|
13768
|
+
* Returns `null` if the id is unknown or has been auto-cleaned
|
|
13769
|
+
* (5 minutes after `completedAt` the record is evicted from memory).
|
|
13770
|
+
*/
|
|
13771
|
+
getBulkUpdateState: method(
|
|
13772
|
+
object({ id: string() }),
|
|
13773
|
+
BulkUpdateStateSchema.nullable(),
|
|
13774
|
+
{ auth: "admin" }
|
|
13775
|
+
),
|
|
13776
|
+
/**
|
|
13777
|
+
* Cancels an in-flight bulk update. The update loop exits after the
|
|
13778
|
+
* currently-processing item completes — cancellation is not
|
|
13779
|
+
* instantaneous. Has no effect once the `restarting` phase has been
|
|
13780
|
+
* entered (the hub is already shutting down at that point).
|
|
13781
|
+
* Returns `{ cancelled: false }` if the id is unknown, the operation
|
|
13782
|
+
* has already completed, or the `restarting` phase is active.
|
|
13783
|
+
*/
|
|
13784
|
+
cancelBulkUpdate: method(
|
|
13785
|
+
object({ id: string() }),
|
|
13786
|
+
object({ cancelled: boolean() }),
|
|
13787
|
+
{ kind: "mutation", auth: "admin" }
|
|
13788
|
+
),
|
|
13789
|
+
/**
|
|
13790
|
+
* Lists all currently active (non-completed) bulk updates.
|
|
13791
|
+
* If `nodeId` is provided, filters to only bulk updates targeting
|
|
13792
|
+
* that node. Useful for restoring an in-progress banner on a fresh
|
|
13793
|
+
* page load when the UI reconnects mid-operation.
|
|
13794
|
+
*/
|
|
13795
|
+
listActiveBulkUpdates: method(
|
|
13796
|
+
object({ nodeId: string().optional() }),
|
|
13797
|
+
array(BulkUpdateStateSchema).readonly(),
|
|
13798
|
+
{ auth: "admin" }
|
|
13799
|
+
),
|
|
13420
13800
|
getVersions: method(
|
|
13421
13801
|
object({ name: string() }),
|
|
13422
13802
|
array(PackageVersionInfoSchema).readonly()
|
|
@@ -13544,6 +13924,7 @@ var EventCategory = /* @__PURE__ */ ((EventCategory2) => {
|
|
|
13544
13924
|
EventCategory2["StreamBrokerOnCamStreamDemand"] = "stream-broker.onCamStreamDemand";
|
|
13545
13925
|
EventCategory2["StreamBrokerOnCamStreamIdle"] = "stream-broker.onCamStreamIdle";
|
|
13546
13926
|
EventCategory2["StreamBrokerOnRequestStreamSourceRefresh"] = "stream-broker.onRequestStreamSourceRefresh";
|
|
13927
|
+
EventCategory2["StreamParamsChanged"] = "stream-params.changed";
|
|
13547
13928
|
EventCategory2["DeviceStateChanged"] = "device.state-changed";
|
|
13548
13929
|
EventCategory2["BatteryOnStatusChanged"] = "battery.onStatusChanged";
|
|
13549
13930
|
EventCategory2["DoorbellOnPressed"] = "doorbell.onPressed";
|
|
@@ -13591,6 +13972,7 @@ var EventCategory = /* @__PURE__ */ ((EventCategory2) => {
|
|
|
13591
13972
|
EventCategory2["NetworkTunnelStarted"] = "network.tunnel.started";
|
|
13592
13973
|
EventCategory2["NetworkTunnelStopped"] = "network.tunnel.stopped";
|
|
13593
13974
|
EventCategory2["LocalNetworkChanged"] = "network.local.changed";
|
|
13975
|
+
EventCategory2["MeshNetworkChanged"] = "network.mesh.changed";
|
|
13594
13976
|
EventCategory2["BackupCompleted"] = "backup.completed";
|
|
13595
13977
|
EventCategory2["BackupRestored"] = "backup.restored";
|
|
13596
13978
|
EventCategory2["NotificationDispatched"] = "notification.dispatched";
|
|
@@ -13601,6 +13983,7 @@ var EventCategory = /* @__PURE__ */ ((EventCategory2) => {
|
|
|
13601
13983
|
EventCategory2["DeviceAwake"] = "device.awake";
|
|
13602
13984
|
EventCategory2["DeviceSleeping"] = "device.sleeping";
|
|
13603
13985
|
EventCategory2["RetentionCleanup"] = "retention.cleanup";
|
|
13986
|
+
EventCategory2["AddonsBulkUpdateProgress"] = "addons.bulk-update-progress";
|
|
13604
13987
|
return EventCategory2;
|
|
13605
13988
|
})(EventCategory || {});
|
|
13606
13989
|
function createEvent(category, source, data) {
|
|
@@ -13750,7 +14133,7 @@ class BaseAddon {
|
|
|
13750
14133
|
}
|
|
13751
14134
|
// ── Settings schemas (override to provide UI) ─────────────────────────
|
|
13752
14135
|
/** Override to provide global-level settings UI schema. */
|
|
13753
|
-
globalSettingsSchema() {
|
|
14136
|
+
globalSettingsSchema(_cap) {
|
|
13754
14137
|
return null;
|
|
13755
14138
|
}
|
|
13756
14139
|
/** Override to provide device-level settings UI schema. */
|
|
@@ -13764,8 +14147,8 @@ class BaseAddon {
|
|
|
13764
14147
|
// blob and every addon used exactly one of them; the distinction was
|
|
13765
14148
|
// never semantically load-bearing. `global` won because it was the
|
|
13766
14149
|
// widely-used one and the name reads naturally (per-node addon config).
|
|
13767
|
-
async getGlobalSettings(overlay) {
|
|
13768
|
-
const schema = this.globalSettingsSchema();
|
|
14150
|
+
async getGlobalSettings(overlay, cap) {
|
|
14151
|
+
const schema = this.globalSettingsSchema(cap);
|
|
13769
14152
|
if (!schema) return { sections: [] };
|
|
13770
14153
|
const raw = await this._ctx?.settings?.readAddonStore() ?? {};
|
|
13771
14154
|
return hydrateSchema(schema, overlay ? { ...raw, ...overlay } : raw);
|
|
@@ -14176,13 +14559,42 @@ function customAction(input, output, options) {
|
|
|
14176
14559
|
scope: options?.scope ?? { kind: "system" }
|
|
14177
14560
|
};
|
|
14178
14561
|
}
|
|
14562
|
+
const CREDENTIAL_PARAM_PATTERNS = [
|
|
14563
|
+
/^user$/i,
|
|
14564
|
+
/^usr$/i,
|
|
14565
|
+
/^username$/i,
|
|
14566
|
+
/^password$/i,
|
|
14567
|
+
/^pwd$/i,
|
|
14568
|
+
/^pass$/i,
|
|
14569
|
+
/^passwd$/i,
|
|
14570
|
+
/^secret$/i,
|
|
14571
|
+
/^token$/i,
|
|
14572
|
+
/^auth$/i,
|
|
14573
|
+
/^auth[_-]?token$/i,
|
|
14574
|
+
/^bearer$/i,
|
|
14575
|
+
/^api[_-]?key$/i,
|
|
14576
|
+
/^access[_-]?token$/i,
|
|
14577
|
+
/^refresh[_-]?token$/i
|
|
14578
|
+
];
|
|
14579
|
+
function isCredentialParam(name) {
|
|
14580
|
+
return CREDENTIAL_PARAM_PATTERNS.some((re) => re.test(name));
|
|
14581
|
+
}
|
|
14179
14582
|
function maskUrlCredentials(rawUrl) {
|
|
14180
14583
|
try {
|
|
14181
14584
|
const u = new URL(rawUrl);
|
|
14182
|
-
|
|
14183
|
-
u.username
|
|
14184
|
-
|
|
14185
|
-
|
|
14585
|
+
let touched = false;
|
|
14586
|
+
if (u.username || u.password) {
|
|
14587
|
+
u.username = "";
|
|
14588
|
+
u.password = "";
|
|
14589
|
+
touched = true;
|
|
14590
|
+
}
|
|
14591
|
+
for (const key of [...u.searchParams.keys()]) {
|
|
14592
|
+
if (isCredentialParam(key)) {
|
|
14593
|
+
u.searchParams.set(key, "***");
|
|
14594
|
+
touched = true;
|
|
14595
|
+
}
|
|
14596
|
+
}
|
|
14597
|
+
return touched ? u.toString() : rawUrl;
|
|
14186
14598
|
} catch {
|
|
14187
14599
|
return rawUrl;
|
|
14188
14600
|
}
|
|
@@ -14268,4 +14680,4 @@ export {
|
|
|
14268
14680
|
DEFAULT_AUDIO_ANALYZER_CONFIG as y,
|
|
14269
14681
|
AUDIO_BACKEND_CHOICES as z
|
|
14270
14682
|
};
|
|
14271
|
-
//# sourceMappingURL=index-
|
|
14683
|
+
//# sourceMappingURL=index-Bmlkm0Fd.mjs.map
|