@camstack/addon-pipeline 1.1.64 → 1.1.66
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 +1 -1
- package/dist/audio-analyzer/index.mjs +1 -1
- package/dist/detection-pipeline/index.js +188 -26
- package/dist/detection-pipeline/index.mjs +188 -26
- package/dist/{dist-BzVZ2I4P.mjs → dist-BpWot5-w.mjs} +13 -55
- package/dist/{dist-B2jTt7Lq.js → dist-D5o9fGxq.js} +13 -55
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/pipeline-runner/index.js +88 -22
- package/dist/pipeline-runner/index.mjs +88 -22
- package/dist/recorder/index.js +141 -1
- package/dist/recorder/index.mjs +141 -1
- package/dist/session-decode/decode-worker-child.js +9 -3
- package/dist/session-decode/decode-worker-child.mjs +9 -3
- package/dist/{step-definitions-DXkY5Zor.js → step-definitions-81eYyJbW.js} +138 -8
- package/dist/{step-definitions-B07M9qhj.mjs → step-definitions-D6R9X0V7.mjs} +138 -8
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-dTMki_1D.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CIIIVPzB.mjs} +2 -2
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CPbLcza9.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-DlALQ_wp.mjs +26 -0
- package/dist/stream-broker/{hostInit-BY2oQAEX.mjs → hostInit-CeBNudbY.mjs} +2 -2
- package/dist/stream-broker/index.js +51 -3
- package/dist/stream-broker/index.mjs +51 -3
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/embed-dist/assets/{MaskShapeCanvas-DI4BY7W2-C03fx7Sp.js → MaskShapeCanvas-DI4BY7W2-CbBbcdZb.js} +1 -1
- package/embed-dist/assets/{MotionZonesSettings-NcxxQN8r-BTxzn1rQ.js → MotionZonesSettings-NcxxQN8r-aA6zvms_.js} +1 -1
- package/embed-dist/assets/{PrivacyMaskSettings-APgPLF7p-GKO8O7rC.js → PrivacyMaskSettings-APgPLF7p-CcGB7iAE.js} +1 -1
- package/embed-dist/assets/index-BRG_Fqb5.js +114 -0
- package/embed-dist/assets/index-D2pF9Z3W.css +2 -0
- package/embed-dist/index.html +2 -2
- package/package.json +1 -1
- package/python/inference_pool.py +30 -0
- package/python/postprocessors/scrfd.py +4 -1
- package/python/postprocessors/softmax.py +17 -5
- package/python/postprocessors/test_softmax.py +52 -0
- package/python/postprocessors/test_yolo_nms.py +45 -0
- package/python/postprocessors/yolo.py +4 -1
- package/python/postprocessors/yolo_seg.py +4 -1
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-bAh96WNb.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-CV2WbUaO.mjs +0 -26
- package/embed-dist/assets/index-Bm9LaQPH.css +0 -2
- package/embed-dist/assets/index-QdssILAA.js +0 -81
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __require } from "../chunk-BdkLduGY.mjs";
|
|
2
|
-
import { $ as sleep, A as pipelineExecutorCapability, B as errMsg, C as evaluateZoneRules, F as runtimeDevices$1, G as createEvent, K as hydrateSchema, R as supportedRuntimes$1, S as detectionPipelineCapability, V as BaseAddon, X as parseJsonUnknown, b as defaultDeviceFor$1, dt as EventCategory, k as nodePin, m as YAMNET_TO_MACRO, t as APPLE_SA_TO_MACRO } from "../dist-
|
|
3
|
-
import { a as getStepDefinition, i as getStep, n as ALL_STEPS, o as resolveModelForFormat, r as getDefaultModelForFormat, t as ALL_PIPELINE_STEPS } from "../step-definitions-
|
|
2
|
+
import { $ as sleep, A as pipelineExecutorCapability, B as errMsg, C as evaluateZoneRules, F as runtimeDevices$1, G as createEvent, K as hydrateSchema, R as supportedRuntimes$1, S as detectionPipelineCapability, V as BaseAddon, X as parseJsonUnknown, b as defaultDeviceFor$1, dt as EventCategory, k as nodePin, lt as string, m as YAMNET_TO_MACRO, st as object, t as APPLE_SA_TO_MACRO, tt as array, ut as union } from "../dist-BpWot5-w.mjs";
|
|
3
|
+
import { a as getStepDefinition, i as getStep, n as ALL_STEPS, o as resolveModelForFormat, r as getDefaultModelForFormat, t as ALL_PIPELINE_STEPS } from "../step-definitions-D6R9X0V7.mjs";
|
|
4
4
|
import { t as pickNodePlatformArch } from "../node-topology-platform-BkR_k6WT.mjs";
|
|
5
5
|
import { a as ensureModel, o as isModelDownloaded, r as deleteModelFromDisk } from "../model-download-service-Cp9f4dk6-CwUb5v3Y.mjs";
|
|
6
6
|
import { spawn } from "node:child_process";
|
|
@@ -308,7 +308,7 @@ function projectNodeEngine(store, nodeId) {
|
|
|
308
308
|
//#endregion
|
|
309
309
|
//#region src/detection-pipeline/default-detection-model.ts
|
|
310
310
|
/** The object-detection step id — the only slot this resolver applies to. */
|
|
311
|
-
var OBJECT_DETECTION_STEP_ID = "object-detection";
|
|
311
|
+
var OBJECT_DETECTION_STEP_ID$1 = "object-detection";
|
|
312
312
|
/**
|
|
313
313
|
* Balanced default object-detection model per accelerator class (measured on
|
|
314
314
|
* COCO val2017). `'cpu'` maps to `null` → the caller substitutes the step's
|
|
@@ -368,7 +368,7 @@ function classifyAccelerator(backend, device) {
|
|
|
368
368
|
function resolveDefaultDetectionModel(backend, device, format, getStepDef = getStepDefinition) {
|
|
369
369
|
let def;
|
|
370
370
|
try {
|
|
371
|
-
def = getStepDef(OBJECT_DETECTION_STEP_ID);
|
|
371
|
+
def = getStepDef(OBJECT_DETECTION_STEP_ID$1);
|
|
372
372
|
} catch {
|
|
373
373
|
return "yolo26n";
|
|
374
374
|
}
|
|
@@ -943,6 +943,9 @@ function serializeModelConfig(config) {
|
|
|
943
943
|
postprocessor: config.postprocessor,
|
|
944
944
|
confidence: config.confidence
|
|
945
945
|
};
|
|
946
|
+
if (config.nmsIouThreshold !== void 0) result["nmsIouThreshold"] = config.nmsIouThreshold;
|
|
947
|
+
if (config.inputNormalization !== void 0) result["inputNormalization"] = config.inputNormalization;
|
|
948
|
+
if (config.outputProbabilities !== void 0) result["outputProbabilities"] = config.outputProbabilities;
|
|
946
949
|
if (config.inputWidth !== void 0) result["inputWidth"] = config.inputWidth;
|
|
947
950
|
if (config.inputHeight !== void 0) result["inputHeight"] = config.inputHeight;
|
|
948
951
|
if (config.inputChannels !== void 0) result["inputChannels"] = config.inputChannels;
|
|
@@ -1250,6 +1253,55 @@ var RUNTIME_TO_FORMAT = {
|
|
|
1250
1253
|
onnxruntime: "onnx",
|
|
1251
1254
|
edgetpu: "tflite"
|
|
1252
1255
|
};
|
|
1256
|
+
/** The step whose detections are re-filtered downstream by the executor's
|
|
1257
|
+
* per-macro `minConfidence*` sliders (`matchesMacroFilter`). Its pool-side
|
|
1258
|
+
* floor must stay BELOW those sliders or it silently pre-empts them. */
|
|
1259
|
+
var OBJECT_DETECTION_STEP_ID = "object-detection";
|
|
1260
|
+
/**
|
|
1261
|
+
* Pool-side confidence FLOOR for the object-detection step (#4 foot-gun fix).
|
|
1262
|
+
*
|
|
1263
|
+
* The pool used to receive `def.defaultConfidence` (0.5) as its floor and drop
|
|
1264
|
+
* every box < 0.5 BEFORE the executor's per-macro `minConfidence*` sliders run —
|
|
1265
|
+
* so a slider set below 0.5 was a silent no-op. Lower the pool floor to a small
|
|
1266
|
+
* constant so the operator-visible per-macro sliders are the authoritative
|
|
1267
|
+
* filter across their full 0–1 range. The per-macro slider DEFAULTS stay at 0.5
|
|
1268
|
+
* (see `step-definitions.ts` getConfigSchema), so default UI behaviour is
|
|
1269
|
+
* unchanged; only sub-0.5 sliders start having an effect. Non-object-detection
|
|
1270
|
+
* steps keep their own `def.defaultConfidence` floor (no per-macro re-filter). */
|
|
1271
|
+
var OBJECT_DETECTION_POOL_CONFIDENCE_FLOOR = .05;
|
|
1272
|
+
/**
|
|
1273
|
+
* Resolve the pool-side confidence FLOOR for a step (#4). The object-detection
|
|
1274
|
+
* step gets the small {@link OBJECT_DETECTION_POOL_CONFIDENCE_FLOOR} so its
|
|
1275
|
+
* per-macro `minConfidence*` sliders (applied downstream by the executor) are
|
|
1276
|
+
* the authoritative filter; every other step keeps its own `defaultConfidence`.
|
|
1277
|
+
*/
|
|
1278
|
+
function resolvePoolConfidenceFloor(stepId, defaultConfidence) {
|
|
1279
|
+
return stepId === OBJECT_DETECTION_STEP_ID ? OBJECT_DETECTION_POOL_CONFIDENCE_FLOOR : defaultConfidence;
|
|
1280
|
+
}
|
|
1281
|
+
/**
|
|
1282
|
+
* Load a model's runtime label list from its `-labels.json` extraFile, if any.
|
|
1283
|
+
*
|
|
1284
|
+
* Accepts BOTH on-disk shapes:
|
|
1285
|
+
* - a flat `string[]` (legacy label files), and
|
|
1286
|
+
* - a `{ "labels": string[], ... }` metadata object (the newer format the
|
|
1287
|
+
* animal / bird / vehicle classifiers ship, which also carries preprocess /
|
|
1288
|
+
* license metadata alongside the label array).
|
|
1289
|
+
*
|
|
1290
|
+
* Returns `undefined` when the model declares no `-labels.json`, the file is
|
|
1291
|
+
* absent, or its contents are not a recognised label shape — the caller then
|
|
1292
|
+
* falls back to the step's `def.labels`.
|
|
1293
|
+
*/
|
|
1294
|
+
var LabelsFileSchema = union([array(string()).readonly(), object({ labels: array(string()).readonly() })]);
|
|
1295
|
+
function readModelLabels(modelsDir, modelEntry) {
|
|
1296
|
+
const labelsFile = modelEntry.extraFiles?.find((f) => f.filename.endsWith("-labels.json"));
|
|
1297
|
+
if (!labelsFile) return void 0;
|
|
1298
|
+
const labelsPath = path$1.join(modelsDir, labelsFile.filename);
|
|
1299
|
+
if (!fs.existsSync(labelsPath)) return void 0;
|
|
1300
|
+
const parsed = LabelsFileSchema.safeParse(JSON.parse(fs.readFileSync(labelsPath, "utf8")));
|
|
1301
|
+
if (!parsed.success) return void 0;
|
|
1302
|
+
const data = parsed.data;
|
|
1303
|
+
return "labels" in data ? data.labels : data;
|
|
1304
|
+
}
|
|
1253
1305
|
var EngineFactory = class {
|
|
1254
1306
|
pool = null;
|
|
1255
1307
|
poolManager = null;
|
|
@@ -1417,14 +1469,7 @@ var EngineFactory = class {
|
|
|
1417
1469
|
const inputHeight = modelEntry.inputSize.height;
|
|
1418
1470
|
const inputSize = Math.max(inputWidth, inputHeight);
|
|
1419
1471
|
const inputChannels = modelEntry.inputChannels ?? 3;
|
|
1420
|
-
|
|
1421
|
-
if (!labels && modelEntry.extraFiles) {
|
|
1422
|
-
const labelsFile = modelEntry.extraFiles.find((f) => f.filename.endsWith("-labels.json"));
|
|
1423
|
-
if (labelsFile) {
|
|
1424
|
-
const labelsPath = path$1.join(this.opts.modelsDir, labelsFile.filename);
|
|
1425
|
-
if (fs.existsSync(labelsPath)) labels = JSON.parse(fs.readFileSync(labelsPath, "utf8"));
|
|
1426
|
-
}
|
|
1427
|
-
}
|
|
1472
|
+
const labels = readModelLabels(this.opts.modelsDir, modelEntry) ?? def.labels;
|
|
1428
1473
|
return {
|
|
1429
1474
|
path: modelPath,
|
|
1430
1475
|
inputSize,
|
|
@@ -1432,8 +1477,11 @@ var EngineFactory = class {
|
|
|
1432
1477
|
inputHeight,
|
|
1433
1478
|
inputChannels,
|
|
1434
1479
|
preprocessMode: modelEntry.preprocessMode ?? "letterbox",
|
|
1480
|
+
inputNormalization: modelEntry.inputNormalization,
|
|
1481
|
+
outputProbabilities: modelEntry.outputProbabilities,
|
|
1435
1482
|
postprocessor: modelEntry.postprocessor ?? def.postprocessor,
|
|
1436
|
-
confidence: def.defaultConfidence,
|
|
1483
|
+
confidence: resolvePoolConfidenceFloor(stepId, def.defaultConfidence),
|
|
1484
|
+
nmsIouThreshold: this.opts.nmsIouThreshold ?? .45,
|
|
1437
1485
|
labels,
|
|
1438
1486
|
charset: def.charset,
|
|
1439
1487
|
numClasses: labels?.length,
|
|
@@ -1552,6 +1600,9 @@ var EngineProvisioner = class {
|
|
|
1552
1600
|
};
|
|
1553
1601
|
//#endregion
|
|
1554
1602
|
//#region src/detection-pipeline/postprocess/dispatch.ts
|
|
1603
|
+
/** Detector NMS IoU fallback — the historical hardcoded literal, used when the
|
|
1604
|
+
* step carries no `nmsIouThreshold` setting (unset == today). */
|
|
1605
|
+
var DEFAULT_NMS_IOU = .45;
|
|
1555
1606
|
var VALID_KINDS = new Set([
|
|
1556
1607
|
"detections",
|
|
1557
1608
|
"classifications",
|
|
@@ -1579,7 +1630,7 @@ function tryStructured(output) {
|
|
|
1579
1630
|
if (!isStepOutput(output.structured)) throw new Error(`Python pool returned structured output with unexpected kind: ${JSON.stringify(output.structured["kind"])}`);
|
|
1580
1631
|
return output.structured;
|
|
1581
1632
|
}
|
|
1582
|
-
function postprocessYolo(output, stepDef) {
|
|
1633
|
+
function postprocessYolo(output, stepDef, nmsIouThreshold) {
|
|
1583
1634
|
const structured = tryStructured(output);
|
|
1584
1635
|
if (structured) return structured;
|
|
1585
1636
|
const tensor = output.tensor;
|
|
@@ -1628,7 +1679,7 @@ function postprocessYolo(output, stepDef) {
|
|
|
1628
1679
|
}
|
|
1629
1680
|
return {
|
|
1630
1681
|
kind: "detections",
|
|
1631
|
-
detections: simpleNms(dets,
|
|
1682
|
+
detections: simpleNms(dets, nmsIouThreshold)
|
|
1632
1683
|
};
|
|
1633
1684
|
}
|
|
1634
1685
|
function postprocessSsd(output, _stepDef) {
|
|
@@ -1636,7 +1687,7 @@ function postprocessSsd(output, _stepDef) {
|
|
|
1636
1687
|
if (structured) return structured;
|
|
1637
1688
|
throw new Error("SSD postprocessing runs in the Python inference pool (ssd.py); no TypeScript raw-tensor path.");
|
|
1638
1689
|
}
|
|
1639
|
-
function postprocessScrfd(output, stepDef) {
|
|
1690
|
+
function postprocessScrfd(output, stepDef, nmsIouThreshold) {
|
|
1640
1691
|
const structured = tryStructured(output);
|
|
1641
1692
|
if (structured) return structured;
|
|
1642
1693
|
if (!output.tensors) throw new Error("SCRFD postprocessor: no tensors in engine output");
|
|
@@ -1714,7 +1765,7 @@ function postprocessScrfd(output, stepDef) {
|
|
|
1714
1765
|
score: c.score,
|
|
1715
1766
|
bbox: c.bbox,
|
|
1716
1767
|
...c.landmarks ? { landmarks: c.landmarks } : {}
|
|
1717
|
-
})),
|
|
1768
|
+
})), nmsIouThreshold)
|
|
1718
1769
|
};
|
|
1719
1770
|
}
|
|
1720
1771
|
/** Match ONNX output tensors to SCRFD strides by expected anchor count. */
|
|
@@ -1919,7 +1970,7 @@ function postprocessSaliency(output, _stepDef) {
|
|
|
1919
1970
|
maskHeight: side
|
|
1920
1971
|
};
|
|
1921
1972
|
}
|
|
1922
|
-
function postprocessYoloSeg(output, stepDef) {
|
|
1973
|
+
function postprocessYoloSeg(output, stepDef, nmsIouThreshold) {
|
|
1923
1974
|
const structured = tryStructured(output);
|
|
1924
1975
|
if (structured) return structured;
|
|
1925
1976
|
const tensors = output.tensors;
|
|
@@ -2044,7 +2095,7 @@ function postprocessYoloSeg(output, stepDef) {
|
|
|
2044
2095
|
class: d.class,
|
|
2045
2096
|
score: d.score,
|
|
2046
2097
|
bbox: d.bbox
|
|
2047
|
-
})),
|
|
2098
|
+
})), nmsIouThreshold);
|
|
2048
2099
|
const keptSet = new Set(keptBoxes.map((d) => `${d.bbox[0]}_${d.bbox[1]}_${d.bbox[2]}_${d.bbox[3]}_${d.score}`));
|
|
2049
2100
|
return {
|
|
2050
2101
|
kind: "detections",
|
|
@@ -2077,10 +2128,11 @@ var DISPATCH = {
|
|
|
2077
2128
|
* Both paths pass through normalizeOutput() to ensure consistent format
|
|
2078
2129
|
* (e.g., classification top-K, alternates).
|
|
2079
2130
|
*/
|
|
2080
|
-
function dispatchPostprocess(output, stepDef) {
|
|
2131
|
+
function dispatchPostprocess(output, stepDef, settings) {
|
|
2081
2132
|
const fn = DISPATCH[stepDef.postprocessor];
|
|
2082
2133
|
if (!fn) throw new Error(`Unknown postprocessor type: "${stepDef.postprocessor}"`);
|
|
2083
|
-
|
|
2134
|
+
const raw = settings?.["nmsIouThreshold"];
|
|
2135
|
+
return normalizeOutput(fn(output, stepDef, typeof raw === "number" && raw > 0 ? raw : DEFAULT_NMS_IOU));
|
|
2084
2136
|
}
|
|
2085
2137
|
/**
|
|
2086
2138
|
* Normalize any StepOutput to a consistent format.
|
|
@@ -2545,7 +2597,8 @@ function applyChildOutput(parent, childStep, output, stepLatencyMs, ctx) {
|
|
|
2545
2597
|
case "classifications": {
|
|
2546
2598
|
const rawEnabled = childStep.settings?.["enabledClasses"];
|
|
2547
2599
|
const enabledSet = Array.isArray(rawEnabled) && rawEnabled.length > 0 ? new Set(rawEnabled.filter((v) => typeof v === "string")) : null;
|
|
2548
|
-
const
|
|
2600
|
+
const rejectSet = childStep.definition.rejectClasses && childStep.definition.rejectClasses.length > 0 ? new Set(childStep.definition.rejectClasses.map((c) => c.toLowerCase())) : /* @__PURE__ */ new Set();
|
|
2601
|
+
const passesClass = (c) => (enabledSet === null || enabledSet.has(c.class)) && !rejectSet.has(c.class.toLowerCase());
|
|
2549
2602
|
const minConfidence = typeof childStep.settings?.["minConfidence"] === "number" ? childStep.settings["minConfidence"] : 0;
|
|
2550
2603
|
const winner = output.classifications[0];
|
|
2551
2604
|
if (winner && passesClass(winner) && winner.score >= minConfidence) parent.ownLabels.push({
|
|
@@ -2881,6 +2934,26 @@ var NATIVE_FACE_CROP_MAX_WIDTH = 320;
|
|
|
2881
2934
|
function isEnrichmentOutput(output) {
|
|
2882
2935
|
return output.kind === "classifications" || output.kind === "embedding" || output.kind === "text";
|
|
2883
2936
|
}
|
|
2937
|
+
/**
|
|
2938
|
+
* Re-project a `crop-zone` root's detections from crop-relative coordinates
|
|
2939
|
+
* back to full-frame image space by the crop's origin — the root analogue of
|
|
2940
|
+
* the crop-roi child re-projection (`transformBboxToImageSpace`). Landmarks (if
|
|
2941
|
+
* any) are shifted by the same origin. Immutable: returns a fresh output.
|
|
2942
|
+
*/
|
|
2943
|
+
function reprojectCropZoneDetections(output, cropOrigin) {
|
|
2944
|
+
const [ox, oy] = cropOrigin;
|
|
2945
|
+
return {
|
|
2946
|
+
kind: "detections",
|
|
2947
|
+
detections: output.detections.map((det) => ({
|
|
2948
|
+
...det,
|
|
2949
|
+
bbox: transformBboxToImageSpace(det.bbox, cropOrigin),
|
|
2950
|
+
...det.landmarks ? { landmarks: det.landmarks.map((l) => ({
|
|
2951
|
+
x: l.x + ox,
|
|
2952
|
+
y: l.y + oy
|
|
2953
|
+
})) } : {}
|
|
2954
|
+
}))
|
|
2955
|
+
};
|
|
2956
|
+
}
|
|
2884
2957
|
var PipelineExecutor = class {
|
|
2885
2958
|
opts;
|
|
2886
2959
|
constructor(opts) {
|
|
@@ -2934,7 +3007,7 @@ var PipelineExecutor = class {
|
|
|
2934
3007
|
*
|
|
2935
3008
|
* @returns FrameResult + optional trace
|
|
2936
3009
|
*/
|
|
2937
|
-
async run(tree, rootInput, fullFrameJpegProvider, imageWidth, imageHeight, deviceId, runOpts, nativeFaceCropProvider) {
|
|
3010
|
+
async run(tree, rootInput, fullFrameJpegProvider, imageWidth, imageHeight, deviceId, runOpts, nativeFaceCropProvider, cropZoneBbox) {
|
|
2938
3011
|
const startMs = Date.now();
|
|
2939
3012
|
const verbosity = runOpts?.traceVerbosity ?? "off";
|
|
2940
3013
|
const traceBuilder = new ExecutionTraceBuilder(verbosity, deviceId, imageWidth, imageHeight, this.opts.engineRuntime);
|
|
@@ -2954,9 +3027,11 @@ var PipelineExecutor = class {
|
|
|
2954
3027
|
};
|
|
2955
3028
|
for (const rootStep of tree.roots) {
|
|
2956
3029
|
if (debug) console.log(`[executor] rootStep=${rootStep.stepId} settings=${JSON.stringify(rootStep.settings ?? {})}`);
|
|
3030
|
+
const cropPrep = rootStep.definition.extractMode === "crop-zone" && cropZoneBbox !== void 0 ? await this.prepareCropZoneInput(cropZoneBbox, fullFrameJpegProvider, imageWidth, imageHeight, deviceId) : null;
|
|
2957
3031
|
const rootStart = Date.now();
|
|
2958
|
-
const
|
|
3032
|
+
const rawRootOutput = await this.executeStep(rootStep, cropPrep?.input ?? rootInput, cropPrep?.width ?? imageWidth, cropPrep?.height ?? imageHeight, "full-frame", void 0, void 0, traceBuilder, stepTimings, poolAgg);
|
|
2959
3033
|
const rootMs = Date.now() - rootStart;
|
|
3034
|
+
const rootOutput = cropPrep && rawRootOutput.kind === "detections" ? reprojectCropZoneDetections(rawRootOutput, cropPrep.origin) : rawRootOutput;
|
|
2960
3035
|
if (rootOutput.kind !== "detections") {
|
|
2961
3036
|
if (isEnrichmentOutput(rootOutput)) {
|
|
2962
3037
|
const mutable = this.synthesizeRootDetection(rootOutput, rootStep, idGen, rootMs, imageWidth, imageHeight);
|
|
@@ -3051,6 +3126,39 @@ var PipelineExecutor = class {
|
|
|
3051
3126
|
]
|
|
3052
3127
|
}, rootStep, idGen, rootStepLatencyMs);
|
|
3053
3128
|
}
|
|
3129
|
+
/**
|
|
3130
|
+
* Crop the full frame to a `crop-zone` root's absolute-pixel zone bbox and
|
|
3131
|
+
* return the cropped JPEG input + the exact origin used, so detections can be
|
|
3132
|
+
* re-projected. Returns null (⇒ full-frame fallback) when the bbox is
|
|
3133
|
+
* degenerate or the crop/encode fails — a package frame is never dropped for
|
|
3134
|
+
* a crop failure. The origin is computed to match `cropJpeg`'s clamp+round
|
|
3135
|
+
* exactly so the re-projection is pixel-accurate.
|
|
3136
|
+
*/
|
|
3137
|
+
async prepareCropZoneInput(cropZoneBbox, fullFrameJpegProvider, imageWidth, imageHeight, deviceId) {
|
|
3138
|
+
if (isBboxDegenerate(cropZoneBbox)) return null;
|
|
3139
|
+
try {
|
|
3140
|
+
const crop = await cropJpeg(await fullFrameJpegProvider(), cropZoneBbox, imageWidth, imageHeight);
|
|
3141
|
+
const ox = Math.max(0, Math.round(cropZoneBbox[0]));
|
|
3142
|
+
const oy = Math.max(0, Math.round(cropZoneBbox[1]));
|
|
3143
|
+
return {
|
|
3144
|
+
input: {
|
|
3145
|
+
kind: "jpeg",
|
|
3146
|
+
data: crop.jpeg
|
|
3147
|
+
},
|
|
3148
|
+
width: crop.width,
|
|
3149
|
+
height: crop.height,
|
|
3150
|
+
origin: [
|
|
3151
|
+
ox,
|
|
3152
|
+
oy,
|
|
3153
|
+
ox + crop.width,
|
|
3154
|
+
oy + crop.height
|
|
3155
|
+
]
|
|
3156
|
+
};
|
|
3157
|
+
} catch (err) {
|
|
3158
|
+
this.throttledWarn(`crop-zone-prep:${deviceId}`, 3e4, "crop-zone frame preparation failed — running package-detection full-frame", { error: errMsg(err) }, deviceId);
|
|
3159
|
+
return null;
|
|
3160
|
+
}
|
|
3161
|
+
}
|
|
3054
3162
|
async executeStep(step, input, inputWidth, inputHeight, inputType, _parentBbox, parentClass, traceBuilder, stepTimings, poolAgg) {
|
|
3055
3163
|
const preprocessStart = Date.now();
|
|
3056
3164
|
const preprocessMs = Date.now() - preprocessStart;
|
|
@@ -3093,7 +3201,7 @@ var PipelineExecutor = class {
|
|
|
3093
3201
|
if (typeof structured.predictMs === "number") poolAgg.predictMs += structured.predictMs;
|
|
3094
3202
|
if (typeof structured.batchSize === "number" && structured.batchSize > poolAgg.batchSize) poolAgg.batchSize = structured.batchSize;
|
|
3095
3203
|
const postprocessStart = Date.now();
|
|
3096
|
-
const output = dispatchPostprocess(engineOutput, step.definition);
|
|
3204
|
+
const output = dispatchPostprocess(engineOutput, step.definition, step.settings);
|
|
3097
3205
|
const postprocessMs = Date.now() - postprocessStart;
|
|
3098
3206
|
stepTimings.push({
|
|
3099
3207
|
source: step.stepId,
|
|
@@ -3240,6 +3348,54 @@ function capitalize(s) {
|
|
|
3240
3348
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
3241
3349
|
}
|
|
3242
3350
|
//#endregion
|
|
3351
|
+
//#region src/detection-pipeline/pipeline/crop-zone.ts
|
|
3352
|
+
/**
|
|
3353
|
+
* Resolve the absolute-pixel crop bbox for a `crop-zone` root detector: the
|
|
3354
|
+
* bounding box of the UNION of every polygon referenced by the device's
|
|
3355
|
+
* ENABLED `package`-stage zone rules. Zone polygons are normalized (0..1); the
|
|
3356
|
+
* union is clamped to [0,1] then scaled to the frame's pixel dimensions.
|
|
3357
|
+
*
|
|
3358
|
+
* Returns `null` when there is nothing usable to crop to — no enabled rules, no
|
|
3359
|
+
* referenced geometry, or a degenerate result — in which case the caller falls
|
|
3360
|
+
* back to full-frame inference (behaviour identical to before the crop-zone
|
|
3361
|
+
* plumbing).
|
|
3362
|
+
*/
|
|
3363
|
+
function resolvePackageCropBbox(zones, packageRules, frameWidth, frameHeight) {
|
|
3364
|
+
if (frameWidth <= 0 || frameHeight <= 0) return null;
|
|
3365
|
+
const enabledRules = packageRules.filter((r) => r.enabled !== false);
|
|
3366
|
+
if (enabledRules.length === 0) return null;
|
|
3367
|
+
const zoneIds = /* @__PURE__ */ new Set();
|
|
3368
|
+
for (const rule of enabledRules) for (const id of rule.zoneIds) zoneIds.add(id);
|
|
3369
|
+
if (zoneIds.size === 0) return null;
|
|
3370
|
+
const zoneById = new Map(zones.map((z) => [z.id, z]));
|
|
3371
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
3372
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
3373
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
3374
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
3375
|
+
let sawPoint = false;
|
|
3376
|
+
for (const id of zoneIds) {
|
|
3377
|
+
const zone = zoneById.get(id);
|
|
3378
|
+
if (!zone || zone.polygon.length === 0) continue;
|
|
3379
|
+
for (const point of zone.polygon) {
|
|
3380
|
+
sawPoint = true;
|
|
3381
|
+
if (point.x < minX) minX = point.x;
|
|
3382
|
+
if (point.y < minY) minY = point.y;
|
|
3383
|
+
if (point.x > maxX) maxX = point.x;
|
|
3384
|
+
if (point.y > maxY) maxY = point.y;
|
|
3385
|
+
}
|
|
3386
|
+
}
|
|
3387
|
+
if (!sawPoint) return null;
|
|
3388
|
+
const clamp01 = (v) => Math.max(0, Math.min(1, v));
|
|
3389
|
+
const bbox = [
|
|
3390
|
+
clamp01(minX) * frameWidth,
|
|
3391
|
+
clamp01(minY) * frameHeight,
|
|
3392
|
+
clamp01(maxX) * frameWidth,
|
|
3393
|
+
clamp01(maxY) * frameHeight
|
|
3394
|
+
];
|
|
3395
|
+
if (isBboxDegenerate(bbox)) return null;
|
|
3396
|
+
return bbox;
|
|
3397
|
+
}
|
|
3398
|
+
//#endregion
|
|
3243
3399
|
//#region src/detection-pipeline/pipeline/tree-builder.ts
|
|
3244
3400
|
/**
|
|
3245
3401
|
* Build an executable tree from user config.
|
|
@@ -4977,10 +5133,16 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
|
|
|
4977
5133
|
const deviceOverrides = effectiveDeviceId > 0 ? await this.readDeviceStore(effectiveDeviceId) : {};
|
|
4978
5134
|
const effectiveTree = Object.keys(deviceOverrides).length > 0 ? applyDeviceOverridesToTree(tree, "object-detection", deviceOverrides) : tree;
|
|
4979
5135
|
const nativeFaceCropProvider = this.buildNativeFaceCropProvider(input.frameHandle);
|
|
5136
|
+
let cropZoneBbox;
|
|
5137
|
+
if (isRuntime && effectiveDeviceId > 0 && effectiveTree.roots.some((r) => r.definition.extractMode === "crop-zone")) {
|
|
5138
|
+
await this.ensureDeviceProxy(effectiveDeviceId);
|
|
5139
|
+
const proxy = this.deviceProxies.get(effectiveDeviceId);
|
|
5140
|
+
if (proxy) cropZoneBbox = resolvePackageCropBbox(proxy.state.zones.value?.zones ?? [], proxy.state.zoneRules.value?.package ?? [], imageWidth, imageHeight) ?? void 0;
|
|
5141
|
+
}
|
|
4980
5142
|
const { result, trace } = await executor.run(effectiveTree, rootInput, jpegProvider, imageWidth, imageHeight, effectiveDeviceId, {
|
|
4981
5143
|
traceVerbosity: isRuntime ? this.eventBus ? "summary" : "off" : "full",
|
|
4982
5144
|
plane: input.plane
|
|
4983
|
-
}, nativeFaceCropProvider);
|
|
5145
|
+
}, nativeFaceCropProvider, cropZoneBbox);
|
|
4984
5146
|
if (isRuntime) {
|
|
4985
5147
|
if (trace && this.eventBus) this.eventBus.emit(createEvent(EventCategory.PipelineTrace, {
|
|
4986
5148
|
type: "device",
|
|
@@ -7207,6 +7207,17 @@ var ModelCatalogEntrySchema = object({
|
|
|
7207
7207
|
"imagenet",
|
|
7208
7208
|
"none"
|
|
7209
7209
|
]).optional(),
|
|
7210
|
+
/**
|
|
7211
|
+
* The model already applies softmax IN-GRAPH — its raw output is a
|
|
7212
|
+
* probability distribution, not logits. When set, the `softmax`
|
|
7213
|
+
* postprocessor must NOT re-apply softmax: re-softmaxing an already-normalised
|
|
7214
|
+
* probability vector collapses it toward uniform (top-1 score craters far
|
|
7215
|
+
* below its true value, making every confidence gate meaningless). Absent ⇒
|
|
7216
|
+
* the output is raw logits and the postprocessor applies softmax (the normal
|
|
7217
|
+
* case). Set on the Google AIY Birds `bird-classifier` (softmax baked into the
|
|
7218
|
+
* TF graph). Threaded to the Python pool via `PoolModelConfig.outputProbabilities`.
|
|
7219
|
+
*/
|
|
7220
|
+
outputProbabilities: boolean().optional(),
|
|
7210
7221
|
preprocessMode: _enum(["letterbox", "resize"]).optional(),
|
|
7211
7222
|
/**
|
|
7212
7223
|
* Per-MODEL postprocessor override. Absent ⇒ the step's own
|
|
@@ -14087,6 +14098,8 @@ method(_void(), _void(), { kind: "mutation" }), method(_void(), _void(), { kind:
|
|
|
14087
14098
|
kind: "mutation",
|
|
14088
14099
|
auth: "admin"
|
|
14089
14100
|
});
|
|
14101
|
+
DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Camera, DeviceType.Hub, DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder;
|
|
14102
|
+
new Set(Object.values(DeviceType));
|
|
14090
14103
|
/**
|
|
14091
14104
|
* Evaluate `rules` against `items`. Returns the items partitioned
|
|
14092
14105
|
* into `passed` (kept by the gate) and `excluded` (dropped). When
|
|
@@ -19617,22 +19630,6 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
|
|
|
19617
19630
|
var RestartAddonResultSchema = unknown();
|
|
19618
19631
|
var InstallPackageResultSchema = unknown();
|
|
19619
19632
|
var ReloadPackagesResultSchema = unknown();
|
|
19620
|
-
/**
|
|
19621
|
-
* Result of `updateFrameworkPackage`. The cap method returns BEFORE the
|
|
19622
|
-
* server restarts so the admin UI can react to the `restartingAt`
|
|
19623
|
-
* timestamp (shows reconnect overlay). The transition from
|
|
19624
|
-
* `fromVersion` to `toVersion` will be confirmed by a subsequent
|
|
19625
|
-
* `system.restart-completed` event after the new process boots.
|
|
19626
|
-
*
|
|
19627
|
-
* Spec: docs/superpowers/specs/2026-05-14-framework-live-update-design.md
|
|
19628
|
-
*/
|
|
19629
|
-
var UpdateFrameworkPackageResultSchema = object({
|
|
19630
|
-
packageName: string(),
|
|
19631
|
-
fromVersion: string(),
|
|
19632
|
-
toVersion: string(),
|
|
19633
|
-
/** Ms-epoch the server scheduled its self-restart. */
|
|
19634
|
-
restartingAt: number()
|
|
19635
|
-
});
|
|
19636
19633
|
var BulkUpdateItemStatusSchema = _enum([
|
|
19637
19634
|
"queued",
|
|
19638
19635
|
"updating",
|
|
@@ -19760,13 +19757,6 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
|
|
|
19760
19757
|
}), object({ success: literal(true) }), {
|
|
19761
19758
|
kind: "mutation",
|
|
19762
19759
|
auth: "admin"
|
|
19763
|
-
}), method(object({
|
|
19764
|
-
packageName: string().min(1),
|
|
19765
|
-
version: string().optional(),
|
|
19766
|
-
deferRestart: boolean().optional()
|
|
19767
|
-
}), UpdateFrameworkPackageResultSchema, {
|
|
19768
|
-
kind: "mutation",
|
|
19769
|
-
auth: "admin"
|
|
19770
19760
|
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
19771
19761
|
kind: "mutation",
|
|
19772
19762
|
auth: "admin"
|
|
@@ -21975,12 +21965,6 @@ Object.freeze({
|
|
|
21975
21965
|
addonId: null,
|
|
21976
21966
|
access: "delete"
|
|
21977
21967
|
},
|
|
21978
|
-
"addons.updateFrameworkPackage": {
|
|
21979
|
-
capName: "addons",
|
|
21980
|
-
capScope: "system",
|
|
21981
|
-
addonId: null,
|
|
21982
|
-
access: "create"
|
|
21983
|
-
},
|
|
21984
21968
|
"addons.updatePackage": {
|
|
21985
21969
|
capName: "addons",
|
|
21986
21970
|
capScope: "system",
|
|
@@ -26569,32 +26553,6 @@ Object.freeze({
|
|
|
26569
26553
|
"network-access": "ingress",
|
|
26570
26554
|
"smtp-provider": "email"
|
|
26571
26555
|
});
|
|
26572
|
-
var frameworkSwapPackageSchema = object({
|
|
26573
|
-
name: string(),
|
|
26574
|
-
stagedPath: string(),
|
|
26575
|
-
backupPath: string(),
|
|
26576
|
-
toVersion: string(),
|
|
26577
|
-
fromVersion: string().nullable()
|
|
26578
|
-
});
|
|
26579
|
-
object({
|
|
26580
|
-
jobId: string(),
|
|
26581
|
-
taskId: string(),
|
|
26582
|
-
packages: array(frameworkSwapPackageSchema),
|
|
26583
|
-
requestedAtMs: number(),
|
|
26584
|
-
schemaVersion: literal(1)
|
|
26585
|
-
});
|
|
26586
|
-
object({
|
|
26587
|
-
jobId: string(),
|
|
26588
|
-
taskId: string(),
|
|
26589
|
-
backups: array(object({
|
|
26590
|
-
name: string(),
|
|
26591
|
-
backupPath: string(),
|
|
26592
|
-
livePath: string()
|
|
26593
|
-
})),
|
|
26594
|
-
appliedAtMs: number(),
|
|
26595
|
-
bootAttempts: number(),
|
|
26596
|
-
schemaVersion: literal(1)
|
|
26597
|
-
});
|
|
26598
26556
|
/**
|
|
26599
26557
|
* Names that, when used as URL query parameters, almost certainly carry
|
|
26600
26558
|
* a secret. Matching is case-insensitive and anchored to the full param
|
|
@@ -7207,6 +7207,17 @@ var ModelCatalogEntrySchema = object({
|
|
|
7207
7207
|
"imagenet",
|
|
7208
7208
|
"none"
|
|
7209
7209
|
]).optional(),
|
|
7210
|
+
/**
|
|
7211
|
+
* The model already applies softmax IN-GRAPH — its raw output is a
|
|
7212
|
+
* probability distribution, not logits. When set, the `softmax`
|
|
7213
|
+
* postprocessor must NOT re-apply softmax: re-softmaxing an already-normalised
|
|
7214
|
+
* probability vector collapses it toward uniform (top-1 score craters far
|
|
7215
|
+
* below its true value, making every confidence gate meaningless). Absent ⇒
|
|
7216
|
+
* the output is raw logits and the postprocessor applies softmax (the normal
|
|
7217
|
+
* case). Set on the Google AIY Birds `bird-classifier` (softmax baked into the
|
|
7218
|
+
* TF graph). Threaded to the Python pool via `PoolModelConfig.outputProbabilities`.
|
|
7219
|
+
*/
|
|
7220
|
+
outputProbabilities: boolean().optional(),
|
|
7210
7221
|
preprocessMode: _enum(["letterbox", "resize"]).optional(),
|
|
7211
7222
|
/**
|
|
7212
7223
|
* Per-MODEL postprocessor override. Absent ⇒ the step's own
|
|
@@ -14087,6 +14098,8 @@ method(_void(), _void(), { kind: "mutation" }), method(_void(), _void(), { kind:
|
|
|
14087
14098
|
kind: "mutation",
|
|
14088
14099
|
auth: "admin"
|
|
14089
14100
|
});
|
|
14101
|
+
DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Camera, DeviceType.Hub, DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder;
|
|
14102
|
+
new Set(Object.values(DeviceType));
|
|
14090
14103
|
/**
|
|
14091
14104
|
* Evaluate `rules` against `items`. Returns the items partitioned
|
|
14092
14105
|
* into `passed` (kept by the gate) and `excluded` (dropped). When
|
|
@@ -19617,22 +19630,6 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
|
|
|
19617
19630
|
var RestartAddonResultSchema = unknown();
|
|
19618
19631
|
var InstallPackageResultSchema = unknown();
|
|
19619
19632
|
var ReloadPackagesResultSchema = unknown();
|
|
19620
|
-
/**
|
|
19621
|
-
* Result of `updateFrameworkPackage`. The cap method returns BEFORE the
|
|
19622
|
-
* server restarts so the admin UI can react to the `restartingAt`
|
|
19623
|
-
* timestamp (shows reconnect overlay). The transition from
|
|
19624
|
-
* `fromVersion` to `toVersion` will be confirmed by a subsequent
|
|
19625
|
-
* `system.restart-completed` event after the new process boots.
|
|
19626
|
-
*
|
|
19627
|
-
* Spec: docs/superpowers/specs/2026-05-14-framework-live-update-design.md
|
|
19628
|
-
*/
|
|
19629
|
-
var UpdateFrameworkPackageResultSchema = object({
|
|
19630
|
-
packageName: string(),
|
|
19631
|
-
fromVersion: string(),
|
|
19632
|
-
toVersion: string(),
|
|
19633
|
-
/** Ms-epoch the server scheduled its self-restart. */
|
|
19634
|
-
restartingAt: number()
|
|
19635
|
-
});
|
|
19636
19633
|
var BulkUpdateItemStatusSchema = _enum([
|
|
19637
19634
|
"queued",
|
|
19638
19635
|
"updating",
|
|
@@ -19760,13 +19757,6 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
|
|
|
19760
19757
|
}), object({ success: literal(true) }), {
|
|
19761
19758
|
kind: "mutation",
|
|
19762
19759
|
auth: "admin"
|
|
19763
|
-
}), method(object({
|
|
19764
|
-
packageName: string().min(1),
|
|
19765
|
-
version: string().optional(),
|
|
19766
|
-
deferRestart: boolean().optional()
|
|
19767
|
-
}), UpdateFrameworkPackageResultSchema, {
|
|
19768
|
-
kind: "mutation",
|
|
19769
|
-
auth: "admin"
|
|
19770
19760
|
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
19771
19761
|
kind: "mutation",
|
|
19772
19762
|
auth: "admin"
|
|
@@ -21975,12 +21965,6 @@ Object.freeze({
|
|
|
21975
21965
|
addonId: null,
|
|
21976
21966
|
access: "delete"
|
|
21977
21967
|
},
|
|
21978
|
-
"addons.updateFrameworkPackage": {
|
|
21979
|
-
capName: "addons",
|
|
21980
|
-
capScope: "system",
|
|
21981
|
-
addonId: null,
|
|
21982
|
-
access: "create"
|
|
21983
|
-
},
|
|
21984
21968
|
"addons.updatePackage": {
|
|
21985
21969
|
capName: "addons",
|
|
21986
21970
|
capScope: "system",
|
|
@@ -26569,32 +26553,6 @@ Object.freeze({
|
|
|
26569
26553
|
"network-access": "ingress",
|
|
26570
26554
|
"smtp-provider": "email"
|
|
26571
26555
|
});
|
|
26572
|
-
var frameworkSwapPackageSchema = object({
|
|
26573
|
-
name: string(),
|
|
26574
|
-
stagedPath: string(),
|
|
26575
|
-
backupPath: string(),
|
|
26576
|
-
toVersion: string(),
|
|
26577
|
-
fromVersion: string().nullable()
|
|
26578
|
-
});
|
|
26579
|
-
object({
|
|
26580
|
-
jobId: string(),
|
|
26581
|
-
taskId: string(),
|
|
26582
|
-
packages: array(frameworkSwapPackageSchema),
|
|
26583
|
-
requestedAtMs: number(),
|
|
26584
|
-
schemaVersion: literal(1)
|
|
26585
|
-
});
|
|
26586
|
-
object({
|
|
26587
|
-
jobId: string(),
|
|
26588
|
-
taskId: string(),
|
|
26589
|
-
backups: array(object({
|
|
26590
|
-
name: string(),
|
|
26591
|
-
backupPath: string(),
|
|
26592
|
-
livePath: string()
|
|
26593
|
-
})),
|
|
26594
|
-
appliedAtMs: number(),
|
|
26595
|
-
bootAttempts: number(),
|
|
26596
|
-
schemaVersion: literal(1)
|
|
26597
|
-
});
|
|
26598
26556
|
/**
|
|
26599
26557
|
* Names that, when used as URL query parameters, almost certainly carry
|
|
26600
26558
|
* a secret. Matching is case-insensitive and anchored to the full param
|
|
@@ -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-D5o9fGxq.js");
|
|
6
6
|
let node_fs = require("node:fs");
|
|
7
7
|
let node_path = require("node:path");
|
|
8
8
|
//#region src/motion-wasm/wasm-motion-detector.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as evaluateZoneRules, K as hydrateSchema, O as motionDetectionCapability, V as BaseAddon, W as DeviceType } from "../dist-
|
|
1
|
+
import { C as evaluateZoneRules, K as hydrateSchema, O as motionDetectionCapability, V as BaseAddon, W as DeviceType } from "../dist-BpWot5-w.mjs";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
//#region src/motion-wasm/wasm-motion-detector.ts
|