@camstack/ui-library 1.2.244 → 1.2.246
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/composites/accelerator-label.d.ts +17 -0
- package/dist/composites/agent-step-editor.d.ts +41 -16
- package/dist/composites/device-step-matrix.d.ts +26 -26
- package/dist/composites/index.d.ts +10 -12
- package/dist/composites/model-bound-slider.d.ts +8 -1
- package/dist/composites/pipeline-builder.d.ts +2 -37
- package/dist/composites/pipeline-matrix-shared.d.ts +11 -1
- package/dist/composites/pipeline-step.d.ts +4 -44
- package/dist/composites/step-inspector/accelerator-tabs.d.ts +12 -0
- package/dist/composites/step-inspector/gate-control.d.ts +20 -0
- package/dist/composites/step-inspector/index.d.ts +10 -0
- package/dist/composites/step-inspector/layered-settings-form.d.ts +38 -0
- package/dist/composites/step-inspector/segmented-choice.d.ts +11 -0
- package/dist/composites/step-inspector/setting-values.d.ts +19 -0
- package/dist/composites/step-inspector/step-detail-dock.d.ts +33 -0
- package/dist/composites/step-inspector/step-inspector-panel.d.ts +26 -0
- package/dist/composites/step-inspector/step-model-list.d.ts +9 -0
- package/dist/composites/step-inspector/step-model-row.d.ts +27 -0
- package/dist/composites/step-inspector/step-search.d.ts +18 -0
- package/dist/composites/{step-tree-master.d.ts → step-tree.d.ts} +0 -12
- package/dist/generated/system-hooks.d.ts +0 -16
- package/dist/index.cjs +1431 -1286
- package/dist/index.js +1407 -1278
- package/package.json +1 -1
- package/dist/composites/pipeline-tree-matrix.d.ts +0 -18
- package/dist/composites/slide-over-panel.d.ts +0 -35
- package/dist/lib/validate-template.d.ts +0 -2
package/dist/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { ThemeProvider, createTheme, darkColors, defaultTheme, lightColors, themeToCss, useThemeMode } from "./theme/index.js";
|
|
2
2
|
import * as __mfHostReact from "react";
|
|
3
|
-
import React, { Fragment, Suspense, createContext, createElement, forwardRef, lazy, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useReducer, useRef, useState, useSyncExternalStore } from "react";
|
|
3
|
+
import React, { Fragment, Suspense, createContext, createElement, forwardRef, lazy, useCallback, useContext, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState, useSyncExternalStore } from "react";
|
|
4
4
|
import * as __mfHostTrpcReactQuery from "@trpc/react-query";
|
|
5
5
|
import { createTRPCReact } from "@trpc/react-query";
|
|
6
6
|
import * as __mfHostReactJsxRuntime from "react/jsx-runtime";
|
|
7
7
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import * as __mfHostReactDOM from "react-dom";
|
|
9
9
|
import { createPortal } from "react-dom";
|
|
10
|
-
import { ALL_CAPABILITY_DEFINITIONS, CAM_PROFILE_ORDER, CLIP_STILL_DISPOSITION_HEADER, CLIP_STILL_REASON_CODE_HEADER, CLIP_STILL_REASON_HEADER, CONTAINER_CHILD_PRIORITY, DEFAULT_EVENTS_BAND_BUFFER_SEC, DEFAULT_EVENT_COLOR, DEVICE_TYPE_CONTROL_KIND, DISPLAY_ICON_GROUPS, DeviceExportStatusSchema, DeviceFeature, DeviceRole, DeviceType, EVENT_TAXONOMY, EXTENSION_SLOTS, EXTENSION_SLOT_IDS, EventCategory, ExposedDeviceSchema, FIRST_LEVEL_MACRO_CLASSES, KNOWN_CAP_NAMES, MAX_SENSOR_TRIGGER_DEVICES, MODEL_PROVIDER_IDS, NAVIGATION_LIGHT_LEVEL_MAX, NAVIGATION_LIGHT_LEVEL_MIN, PET_FEEDER_MANUAL_FEED_MAX, PET_FEEDER_MANUAL_FEED_MIN, RECORDING_AUDIO_TRIGGER_OFFERED_DBFS, RECORDING_SOURCE_CAMSTACK_ADDON, RecordingConfigSchema, RecordingStatusSchema, SOURCE_CAP_ACTIVE_FIELD, STATIONARY_OVERLAY_STYLE, TIMEZONES, USE_ROOT_MODEL_SETTING_KEY, buildModelVariantGroups, canConvertUnit, clearModelBoundOverrides, clearModelBoundSetting, clusterStepSettingFieldsFor, createDeviceProxy, createLazyTrpcSource, createSliceHandle, deriveRecordingMode, describeModelVariant, findTimezone, formatParkedFor, hasModelBoundOverrides, isRootSuppliableStepId, normalizeUnit, publicEventCategories, resolveContainerPrimaryChild, resolveDeviceControlKind, resolveModelBoundSetting, resolveRecordingProfiles, resolveRootSupply, resolveVariantModelId, resolveViewableDeviceIds, searchDisplayIcons, selectAssignedProfileSlots, tryConvertUnit, unitsForDimension, writeModelBoundSetting } from "@camstack/types";
|
|
10
|
+
import { ALL_CAPABILITY_DEFINITIONS, CAM_PROFILE_ORDER, CLIP_STILL_DISPOSITION_HEADER, CLIP_STILL_REASON_CODE_HEADER, CLIP_STILL_REASON_HEADER, CONTAINER_CHILD_PRIORITY, DEFAULT_EVENTS_BAND_BUFFER_SEC, DEFAULT_EVENT_COLOR, DEVICE_TYPE_CONTROL_KIND, DISPLAY_ICON_GROUPS, DeviceExportStatusSchema, DeviceFeature, DeviceRole, DeviceType, EVENT_TAXONOMY, EXTENSION_SLOTS, EXTENSION_SLOT_IDS, EventCategory, ExposedDeviceSchema, FIRST_LEVEL_MACRO_CLASSES, KNOWN_CAP_NAMES, MAX_SENSOR_TRIGGER_DEVICES, MODEL_PROVIDER_IDS, NAVIGATION_LIGHT_LEVEL_MAX, NAVIGATION_LIGHT_LEVEL_MIN, PET_FEEDER_MANUAL_FEED_MAX, PET_FEEDER_MANUAL_FEED_MIN, RECORDING_AUDIO_TRIGGER_OFFERED_DBFS, RECORDING_SOURCE_CAMSTACK_ADDON, RecordingConfigSchema, RecordingStatusSchema, SOURCE_CAP_ACTIVE_FIELD, STATIONARY_OVERLAY_STYLE, TIMEZONES, USE_ROOT_MODEL_SETTING_KEY, buildModelVariantGroups, canConvertUnit, clearModelBoundOverrides, clearModelBoundSetting, clusterStepSettingFieldsFor, collectModelBoundKeys, createDeviceProxy, createLazyTrpcSource, createSliceHandle, deriveRecordingMode, describeModelVariant, effectiveStepSettings, findTimezone, formatParkedFor, hasModelBoundOverrides, isRootSuppliableStepId, modelBindingKey, normalizeUnit, publicEventCategories, resolveContainerPrimaryChild, resolveDeviceControlKind, resolveModelBoundSetting, resolveRecordingProfiles, resolveRootSupply, resolveVariantModelId, resolveViewableDeviceIds, searchDisplayIcons, selectAssignedProfileSlots, stepSettingSource, tryConvertUnit, unitsForDimension, withFieldFrom, withoutField, writeModelBoundSetting } from "@camstack/types";
|
|
11
11
|
import * as __mfHostTanstackQuery from "@tanstack/react-query";
|
|
12
12
|
import { QueryClient, QueryClientProvider, useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
13
13
|
import * as __mfHostReactDOMClient from "react-dom/client";
|
|
@@ -1683,41 +1683,6 @@ var CookingPot = createLucideIcon("cooking-pot", [
|
|
|
1683
1683
|
* This source code is licensed under the ISC license.
|
|
1684
1684
|
* See the LICENSE file in the root directory of this source tree.
|
|
1685
1685
|
*/
|
|
1686
|
-
var CopyPlus = createLucideIcon("copy-plus", [
|
|
1687
|
-
["line", {
|
|
1688
|
-
x1: "15",
|
|
1689
|
-
x2: "15",
|
|
1690
|
-
y1: "12",
|
|
1691
|
-
y2: "18",
|
|
1692
|
-
key: "1p7wdc"
|
|
1693
|
-
}],
|
|
1694
|
-
["line", {
|
|
1695
|
-
x1: "12",
|
|
1696
|
-
x2: "18",
|
|
1697
|
-
y1: "15",
|
|
1698
|
-
y2: "15",
|
|
1699
|
-
key: "1nscbv"
|
|
1700
|
-
}],
|
|
1701
|
-
["rect", {
|
|
1702
|
-
width: "14",
|
|
1703
|
-
height: "14",
|
|
1704
|
-
x: "8",
|
|
1705
|
-
y: "8",
|
|
1706
|
-
rx: "2",
|
|
1707
|
-
ry: "2",
|
|
1708
|
-
key: "17jyea"
|
|
1709
|
-
}],
|
|
1710
|
-
["path", {
|
|
1711
|
-
d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",
|
|
1712
|
-
key: "zix9uf"
|
|
1713
|
-
}]
|
|
1714
|
-
]);
|
|
1715
|
-
/**
|
|
1716
|
-
* @license lucide-react v0.576.0 - ISC
|
|
1717
|
-
*
|
|
1718
|
-
* This source code is licensed under the ISC license.
|
|
1719
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
1720
|
-
*/
|
|
1721
1686
|
var Copy = createLucideIcon("copy", [["rect", {
|
|
1722
1687
|
width: "14",
|
|
1723
1688
|
height: "14",
|
|
@@ -7890,14 +7855,6 @@ var usePipelineExecutorGetGlobalPipelineConfig = trpc.pipelineExecutor.getGlobal
|
|
|
7890
7855
|
var usePipelineExecutorGetOrchestratorConfigSchema = trpc.pipelineExecutor.getOrchestratorConfigSchema.useQuery;
|
|
7891
7856
|
/** Generated alias around `trpc.pipelineExecutor.validatePipeline.useQuery`. */
|
|
7892
7857
|
var usePipelineExecutorValidatePipeline = trpc.pipelineExecutor.validatePipeline.useQuery;
|
|
7893
|
-
/** Generated alias around `trpc.pipelineExecutor.listTemplates.useQuery`. */
|
|
7894
|
-
var usePipelineExecutorListTemplates = trpc.pipelineExecutor.listTemplates.useQuery;
|
|
7895
|
-
/** Generated alias around `trpc.pipelineExecutor.saveTemplate.useMutation`. */
|
|
7896
|
-
var usePipelineExecutorSaveTemplate = trpc.pipelineExecutor.saveTemplate.useMutation;
|
|
7897
|
-
/** Generated alias around `trpc.pipelineExecutor.updateTemplate.useMutation`. */
|
|
7898
|
-
var usePipelineExecutorUpdateTemplate = trpc.pipelineExecutor.updateTemplate.useMutation;
|
|
7899
|
-
/** Generated alias around `trpc.pipelineExecutor.deleteTemplate.useMutation`. */
|
|
7900
|
-
var usePipelineExecutorDeleteTemplate = trpc.pipelineExecutor.deleteTemplate.useMutation;
|
|
7901
7858
|
/** Generated alias around `trpc.pipelineExecutor.getCapabilities.useQuery`. */
|
|
7902
7859
|
var usePipelineExecutorGetCapabilities = trpc.pipelineExecutor.getCapabilities.useQuery;
|
|
7903
7860
|
/** Generated alias around `trpc.pipelineExecutor.getAddonModels.useQuery`. */
|
|
@@ -8044,14 +8001,6 @@ var usePipelineOrchestratorSetCameraSensors = trpc.pipelineOrchestrator.setCamer
|
|
|
8044
8001
|
var usePipelineOrchestratorReconcileFromDisk = trpc.pipelineOrchestrator.reconcileFromDisk.useMutation;
|
|
8045
8002
|
/** Generated alias around `trpc.pipelineOrchestrator.getReconcileFromDiskStatus.useQuery`. */
|
|
8046
8003
|
var usePipelineOrchestratorGetReconcileFromDiskStatus = trpc.pipelineOrchestrator.getReconcileFromDiskStatus.useQuery;
|
|
8047
|
-
/** Generated alias around `trpc.pipelineOrchestrator.listTemplates.useQuery`. */
|
|
8048
|
-
var usePipelineOrchestratorListTemplates = trpc.pipelineOrchestrator.listTemplates.useQuery;
|
|
8049
|
-
/** Generated alias around `trpc.pipelineOrchestrator.saveTemplate.useMutation`. */
|
|
8050
|
-
var usePipelineOrchestratorSaveTemplate = trpc.pipelineOrchestrator.saveTemplate.useMutation;
|
|
8051
|
-
/** Generated alias around `trpc.pipelineOrchestrator.updateTemplate.useMutation`. */
|
|
8052
|
-
var usePipelineOrchestratorUpdateTemplate = trpc.pipelineOrchestrator.updateTemplate.useMutation;
|
|
8053
|
-
/** Generated alias around `trpc.pipelineOrchestrator.deleteTemplate.useMutation`. */
|
|
8054
|
-
var usePipelineOrchestratorDeleteTemplate = trpc.pipelineOrchestrator.deleteTemplate.useMutation;
|
|
8055
8004
|
/** Generated alias around `trpc.pipelineOrchestrator.getDeviceSettingsContribution.useQuery`. */
|
|
8056
8005
|
var usePipelineOrchestratorGetDeviceSettingsContribution = trpc.pipelineOrchestrator.getDeviceSettingsContribution.useQuery;
|
|
8057
8006
|
/** Generated alias around `trpc.pipelineOrchestrator.getDeviceLiveContribution.useQuery`. */
|
|
@@ -28722,30 +28671,43 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
|
|
|
28722
28671
|
});
|
|
28723
28672
|
}
|
|
28724
28673
|
//#endregion
|
|
28725
|
-
//#region src/
|
|
28726
|
-
function
|
|
28727
|
-
|
|
28728
|
-
|
|
28729
|
-
|
|
28730
|
-
|
|
28731
|
-
|
|
28732
|
-
|
|
28733
|
-
|
|
28734
|
-
|
|
28735
|
-
|
|
28736
|
-
|
|
28737
|
-
|
|
28738
|
-
|
|
28739
|
-
|
|
28740
|
-
|
|
28741
|
-
|
|
28742
|
-
|
|
28743
|
-
|
|
28744
|
-
|
|
28745
|
-
|
|
28746
|
-
|
|
28747
|
-
|
|
28748
|
-
}
|
|
28674
|
+
//#region src/composites/accelerator-label.ts
|
|
28675
|
+
function names(device) {
|
|
28676
|
+
const backend = device.backend.toLowerCase();
|
|
28677
|
+
const dev = device.device.toLowerCase();
|
|
28678
|
+
if (device.key === "cpu" || dev === "cpu" || backend === "cpu") return {
|
|
28679
|
+
label: "CPU",
|
|
28680
|
+
short: "CPU"
|
|
28681
|
+
};
|
|
28682
|
+
if (dev === "npu") return {
|
|
28683
|
+
label: "Intel NPU",
|
|
28684
|
+
short: "NPU"
|
|
28685
|
+
};
|
|
28686
|
+
if (dev === "gpu" || dev === "igpu") return {
|
|
28687
|
+
label: "Intel iGPU",
|
|
28688
|
+
short: "iGPU"
|
|
28689
|
+
};
|
|
28690
|
+
if (backend === "edgetpu") return {
|
|
28691
|
+
label: "Coral Edge TPU",
|
|
28692
|
+
short: "Coral"
|
|
28693
|
+
};
|
|
28694
|
+
if (backend === "coreml") return {
|
|
28695
|
+
label: "Apple Neural Engine",
|
|
28696
|
+
short: "ANE"
|
|
28697
|
+
};
|
|
28698
|
+
const pretty = `${device.backend} ${device.device}`.trim().replace(/\b\w/g, (c) => c.toUpperCase());
|
|
28699
|
+
return {
|
|
28700
|
+
label: pretty.length > 0 ? pretty : device.key,
|
|
28701
|
+
short: device.backend || device.key
|
|
28702
|
+
};
|
|
28703
|
+
}
|
|
28704
|
+
/** "Intel NPU", "Apple Neural Engine", "Coral Edge TPU", "CPU" — Auto tune's names too. */
|
|
28705
|
+
function acceleratorLabel(device) {
|
|
28706
|
+
return names(device).label;
|
|
28707
|
+
}
|
|
28708
|
+
/** "NPU", "ANE", "Coral", "CPU" — chips and tabs. */
|
|
28709
|
+
function acceleratorShortLabel(device) {
|
|
28710
|
+
return names(device).short;
|
|
28749
28711
|
}
|
|
28750
28712
|
//#endregion
|
|
28751
28713
|
//#region src/composites/grouped-model-selector.tsx
|
|
@@ -29028,6 +28990,257 @@ function ModelPicker({ models, value, onChange, disabled, defaultModelId }) {
|
|
|
29028
28990
|
});
|
|
29029
28991
|
}
|
|
29030
28992
|
//#endregion
|
|
28993
|
+
//#region src/composites/resolve-step-default-model.ts
|
|
28994
|
+
function resolveStepDefaultModel(catalog, format) {
|
|
28995
|
+
const hasFormatBuild = (modelId) => catalog.models.find((m) => m.id === modelId)?.formats[format] !== void 0;
|
|
28996
|
+
const declared = catalog.defaultModelIdByFormat?.[format];
|
|
28997
|
+
if (declared !== void 0 && hasFormatBuild(declared)) return declared;
|
|
28998
|
+
if (hasFormatBuild(catalog.defaultModelId)) return catalog.defaultModelId;
|
|
28999
|
+
const available = catalog.models.filter((m) => m.formats[format] !== void 0 && m.legacy !== true);
|
|
29000
|
+
if (available.length === 0) return catalog.defaultModelId;
|
|
29001
|
+
return [...available].toSorted((a, b) => (a.formats[format]?.sizeMB ?? Infinity) - (b.formats[format]?.sizeMB ?? Infinity))[0].id;
|
|
29002
|
+
}
|
|
29003
|
+
/**
|
|
29004
|
+
* The model a matrix CELL shows as this step's effective default on `device`.
|
|
29005
|
+
*
|
|
29006
|
+
* The device's ELECTED model (`device.defaultModelId`, the per-device
|
|
29007
|
+
* object-detection election) applies ONLY when this step's catalog actually
|
|
29008
|
+
* contains it — `slot === 'detector'` alone is too wide, because
|
|
29009
|
+
* package-detection shares the detector slot with the root step. Bit live
|
|
29010
|
+
* 2026-08-08: rfdetr-package became the package step's default and every
|
|
29011
|
+
* matrix cell still showed the device's yolo as the "selected" model, because
|
|
29012
|
+
* the election was applied slot-wide. Membership is the principled gate: an
|
|
29013
|
+
* elected model this step cannot run is never displayed for it.
|
|
29014
|
+
*/
|
|
29015
|
+
function resolveEffectiveDefaultModel(catalog, device) {
|
|
29016
|
+
const format = device?.format;
|
|
29017
|
+
if (format === void 0) return void 0;
|
|
29018
|
+
const elected = device?.defaultModelId;
|
|
29019
|
+
return catalog.slot === "detector" && elected !== void 0 && catalog.models.some((m) => m.id === elected) ? elected : resolveStepDefaultModel(catalog, format);
|
|
29020
|
+
}
|
|
29021
|
+
/**
|
|
29022
|
+
* The models a step may run on an engine `format` — the ONE derivation of the
|
|
29023
|
+
* option list. An unknown format yields NOTHING rather than everything: a
|
|
29024
|
+
* picker that offered a model with no build for the device would write a pin
|
|
29025
|
+
* the runner cannot honour.
|
|
29026
|
+
*/
|
|
29027
|
+
function stepModelOptions(models, format) {
|
|
29028
|
+
if (format === void 0) return [];
|
|
29029
|
+
return models.filter((m) => m.formats[format] !== void 0);
|
|
29030
|
+
}
|
|
29031
|
+
/** Can this step run on `format` at all? (`false` ⇒ the caller renders "⚠ skip"/"—".) */
|
|
29032
|
+
function stepHasModelForFormat(models, format) {
|
|
29033
|
+
return stepModelOptions(models, format).length > 0;
|
|
29034
|
+
}
|
|
29035
|
+
/**
|
|
29036
|
+
* The model a step ACTUALLY runs for a (device, camera) — the whole effective
|
|
29037
|
+
* chain in one place: per-camera override → per-(node,device) base → the
|
|
29038
|
+
* resolved default (`resolveEffectiveDefaultModel`).
|
|
29039
|
+
*
|
|
29040
|
+
* Every surface calls this: the matrix cell, and the drawer's picker seed. They
|
|
29041
|
+
* are the same number, and the only way to keep them the same number is to have
|
|
29042
|
+
* one function produce it. A surface that owns fewer layers omits them (the node
|
|
29043
|
+
* matrix passes no `override`) — it does NOT get its own resolver.
|
|
29044
|
+
*/
|
|
29045
|
+
function resolveEffectiveStepModel(input) {
|
|
29046
|
+
return input.override ?? input.base ?? resolveEffectiveDefaultModel(input.catalog, input.device);
|
|
29047
|
+
}
|
|
29048
|
+
//#endregion
|
|
29049
|
+
//#region src/composites/root-model-source.tsx
|
|
29050
|
+
/**
|
|
29051
|
+
* "Use the root model" — the step editor's control for a step the camera's
|
|
29052
|
+
* ROOT detection model can supply (D730).
|
|
29053
|
+
*
|
|
29054
|
+
* The flag (`useRootModel`, in the step's own settings) is an operator INTENT
|
|
29055
|
+
* kept beside the step's model: checking it never changes the model, and a
|
|
29056
|
+
* root that cannot supply the step leaves the step running its own model while
|
|
29057
|
+
* the flag waits, inactive, for a root that can. Whether it is in force is
|
|
29058
|
+
* `resolveRootSupply` — the same function the runner decides with.
|
|
29059
|
+
*/
|
|
29060
|
+
/** The editor's view of the flag for one step, or `null` for a step no root can supply. */
|
|
29061
|
+
function rootSourceState(stepId, settings, rootModel) {
|
|
29062
|
+
if (!isRootSuppliableStepId(stepId)) return null;
|
|
29063
|
+
return resolveRootSupply(stepId, settings, rootModel?.supplies);
|
|
29064
|
+
}
|
|
29065
|
+
/** The settings bag with the flag set — every other key untouched. */
|
|
29066
|
+
function withUseRootModel(settings, value) {
|
|
29067
|
+
return {
|
|
29068
|
+
...settings,
|
|
29069
|
+
[USE_ROOT_MODEL_SETTING_KEY]: value
|
|
29070
|
+
};
|
|
29071
|
+
}
|
|
29072
|
+
/** What the operator must know about a supply, beyond "it is on". */
|
|
29073
|
+
function supplyNotes(supply) {
|
|
29074
|
+
if (supply.kind === "label") {
|
|
29075
|
+
const notes = supply.uncovered.length > 0 ? [`Not produced by this model: ${supply.uncovered.join(", ")}.`] : [];
|
|
29076
|
+
if (supply.stepId === "package-detection") return [...notes, "The root model's own package boxes become the package result at this step's threshold; this step's zone-crop view is not used, so small parcels the full-frame model misses stay missed."];
|
|
29077
|
+
return [...notes, "This step's class list decides which of the root's labels become the fine class; a switched-off class stays at its macro."];
|
|
29078
|
+
}
|
|
29079
|
+
if (supply.kind === "mask") return ["Masks come from the root model: each detection carries the root's own instance mask, so this step's model does not run. A root mask follows the model's mask grid (a quarter of its input), coarser than this step's own per-crop mask."];
|
|
29080
|
+
if (supply.stepId === "face-detection") return ["Face boxes come from the root model. Each is re-found by this step's face detector in a square around it before recognition, so only a face it finds is recognised; a box with no face in it is dropped."];
|
|
29081
|
+
return ["Plate boxes come from the root model and the plate reader reads them. The crop margin around a root plate box has not been measured for this model yet."];
|
|
29082
|
+
}
|
|
29083
|
+
/** The reason an intended supply is not in force, in the operator's words. */
|
|
29084
|
+
function inactiveText(state, rootModel) {
|
|
29085
|
+
switch (state.inactiveReason) {
|
|
29086
|
+
case "root-input-too-small": return `the current root model (${rootModel.name}) sees the frame too small to find faces reliably (it needs an input of 640 px or more).`;
|
|
29087
|
+
case "root-does-not-declare":
|
|
29088
|
+
case void 0: return `the current root model (${rootModel.name}) cannot supply this.`;
|
|
29089
|
+
}
|
|
29090
|
+
}
|
|
29091
|
+
function RootModelSourceControl({ stepId, settings, rootModel, disabled, onChange }) {
|
|
29092
|
+
if (rootModel === void 0) return null;
|
|
29093
|
+
const state = rootSourceState(stepId, settings, rootModel);
|
|
29094
|
+
if (state === null) return null;
|
|
29095
|
+
const inactiveNote = state.inactive ? /* @__PURE__ */ jsxs("div", {
|
|
29096
|
+
className: "rounded bg-muted/40 px-3 py-2 text-[11px] text-foreground-subtle",
|
|
29097
|
+
"data-testid": "root-model-inactive",
|
|
29098
|
+
children: [
|
|
29099
|
+
"Use the root model: inactive — ",
|
|
29100
|
+
inactiveText(state, rootModel),
|
|
29101
|
+
" The step runs its own model."
|
|
29102
|
+
]
|
|
29103
|
+
}) : null;
|
|
29104
|
+
if (state.supply === void 0) return inactiveNote;
|
|
29105
|
+
const checked = state.intent;
|
|
29106
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
29107
|
+
className: "space-y-1",
|
|
29108
|
+
"data-testid": "root-model-source",
|
|
29109
|
+
children: [
|
|
29110
|
+
/* @__PURE__ */ jsxs("label", {
|
|
29111
|
+
className: "flex items-center gap-2 text-xs text-foreground",
|
|
29112
|
+
children: [
|
|
29113
|
+
/* @__PURE__ */ jsx("input", {
|
|
29114
|
+
type: "checkbox",
|
|
29115
|
+
checked,
|
|
29116
|
+
disabled,
|
|
29117
|
+
onChange: (e) => onChange(e.target.checked)
|
|
29118
|
+
}),
|
|
29119
|
+
"Use the root model (",
|
|
29120
|
+
rootModel.name,
|
|
29121
|
+
")"
|
|
29122
|
+
]
|
|
29123
|
+
}),
|
|
29124
|
+
inactiveNote,
|
|
29125
|
+
state.effective && supplyNotes(state.supply).map((note) => /* @__PURE__ */ jsx("p", {
|
|
29126
|
+
className: "text-[10px] leading-snug text-foreground-subtle",
|
|
29127
|
+
children: note
|
|
29128
|
+
}, note))
|
|
29129
|
+
]
|
|
29130
|
+
});
|
|
29131
|
+
}
|
|
29132
|
+
//#endregion
|
|
29133
|
+
//#region src/lib/responsive.ts
|
|
29134
|
+
/**
|
|
29135
|
+
* Responsive design tokens — three-tier system.
|
|
29136
|
+
*
|
|
29137
|
+
* The admin-ui targets three width tiers; every component should pick
|
|
29138
|
+
* the right token from this file instead of hand-coding breakpoints.
|
|
29139
|
+
* Adopting the tokens uniformly is what makes the app feel consistent
|
|
29140
|
+
* across operator devices (mobile / tablet / desktop) and what unlocks
|
|
29141
|
+
* targeted tuning (e.g. shrink every label by 1px in one place).
|
|
29142
|
+
*
|
|
29143
|
+
* Tier definitions (Tailwind breakpoints):
|
|
29144
|
+
*
|
|
29145
|
+
* • **L1 — Compact** (`< 640px`, default = mobile portrait)
|
|
29146
|
+
* Single column, tight padding, smallest text, icon-only buttons
|
|
29147
|
+
* where labels can be inferred. The operator can still see every
|
|
29148
|
+
* stat / action — no horizontal scroll, no clipped text. The user
|
|
29149
|
+
* directive: "molta informazione in poco spazio quando la width è
|
|
29150
|
+
* bassa." [a lot of information in little space when the width is low.]
|
|
29151
|
+
*
|
|
29152
|
+
* • **L2 — Standard** (`sm` — `640–1023px`, tablet + small laptop)
|
|
29153
|
+
* 2-column grids, side panels become visible, button labels return.
|
|
29154
|
+
* Targets ~768px–1024px viewports — the most common operator sizes.
|
|
29155
|
+
*
|
|
29156
|
+
* • **L3 — Spacious** (`lg+` — `≥ 1024px`, desktop)
|
|
29157
|
+
* 4-column grids, generous padding, full-width header text,
|
|
29158
|
+
* side-by-side composite layouts. The operator has elbow room.
|
|
29159
|
+
*
|
|
29160
|
+
* Conventions:
|
|
29161
|
+
* - **Always start from L1** — the bare class is always the compact
|
|
29162
|
+
* variant, then `sm:` adds room at 640px, `lg:` at 1024px. No
|
|
29163
|
+
* desktop-first breakpoints; no max-width queries.
|
|
29164
|
+
* - **Token strings are static** — kept as `as const` so callers can
|
|
29165
|
+
* compose them via `cn()` / template literals without running a
|
|
29166
|
+
* class generator at runtime.
|
|
29167
|
+
* - **Pair the token with a comment** — the comment in the file
|
|
29168
|
+
* names every breakpoint it crosses, so a reader can predict the
|
|
29169
|
+
* layout without going to Tailwind docs.
|
|
29170
|
+
*/
|
|
29171
|
+
/** Container padding for a card-style section (header + body). */
|
|
29172
|
+
var SECTION_CARD = "rounded-lg border border-border bg-surface overflow-hidden";
|
|
29173
|
+
/** Header strip inside a card (between border-b lines). */
|
|
29174
|
+
var SECTION_HEADER = "border-b border-border px-3 sm:px-4 py-1.5 sm:py-2";
|
|
29175
|
+
/** Body padding for a card-style section. */
|
|
29176
|
+
var SECTION_BODY = "p-2 sm:p-3 lg:p-4";
|
|
29177
|
+
/** Gap between cards in a vertical stack. */
|
|
29178
|
+
var STACK_GAP = "space-y-3 sm:space-y-4";
|
|
29179
|
+
/** Gap between cards in a grid (4 cells / row at lg). */
|
|
29180
|
+
var GRID_GAP = "gap-2 sm:gap-3";
|
|
29181
|
+
/** Row padding inside a divided list (e.g. InfoRow). */
|
|
29182
|
+
var LIST_ROW = "px-3 sm:px-4 py-1.5 sm:py-2";
|
|
29183
|
+
/** 1-up at L1, 2-up at L2, 4-up at L3 — quick-stat row. */
|
|
29184
|
+
var GRID_QUICK_STATS = "grid grid-cols-2 sm:grid-cols-2 lg:grid-cols-4";
|
|
29185
|
+
/** 1-up at L1, 2-up at L2+ — paired panels (motion + detection rules). */
|
|
29186
|
+
var GRID_PAIRED = "grid grid-cols-1 lg:grid-cols-2";
|
|
29187
|
+
/** Side-by-side layout that stacks below md (canvas + side panel). */
|
|
29188
|
+
var SPLIT_PANEL_OUTER = "flex flex-col-reverse md:flex-row";
|
|
29189
|
+
/** Sidebar narrow lane in a SPLIT_PANEL_OUTER layout. */
|
|
29190
|
+
var SPLIT_PANEL_SIDE = "w-full md:w-44 lg:w-52 md:flex-shrink-0 border-b md:border-b-0 md:border-l border-border";
|
|
29191
|
+
/**
|
|
29192
|
+
* The tier boundary at which a settings label/value row stops stacking.
|
|
29193
|
+
*
|
|
29194
|
+
* Below it (L1 — compact) the row is ONE column: label on its own line, value
|
|
29195
|
+
* on the next at full width. Above it the row is label-left / value-right as
|
|
29196
|
+
* before. The two-column form needs `SETTING_ROW_LABEL`'s lane plus a readable
|
|
29197
|
+
* value beside it; a phone has neither, and the failure mode is not "cramped"
|
|
29198
|
+
* but "the value is the part that gets cut" — the one thing the operator
|
|
29199
|
+
* opened the page to read.
|
|
29200
|
+
*/
|
|
29201
|
+
var SETTING_ROW_STACK_BREAKPOINT = "sm";
|
|
29202
|
+
/** Outer row: single column at L1, label/value columns from `sm` up. */
|
|
29203
|
+
var SETTING_ROW = "flex min-w-0 flex-col gap-0.5 py-1.5 sm:flex-row sm:items-center";
|
|
29204
|
+
/** Label lane. Full width (and free to wrap) at L1; a fixed lane from `sm` up. */
|
|
29205
|
+
var SETTING_ROW_LABEL = "min-w-0 text-[11px] leading-tight text-foreground-subtle sm:w-32 sm:shrink-0 sm:pr-2";
|
|
29206
|
+
/**
|
|
29207
|
+
* Value lane — the value text plus its trailing affordances (copy / reveal).
|
|
29208
|
+
* `w-full` at L1 so the value owns the whole row once the label is above it;
|
|
29209
|
+
* `sm:flex-1` makes it share the row again from `sm` up.
|
|
29210
|
+
*/
|
|
29211
|
+
var SETTING_ROW_VALUE = "flex w-full min-w-0 items-center gap-1 sm:flex-1";
|
|
29212
|
+
/**
|
|
29213
|
+
* The value text itself. `break-all` lets an opaque token (a key, a URL) wrap
|
|
29214
|
+
* at L1 instead of being cut mid-word; `sm:truncate` restores the single-line
|
|
29215
|
+
* desktop form, where the row is wide enough for truncation to be a choice
|
|
29216
|
+
* rather than data loss.
|
|
29217
|
+
*/
|
|
29218
|
+
var SETTING_ROW_VALUE_TEXT = "min-w-0 break-all text-xs text-foreground sm:truncate";
|
|
29219
|
+
/** Section header label (uppercase tracking-wider). */
|
|
29220
|
+
var TEXT_SECTION_LABEL = "text-[10px] sm:text-[11px] font-semibold text-foreground uppercase tracking-wider";
|
|
29221
|
+
/** Field label inside a row. */
|
|
29222
|
+
var TEXT_FIELD_LABEL = "text-[11px] sm:text-xs text-foreground";
|
|
29223
|
+
/** Sub-label / hint text. */
|
|
29224
|
+
var TEXT_HINT = "text-[10px] text-foreground-subtle";
|
|
29225
|
+
/** Primary value (a metric, badge, …). */
|
|
29226
|
+
var TEXT_VALUE = "text-[11px] sm:text-xs font-medium text-foreground";
|
|
29227
|
+
/** Big metric value (StatCard). */
|
|
29228
|
+
var TEXT_METRIC = "text-base sm:text-lg font-semibold leading-tight text-foreground";
|
|
29229
|
+
/** Default compact button. */
|
|
29230
|
+
var BTN_COMPACT = "inline-flex items-center justify-center gap-1 rounded border border-border bg-surface px-1.5 py-0.5 sm:px-2 sm:py-1 text-[10px] sm:text-[11px] font-medium text-foreground hover:bg-surface-hover transition-colors disabled:opacity-40";
|
|
29231
|
+
/** Primary compact button. */
|
|
29232
|
+
var BTN_COMPACT_PRIMARY = "inline-flex items-center justify-center gap-1 rounded border border-primary/40 bg-primary/15 px-1.5 py-0.5 sm:px-2 sm:py-1 text-[10px] sm:text-[11px] font-medium text-primary hover:bg-primary/25 transition-colors disabled:opacity-40";
|
|
29233
|
+
/** Danger compact button. */
|
|
29234
|
+
var BTN_COMPACT_DANGER = "inline-flex items-center justify-center gap-1 rounded border border-danger/40 bg-danger/10 px-1.5 py-0.5 sm:px-2 sm:py-1 text-[10px] sm:text-[11px] font-medium text-danger hover:bg-danger/20 transition-colors disabled:opacity-40";
|
|
29235
|
+
/** Warning compact button (e.g. cancel-drawing). */
|
|
29236
|
+
var BTN_COMPACT_WARNING = "inline-flex items-center justify-center gap-1 rounded border border-warning/40 bg-warning/10 px-1.5 py-0.5 sm:px-2 sm:py-1 text-[10px] sm:text-[11px] font-medium text-warning hover:bg-warning/20 transition-colors disabled:opacity-40";
|
|
29237
|
+
/** Compact text/select/number input. */
|
|
29238
|
+
var INPUT_COMPACT = "w-full rounded border border-border bg-background px-1.5 py-0.5 sm:px-2 sm:py-1 text-[11px] sm:text-xs text-foreground focus:border-primary focus:ring-1 focus:ring-primary/30 outline-none";
|
|
29239
|
+
/** Chip-style toggle (zone / class selectors in ZoneRulesEditor). */
|
|
29240
|
+
var CHIP_BASE = "inline-flex items-center gap-1 rounded-full border px-1.5 py-0.5 text-[10px] font-medium transition-colors";
|
|
29241
|
+
var CHIP_ACTIVE = "border-primary/50 bg-primary/15 text-primary";
|
|
29242
|
+
var CHIP_INACTIVE = "border-border bg-surface text-foreground-subtle hover:bg-surface-hover";
|
|
29243
|
+
//#endregion
|
|
29031
29244
|
//#region src/composites/model-bound-slider.tsx
|
|
29032
29245
|
var SOURCE_LABEL = {
|
|
29033
29246
|
override: "Override for this model",
|
|
@@ -29037,7 +29250,7 @@ var SOURCE_LABEL = {
|
|
|
29037
29250
|
function formatNumber(value, scale) {
|
|
29038
29251
|
return (scale !== void 0 ? value / scale : value).toFixed(2).replace(/\.?0+$/, "");
|
|
29039
29252
|
}
|
|
29040
|
-
function ModelBoundSlider({ field, modelId, settings, disabled, onChangeSettings }) {
|
|
29253
|
+
function ModelBoundSlider({ field, modelId, settings, disabled, onChangeSettings, hideSourceRow = false }) {
|
|
29041
29254
|
const modelDefault = field.modelApplicability?.defaultByModel?.[modelId];
|
|
29042
29255
|
const state = resolveModelBoundSetting(settings, field.key, modelId.length > 0 ? modelId : void 0, modelDefault, field.default);
|
|
29043
29256
|
const fallback = typeof field.default === "number" ? field.default : field.min ?? 0;
|
|
@@ -29077,7 +29290,7 @@ function ModelBoundSlider({ field, modelId, settings, disabled, onChangeSettings
|
|
|
29077
29290
|
onChange: (e) => handleChange(Number(e.target.value)),
|
|
29078
29291
|
className: "w-full accent-primary h-1.5"
|
|
29079
29292
|
}),
|
|
29080
|
-
/* @__PURE__ */ jsxs("div", {
|
|
29293
|
+
!hideSourceRow && /* @__PURE__ */ jsxs("div", {
|
|
29081
29294
|
className: "mt-1 flex items-center justify-between gap-2 text-[10px]",
|
|
29082
29295
|
children: [/* @__PURE__ */ jsx("span", {
|
|
29083
29296
|
"data-testid": "model-bound-source",
|
|
@@ -29128,6 +29341,32 @@ function ResetModelDefaultsButton({ fields, modelId, settings, disabled, onReset
|
|
|
29128
29341
|
});
|
|
29129
29342
|
}
|
|
29130
29343
|
//#endregion
|
|
29344
|
+
//#region src/primitives/collapsible-card.tsx
|
|
29345
|
+
function CollapsibleCard({ expanded, onExpandedChange, header, children, dimmed = false, hideChevron = false, className }) {
|
|
29346
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
29347
|
+
className: cn("rounded-lg border border-border bg-surface overflow-hidden", dimmed && "opacity-[0.45]", className),
|
|
29348
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
29349
|
+
role: "button",
|
|
29350
|
+
tabIndex: 0,
|
|
29351
|
+
className: "flex items-center gap-2.5 px-3 py-2.5 cursor-pointer select-none",
|
|
29352
|
+
onClick: () => onExpandedChange(!expanded),
|
|
29353
|
+
onKeyDown: (e) => {
|
|
29354
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
29355
|
+
e.preventDefault();
|
|
29356
|
+
onExpandedChange(!expanded);
|
|
29357
|
+
}
|
|
29358
|
+
},
|
|
29359
|
+
children: [!hideChevron && /* @__PURE__ */ jsx("span", {
|
|
29360
|
+
className: "text-foreground-subtle shrink-0",
|
|
29361
|
+
children: expanded ? /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
|
|
29362
|
+
}), header]
|
|
29363
|
+
}), expanded && children && /* @__PURE__ */ jsx("div", {
|
|
29364
|
+
className: "border-t border-border px-3 py-3",
|
|
29365
|
+
children
|
|
29366
|
+
})]
|
|
29367
|
+
});
|
|
29368
|
+
}
|
|
29369
|
+
//#endregion
|
|
29131
29370
|
//#region src/composites/pipeline-step.tsx
|
|
29132
29371
|
/**
|
|
29133
29372
|
* PipelineStep — single step card in the pipeline builder.
|
|
@@ -29139,124 +29378,77 @@ function ResetModelDefaultsButton({ fields, modelId, settings, disabled, onReset
|
|
|
29139
29378
|
function modelsForStep(schema) {
|
|
29140
29379
|
return schema?.models ?? [];
|
|
29141
29380
|
}
|
|
29142
|
-
function PipelineStep({ step, schema, allSchemas: _allSchemas, depth: _depth = 0, onChange, onDelete: _onDelete, readOnly = false
|
|
29381
|
+
function PipelineStep({ step, schema, allSchemas: _allSchemas, depth: _depth = 0, onChange, onDelete: _onDelete, readOnly = false }) {
|
|
29143
29382
|
const [expanded, setExpanded] = useState(false);
|
|
29144
29383
|
const models = modelsForStep(schema);
|
|
29145
|
-
|
|
29146
|
-
if (models.length > 0 && !isAutoSentinel && !models.some((m) => m.id === step.modelId) && !readOnly) {
|
|
29384
|
+
if (models.length > 0 && !models.some((m) => m.id === step.modelId) && !readOnly) {
|
|
29147
29385
|
const fallback = (schema?.defaultModelId ? models.find((m) => m.id === schema.defaultModelId) : null) ?? models[0];
|
|
29148
29386
|
if (fallback && fallback.id !== step.modelId) queueMicrotask(() => onChange({
|
|
29149
29387
|
...step,
|
|
29150
29388
|
modelId: fallback.id
|
|
29151
29389
|
}));
|
|
29152
29390
|
}
|
|
29153
|
-
const header = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
29154
|
-
|
|
29155
|
-
|
|
29156
|
-
|
|
29157
|
-
|
|
29158
|
-
|
|
29159
|
-
|
|
29160
|
-
|
|
29161
|
-
|
|
29162
|
-
|
|
29163
|
-
|
|
29164
|
-
|
|
29165
|
-
|
|
29166
|
-
|
|
29167
|
-
|
|
29168
|
-
|
|
29169
|
-
|
|
29170
|
-
|
|
29171
|
-
|
|
29172
|
-
|
|
29173
|
-
|
|
29174
|
-
|
|
29175
|
-
|
|
29176
|
-
|
|
29177
|
-
|
|
29178
|
-
|
|
29179
|
-
|
|
29180
|
-
|
|
29181
|
-
|
|
29182
|
-
|
|
29183
|
-
|
|
29184
|
-
|
|
29185
|
-
|
|
29186
|
-
|
|
29187
|
-
|
|
29188
|
-
|
|
29189
|
-
|
|
29190
|
-
|
|
29191
|
-
|
|
29192
|
-
|
|
29193
|
-
children: /* @__PURE__ */ jsx("span", { className: cn("inline-block h-4 w-4 rounded-full bg-white shadow transition-transform", step.enabled ? "translate-x-6" : "translate-x-1") })
|
|
29194
|
-
}),
|
|
29195
|
-
!readOnly && toggleMode === "threeState" && onOverrideChange && /* @__PURE__ */ jsxs("div", {
|
|
29196
|
-
className: "flex items-center gap-0.5 rounded-md border border-border p-0.5",
|
|
29197
|
-
onClick: (e) => e.stopPropagation(),
|
|
29198
|
-
children: [
|
|
29199
|
-
/* @__PURE__ */ jsx(ThreeStateButton, {
|
|
29200
|
-
label: "Inherit",
|
|
29201
|
-
active: overrideState === null,
|
|
29202
|
-
variant: "inherit",
|
|
29203
|
-
subtext: inheritedEnabled === void 0 ? void 0 : inheritedEnabled ? "on" : "off",
|
|
29204
|
-
onClick: () => onOverrideChange(null)
|
|
29205
|
-
}),
|
|
29206
|
-
/* @__PURE__ */ jsx(ThreeStateButton, {
|
|
29207
|
-
label: "On",
|
|
29208
|
-
active: overrideState === true,
|
|
29209
|
-
variant: "on",
|
|
29210
|
-
onClick: () => onOverrideChange(true)
|
|
29211
|
-
}),
|
|
29212
|
-
/* @__PURE__ */ jsx(ThreeStateButton, {
|
|
29213
|
-
label: "Off",
|
|
29214
|
-
active: overrideState === false,
|
|
29215
|
-
variant: "off",
|
|
29216
|
-
onClick: () => onOverrideChange(false)
|
|
29217
|
-
})
|
|
29218
|
-
]
|
|
29219
|
-
})
|
|
29220
|
-
] });
|
|
29391
|
+
const header = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("div", {
|
|
29392
|
+
className: "flex-1 min-w-0",
|
|
29393
|
+
children: [
|
|
29394
|
+
/* @__PURE__ */ jsx("span", {
|
|
29395
|
+
className: "text-[10px] uppercase tracking-wider font-medium text-foreground-subtle/60 block leading-none",
|
|
29396
|
+
children: step.slot
|
|
29397
|
+
}),
|
|
29398
|
+
/* @__PURE__ */ jsx("span", {
|
|
29399
|
+
className: "text-sm font-semibold text-foreground truncate block leading-tight",
|
|
29400
|
+
children: step.addonName
|
|
29401
|
+
}),
|
|
29402
|
+
/* @__PURE__ */ jsxs("div", {
|
|
29403
|
+
className: "flex items-center gap-1 mt-0.5 flex-wrap",
|
|
29404
|
+
children: [
|
|
29405
|
+
step.inputClasses.map((c) => /* @__PURE__ */ jsx("span", {
|
|
29406
|
+
className: "text-[9px] uppercase font-semibold tracking-wide px-1.5 py-0.5 rounded bg-blue-500/12 text-blue-400",
|
|
29407
|
+
children: c
|
|
29408
|
+
}, c)),
|
|
29409
|
+
step.inputClasses.length > 0 && step.outputClasses.length > 0 && /* @__PURE__ */ jsx("span", {
|
|
29410
|
+
className: "text-foreground-subtle/40 text-[10px]",
|
|
29411
|
+
children: "→"
|
|
29412
|
+
}),
|
|
29413
|
+
step.outputClasses.map((c) => /* @__PURE__ */ jsx("span", {
|
|
29414
|
+
className: "text-[9px] uppercase font-semibold tracking-wide px-1.5 py-0.5 rounded bg-green-500/12 text-green-400",
|
|
29415
|
+
children: c
|
|
29416
|
+
}, c))
|
|
29417
|
+
]
|
|
29418
|
+
})
|
|
29419
|
+
]
|
|
29420
|
+
}), !readOnly && /* @__PURE__ */ jsx("button", {
|
|
29421
|
+
onClick: (e) => {
|
|
29422
|
+
e.stopPropagation();
|
|
29423
|
+
onChange({
|
|
29424
|
+
...step,
|
|
29425
|
+
enabled: !step.enabled
|
|
29426
|
+
});
|
|
29427
|
+
},
|
|
29428
|
+
className: cn("relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors", step.enabled ? "bg-success" : "bg-foreground-subtle/30"),
|
|
29429
|
+
children: /* @__PURE__ */ jsx("span", { className: cn("inline-block h-4 w-4 rounded-full bg-white shadow transition-transform", step.enabled ? "translate-x-6" : "translate-x-1") })
|
|
29430
|
+
})] });
|
|
29221
29431
|
return /* @__PURE__ */ jsx(CollapsibleCard, {
|
|
29222
29432
|
expanded,
|
|
29223
29433
|
onExpandedChange: setExpanded,
|
|
29224
29434
|
dimmed: !step.enabled,
|
|
29225
29435
|
header,
|
|
29226
|
-
children:
|
|
29227
|
-
className: "text-[11px] text-foreground-subtle",
|
|
29228
|
-
children: "Model and detection settings are managed per agent — open the Pipeline page for this camera's agent to edit them."
|
|
29229
|
-
}) : /* @__PURE__ */ jsxs("div", {
|
|
29436
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
29230
29437
|
className: "space-y-3",
|
|
29231
29438
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
29232
29439
|
className: "space-y-2",
|
|
29233
|
-
children: [
|
|
29234
|
-
|
|
29235
|
-
|
|
29236
|
-
|
|
29237
|
-
|
|
29238
|
-
|
|
29239
|
-
|
|
29240
|
-
|
|
29241
|
-
|
|
29242
|
-
|
|
29243
|
-
disabled: readOnly,
|
|
29244
|
-
onChange: (e) => onChange({
|
|
29245
|
-
...step,
|
|
29246
|
-
modelId: e.target.checked ? "" : schema?.defaultModelId ?? models[0]?.id ?? ""
|
|
29247
|
-
})
|
|
29248
|
-
}), "Auto (node default)"]
|
|
29249
|
-
}),
|
|
29250
|
-
!isAutoSentinel && /* @__PURE__ */ jsx(ModelPicker, {
|
|
29251
|
-
models,
|
|
29252
|
-
value: step.modelId,
|
|
29253
|
-
disabled: readOnly,
|
|
29254
|
-
onChange: (id) => onChange({
|
|
29255
|
-
...step,
|
|
29256
|
-
modelId: id
|
|
29257
|
-
})
|
|
29440
|
+
children: [/* @__PURE__ */ jsx("label", {
|
|
29441
|
+
className: "block text-[10px] font-medium text-foreground-subtle uppercase tracking-wide",
|
|
29442
|
+
children: "Model"
|
|
29443
|
+
}), /* @__PURE__ */ jsx(ModelPicker, {
|
|
29444
|
+
models,
|
|
29445
|
+
value: step.modelId,
|
|
29446
|
+
disabled: readOnly,
|
|
29447
|
+
onChange: (id) => onChange({
|
|
29448
|
+
...step,
|
|
29449
|
+
modelId: id
|
|
29258
29450
|
})
|
|
29259
|
-
]
|
|
29451
|
+
})]
|
|
29260
29452
|
}), schema?.configSchema?.map((field) => /* @__PURE__ */ jsx(ConfigSchemaField, {
|
|
29261
29453
|
field,
|
|
29262
29454
|
allFields: schema.configSchema ?? [],
|
|
@@ -29323,7 +29515,7 @@ function resolveSettingValue(key, step, allFields) {
|
|
|
29323
29515
|
const sibling = allFields.find((f) => "key" in f && f.key === key);
|
|
29324
29516
|
return sibling && "default" in sibling ? sibling.default : void 0;
|
|
29325
29517
|
}
|
|
29326
|
-
function ConfigSchemaField({ field, allFields, step, disabled, onChange }) {
|
|
29518
|
+
function ConfigSchemaField({ field, allFields, step, disabled, onChange, hideModelBoundSourceRow }) {
|
|
29327
29519
|
const applicability = "modelApplicability" in field ? field.modelApplicability : void 0;
|
|
29328
29520
|
const inapplicableReason = applicability?.inapplicable?.[step.modelId];
|
|
29329
29521
|
const control = /* @__PURE__ */ jsx(ConfigSchemaFieldControl, {
|
|
@@ -29332,7 +29524,8 @@ function ConfigSchemaField({ field, allFields, step, disabled, onChange }) {
|
|
|
29332
29524
|
step,
|
|
29333
29525
|
disabled: disabled || inapplicableReason !== void 0,
|
|
29334
29526
|
modelScopedOptions: applicability?.optionsByModel?.[step.modelId],
|
|
29335
|
-
onChange
|
|
29527
|
+
onChange,
|
|
29528
|
+
hideModelBoundSourceRow: hideModelBoundSourceRow === true
|
|
29336
29529
|
});
|
|
29337
29530
|
if (inapplicableReason === void 0) return control;
|
|
29338
29531
|
return /* @__PURE__ */ jsxs("div", {
|
|
@@ -29343,7 +29536,7 @@ function ConfigSchemaField({ field, allFields, step, disabled, onChange }) {
|
|
|
29343
29536
|
})]
|
|
29344
29537
|
});
|
|
29345
29538
|
}
|
|
29346
|
-
function ConfigSchemaFieldControl({ field, allFields, step, disabled, modelScopedOptions, onChange }) {
|
|
29539
|
+
function ConfigSchemaFieldControl({ field, allFields, step, disabled, modelScopedOptions, onChange, hideModelBoundSourceRow }) {
|
|
29347
29540
|
const showWhen = field.type !== "separator" && field.type !== "info" ? field.showWhen : void 0;
|
|
29348
29541
|
if (showWhen) {
|
|
29349
29542
|
const { field: condField, equals, notEquals, in: inList, notIn } = showWhen;
|
|
@@ -29393,7 +29586,8 @@ function ConfigSchemaFieldControl({ field, allFields, step, disabled, modelScope
|
|
|
29393
29586
|
onChangeSettings: (settings) => onChange({
|
|
29394
29587
|
...step,
|
|
29395
29588
|
settings
|
|
29396
|
-
})
|
|
29589
|
+
}),
|
|
29590
|
+
hideSourceRow: hideModelBoundSourceRow
|
|
29397
29591
|
});
|
|
29398
29592
|
if (field.type === "slider" || field.type === "number") {
|
|
29399
29593
|
const raw = step.settings?.[field.key];
|
|
@@ -29479,204 +29673,247 @@ function ConfigSchemaFieldControl({ field, allFields, step, disabled, modelScope
|
|
|
29479
29673
|
});
|
|
29480
29674
|
return null;
|
|
29481
29675
|
}
|
|
29482
|
-
function ThreeStateButton({ label, active, variant, subtext, onClick }) {
|
|
29483
|
-
return /* @__PURE__ */ jsxs("button", {
|
|
29484
|
-
type: "button",
|
|
29485
|
-
onClick,
|
|
29486
|
-
className: cn("px-2 py-1 text-[10px] font-medium rounded transition-colors", active ? variant === "on" ? "bg-green-500/20 text-green-400" : variant === "off" ? "bg-red-500/20 text-red-400" : "bg-primary/20 text-primary" : "text-foreground-subtle hover:bg-surface-hover"),
|
|
29487
|
-
children: [label, subtext && active && /* @__PURE__ */ jsxs("span", {
|
|
29488
|
-
className: "ml-1 opacity-60",
|
|
29489
|
-
children: [
|
|
29490
|
-
"(",
|
|
29491
|
-
subtext,
|
|
29492
|
-
")"
|
|
29493
|
-
]
|
|
29494
|
-
})]
|
|
29495
|
-
});
|
|
29496
|
-
}
|
|
29497
29676
|
//#endregion
|
|
29498
|
-
//#region src/composites/
|
|
29499
|
-
function
|
|
29500
|
-
|
|
29501
|
-
const declared = catalog.defaultModelIdByFormat?.[format];
|
|
29502
|
-
if (declared !== void 0 && hasFormatBuild(declared)) return declared;
|
|
29503
|
-
if (hasFormatBuild(catalog.defaultModelId)) return catalog.defaultModelId;
|
|
29504
|
-
const available = catalog.models.filter((m) => m.formats[format] !== void 0 && m.legacy !== true);
|
|
29505
|
-
if (available.length === 0) return catalog.defaultModelId;
|
|
29506
|
-
return [...available].toSorted((a, b) => (a.formats[format]?.sizeMB ?? Infinity) - (b.formats[format]?.sizeMB ?? Infinity))[0].id;
|
|
29677
|
+
//#region src/composites/step-inspector/setting-values.ts
|
|
29678
|
+
function isValueField(field) {
|
|
29679
|
+
return field.type !== "separator" && field.type !== "info" && field.type !== "group";
|
|
29507
29680
|
}
|
|
29508
|
-
/**
|
|
29509
|
-
|
|
29510
|
-
|
|
29511
|
-
* The device's ELECTED model (`device.defaultModelId`, the per-device
|
|
29512
|
-
* object-detection election) applies ONLY when this step's catalog actually
|
|
29513
|
-
* contains it — `slot === 'detector'` alone is too wide, because
|
|
29514
|
-
* package-detection shares the detector slot with the root step. Bit live
|
|
29515
|
-
* 2026-08-08: rfdetr-package became the package step's default and every
|
|
29516
|
-
* matrix cell still showed the device's yolo as the "selected" model, because
|
|
29517
|
-
* the election was applied slot-wide. Membership is the principled gate: an
|
|
29518
|
-
* elected model this step cannot run is never displayed for it.
|
|
29519
|
-
*/
|
|
29520
|
-
function resolveEffectiveDefaultModel(catalog, device) {
|
|
29521
|
-
const format = device?.format;
|
|
29522
|
-
if (format === void 0) return void 0;
|
|
29523
|
-
const elected = device?.defaultModelId;
|
|
29524
|
-
return catalog.slot === "detector" && elected !== void 0 && catalog.models.some((m) => m.id === elected) ? elected : resolveStepDefaultModel(catalog, format);
|
|
29681
|
+
/** True for a D738 field whose value is stored with the model it was made for. */
|
|
29682
|
+
function bindsToModel(field) {
|
|
29683
|
+
return (field.type === "slider" || field.type === "number") && field.bindsToModel === true;
|
|
29525
29684
|
}
|
|
29526
29685
|
/**
|
|
29527
|
-
*
|
|
29528
|
-
*
|
|
29529
|
-
*
|
|
29530
|
-
* the runner cannot honour.
|
|
29686
|
+
* What runs when no layer stores the field: the running model's default for a
|
|
29687
|
+
* model-bound field that the model declares one for (D738), else the field's
|
|
29688
|
+
* own default. `fromModel` says which.
|
|
29531
29689
|
*/
|
|
29532
|
-
function
|
|
29533
|
-
|
|
29534
|
-
|
|
29690
|
+
function defaultOfField(field, modelId) {
|
|
29691
|
+
const byModel = "modelApplicability" in field ? field.modelApplicability?.defaultByModel?.[modelId] : void 0;
|
|
29692
|
+
if (byModel !== void 0) return {
|
|
29693
|
+
value: byModel,
|
|
29694
|
+
fromModel: true
|
|
29695
|
+
};
|
|
29696
|
+
return {
|
|
29697
|
+
value: "default" in field ? field.default : void 0,
|
|
29698
|
+
fromModel: false
|
|
29699
|
+
};
|
|
29535
29700
|
}
|
|
29536
|
-
|
|
29537
|
-
|
|
29538
|
-
return stepModelOptions(models, format).length > 0;
|
|
29701
|
+
function trimNumber(n) {
|
|
29702
|
+
return n.toFixed(2).replace(/\.?0+$/, "");
|
|
29539
29703
|
}
|
|
29540
|
-
/**
|
|
29541
|
-
|
|
29542
|
-
|
|
29543
|
-
|
|
29544
|
-
|
|
29545
|
-
|
|
29546
|
-
|
|
29547
|
-
|
|
29548
|
-
|
|
29549
|
-
|
|
29550
|
-
|
|
29551
|
-
|
|
29704
|
+
/** One stored value as the operator reads it (`0.65`, `on`, `Person, Vehicle`, `—`). */
|
|
29705
|
+
function formatSettingValue(field, value) {
|
|
29706
|
+
if (value === void 0 || value === null) return "—";
|
|
29707
|
+
if (typeof value === "boolean") return value ? "on" : "off";
|
|
29708
|
+
if (typeof value === "number") {
|
|
29709
|
+
const scale = field.type === "slider" ? field.displayScale : void 0;
|
|
29710
|
+
const unit = "unit" in field && typeof field.unit === "string" ? ` ${field.unit}` : "";
|
|
29711
|
+
return `${trimNumber(scale !== void 0 ? value / scale : value)}${unit}`;
|
|
29712
|
+
}
|
|
29713
|
+
const options = "options" in field && Array.isArray(field.options) ? field.options : [];
|
|
29714
|
+
const labelOf = (v) => {
|
|
29715
|
+
const hit = options.find((o) => o.value === v);
|
|
29716
|
+
return hit ? hit.label : String(v);
|
|
29717
|
+
};
|
|
29718
|
+
if (Array.isArray(value)) return value.length === 0 ? "none" : value.map(labelOf).join(", ");
|
|
29719
|
+
if (typeof value === "string") return labelOf(value);
|
|
29720
|
+
return JSON.stringify(value);
|
|
29552
29721
|
}
|
|
29553
29722
|
//#endregion
|
|
29554
|
-
//#region src/composites/
|
|
29555
|
-
|
|
29556
|
-
|
|
29557
|
-
|
|
29558
|
-
|
|
29559
|
-
|
|
29560
|
-
|
|
29561
|
-
|
|
29562
|
-
|
|
29563
|
-
|
|
29564
|
-
*/
|
|
29565
|
-
/** The editor's view of the flag for one step, or `null` for a step no root can supply. */
|
|
29566
|
-
function rootSourceState(stepId, settings, rootModel) {
|
|
29567
|
-
if (!isRootSuppliableStepId(stepId)) return null;
|
|
29568
|
-
return resolveRootSupply(stepId, settings, rootModel?.supplies);
|
|
29723
|
+
//#region src/composites/step-inspector/layered-settings-form.tsx
|
|
29724
|
+
var SOURCE_TONE$1 = {
|
|
29725
|
+
accelerator: "border-amber-500/40 bg-amber-500/10 text-amber-500",
|
|
29726
|
+
camera: "border-primary/40 bg-primary/10 text-primary",
|
|
29727
|
+
node: "border-border bg-muted/40 text-foreground",
|
|
29728
|
+
default: "border-border/60 text-foreground-subtle"
|
|
29729
|
+
};
|
|
29730
|
+
/** DOM id of a field's box — the target of a search hit. */
|
|
29731
|
+
function stepFieldDomId(key) {
|
|
29732
|
+
return `step-field-${key}`;
|
|
29569
29733
|
}
|
|
29570
|
-
|
|
29571
|
-
function withUseRootModel(settings, value) {
|
|
29734
|
+
function displayStep(addon, modelId, settings) {
|
|
29572
29735
|
return {
|
|
29573
|
-
|
|
29574
|
-
|
|
29736
|
+
addonId: addon.id,
|
|
29737
|
+
addonName: addon.name,
|
|
29738
|
+
slot: addon.slot,
|
|
29739
|
+
inputClasses: [...addon.inputClasses],
|
|
29740
|
+
outputClasses: [...addon.outputClasses],
|
|
29741
|
+
enabled: true,
|
|
29742
|
+
modelId,
|
|
29743
|
+
children: [],
|
|
29744
|
+
settings: { ...settings }
|
|
29575
29745
|
};
|
|
29576
29746
|
}
|
|
29577
|
-
|
|
29578
|
-
|
|
29579
|
-
|
|
29580
|
-
|
|
29581
|
-
|
|
29582
|
-
|
|
29583
|
-
|
|
29584
|
-
|
|
29585
|
-
|
|
29586
|
-
|
|
29587
|
-
|
|
29588
|
-
|
|
29589
|
-
|
|
29590
|
-
|
|
29591
|
-
|
|
29592
|
-
|
|
29593
|
-
|
|
29594
|
-
|
|
29595
|
-
}
|
|
29596
|
-
|
|
29597
|
-
|
|
29598
|
-
const
|
|
29599
|
-
|
|
29600
|
-
const
|
|
29601
|
-
|
|
29602
|
-
|
|
29747
|
+
var LAYER_IDS = [
|
|
29748
|
+
"accelerator",
|
|
29749
|
+
"camera",
|
|
29750
|
+
"node"
|
|
29751
|
+
];
|
|
29752
|
+
/** "Camera · node 0.65 · model default 0.78 · [Reset to node]" under one field. */
|
|
29753
|
+
function SettingProvenance({ field, layers, target, labels, boundKeys, modelId, pinned, disabled, onReset, action }) {
|
|
29754
|
+
const effective = effectiveStepSettings(layers);
|
|
29755
|
+
const fallback = defaultOfField(field, modelId);
|
|
29756
|
+
const defaultLabel = fallback.fromModel ? "model default" : "default";
|
|
29757
|
+
const stored = stepSettingSource(layers, field.key, boundKeys);
|
|
29758
|
+
const bound = bindsToModel(field);
|
|
29759
|
+
const state = bound ? resolveModelBoundSetting(effective, field.key, modelId, fallback.value, fallback.value) : null;
|
|
29760
|
+
const source = state === null || state.source === "override" ? stored : "default";
|
|
29761
|
+
const sourceText = source === "default" ? defaultLabel : labels[source] ?? source;
|
|
29762
|
+
const levels = LAYER_IDS.filter((id) => id !== source && labels[id] !== void 0).filter((id) => layers[id]?.[field.key] !== void 0).map((id) => {
|
|
29763
|
+
const binding = bound ? layers[id]?.[modelBindingKey(field.key)] : void 0;
|
|
29764
|
+
const forOther = typeof binding === "string" && binding !== modelId ? ` (for ${binding})` : "";
|
|
29765
|
+
return `${labels[id]} ${formatSettingValue(field, layers[id]?.[field.key])}${forOther}`;
|
|
29766
|
+
});
|
|
29767
|
+
const withDefault = source === "default" ? levels : [...levels, `${defaultLabel} ${formatSettingValue(field, fallback.value)}`];
|
|
29768
|
+
const targetStores = stepSettingSource({ [target]: layers[target] }, field.key, boundKeys) !== "default";
|
|
29769
|
+
const below = LAYER_IDS.slice(LAYER_IDS.indexOf(target) + 1).find((id) => labels[id] !== void 0 && layers[id]?.[field.key] !== void 0);
|
|
29770
|
+
const resetTo = below !== void 0 ? labels[below] ?? below : defaultLabel;
|
|
29771
|
+
const belowSource = stored === "default" ? "default" : stepSettingSource({
|
|
29772
|
+
...layers,
|
|
29773
|
+
[stored]: void 0
|
|
29774
|
+
}, field.key, boundKeys);
|
|
29775
|
+
const pinnedAt = belowSource === "default" ? defaultLabel : labels[belowSource] ?? belowSource;
|
|
29776
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
29777
|
+
className: "mt-1 flex flex-wrap items-center gap-x-2 gap-y-1 text-[10px]",
|
|
29603
29778
|
children: [
|
|
29604
|
-
|
|
29605
|
-
|
|
29606
|
-
|
|
29779
|
+
/* @__PURE__ */ jsx("span", {
|
|
29780
|
+
"data-testid": "setting-source",
|
|
29781
|
+
className: cn("rounded border px-1.5 py-px font-medium", SOURCE_TONE$1[source]),
|
|
29782
|
+
children: sourceText
|
|
29783
|
+
}),
|
|
29784
|
+
withDefault.length > 0 && /* @__PURE__ */ jsx("span", {
|
|
29785
|
+
"data-testid": "setting-levels",
|
|
29786
|
+
className: "text-foreground-subtle",
|
|
29787
|
+
children: withDefault.join(" · ")
|
|
29788
|
+
}),
|
|
29789
|
+
pinned && /* @__PURE__ */ jsxs("span", {
|
|
29790
|
+
className: "rounded border border-amber-500/40 px-1.5 py-px text-amber-500",
|
|
29791
|
+
title: "Stored by an older editor as a copy of the value below. It changes nothing today, but it stops later changes below from reaching this camera.",
|
|
29792
|
+
children: [
|
|
29793
|
+
"pinned at the ",
|
|
29794
|
+
pinnedAt.toLowerCase(),
|
|
29795
|
+
" value"
|
|
29796
|
+
]
|
|
29797
|
+
}),
|
|
29798
|
+
/* @__PURE__ */ jsxs("span", {
|
|
29799
|
+
className: "ml-auto flex items-center gap-2",
|
|
29800
|
+
children: [action, targetStores && /* @__PURE__ */ jsxs("button", {
|
|
29801
|
+
type: "button",
|
|
29802
|
+
disabled,
|
|
29803
|
+
onClick: onReset,
|
|
29804
|
+
className: "rounded px-1 text-foreground-subtle hover:bg-muted hover:text-foreground disabled:opacity-50",
|
|
29805
|
+
children: ["Reset to ", resetTo.toLowerCase()]
|
|
29806
|
+
})]
|
|
29807
|
+
})
|
|
29607
29808
|
]
|
|
29608
|
-
})
|
|
29609
|
-
|
|
29610
|
-
|
|
29809
|
+
});
|
|
29810
|
+
}
|
|
29811
|
+
function LayeredSettingsForm({ addon, fields, layers, target, labels, modelId, onChangeLayer, rootModel, pinnedKeys = [], fieldActions, headerActions, highlightKey = null, disabled = false }) {
|
|
29812
|
+
const boundKeys = collectModelBoundKeys(fields);
|
|
29813
|
+
const effective = effectiveStepSettings(layers);
|
|
29814
|
+
const targetLayer = layers[target];
|
|
29815
|
+
const step = displayStep(addon, modelId, effective);
|
|
29816
|
+
const rootState = rootSourceState(addon.id, effective, rootModel);
|
|
29611
29817
|
return /* @__PURE__ */ jsxs("div", {
|
|
29612
|
-
className: "space-y-
|
|
29613
|
-
"data-testid": "root-model-source",
|
|
29818
|
+
className: "space-y-2 text-xs",
|
|
29614
29819
|
children: [
|
|
29615
|
-
/* @__PURE__ */ jsxs("
|
|
29616
|
-
className: "flex items-center gap-2
|
|
29820
|
+
/* @__PURE__ */ jsxs("div", {
|
|
29821
|
+
className: "flex flex-wrap items-center gap-2",
|
|
29617
29822
|
children: [
|
|
29618
|
-
/* @__PURE__ */ jsx("
|
|
29619
|
-
|
|
29620
|
-
|
|
29621
|
-
disabled,
|
|
29622
|
-
onChange: (e) => onChange(e.target.checked)
|
|
29823
|
+
/* @__PURE__ */ jsx("h3", {
|
|
29824
|
+
className: TEXT_SECTION_LABEL,
|
|
29825
|
+
children: "Settings"
|
|
29623
29826
|
}),
|
|
29624
|
-
|
|
29625
|
-
|
|
29626
|
-
|
|
29827
|
+
/* @__PURE__ */ jsxs("span", {
|
|
29828
|
+
className: TEXT_HINT,
|
|
29829
|
+
children: ["editing: ", labels[target] ?? target]
|
|
29830
|
+
}),
|
|
29831
|
+
/* @__PURE__ */ jsxs("span", {
|
|
29832
|
+
className: "ml-auto flex flex-wrap items-center gap-3",
|
|
29833
|
+
children: [headerActions, /* @__PURE__ */ jsx(ResetModelDefaultsButton, {
|
|
29834
|
+
fields,
|
|
29835
|
+
modelId,
|
|
29836
|
+
settings: targetLayer,
|
|
29837
|
+
disabled,
|
|
29838
|
+
onReset: (next) => onChangeLayer(next)
|
|
29839
|
+
})]
|
|
29840
|
+
})
|
|
29627
29841
|
]
|
|
29628
29842
|
}),
|
|
29629
|
-
|
|
29630
|
-
|
|
29631
|
-
|
|
29632
|
-
|
|
29633
|
-
|
|
29843
|
+
rootState !== null && /* @__PURE__ */ jsx(RootModelSourceControl, {
|
|
29844
|
+
stepId: addon.id,
|
|
29845
|
+
settings: effective,
|
|
29846
|
+
rootModel,
|
|
29847
|
+
disabled,
|
|
29848
|
+
onChange: (v) => onChangeLayer(withFieldFrom(targetLayer, USE_ROOT_MODEL_SETTING_KEY, withUseRootModel(effective, v), []))
|
|
29849
|
+
}),
|
|
29850
|
+
fields.map((field) => {
|
|
29851
|
+
if (!isValueField(field)) return /* @__PURE__ */ jsx(ConfigSchemaField, {
|
|
29852
|
+
field,
|
|
29853
|
+
allFields: fields,
|
|
29854
|
+
step,
|
|
29855
|
+
disabled,
|
|
29856
|
+
onChange: () => {}
|
|
29857
|
+
}, field.key);
|
|
29858
|
+
const highlighted = highlightKey === field.key;
|
|
29859
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
29860
|
+
id: stepFieldDomId(field.key),
|
|
29861
|
+
"data-field-key": field.key,
|
|
29862
|
+
className: cn("rounded-md border border-transparent px-2 py-1 -mx-2", highlighted && "border-primary/50 bg-primary/5"),
|
|
29863
|
+
children: [/* @__PURE__ */ jsx(ConfigSchemaField, {
|
|
29864
|
+
field,
|
|
29865
|
+
allFields: fields,
|
|
29866
|
+
step,
|
|
29867
|
+
disabled,
|
|
29868
|
+
hideModelBoundSourceRow: true,
|
|
29869
|
+
onChange: (next) => onChangeLayer(withFieldFrom(targetLayer, field.key, next.settings ?? {}, boundKeys))
|
|
29870
|
+
}), /* @__PURE__ */ jsx(SettingProvenance, {
|
|
29871
|
+
field,
|
|
29872
|
+
layers,
|
|
29873
|
+
target,
|
|
29874
|
+
labels,
|
|
29875
|
+
boundKeys,
|
|
29876
|
+
modelId,
|
|
29877
|
+
pinned: pinnedKeys.includes(field.key),
|
|
29878
|
+
disabled,
|
|
29879
|
+
onReset: () => onChangeLayer(withoutField(targetLayer, field.key, boundKeys)),
|
|
29880
|
+
action: fieldActions?.(field.key, stepSettingSource(layers, field.key, boundKeys))
|
|
29881
|
+
})]
|
|
29882
|
+
}, field.key);
|
|
29883
|
+
})
|
|
29634
29884
|
]
|
|
29635
29885
|
});
|
|
29636
29886
|
}
|
|
29637
29887
|
//#endregion
|
|
29638
29888
|
//#region src/composites/agent-step-editor.tsx
|
|
29639
29889
|
/**
|
|
29640
|
-
*
|
|
29641
|
-
*
|
|
29642
|
-
*
|
|
29890
|
+
* A step's node-local fields: the catalog schema minus the knobs the CLUSTER
|
|
29891
|
+
* owns (`clusterStepSettingFieldsFor`). Those still exist on the schema so the
|
|
29892
|
+
* runner can hydrate `child.settings`, but writing them per node or per camera
|
|
29643
29893
|
* would be a second store the overlay silently ignores.
|
|
29644
29894
|
*/
|
|
29645
|
-
function
|
|
29895
|
+
function stepLocalFields(addon) {
|
|
29646
29896
|
const clusterKeys = new Set(clusterStepSettingFieldsFor(addon.id).map((field) => field.key));
|
|
29647
29897
|
return (addon.configSchema ?? []).filter((field) => !clusterKeys.has(field.key));
|
|
29648
29898
|
}
|
|
29649
|
-
function ClusterSettingsHint({ addonId }) {
|
|
29650
|
-
if (clusterStepSettingFieldsFor(addonId).length === 0) return null;
|
|
29651
|
-
return /* @__PURE__ */ jsx("p", {
|
|
29652
|
-
className: "text-[10px] leading-snug text-foreground-subtle",
|
|
29653
|
-
children: "Admission knobs for this step live in Pipeline → Cluster → Settings → Enrichment models. They apply to every camera — a per-device copy would fill the shared index from two policies."
|
|
29654
|
-
});
|
|
29655
|
-
}
|
|
29656
29899
|
/**
|
|
29657
|
-
* The model
|
|
29900
|
+
* The model a step's settings are read and written for — what a model-bound
|
|
29658
29901
|
* field (D738) binds to. While the ROOT supplies the step's fine label (D741),
|
|
29659
29902
|
* that is the root model: the step's threshold then gates the root's label, on
|
|
29660
29903
|
* the root's score scale. Otherwise the step's own model: its pin, else the
|
|
29661
29904
|
* model the row really runs (`effectiveModelId` — the device's hardware-aware
|
|
29662
29905
|
* default when unpinned), else the step's flat catalog default.
|
|
29663
29906
|
*/
|
|
29664
|
-
function settingsModelIdFor(addon,
|
|
29665
|
-
if (rootModel !== void 0 && rootSourceState(addon.id,
|
|
29666
|
-
return
|
|
29907
|
+
function settingsModelIdFor(addon, modelId, settings, rootModel) {
|
|
29908
|
+
if (rootModel !== void 0 && rootSourceState(addon.id, settings, rootModel)?.effective) return rootModel.modelId;
|
|
29909
|
+
return modelId ?? addon.defaultModelId;
|
|
29667
29910
|
}
|
|
29668
|
-
function
|
|
29669
|
-
return
|
|
29670
|
-
|
|
29671
|
-
|
|
29672
|
-
|
|
29673
|
-
|
|
29674
|
-
outputClasses: [...addon.outputClasses],
|
|
29675
|
-
enabled: cfg.enabled,
|
|
29676
|
-
modelId,
|
|
29677
|
-
children: [],
|
|
29678
|
-
settings: { ...cfg.settings }
|
|
29679
|
-
};
|
|
29911
|
+
function ClusterSettingsHint({ addonId }) {
|
|
29912
|
+
if (clusterStepSettingFieldsFor(addonId).length === 0) return null;
|
|
29913
|
+
return /* @__PURE__ */ jsx("p", {
|
|
29914
|
+
className: "text-[10px] leading-snug text-foreground-subtle",
|
|
29915
|
+
children: "Admission knobs for this step live in Pipeline → Cluster → Settings → Enrichment models. They apply to every camera — a per-device copy would fill the shared index from two policies."
|
|
29916
|
+
});
|
|
29680
29917
|
}
|
|
29681
29918
|
/**
|
|
29682
29919
|
* Shown in place of the model picker while the root model supplies the step:
|
|
@@ -29697,233 +29934,57 @@ function RootSuppliedModelNote({ rootModel, stepModelId }) {
|
|
|
29697
29934
|
]
|
|
29698
29935
|
});
|
|
29699
29936
|
}
|
|
29700
|
-
|
|
29701
|
-
|
|
29702
|
-
|
|
29703
|
-
|
|
29704
|
-
|
|
29705
|
-
|
|
29706
|
-
|
|
29707
|
-
}
|
|
29708
|
-
|
|
29937
|
+
/**
|
|
29938
|
+
* AgentStepEditor — one step on ONE accelerator: its model and its settings,
|
|
29939
|
+
* as a single node-level layer. Model Studio's "settings for this installed
|
|
29940
|
+
* model" dialog uses it. The pipeline pages use the step matrix's panel, which lays
|
|
29941
|
+
* the same parts out across accelerators and layers (D754/D757); the settings
|
|
29942
|
+
* form here is that panel's `LayeredSettingsForm` with one layer.
|
|
29943
|
+
*/
|
|
29944
|
+
function AgentStepEditor({ addon, agentDefault, onChangeAgentConfig, engineFormat, effectiveModelId, rootModel }) {
|
|
29945
|
+
const modelsForFormat = useMemo(() => stepModelOptions(addon.models, engineFormat), [addon.models, engineFormat]);
|
|
29709
29946
|
const update = (patch) => {
|
|
29710
29947
|
onChangeAgentConfig?.({
|
|
29711
29948
|
...agentDefault,
|
|
29712
29949
|
...patch
|
|
29713
29950
|
});
|
|
29714
29951
|
};
|
|
29715
|
-
const
|
|
29952
|
+
const fields = stepLocalFields(addon);
|
|
29716
29953
|
const formatDefault = addon.defaultModelIdByFormat?.[engineFormat] ?? addon.defaultModelId;
|
|
29717
29954
|
const rootSupplied = rootSourceState(addon.id, agentDefault.settings, rootModel)?.effective === true;
|
|
29955
|
+
const runningModel = agentDefault.modelId ?? effectiveModelId;
|
|
29718
29956
|
return /* @__PURE__ */ jsxs("div", {
|
|
29719
29957
|
className: "space-y-4 text-xs",
|
|
29720
29958
|
children: [
|
|
29721
|
-
/* @__PURE__ */ jsx(RootModelSourceControl, {
|
|
29722
|
-
stepId: addon.id,
|
|
29723
|
-
settings: agentDefault.settings,
|
|
29724
|
-
rootModel,
|
|
29725
|
-
onChange: (v) => update({ settings: withUseRootModel(agentDefault.settings, v) })
|
|
29726
|
-
}),
|
|
29727
29959
|
rootSupplied && rootModel !== void 0 ? /* @__PURE__ */ jsx(RootSuppliedModelNote, {
|
|
29728
29960
|
rootModel,
|
|
29729
|
-
stepModelId:
|
|
29961
|
+
stepModelId: runningModel
|
|
29730
29962
|
}) : /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
|
|
29731
29963
|
className: "text-[10px] uppercase tracking-widest text-foreground-subtle mb-1",
|
|
29732
29964
|
children: "Model"
|
|
29733
29965
|
}), /* @__PURE__ */ jsx(ModelPicker, {
|
|
29734
29966
|
models: modelsForFormat,
|
|
29735
|
-
value:
|
|
29967
|
+
value: runningModel ?? "",
|
|
29736
29968
|
defaultModelId: formatDefault,
|
|
29737
29969
|
onChange: (modelId) => update({ modelId })
|
|
29738
29970
|
})] }),
|
|
29739
|
-
|
|
29740
|
-
className: "pt-2 border-t border-border/50
|
|
29741
|
-
children:
|
|
29742
|
-
|
|
29743
|
-
|
|
29744
|
-
|
|
29745
|
-
|
|
29746
|
-
|
|
29747
|
-
|
|
29748
|
-
|
|
29749
|
-
|
|
29750
|
-
|
|
29751
|
-
})]
|
|
29752
|
-
}), localSchema.map((field) => /* @__PURE__ */ jsx(ConfigSchemaField, {
|
|
29753
|
-
field,
|
|
29754
|
-
allFields: localSchema,
|
|
29755
|
-
step: buildDisplayStep(addon, agentDefault, settingsModelIdFor(addon, agentDefault, effectiveModelId, rootModel)),
|
|
29756
|
-
disabled: false,
|
|
29757
|
-
onChange: (next) => update({ settings: { ...next.settings } })
|
|
29758
|
-
}, field.key))]
|
|
29971
|
+
(fields.length > 0 || rootSourceState(addon.id, agentDefault.settings, rootModel)) && /* @__PURE__ */ jsx("div", {
|
|
29972
|
+
className: "pt-2 border-t border-border/50",
|
|
29973
|
+
children: /* @__PURE__ */ jsx(LayeredSettingsForm, {
|
|
29974
|
+
addon,
|
|
29975
|
+
fields,
|
|
29976
|
+
layers: { node: agentDefault.settings },
|
|
29977
|
+
target: "node",
|
|
29978
|
+
labels: { node: "This node" },
|
|
29979
|
+
modelId: settingsModelIdFor(addon, runningModel, agentDefault.settings, rootModel),
|
|
29980
|
+
...rootModel !== void 0 ? { rootModel } : {},
|
|
29981
|
+
onChangeLayer: (settings) => update({ settings })
|
|
29982
|
+
})
|
|
29759
29983
|
}),
|
|
29760
29984
|
/* @__PURE__ */ jsx(ClusterSettingsHint, { addonId: addon.id })
|
|
29761
29985
|
]
|
|
29762
29986
|
});
|
|
29763
29987
|
}
|
|
29764
|
-
function DeviceModeEditor({ addon, agentDefault, agentNodeId, currentPatch, modelsForFormat, engineFormat, effectiveModelId, rootModel, onChangePatch }) {
|
|
29765
|
-
const effective = computeEffective("device", agentDefault, currentPatch);
|
|
29766
|
-
const inheritedModelId = agentDefault.modelId ?? effectiveModelId;
|
|
29767
|
-
const formatDefault = addon.defaultModelIdByFormat?.[engineFormat] ?? addon.defaultModelId;
|
|
29768
|
-
const commitPatch = (next) => {
|
|
29769
|
-
const hasAnyField = next.modelId !== void 0 || next.settings !== void 0;
|
|
29770
|
-
onChangePatch?.(hasAnyField ? next : null);
|
|
29771
|
-
};
|
|
29772
|
-
const setModel = (modelId) => {
|
|
29773
|
-
const { modelId: _prev, ...rest } = currentPatch ?? {};
|
|
29774
|
-
commitPatch(modelId === void 0 ? rest : {
|
|
29775
|
-
...rest,
|
|
29776
|
-
modelId
|
|
29777
|
-
});
|
|
29778
|
-
};
|
|
29779
|
-
const setSettings = (settings) => {
|
|
29780
|
-
const { settings: _prev, ...rest } = currentPatch ?? {};
|
|
29781
|
-
commitPatch(settings === void 0 ? rest : {
|
|
29782
|
-
...rest,
|
|
29783
|
-
settings
|
|
29784
|
-
});
|
|
29785
|
-
};
|
|
29786
|
-
const modelOverridden = currentPatch?.modelId !== void 0;
|
|
29787
|
-
const localSchema = nodeLocalConfigSchema(addon);
|
|
29788
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
29789
|
-
className: "space-y-4 text-xs",
|
|
29790
|
-
children: [
|
|
29791
|
-
/* @__PURE__ */ jsxs("div", {
|
|
29792
|
-
className: "rounded bg-muted/40 px-3 py-2 text-[11px] text-foreground-subtle",
|
|
29793
|
-
children: [
|
|
29794
|
-
"Provisioning for ",
|
|
29795
|
-
/* @__PURE__ */ jsx("span", {
|
|
29796
|
-
className: "font-semibold text-foreground",
|
|
29797
|
-
children: agentNodeId
|
|
29798
|
-
}),
|
|
29799
|
-
" — model + settings only. Whether this camera runs the step is set by its per-camera gate above."
|
|
29800
|
-
]
|
|
29801
|
-
}),
|
|
29802
|
-
/* @__PURE__ */ jsx(RootModelSourceControl, {
|
|
29803
|
-
stepId: addon.id,
|
|
29804
|
-
settings: effective.settings,
|
|
29805
|
-
rootModel,
|
|
29806
|
-
onChange: (v) => setSettings(withUseRootModel(effective.settings, v))
|
|
29807
|
-
}),
|
|
29808
|
-
rootSourceState(addon.id, effective.settings, rootModel)?.effective === true && rootModel !== void 0 ? /* @__PURE__ */ jsx(RootSuppliedModelNote, {
|
|
29809
|
-
rootModel,
|
|
29810
|
-
stepModelId: effective.modelId ?? inheritedModelId
|
|
29811
|
-
}) : /* @__PURE__ */ jsxs("div", { children: [
|
|
29812
|
-
/* @__PURE__ */ jsxs("div", {
|
|
29813
|
-
className: "flex items-center justify-between mb-1",
|
|
29814
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
29815
|
-
className: "text-[10px] uppercase tracking-widest text-foreground-subtle",
|
|
29816
|
-
children: "Model"
|
|
29817
|
-
}), modelOverridden ? /* @__PURE__ */ jsx("button", {
|
|
29818
|
-
type: "button",
|
|
29819
|
-
className: "text-[10px] text-foreground-subtle hover:text-foreground",
|
|
29820
|
-
onClick: () => setModel(void 0),
|
|
29821
|
-
children: "Clear"
|
|
29822
|
-
}) : /* @__PURE__ */ jsx("button", {
|
|
29823
|
-
type: "button",
|
|
29824
|
-
className: "text-[10px] text-primary hover:underline",
|
|
29825
|
-
onClick: () => setModel(inheritedModelId),
|
|
29826
|
-
children: "Override"
|
|
29827
|
-
})]
|
|
29828
|
-
}),
|
|
29829
|
-
/* @__PURE__ */ jsx(ModelPicker, {
|
|
29830
|
-
models: modelsForFormat,
|
|
29831
|
-
disabled: !modelOverridden,
|
|
29832
|
-
value: (modelOverridden ? currentPatch?.modelId ?? inheritedModelId : inheritedModelId) ?? "",
|
|
29833
|
-
defaultModelId: formatDefault,
|
|
29834
|
-
onChange: (modelId) => setModel(modelId)
|
|
29835
|
-
}),
|
|
29836
|
-
!modelOverridden && /* @__PURE__ */ jsxs("div", {
|
|
29837
|
-
className: "text-[10px] text-foreground-subtle mt-1",
|
|
29838
|
-
children: ["inherits from ", agentNodeId]
|
|
29839
|
-
})
|
|
29840
|
-
] }),
|
|
29841
|
-
localSchema.length > 0 && (() => {
|
|
29842
|
-
const settingsOverridden = currentPatch?.settings !== void 0;
|
|
29843
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
29844
|
-
className: "pt-2 border-t border-border/50 space-y-3",
|
|
29845
|
-
children: [
|
|
29846
|
-
/* @__PURE__ */ jsxs("div", {
|
|
29847
|
-
className: "flex items-center justify-between",
|
|
29848
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
29849
|
-
className: "text-[10px] uppercase tracking-widest text-foreground-subtle",
|
|
29850
|
-
children: "Settings"
|
|
29851
|
-
}), settingsOverridden ? /* @__PURE__ */ jsxs("div", {
|
|
29852
|
-
className: "flex items-center gap-3",
|
|
29853
|
-
children: [/* @__PURE__ */ jsx(ResetModelDefaultsButton, {
|
|
29854
|
-
fields: localSchema,
|
|
29855
|
-
modelId: settingsModelIdFor(addon, effective, inheritedModelId, rootModel),
|
|
29856
|
-
settings: currentPatch?.settings,
|
|
29857
|
-
onReset: (settings) => setSettings(settings)
|
|
29858
|
-
}), /* @__PURE__ */ jsx("button", {
|
|
29859
|
-
type: "button",
|
|
29860
|
-
className: "text-[10px] text-foreground-subtle hover:text-foreground",
|
|
29861
|
-
onClick: () => setSettings(void 0),
|
|
29862
|
-
children: "Clear"
|
|
29863
|
-
})]
|
|
29864
|
-
}) : /* @__PURE__ */ jsx("button", {
|
|
29865
|
-
type: "button",
|
|
29866
|
-
className: "text-[10px] text-primary hover:underline",
|
|
29867
|
-
onClick: () => setSettings({ ...agentDefault.settings }),
|
|
29868
|
-
children: "Override"
|
|
29869
|
-
})]
|
|
29870
|
-
}),
|
|
29871
|
-
localSchema.map((field) => /* @__PURE__ */ jsx(ConfigSchemaField, {
|
|
29872
|
-
field,
|
|
29873
|
-
allFields: localSchema,
|
|
29874
|
-
step: buildDisplayStep(addon, effective, settingsModelIdFor(addon, effective, inheritedModelId, rootModel)),
|
|
29875
|
-
disabled: !settingsOverridden,
|
|
29876
|
-
onChange: (next) => setSettings({ ...next.settings })
|
|
29877
|
-
}, field.key)),
|
|
29878
|
-
!settingsOverridden && /* @__PURE__ */ jsxs("div", {
|
|
29879
|
-
className: "text-[10px] text-foreground-subtle",
|
|
29880
|
-
children: ["inherits from ", agentNodeId]
|
|
29881
|
-
})
|
|
29882
|
-
]
|
|
29883
|
-
});
|
|
29884
|
-
})(),
|
|
29885
|
-
/* @__PURE__ */ jsx(ClusterSettingsHint, { addonId: addon.id }),
|
|
29886
|
-
/* @__PURE__ */ jsxs("div", {
|
|
29887
|
-
className: "rounded bg-muted/40 px-3 py-2 text-[11px] text-foreground-subtle",
|
|
29888
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
29889
|
-
className: "font-semibold text-foreground mb-0.5",
|
|
29890
|
-
children: "Effective provisioning preview"
|
|
29891
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
29892
|
-
className: "font-mono truncate",
|
|
29893
|
-
children: [
|
|
29894
|
-
addon.id,
|
|
29895
|
-
" · model: ",
|
|
29896
|
-
effective.modelId ?? inheritedModelId ?? "Auto"
|
|
29897
|
-
]
|
|
29898
|
-
})]
|
|
29899
|
-
})
|
|
29900
|
-
]
|
|
29901
|
-
});
|
|
29902
|
-
}
|
|
29903
|
-
function AgentStepEditor(props) {
|
|
29904
|
-
const { mode, addon, agentDefault, agentNodeId, currentPatch, onChangeAgentConfig, onChangePatch, engineFormat, effectiveModelId, rootModel } = props;
|
|
29905
|
-
const modelsForFormat = useMemo(() => stepModelOptions(addon.models, engineFormat), [addon.models, engineFormat]);
|
|
29906
|
-
if (mode === "agent") return /* @__PURE__ */ jsx(AgentModeEditor, {
|
|
29907
|
-
addon,
|
|
29908
|
-
agentDefault,
|
|
29909
|
-
modelsForFormat,
|
|
29910
|
-
engineFormat,
|
|
29911
|
-
effectiveModelId,
|
|
29912
|
-
...rootModel !== void 0 ? { rootModel } : {},
|
|
29913
|
-
onChangeAgentConfig
|
|
29914
|
-
});
|
|
29915
|
-
return /* @__PURE__ */ jsx(DeviceModeEditor, {
|
|
29916
|
-
addon,
|
|
29917
|
-
agentDefault,
|
|
29918
|
-
agentNodeId,
|
|
29919
|
-
currentPatch,
|
|
29920
|
-
modelsForFormat,
|
|
29921
|
-
engineFormat,
|
|
29922
|
-
effectiveModelId,
|
|
29923
|
-
...rootModel !== void 0 ? { rootModel } : {},
|
|
29924
|
-
onChangePatch
|
|
29925
|
-
});
|
|
29926
|
-
}
|
|
29927
29988
|
//#endregion
|
|
29928
29989
|
//#region src/primitives/icon-button.tsx
|
|
29929
29990
|
var iconButtonVariants = cva("inline-flex items-center justify-center rounded-md font-medium transition-colors cursor-pointer disabled:opacity-50 disabled:pointer-events-none", {
|
|
@@ -33838,117 +33899,6 @@ async function waitForIceGathering(pc) {
|
|
|
33838
33899
|
});
|
|
33839
33900
|
}
|
|
33840
33901
|
//#endregion
|
|
33841
|
-
//#region src/lib/responsive.ts
|
|
33842
|
-
/**
|
|
33843
|
-
* Responsive design tokens — three-tier system.
|
|
33844
|
-
*
|
|
33845
|
-
* The admin-ui targets three width tiers; every component should pick
|
|
33846
|
-
* the right token from this file instead of hand-coding breakpoints.
|
|
33847
|
-
* Adopting the tokens uniformly is what makes the app feel consistent
|
|
33848
|
-
* across operator devices (mobile / tablet / desktop) and what unlocks
|
|
33849
|
-
* targeted tuning (e.g. shrink every label by 1px in one place).
|
|
33850
|
-
*
|
|
33851
|
-
* Tier definitions (Tailwind breakpoints):
|
|
33852
|
-
*
|
|
33853
|
-
* • **L1 — Compact** (`< 640px`, default = mobile portrait)
|
|
33854
|
-
* Single column, tight padding, smallest text, icon-only buttons
|
|
33855
|
-
* where labels can be inferred. The operator can still see every
|
|
33856
|
-
* stat / action — no horizontal scroll, no clipped text. The user
|
|
33857
|
-
* directive: "molta informazione in poco spazio quando la width è
|
|
33858
|
-
* bassa." [a lot of information in little space when the width is low.]
|
|
33859
|
-
*
|
|
33860
|
-
* • **L2 — Standard** (`sm` — `640–1023px`, tablet + small laptop)
|
|
33861
|
-
* 2-column grids, side panels become visible, button labels return.
|
|
33862
|
-
* Targets ~768px–1024px viewports — the most common operator sizes.
|
|
33863
|
-
*
|
|
33864
|
-
* • **L3 — Spacious** (`lg+` — `≥ 1024px`, desktop)
|
|
33865
|
-
* 4-column grids, generous padding, full-width header text,
|
|
33866
|
-
* side-by-side composite layouts. The operator has elbow room.
|
|
33867
|
-
*
|
|
33868
|
-
* Conventions:
|
|
33869
|
-
* - **Always start from L1** — the bare class is always the compact
|
|
33870
|
-
* variant, then `sm:` adds room at 640px, `lg:` at 1024px. No
|
|
33871
|
-
* desktop-first breakpoints; no max-width queries.
|
|
33872
|
-
* - **Token strings are static** — kept as `as const` so callers can
|
|
33873
|
-
* compose them via `cn()` / template literals without running a
|
|
33874
|
-
* class generator at runtime.
|
|
33875
|
-
* - **Pair the token with a comment** — the comment in the file
|
|
33876
|
-
* names every breakpoint it crosses, so a reader can predict the
|
|
33877
|
-
* layout without going to Tailwind docs.
|
|
33878
|
-
*/
|
|
33879
|
-
/** Container padding for a card-style section (header + body). */
|
|
33880
|
-
var SECTION_CARD = "rounded-lg border border-border bg-surface overflow-hidden";
|
|
33881
|
-
/** Header strip inside a card (between border-b lines). */
|
|
33882
|
-
var SECTION_HEADER = "border-b border-border px-3 sm:px-4 py-1.5 sm:py-2";
|
|
33883
|
-
/** Body padding for a card-style section. */
|
|
33884
|
-
var SECTION_BODY = "p-2 sm:p-3 lg:p-4";
|
|
33885
|
-
/** Gap between cards in a vertical stack. */
|
|
33886
|
-
var STACK_GAP = "space-y-3 sm:space-y-4";
|
|
33887
|
-
/** Gap between cards in a grid (4 cells / row at lg). */
|
|
33888
|
-
var GRID_GAP = "gap-2 sm:gap-3";
|
|
33889
|
-
/** Row padding inside a divided list (e.g. InfoRow). */
|
|
33890
|
-
var LIST_ROW = "px-3 sm:px-4 py-1.5 sm:py-2";
|
|
33891
|
-
/** 1-up at L1, 2-up at L2, 4-up at L3 — quick-stat row. */
|
|
33892
|
-
var GRID_QUICK_STATS = "grid grid-cols-2 sm:grid-cols-2 lg:grid-cols-4";
|
|
33893
|
-
/** 1-up at L1, 2-up at L2+ — paired panels (motion + detection rules). */
|
|
33894
|
-
var GRID_PAIRED = "grid grid-cols-1 lg:grid-cols-2";
|
|
33895
|
-
/** Side-by-side layout that stacks below md (canvas + side panel). */
|
|
33896
|
-
var SPLIT_PANEL_OUTER = "flex flex-col-reverse md:flex-row";
|
|
33897
|
-
/** Sidebar narrow lane in a SPLIT_PANEL_OUTER layout. */
|
|
33898
|
-
var SPLIT_PANEL_SIDE = "w-full md:w-44 lg:w-52 md:flex-shrink-0 border-b md:border-b-0 md:border-l border-border";
|
|
33899
|
-
/**
|
|
33900
|
-
* The tier boundary at which a settings label/value row stops stacking.
|
|
33901
|
-
*
|
|
33902
|
-
* Below it (L1 — compact) the row is ONE column: label on its own line, value
|
|
33903
|
-
* on the next at full width. Above it the row is label-left / value-right as
|
|
33904
|
-
* before. The two-column form needs `SETTING_ROW_LABEL`'s lane plus a readable
|
|
33905
|
-
* value beside it; a phone has neither, and the failure mode is not "cramped"
|
|
33906
|
-
* but "the value is the part that gets cut" — the one thing the operator
|
|
33907
|
-
* opened the page to read.
|
|
33908
|
-
*/
|
|
33909
|
-
var SETTING_ROW_STACK_BREAKPOINT = "sm";
|
|
33910
|
-
/** Outer row: single column at L1, label/value columns from `sm` up. */
|
|
33911
|
-
var SETTING_ROW = "flex min-w-0 flex-col gap-0.5 py-1.5 sm:flex-row sm:items-center";
|
|
33912
|
-
/** Label lane. Full width (and free to wrap) at L1; a fixed lane from `sm` up. */
|
|
33913
|
-
var SETTING_ROW_LABEL = "min-w-0 text-[11px] leading-tight text-foreground-subtle sm:w-32 sm:shrink-0 sm:pr-2";
|
|
33914
|
-
/**
|
|
33915
|
-
* Value lane — the value text plus its trailing affordances (copy / reveal).
|
|
33916
|
-
* `w-full` at L1 so the value owns the whole row once the label is above it;
|
|
33917
|
-
* `sm:flex-1` makes it share the row again from `sm` up.
|
|
33918
|
-
*/
|
|
33919
|
-
var SETTING_ROW_VALUE = "flex w-full min-w-0 items-center gap-1 sm:flex-1";
|
|
33920
|
-
/**
|
|
33921
|
-
* The value text itself. `break-all` lets an opaque token (a key, a URL) wrap
|
|
33922
|
-
* at L1 instead of being cut mid-word; `sm:truncate` restores the single-line
|
|
33923
|
-
* desktop form, where the row is wide enough for truncation to be a choice
|
|
33924
|
-
* rather than data loss.
|
|
33925
|
-
*/
|
|
33926
|
-
var SETTING_ROW_VALUE_TEXT = "min-w-0 break-all text-xs text-foreground sm:truncate";
|
|
33927
|
-
/** Section header label (uppercase tracking-wider). */
|
|
33928
|
-
var TEXT_SECTION_LABEL = "text-[10px] sm:text-[11px] font-semibold text-foreground uppercase tracking-wider";
|
|
33929
|
-
/** Field label inside a row. */
|
|
33930
|
-
var TEXT_FIELD_LABEL = "text-[11px] sm:text-xs text-foreground";
|
|
33931
|
-
/** Sub-label / hint text. */
|
|
33932
|
-
var TEXT_HINT = "text-[10px] text-foreground-subtle";
|
|
33933
|
-
/** Primary value (a metric, badge, …). */
|
|
33934
|
-
var TEXT_VALUE = "text-[11px] sm:text-xs font-medium text-foreground";
|
|
33935
|
-
/** Big metric value (StatCard). */
|
|
33936
|
-
var TEXT_METRIC = "text-base sm:text-lg font-semibold leading-tight text-foreground";
|
|
33937
|
-
/** Default compact button. */
|
|
33938
|
-
var BTN_COMPACT = "inline-flex items-center justify-center gap-1 rounded border border-border bg-surface px-1.5 py-0.5 sm:px-2 sm:py-1 text-[10px] sm:text-[11px] font-medium text-foreground hover:bg-surface-hover transition-colors disabled:opacity-40";
|
|
33939
|
-
/** Primary compact button. */
|
|
33940
|
-
var BTN_COMPACT_PRIMARY = "inline-flex items-center justify-center gap-1 rounded border border-primary/40 bg-primary/15 px-1.5 py-0.5 sm:px-2 sm:py-1 text-[10px] sm:text-[11px] font-medium text-primary hover:bg-primary/25 transition-colors disabled:opacity-40";
|
|
33941
|
-
/** Danger compact button. */
|
|
33942
|
-
var BTN_COMPACT_DANGER = "inline-flex items-center justify-center gap-1 rounded border border-danger/40 bg-danger/10 px-1.5 py-0.5 sm:px-2 sm:py-1 text-[10px] sm:text-[11px] font-medium text-danger hover:bg-danger/20 transition-colors disabled:opacity-40";
|
|
33943
|
-
/** Warning compact button (e.g. cancel-drawing). */
|
|
33944
|
-
var BTN_COMPACT_WARNING = "inline-flex items-center justify-center gap-1 rounded border border-warning/40 bg-warning/10 px-1.5 py-0.5 sm:px-2 sm:py-1 text-[10px] sm:text-[11px] font-medium text-warning hover:bg-warning/20 transition-colors disabled:opacity-40";
|
|
33945
|
-
/** Compact text/select/number input. */
|
|
33946
|
-
var INPUT_COMPACT = "w-full rounded border border-border bg-background px-1.5 py-0.5 sm:px-2 sm:py-1 text-[11px] sm:text-xs text-foreground focus:border-primary focus:ring-1 focus:ring-primary/30 outline-none";
|
|
33947
|
-
/** Chip-style toggle (zone / class selectors in ZoneRulesEditor). */
|
|
33948
|
-
var CHIP_BASE = "inline-flex items-center gap-1 rounded-full border px-1.5 py-0.5 text-[10px] font-medium transition-colors";
|
|
33949
|
-
var CHIP_ACTIVE = "border-primary/50 bg-primary/15 text-primary";
|
|
33950
|
-
var CHIP_INACTIVE = "border-border bg-surface text-foreground-subtle hover:bg-surface-hover";
|
|
33951
|
-
//#endregion
|
|
33952
33902
|
//#region src/composites/data-table-layout.ts
|
|
33953
33903
|
/**
|
|
33954
33904
|
* At this many columns and above, `auto` switches a narrow viewport to cards.
|
|
@@ -55419,25 +55369,46 @@ function ClassChips({ inputs, outputs }) {
|
|
|
55419
55369
|
* the first column; each device's real format is shown per sub-column instead
|
|
55420
55370
|
* ("Coral Edge TPU · tflite").
|
|
55421
55371
|
*/
|
|
55372
|
+
/** The per-accelerator lines of a column header: name, format, model, off. */
|
|
55373
|
+
function AgentColumnLines({ column }) {
|
|
55374
|
+
const name = column.deviceLabel ?? column.deviceKey;
|
|
55375
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
55376
|
+
(name !== void 0 || column.disabled === true) && /* @__PURE__ */ jsxs("div", {
|
|
55377
|
+
className: "flex min-w-0 items-center gap-1",
|
|
55378
|
+
children: [name !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
55379
|
+
className: "truncate text-[10px] font-medium text-foreground/90",
|
|
55380
|
+
children: name
|
|
55381
|
+
}), column.disabled === true && /* @__PURE__ */ jsx("span", {
|
|
55382
|
+
className: "shrink-0 rounded bg-muted px-1 text-[8px] font-semibold uppercase text-foreground-subtle",
|
|
55383
|
+
children: "off"
|
|
55384
|
+
})]
|
|
55385
|
+
}),
|
|
55386
|
+
/* @__PURE__ */ jsx("div", {
|
|
55387
|
+
className: "truncate text-[9px] text-foreground-subtle",
|
|
55388
|
+
children: column.engineLabel
|
|
55389
|
+
}),
|
|
55390
|
+
column.detail !== void 0 && /* @__PURE__ */ jsx("div", {
|
|
55391
|
+
className: "truncate font-mono text-[9px] text-foreground-subtle",
|
|
55392
|
+
title: column.detail,
|
|
55393
|
+
children: column.detail
|
|
55394
|
+
})
|
|
55395
|
+
] });
|
|
55396
|
+
}
|
|
55422
55397
|
function GroupedAgentHeader({ group }) {
|
|
55398
|
+
const nodeLabel = group.columns[0]?.nodeLabel ?? group.agentNodeId;
|
|
55423
55399
|
return /* @__PURE__ */ jsxs("div", {
|
|
55400
|
+
role: "columnheader",
|
|
55424
55401
|
className: "sticky top-0 z-10 min-w-0 border-b border-l border-border bg-muted/60",
|
|
55425
55402
|
style: { gridColumn: `span ${group.columns.length}` },
|
|
55426
55403
|
children: [/* @__PURE__ */ jsx("div", {
|
|
55427
55404
|
className: "truncate px-3 pt-2 pb-1 text-xs font-semibold text-foreground",
|
|
55428
|
-
children:
|
|
55405
|
+
children: nodeLabel
|
|
55429
55406
|
}), /* @__PURE__ */ jsx("div", {
|
|
55430
55407
|
className: "mt-1 flex border-t border-border/50",
|
|
55431
|
-
children: group.columns.map((c, i) => /* @__PURE__ */
|
|
55432
|
-
className: cn("min-w-0 flex-1 px-3 py-1", i > 0 && "border-l border-border/50"),
|
|
55433
|
-
title: `${c.deviceLabel ?? c.deviceKey} · ${c.engineLabel}`,
|
|
55434
|
-
children:
|
|
55435
|
-
className: "truncate text-[10px] font-medium text-foreground/90",
|
|
55436
|
-
children: c.deviceLabel ?? c.deviceKey
|
|
55437
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
55438
|
-
className: "truncate text-[9px] text-foreground-subtle",
|
|
55439
|
-
children: c.engineLabel
|
|
55440
|
-
})]
|
|
55408
|
+
children: group.columns.map((c, i) => /* @__PURE__ */ jsx("div", {
|
|
55409
|
+
className: cn("min-w-0 flex-1 px-3 py-1", i > 0 && "border-l border-border/50", c.disabled === true && "opacity-70"),
|
|
55410
|
+
title: `${c.deviceLabel ?? c.deviceKey} · ${c.engineLabel}${c.detail ? ` · ${c.detail}` : ""}`,
|
|
55411
|
+
children: /* @__PURE__ */ jsx(AgentColumnLines, { column: c })
|
|
55441
55412
|
}, agentColumnKey(c)))
|
|
55442
55413
|
})]
|
|
55443
55414
|
});
|
|
@@ -55541,97 +55512,75 @@ function cellButtonClass(state, isSelected, extra) {
|
|
|
55541
55512
|
//#endregion
|
|
55542
55513
|
//#region src/composites/device-step-matrix.tsx
|
|
55543
55514
|
/**
|
|
55544
|
-
* DeviceStepMatrix — the
|
|
55545
|
-
*
|
|
55546
|
-
*
|
|
55547
|
-
*
|
|
55548
|
-
*
|
|
55549
|
-
*
|
|
55550
|
-
*
|
|
55551
|
-
*
|
|
55552
|
-
* the
|
|
55553
|
-
*
|
|
55554
|
-
*
|
|
55555
|
-
*
|
|
55556
|
-
*
|
|
55557
|
-
*
|
|
55558
|
-
*
|
|
55559
|
-
*
|
|
55560
|
-
*
|
|
55561
|
-
*
|
|
55562
|
-
*
|
|
55563
|
-
|
|
55564
|
-
|
|
55565
|
-
|
|
55566
|
-
|
|
55567
|
-
|
|
55568
|
-
* Narrow (mobile) step-column width. On a phone the wide 21rem column would
|
|
55569
|
-
* occlude nearly the whole viewport, so the single-node layout pins a slimmer
|
|
55570
|
-
* sticky step column and lets the device columns scroll horizontally beside it
|
|
55571
|
-
* (both fully readable) rather than cramming every column into the viewport.
|
|
55515
|
+
* DeviceStepMatrix — the step × accelerator TABLE of a detection pipeline
|
|
55516
|
+
* (D757): the node's Pipeline tab and the camera's Detection pipeline → Steps
|
|
55517
|
+
* are this matrix, and a click on a cell (or a step's header) opens that step's
|
|
55518
|
+
* settings in a docked panel (`StepDetailDock`) that overlays the page instead
|
|
55519
|
+
* of reflowing the matrix.
|
|
55520
|
+
*
|
|
55521
|
+
* Column 1 (STICKY): the indented step tree — slot, name, class-flow chips,
|
|
55522
|
+
* and an optional badge (the camera's gate). The header is a button: it
|
|
55523
|
+
* opens the step on the selected accelerator.
|
|
55524
|
+
* Columns 2..N: one per accelerator, grouped under their node; the header
|
|
55525
|
+
* names the accelerator, its format, the model it elects, and "off" for a
|
|
55526
|
+
* switched-off one. A cell shows the model that runs there, or "⚠ skip",
|
|
55527
|
+
* "→ iGPU", "root", "cluster", "ovr", "—".
|
|
55528
|
+
*
|
|
55529
|
+
* Keyboard: ONE Tab stop (a roving tabindex over the step headers and cells);
|
|
55530
|
+
* arrows move, Home / End go to the row's ends, Enter or Space opens.
|
|
55531
|
+
*
|
|
55532
|
+
* `reserveRightPx`: the width a docked panel covers at the right of the
|
|
55533
|
+
* viewport. The matrix adds a trailing spacer that wide (so any column can
|
|
55534
|
+
* scroll clear of it) and scrolls the selected cell into the uncovered part —
|
|
55535
|
+
* it never shrinks, so nothing reflows when the panel opens.
|
|
55536
|
+
*
|
|
55537
|
+
* Responsive, container-measured: narrower than the step column plus two
|
|
55538
|
+
* columns, the matrix shows ONE node at a time with a node selector.
|
|
55572
55539
|
*/
|
|
55573
|
-
|
|
55574
|
-
|
|
55575
|
-
|
|
55576
|
-
return gate.effectiveOn ? "on" : "off";
|
|
55577
|
-
}
|
|
55540
|
+
/** The sticky step column. */
|
|
55541
|
+
var STEP_COL_REM = 18;
|
|
55542
|
+
var STEP_COL_PX = STEP_COL_REM * 16;
|
|
55578
55543
|
/**
|
|
55579
|
-
*
|
|
55580
|
-
* the
|
|
55581
|
-
*
|
|
55544
|
+
* Narrow (mobile) step-column width. On a phone the wide column would occlude
|
|
55545
|
+
* nearly the whole viewport, so the single-node layout pins a slimmer sticky
|
|
55546
|
+
* step column and lets the device columns scroll horizontally beside it.
|
|
55582
55547
|
*/
|
|
55583
|
-
|
|
55584
|
-
|
|
55585
|
-
|
|
55586
|
-
|
|
55587
|
-
|
|
55588
|
-
|
|
55589
|
-
|
|
55590
|
-
|
|
55591
|
-
|
|
55592
|
-
|
|
55593
|
-
|
|
55594
|
-
|
|
55595
|
-
|
|
55596
|
-
|
|
55597
|
-
|
|
55598
|
-
|
|
55599
|
-
|
|
55600
|
-
|
|
55601
|
-
/* @__PURE__ */ jsx("span", { className: "w-px self-stretch bg-border" }),
|
|
55602
|
-
seg("off", "Off", false, "bg-foreground-subtle/70 text-white")
|
|
55603
|
-
]
|
|
55604
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
55605
|
-
className: "text-[10px] leading-none text-foreground-subtle",
|
|
55606
|
-
children: active === "default" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
55607
|
-
"= default (",
|
|
55608
|
-
gate.defaultOn ? "on" : "off",
|
|
55609
|
-
")"
|
|
55610
|
-
] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: ["overridden · default ", gate.defaultOn ? "on" : "off"] })
|
|
55611
|
-
})]
|
|
55612
|
-
});
|
|
55613
|
-
}
|
|
55614
|
-
function ZoneBadge() {
|
|
55615
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
55616
|
-
className: "flex flex-col gap-1",
|
|
55617
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
55618
|
-
className: "inline-flex w-fit items-center gap-1 rounded-md border border-violet-500/40 bg-violet-500/10 px-2 py-1 text-[11px] font-medium text-violet-400",
|
|
55619
|
-
children: "Zones"
|
|
55620
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
55621
|
-
className: "text-[10px] leading-none text-foreground-subtle",
|
|
55622
|
-
children: "driven by package zones"
|
|
55623
|
-
})]
|
|
55624
|
-
});
|
|
55548
|
+
var STEP_COL_SINGLE_REM = 11;
|
|
55549
|
+
/** Where a key press moves the roving focus in a `rows × cols` grid. */
|
|
55550
|
+
function nextGridPosition(key, pos, rows, cols) {
|
|
55551
|
+
const clamp = (r, c) => ({
|
|
55552
|
+
r: Math.max(0, Math.min(rows - 1, r)),
|
|
55553
|
+
c: Math.max(0, Math.min(cols - 1, c))
|
|
55554
|
+
});
|
|
55555
|
+
switch (key) {
|
|
55556
|
+
case "ArrowRight": return clamp(pos.r, pos.c + 1);
|
|
55557
|
+
case "ArrowLeft": return clamp(pos.r, pos.c - 1);
|
|
55558
|
+
case "ArrowDown": return clamp(pos.r + 1, pos.c);
|
|
55559
|
+
case "ArrowUp": return clamp(pos.r - 1, pos.c);
|
|
55560
|
+
case "Home": return clamp(pos.r, 0);
|
|
55561
|
+
case "End": return clamp(pos.r, cols - 1);
|
|
55562
|
+
case "PageDown": return clamp(rows - 1, pos.c);
|
|
55563
|
+
case "PageUp": return clamp(0, pos.c);
|
|
55564
|
+
default: return null;
|
|
55565
|
+
}
|
|
55625
55566
|
}
|
|
55626
|
-
function
|
|
55627
|
-
return /* @__PURE__ */
|
|
55628
|
-
|
|
55629
|
-
|
|
55630
|
-
children:
|
|
55631
|
-
|
|
55632
|
-
|
|
55633
|
-
|
|
55634
|
-
|
|
55567
|
+
function StepCell({ node, depth, r, tabbable, selected, badge, onClick, sticky }) {
|
|
55568
|
+
return /* @__PURE__ */ jsx("div", {
|
|
55569
|
+
role: "rowheader",
|
|
55570
|
+
className: cn("min-w-0 border-b border-border bg-surface", sticky && "sticky left-0 z-10"),
|
|
55571
|
+
children: /* @__PURE__ */ jsxs("button", {
|
|
55572
|
+
type: "button",
|
|
55573
|
+
"data-r": r,
|
|
55574
|
+
"data-c": 0,
|
|
55575
|
+
"data-step": node.addonId,
|
|
55576
|
+
"data-col": "",
|
|
55577
|
+
tabIndex: tabbable ? 0 : -1,
|
|
55578
|
+
"aria-current": selected ? "true" : void 0,
|
|
55579
|
+
onClick: onClick ? (e) => onClick(e.detail === 0) : void 0,
|
|
55580
|
+
className: cn("flex h-full w-full min-w-0 items-start gap-2 px-3 py-2 text-left text-xs outline-none", "hover:bg-muted/40 focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary", selected && "bg-primary/10 shadow-[inset_3px_0_0_var(--color-primary)]"),
|
|
55581
|
+
style: { paddingLeft: `${12 + depth * 14}px` },
|
|
55582
|
+
children: [/* @__PURE__ */ jsx(StepLabel, { node }), badge]
|
|
55583
|
+
})
|
|
55635
55584
|
});
|
|
55636
55585
|
}
|
|
55637
55586
|
/**
|
|
@@ -55661,76 +55610,179 @@ function NodeSelectorBar({ nodes, selected, onSelect }) {
|
|
|
55661
55610
|
role: "tab",
|
|
55662
55611
|
"aria-selected": isSelected,
|
|
55663
55612
|
onClick: () => onSelect(a.agentNodeId),
|
|
55664
|
-
title: `${a.agentNodeId} · ${a.engineLabel}`,
|
|
55613
|
+
title: `${a.columns[0]?.nodeLabel ?? a.agentNodeId} · ${a.engineLabel}`,
|
|
55665
55614
|
className: cn("px-2.5 py-1 transition-colors", isSelected ? "bg-primary/15 text-primary" : "bg-transparent text-foreground-subtle hover:bg-surface-hover hover:text-foreground", idx > 0 && "border-l border-border"),
|
|
55666
|
-
children: a.agentNodeId
|
|
55615
|
+
children: a.columns[0]?.nodeLabel ?? a.agentNodeId
|
|
55667
55616
|
}, a.agentNodeId);
|
|
55668
55617
|
})
|
|
55669
55618
|
})
|
|
55670
55619
|
]
|
|
55671
55620
|
});
|
|
55672
55621
|
}
|
|
55673
|
-
function MatrixGrid
|
|
55622
|
+
var MatrixGrid = forwardRef(function MatrixGrid({ tree, agents, getCellState, onCellClick, onStepClick, stepBadge, selectedCell, single, reserveRightPx, label }, ref) {
|
|
55674
55623
|
const rows = useMemo(() => flattenTree(tree), [tree]);
|
|
55675
55624
|
const groups = useMemo(() => groupAgentColumns(agents), [agents]);
|
|
55625
|
+
const boxRef = useRef(null);
|
|
55626
|
+
const stepColRem = single ? STEP_COL_SINGLE_REM : STEP_COL_REM;
|
|
55627
|
+
const gridTemplate = `${stepColRem}rem repeat(${agents.length}, 13rem)`;
|
|
55628
|
+
const cols = agents.length + 1;
|
|
55629
|
+
const [stickySteps, setStickySteps] = useState(true);
|
|
55630
|
+
useLayoutEffect(() => {
|
|
55631
|
+
const box = boxRef.current;
|
|
55632
|
+
if (!box || reserveRightPx <= 0) {
|
|
55633
|
+
setStickySteps(true);
|
|
55634
|
+
return;
|
|
55635
|
+
}
|
|
55636
|
+
const measure = () => {
|
|
55637
|
+
const left = box.getBoundingClientRect().left;
|
|
55638
|
+
setStickySteps(window.innerWidth - reserveRightPx - left >= stepColRem * 16 + 208 + 24);
|
|
55639
|
+
};
|
|
55640
|
+
measure();
|
|
55641
|
+
window.addEventListener("resize", measure);
|
|
55642
|
+
return () => window.removeEventListener("resize", measure);
|
|
55643
|
+
}, [reserveRightPx, stepColRem]);
|
|
55644
|
+
const selectedPos = useMemo(() => {
|
|
55645
|
+
if (selectedCell === null) return null;
|
|
55646
|
+
const r = rows.findIndex((row) => row.node.addonId === selectedCell.addonId);
|
|
55647
|
+
if (r < 0) return null;
|
|
55648
|
+
const c = agents.findIndex((a) => agentColumnKey(a) === agentColumnKey(selectedCell));
|
|
55649
|
+
return {
|
|
55650
|
+
r,
|
|
55651
|
+
c: c < 0 ? 0 : c + 1
|
|
55652
|
+
};
|
|
55653
|
+
}, [
|
|
55654
|
+
selectedCell,
|
|
55655
|
+
rows,
|
|
55656
|
+
agents
|
|
55657
|
+
]);
|
|
55658
|
+
const [focusPos, setFocusPos] = useState({
|
|
55659
|
+
r: 0,
|
|
55660
|
+
c: 0
|
|
55661
|
+
});
|
|
55662
|
+
useEffect(() => {
|
|
55663
|
+
if (selectedPos !== null) setFocusPos(selectedPos);
|
|
55664
|
+
}, [selectedPos]);
|
|
55665
|
+
const tab = focusPos.r < rows.length && focusPos.c < cols ? focusPos : {
|
|
55666
|
+
r: 0,
|
|
55667
|
+
c: 0
|
|
55668
|
+
};
|
|
55669
|
+
const focusAt = (r, c) => {
|
|
55670
|
+
boxRef.current?.querySelector(`[data-r="${r}"][data-c="${c}"]`)?.focus();
|
|
55671
|
+
};
|
|
55672
|
+
useImperativeHandle(ref, () => ({ focusCell: (addonId, columnKey) => {
|
|
55673
|
+
const r = rows.findIndex((row) => row.node.addonId === addonId);
|
|
55674
|
+
if (r < 0) return;
|
|
55675
|
+
const index = columnKey === null ? -1 : agents.findIndex((a) => agentColumnKey(a) === columnKey);
|
|
55676
|
+
const c = index < 0 ? 0 : index + 1;
|
|
55677
|
+
setFocusPos({
|
|
55678
|
+
r,
|
|
55679
|
+
c
|
|
55680
|
+
});
|
|
55681
|
+
focusAt(r, c);
|
|
55682
|
+
} }), [rows, agents]);
|
|
55683
|
+
useLayoutEffect(() => {
|
|
55684
|
+
if (selectedPos === null) return;
|
|
55685
|
+
const box = boxRef.current;
|
|
55686
|
+
const el = box?.querySelector(`[data-r="${selectedPos.r}"][data-c="${selectedPos.c}"]`);
|
|
55687
|
+
if (!box || !el) return;
|
|
55688
|
+
if (typeof el.scrollIntoView === "function") el.scrollIntoView({
|
|
55689
|
+
block: "nearest",
|
|
55690
|
+
inline: "nearest"
|
|
55691
|
+
});
|
|
55692
|
+
if (reserveRightPx <= 0) return;
|
|
55693
|
+
const limit = window.innerWidth - reserveRightPx - 12;
|
|
55694
|
+
const right = el.getBoundingClientRect().right;
|
|
55695
|
+
if (right > limit) box.scrollLeft += right - limit;
|
|
55696
|
+
}, [
|
|
55697
|
+
selectedPos,
|
|
55698
|
+
reserveRightPx,
|
|
55699
|
+
stickySteps
|
|
55700
|
+
]);
|
|
55701
|
+
const onKeyDown = (e) => {
|
|
55702
|
+
if (!(e.target instanceof HTMLElement) || e.target.dataset.r === void 0) return;
|
|
55703
|
+
const pos = {
|
|
55704
|
+
r: Number(e.target.dataset.r),
|
|
55705
|
+
c: Number(e.target.dataset.c)
|
|
55706
|
+
};
|
|
55707
|
+
const next = nextGridPosition(e.key, pos, rows.length, cols);
|
|
55708
|
+
if (next === null) return;
|
|
55709
|
+
e.preventDefault();
|
|
55710
|
+
setFocusPos(next);
|
|
55711
|
+
focusAt(next.r, next.c);
|
|
55712
|
+
};
|
|
55676
55713
|
return /* @__PURE__ */ jsx("div", {
|
|
55714
|
+
ref: boxRef,
|
|
55677
55715
|
className: "overflow-auto rounded border border-border",
|
|
55678
55716
|
children: /* @__PURE__ */ jsxs("div", {
|
|
55679
|
-
className: "
|
|
55680
|
-
|
|
55681
|
-
|
|
55682
|
-
|
|
55683
|
-
|
|
55684
|
-
|
|
55685
|
-
}
|
|
55686
|
-
|
|
55687
|
-
|
|
55717
|
+
className: "flex w-max",
|
|
55718
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
55719
|
+
role: "grid",
|
|
55720
|
+
"aria-label": label,
|
|
55721
|
+
"aria-rowcount": rows.length + 1,
|
|
55722
|
+
className: "grid w-max",
|
|
55723
|
+
style: { gridTemplateColumns: gridTemplate },
|
|
55724
|
+
onKeyDown,
|
|
55725
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
55726
|
+
role: "row",
|
|
55727
|
+
className: "contents",
|
|
55688
55728
|
children: [/* @__PURE__ */ jsx("div", {
|
|
55689
|
-
|
|
55690
|
-
|
|
55691
|
-
|
|
55692
|
-
|
|
55693
|
-
|
|
55729
|
+
role: "columnheader",
|
|
55730
|
+
className: cn("top-0 z-20 border-b border-border bg-muted/60 px-3 py-2 text-[10px] uppercase tracking-widest text-foreground-subtle", stickySteps ? "sticky left-0" : "sticky"),
|
|
55731
|
+
children: "Step"
|
|
55732
|
+
}), groups.map((group) => group.grouped ? /* @__PURE__ */ jsx(GroupedAgentHeader, { group }, group.agentNodeId) : group.columns.map((col) => /* @__PURE__ */ jsxs("div", {
|
|
55733
|
+
role: "columnheader",
|
|
55734
|
+
className: cn("sticky top-0 z-10 min-w-0 border-b border-l border-border bg-muted/60 px-3 py-2", col.disabled === true && "opacity-70"),
|
|
55735
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
55736
|
+
className: "truncate text-xs font-semibold text-foreground",
|
|
55737
|
+
children: col.nodeLabel ?? col.agentNodeId
|
|
55738
|
+
}), /* @__PURE__ */ jsx(AgentColumnLines, { column: col })]
|
|
55739
|
+
}, agentColumnKey(col))))]
|
|
55740
|
+
}), rows.map(({ node, depth }, r) => /* @__PURE__ */ jsxs("div", {
|
|
55741
|
+
role: "row",
|
|
55742
|
+
className: "contents",
|
|
55743
|
+
children: [/* @__PURE__ */ jsx(StepCell, {
|
|
55744
|
+
node,
|
|
55745
|
+
depth,
|
|
55746
|
+
r,
|
|
55747
|
+
tabbable: tab.r === r && tab.c === 0,
|
|
55748
|
+
selected: selectedCell?.addonId === node.addonId,
|
|
55749
|
+
badge: stepBadge?.(node.addonId),
|
|
55750
|
+
onClick: onStepClick ? (kb) => onStepClick(node.addonId, kb) : void 0,
|
|
55751
|
+
sticky: stickySteps
|
|
55752
|
+
}), agents.map((a, i) => {
|
|
55753
|
+
const state = getCellState(node.addonId, a);
|
|
55754
|
+
const isSelected = selectedCell !== null && selectedCell.addonId === node.addonId && agentColumnKey(selectedCell) === agentColumnKey(a);
|
|
55755
|
+
const actionable = state.kind === "enabled" || state.kind === "skip";
|
|
55756
|
+
return /* @__PURE__ */ jsx("div", {
|
|
55757
|
+
role: "gridcell",
|
|
55758
|
+
className: "min-w-0 border-b border-l border-border",
|
|
55759
|
+
children: /* @__PURE__ */ jsx("button", {
|
|
55760
|
+
type: "button",
|
|
55761
|
+
"data-r": r,
|
|
55762
|
+
"data-c": i + 1,
|
|
55763
|
+
"data-step": node.addonId,
|
|
55764
|
+
"data-col": agentColumnKey(a),
|
|
55765
|
+
tabIndex: tab.r === r && tab.c === i + 1 ? 0 : -1,
|
|
55766
|
+
"aria-disabled": !actionable,
|
|
55767
|
+
"aria-selected": isSelected,
|
|
55768
|
+
onClick: (e) => {
|
|
55769
|
+
if (actionable) onCellClick(node.addonId, a, e.detail === 0);
|
|
55770
|
+
},
|
|
55771
|
+
className: cellButtonClass(state, isSelected, cn("h-full w-full min-w-0 overflow-hidden px-3 py-2 outline-none", "focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary", !actionable && "cursor-default hover:bg-transparent", a.disabled === true && "opacity-70")),
|
|
55772
|
+
children: renderCellContent(state)
|
|
55773
|
+
})
|
|
55774
|
+
}, agentColumnKey(a));
|
|
55694
55775
|
})]
|
|
55695
|
-
},
|
|
55696
|
-
|
|
55697
|
-
|
|
55698
|
-
|
|
55699
|
-
|
|
55700
|
-
|
|
55701
|
-
getCellState,
|
|
55702
|
-
onCellClick,
|
|
55703
|
-
selectedCell,
|
|
55704
|
-
onSetGate,
|
|
55705
|
-
gateBusy,
|
|
55706
|
-
hideGate
|
|
55707
|
-
}, node.addonId))
|
|
55708
|
-
]
|
|
55776
|
+
}, node.addonId))]
|
|
55777
|
+
}), reserveRightPx > 0 && /* @__PURE__ */ jsx("div", {
|
|
55778
|
+
"aria-hidden": true,
|
|
55779
|
+
style: { width: reserveRightPx },
|
|
55780
|
+
className: "shrink-0"
|
|
55781
|
+
})]
|
|
55709
55782
|
})
|
|
55710
55783
|
});
|
|
55711
|
-
}
|
|
55712
|
-
function
|
|
55713
|
-
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(StepGateCell, {
|
|
55714
|
-
node,
|
|
55715
|
-
depth,
|
|
55716
|
-
gate,
|
|
55717
|
-
busy: gateBusy,
|
|
55718
|
-
onSet: (next) => onSetGate(node.addonId, next),
|
|
55719
|
-
hideGate
|
|
55720
|
-
}), agents.map((a) => {
|
|
55721
|
-
const state = getCellState(node.addonId, a);
|
|
55722
|
-
const isSelected = selectedCell !== null && selectedCell.addonId === node.addonId && agentColumnKey(selectedCell) === agentColumnKey(a);
|
|
55723
|
-
const actionable = state.kind === "enabled" || state.kind === "skip";
|
|
55724
|
-
return /* @__PURE__ */ jsx("button", {
|
|
55725
|
-
type: "button",
|
|
55726
|
-
disabled: !actionable,
|
|
55727
|
-
onClick: () => onCellClick(node.addonId, a),
|
|
55728
|
-
className: cellButtonClass(state, isSelected, cn("min-w-0 overflow-hidden border-b border-l border-border px-3 py-2", !actionable && "cursor-default hover:bg-transparent")),
|
|
55729
|
-
children: renderCellContent(state)
|
|
55730
|
-
}, agentColumnKey(a));
|
|
55731
|
-
})] });
|
|
55732
|
-
}
|
|
55733
|
-
function DeviceStepMatrix({ tree, agents, gateFor, getCellState, onCellClick, selectedCell, onSetGate, gateBusy, fallbackNodeId, onFallbackNodeChange, hideGate }) {
|
|
55784
|
+
});
|
|
55785
|
+
var DeviceStepMatrix = forwardRef(function DeviceStepMatrix({ tree, agents, getCellState, onCellClick, selectedCell, fallbackNodeId, onFallbackNodeChange, onStepClick, stepBadge, reserveRightPx = 0, label = "Detection steps" }, ref) {
|
|
55734
55786
|
const containerRef = useRef(null);
|
|
55735
55787
|
const [width, setWidth] = useState(0);
|
|
55736
55788
|
useLayoutEffect(() => {
|
|
@@ -55748,6 +55800,15 @@ function DeviceStepMatrix({ tree, agents, gateFor, getCellState, onCellClick, se
|
|
|
55748
55800
|
if (nodes.length === 0) return null;
|
|
55749
55801
|
return nodes.find((n) => n.agentNodeId === fallbackNodeId) ?? nodes[0] ?? null;
|
|
55750
55802
|
}, [nodes, fallbackNodeId]);
|
|
55803
|
+
const selectedNodeId = selectedCell?.agentNodeId;
|
|
55804
|
+
useEffect(() => {
|
|
55805
|
+
if (single && selectedNodeId !== void 0 && selectedNodeId !== fallbackNodeId) onFallbackNodeChange(selectedNodeId);
|
|
55806
|
+
}, [
|
|
55807
|
+
single,
|
|
55808
|
+
selectedNodeId,
|
|
55809
|
+
fallbackNodeId,
|
|
55810
|
+
onFallbackNodeChange
|
|
55811
|
+
]);
|
|
55751
55812
|
const shownAgents = single && selectedNode ? selectedNode.columns : agents;
|
|
55752
55813
|
return /* @__PURE__ */ jsxs("div", {
|
|
55753
55814
|
ref: containerRef,
|
|
@@ -55756,20 +55817,21 @@ function DeviceStepMatrix({ tree, agents, gateFor, getCellState, onCellClick, se
|
|
|
55756
55817
|
nodes,
|
|
55757
55818
|
selected: selectedNode.agentNodeId,
|
|
55758
55819
|
onSelect: onFallbackNodeChange
|
|
55759
|
-
}), /* @__PURE__ */ jsx(MatrixGrid
|
|
55820
|
+
}), /* @__PURE__ */ jsx(MatrixGrid, {
|
|
55821
|
+
ref,
|
|
55760
55822
|
tree,
|
|
55761
55823
|
agents: shownAgents,
|
|
55762
|
-
gateFor,
|
|
55763
55824
|
getCellState,
|
|
55764
55825
|
onCellClick,
|
|
55826
|
+
onStepClick,
|
|
55827
|
+
stepBadge,
|
|
55765
55828
|
selectedCell,
|
|
55766
|
-
onSetGate,
|
|
55767
|
-
gateBusy,
|
|
55768
55829
|
single: single && selectedNode !== null,
|
|
55769
|
-
|
|
55830
|
+
reserveRightPx,
|
|
55831
|
+
label
|
|
55770
55832
|
})]
|
|
55771
55833
|
});
|
|
55772
|
-
}
|
|
55834
|
+
});
|
|
55773
55835
|
//#endregion
|
|
55774
55836
|
//#region src/composites/discovery-panel.tsx
|
|
55775
55837
|
function DiscoveryPanel({ deviceId, className = "", onOpenChild }) {
|
|
@@ -56708,43 +56770,13 @@ function PhaseIcon({ phase, ...props }) {
|
|
|
56708
56770
|
return /* @__PURE__ */ jsx(Icon, { ...props });
|
|
56709
56771
|
}
|
|
56710
56772
|
//#endregion
|
|
56711
|
-
//#region src/lib/validate-template.ts
|
|
56712
|
-
function validateTemplate(steps, schema) {
|
|
56713
|
-
const availableAddonIds = new Set(schema.slots.flatMap((s) => s.addons.map((a) => a.id)));
|
|
56714
|
-
const warnings = [];
|
|
56715
|
-
function validateStep(step) {
|
|
56716
|
-
if (!availableAddonIds.has(step.addonId)) {
|
|
56717
|
-
warnings.push(`Addon "${step.addonId}" is no longer available — step removed`);
|
|
56718
|
-
return null;
|
|
56719
|
-
}
|
|
56720
|
-
const addon = schema.slots.flatMap((s) => s.addons).find((a) => a.id === step.addonId);
|
|
56721
|
-
let modelId = step.modelId;
|
|
56722
|
-
if (addon && !addon.models.some((m) => m.id === modelId)) {
|
|
56723
|
-
const fallback = addon.defaultModelId;
|
|
56724
|
-
warnings.push(`Model "${modelId}" not available for ${step.addonId} — using "${fallback}"`);
|
|
56725
|
-
modelId = fallback;
|
|
56726
|
-
}
|
|
56727
|
-
const validChildren = step.children.map((c) => validateStep(c)).filter((c) => c !== null);
|
|
56728
|
-
return {
|
|
56729
|
-
...step,
|
|
56730
|
-
modelId,
|
|
56731
|
-
children: validChildren
|
|
56732
|
-
};
|
|
56733
|
-
}
|
|
56734
|
-
const validSteps = steps.map((s) => validateStep(s)).filter((s) => s !== null);
|
|
56735
|
-
return {
|
|
56736
|
-
valid: warnings.length === 0,
|
|
56737
|
-
steps: validSteps,
|
|
56738
|
-
warnings
|
|
56739
|
-
};
|
|
56740
|
-
}
|
|
56741
|
-
//#endregion
|
|
56742
56773
|
//#region src/composites/pipeline-builder.tsx
|
|
56743
56774
|
/**
|
|
56744
|
-
* PipelineBuilder — orchestrates the pipeline step tree
|
|
56775
|
+
* PipelineBuilder — orchestrates the pipeline step tree.
|
|
56745
56776
|
*
|
|
56746
|
-
* Renders
|
|
56747
|
-
*
|
|
56777
|
+
* Renders the step tree from schema with nested children and placeholder steps
|
|
56778
|
+
* for disabled addons, all driven by API schema. There are no saved pipeline
|
|
56779
|
+
* templates (D759): the tree is the caller's state.
|
|
56748
56780
|
*/
|
|
56749
56781
|
function buildSchemaMap(schema) {
|
|
56750
56782
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -56796,41 +56828,9 @@ function PlaceholderStep({ addon, onClick }) {
|
|
|
56796
56828
|
})
|
|
56797
56829
|
});
|
|
56798
56830
|
}
|
|
56799
|
-
function PipelineBuilder({ schema, steps, onChange,
|
|
56800
|
-
const stepExtraProps = (addonId) => ({
|
|
56801
|
-
toggleMode,
|
|
56802
|
-
hideModelAndSettings,
|
|
56803
|
-
allowAutoModel,
|
|
56804
|
-
...toggleMode === "threeState" ? {
|
|
56805
|
-
overrideState: overrides[addonId] !== void 0 ? overrides[addonId] : null,
|
|
56806
|
-
onOverrideChange: onOverrideChange ? (next) => onOverrideChange(addonId, next) : void 0,
|
|
56807
|
-
inheritedEnabled: inheritedEnabledByAddon[addonId]
|
|
56808
|
-
} : {}
|
|
56809
|
-
});
|
|
56831
|
+
function PipelineBuilder({ schema, steps, onChange, readOnly = false, excludeAddons = [], showOnlyEnabled = false, showSlotLabels = false }) {
|
|
56810
56832
|
const excluded = useMemo(() => new Set(excludeAddons), [excludeAddons]);
|
|
56811
56833
|
const schemaMap = useMemo(() => buildSchemaMap(schema), [schema]);
|
|
56812
|
-
const [warnings, setWarnings] = useState([]);
|
|
56813
|
-
const dirty = selectedTemplateId ? JSON.stringify(steps) !== JSON.stringify(templates.find((t) => t.id === selectedTemplateId)?.steps) : false;
|
|
56814
|
-
function handleSelectTemplate(e) {
|
|
56815
|
-
const id = e.target.value || null;
|
|
56816
|
-
if (id) {
|
|
56817
|
-
const tpl = templates.find((t) => t.id === id);
|
|
56818
|
-
if (tpl) setWarnings([...validateTemplate(tpl.steps, schema).warnings]);
|
|
56819
|
-
} else setWarnings([]);
|
|
56820
|
-
onSelectTemplate(id);
|
|
56821
|
-
}
|
|
56822
|
-
function handleSave() {
|
|
56823
|
-
if (selectedTemplateId) onUpdateTemplate(selectedTemplateId, steps);
|
|
56824
|
-
}
|
|
56825
|
-
function handleSaveAs() {
|
|
56826
|
-
const name = window.prompt("Template name:");
|
|
56827
|
-
if (name?.trim()) onSaveTemplate(name.trim(), steps);
|
|
56828
|
-
}
|
|
56829
|
-
function handleDelete() {
|
|
56830
|
-
if (!selectedTemplateId) return;
|
|
56831
|
-
const tpl = templates.find((t) => t.id === selectedTemplateId);
|
|
56832
|
-
if (tpl && window.confirm(`Delete template "${tpl.name}"?`)) onDeleteTemplate(selectedTemplateId);
|
|
56833
|
-
}
|
|
56834
56834
|
/**
|
|
56835
56835
|
* When a step is updated, auto-enable the entire ancestor chain if a
|
|
56836
56836
|
* child/grandchild was just enabled. This ensures enabling face-recognition
|
|
@@ -56913,8 +56913,7 @@ function PipelineBuilder({ schema, steps, onChange, templates, selectedTemplateI
|
|
|
56913
56913
|
allSchemas: schemaMap,
|
|
56914
56914
|
onChange: handleStepChange,
|
|
56915
56915
|
onDelete: readOnly ? void 0 : (id) => onChange(steps.filter((s) => s.addonId !== id)),
|
|
56916
|
-
readOnly
|
|
56917
|
-
...stepExtraProps(step.addonId)
|
|
56916
|
+
readOnly
|
|
56918
56917
|
}), (step.children.length > 0 || childPlaceholders.length > 0) && /* @__PURE__ */ jsxs("div", {
|
|
56919
56918
|
className: "ml-4 pl-3 border-l border-border/60 space-y-1.5",
|
|
56920
56919
|
children: [
|
|
@@ -56943,8 +56942,7 @@ function PipelineBuilder({ schema, steps, onChange, templates, selectedTemplateI
|
|
|
56943
56942
|
children: step.children.filter((c) => c.addonId !== id)
|
|
56944
56943
|
});
|
|
56945
56944
|
},
|
|
56946
|
-
readOnly
|
|
56947
|
-
...stepExtraProps(child.addonId)
|
|
56945
|
+
readOnly
|
|
56948
56946
|
}), (child.children.length > 0 || childChildPlaceholders.length > 0) && /* @__PURE__ */ jsxs("div", {
|
|
56949
56947
|
className: "ml-4 pl-3 border-l border-border/40 space-y-1.5",
|
|
56950
56948
|
children: [
|
|
@@ -56975,8 +56973,7 @@ function PipelineBuilder({ schema, steps, onChange, templates, selectedTemplateI
|
|
|
56975
56973
|
} : c)
|
|
56976
56974
|
});
|
|
56977
56975
|
},
|
|
56978
|
-
readOnly
|
|
56979
|
-
...stepExtraProps(grandchild.addonId)
|
|
56976
|
+
readOnly
|
|
56980
56977
|
}, grandchild.addonId)),
|
|
56981
56978
|
!readOnly && childChildPlaceholders.map((addon) => /* @__PURE__ */ jsx(PlaceholderStep, {
|
|
56982
56979
|
addon,
|
|
@@ -57003,104 +57000,42 @@ function PipelineBuilder({ schema, steps, onChange, templates, selectedTemplateI
|
|
|
57003
57000
|
})]
|
|
57004
57001
|
}, step.addonId);
|
|
57005
57002
|
}
|
|
57006
|
-
|
|
57007
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
57003
|
+
return /* @__PURE__ */ jsx("div", {
|
|
57008
57004
|
className: "space-y-4",
|
|
57009
|
-
children:
|
|
57010
|
-
|
|
57011
|
-
|
|
57012
|
-
|
|
57013
|
-
|
|
57014
|
-
|
|
57015
|
-
|
|
57016
|
-
|
|
57017
|
-
|
|
57018
|
-
|
|
57019
|
-
|
|
57020
|
-
|
|
57021
|
-
|
|
57022
|
-
|
|
57023
|
-
|
|
57024
|
-
|
|
57025
|
-
|
|
57026
|
-
|
|
57027
|
-
|
|
57028
|
-
|
|
57029
|
-
|
|
57030
|
-
|
|
57031
|
-
|
|
57032
|
-
|
|
57033
|
-
|
|
57034
|
-
|
|
57035
|
-
|
|
57036
|
-
|
|
57037
|
-
|
|
57038
|
-
|
|
57039
|
-
|
|
57040
|
-
|
|
57041
|
-
|
|
57042
|
-
|
|
57043
|
-
children: /* @__PURE__ */ jsx(CopyPlus, { className: "h-4 w-4" })
|
|
57044
|
-
}),
|
|
57045
|
-
/* @__PURE__ */ jsx("button", {
|
|
57046
|
-
onClick: handleDelete,
|
|
57047
|
-
disabled: !selectedTemplateId || readOnly,
|
|
57048
|
-
title: "Delete",
|
|
57049
|
-
className: cn("p-2 rounded-lg border border-border transition-colors", selectedTemplateId && !readOnly ? "text-foreground-subtle hover:text-danger" : "text-foreground-subtle/30 cursor-not-allowed"),
|
|
57050
|
-
children: /* @__PURE__ */ jsx(Trash2, { className: "h-4 w-4" })
|
|
57051
|
-
})
|
|
57052
|
-
]
|
|
57053
|
-
})
|
|
57054
|
-
}),
|
|
57055
|
-
warnings.length > 0 && /* @__PURE__ */ jsxs("div", {
|
|
57056
|
-
className: "rounded-lg border border-amber-500/30 bg-amber-500/5 p-3 text-xs text-amber-400 space-y-1",
|
|
57057
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
57058
|
-
className: "flex items-center justify-between",
|
|
57059
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
57060
|
-
className: "font-medium",
|
|
57061
|
-
children: "Template loaded with warnings:"
|
|
57062
|
-
}), /* @__PURE__ */ jsx("button", {
|
|
57063
|
-
onClick: () => setWarnings([]),
|
|
57064
|
-
className: "text-amber-400/60 hover:text-amber-400",
|
|
57065
|
-
children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5" })
|
|
57066
|
-
})]
|
|
57067
|
-
}), warnings.map((w, i) => /* @__PURE__ */ jsxs("div", { children: ["• ", w] }, i))]
|
|
57068
|
-
}),
|
|
57069
|
-
rootSlots.map((slot) => {
|
|
57070
|
-
const allSlotSteps = steps.filter((s) => s.slot === slot.id && !excluded.has(s.addonId));
|
|
57071
|
-
const slotSteps = showOnlyEnabled ? allSlotSteps.filter((s) => s.enabled) : allSlotSteps;
|
|
57072
|
-
const missingRootAddons = showOnlyEnabled ? [] : slot.addons.filter((a) => !existingIds.has(a.id) && !excluded.has(a.id));
|
|
57073
|
-
const groups = /* @__PURE__ */ new Map();
|
|
57074
|
-
const ungrouped = [];
|
|
57075
|
-
for (const step of slotSteps) if (step.group) {
|
|
57076
|
-
if (!groups.has(step.group)) groups.set(step.group, []);
|
|
57077
|
-
groups.get(step.group).push(step);
|
|
57078
|
-
} else ungrouped.push(step);
|
|
57079
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
57080
|
-
className: "space-y-2",
|
|
57081
|
-
children: [
|
|
57082
|
-
showSlotLabels && /* @__PURE__ */ jsxs("span", {
|
|
57083
|
-
className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/50",
|
|
57084
|
-
children: ["Slot: ", slot.label]
|
|
57085
|
-
}),
|
|
57086
|
-
ungrouped.map((step) => renderStep(step)),
|
|
57087
|
-
[...groups.entries()].map(([groupName, groupSteps]) => /* @__PURE__ */ jsxs("div", {
|
|
57088
|
-
className: "space-y-2 rounded-lg border border-border/40 p-2",
|
|
57089
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
57090
|
-
className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/50 px-1",
|
|
57091
|
-
children: groupName
|
|
57092
|
-
}), groupSteps.map((step) => renderStep(step))]
|
|
57093
|
-
}, groupName)),
|
|
57094
|
-
!readOnly && missingRootAddons.map((addon) => /* @__PURE__ */ jsx(PlaceholderStep, {
|
|
57095
|
-
addon,
|
|
57096
|
-
onClick: () => {
|
|
57097
|
-
onChange([...steps, createDefaultStep(addon)]);
|
|
57098
|
-
}
|
|
57099
|
-
}, addon.id))
|
|
57100
|
-
]
|
|
57101
|
-
}, slot.id);
|
|
57102
|
-
})
|
|
57103
|
-
]
|
|
57005
|
+
children: schema.slots.filter((s) => s.parentSlot === null).toSorted((a, b) => a.priority - b.priority).map((slot) => {
|
|
57006
|
+
const allSlotSteps = steps.filter((s) => s.slot === slot.id && !excluded.has(s.addonId));
|
|
57007
|
+
const slotSteps = showOnlyEnabled ? allSlotSteps.filter((s) => s.enabled) : allSlotSteps;
|
|
57008
|
+
const missingRootAddons = showOnlyEnabled ? [] : slot.addons.filter((a) => !existingIds.has(a.id) && !excluded.has(a.id));
|
|
57009
|
+
const groups = /* @__PURE__ */ new Map();
|
|
57010
|
+
const ungrouped = [];
|
|
57011
|
+
for (const step of slotSteps) if (step.group) {
|
|
57012
|
+
if (!groups.has(step.group)) groups.set(step.group, []);
|
|
57013
|
+
groups.get(step.group).push(step);
|
|
57014
|
+
} else ungrouped.push(step);
|
|
57015
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
57016
|
+
className: "space-y-2",
|
|
57017
|
+
children: [
|
|
57018
|
+
showSlotLabels && /* @__PURE__ */ jsxs("span", {
|
|
57019
|
+
className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/50",
|
|
57020
|
+
children: ["Slot: ", slot.label]
|
|
57021
|
+
}),
|
|
57022
|
+
ungrouped.map((step) => renderStep(step)),
|
|
57023
|
+
[...groups.entries()].map(([groupName, groupSteps]) => /* @__PURE__ */ jsxs("div", {
|
|
57024
|
+
className: "space-y-2 rounded-lg border border-border/40 p-2",
|
|
57025
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
57026
|
+
className: "text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/50 px-1",
|
|
57027
|
+
children: groupName
|
|
57028
|
+
}), groupSteps.map((step) => renderStep(step))]
|
|
57029
|
+
}, groupName)),
|
|
57030
|
+
!readOnly && missingRootAddons.map((addon) => /* @__PURE__ */ jsx(PlaceholderStep, {
|
|
57031
|
+
addon,
|
|
57032
|
+
onClick: () => {
|
|
57033
|
+
onChange([...steps, createDefaultStep(addon)]);
|
|
57034
|
+
}
|
|
57035
|
+
}, addon.id))
|
|
57036
|
+
]
|
|
57037
|
+
}, slot.id);
|
|
57038
|
+
})
|
|
57104
57039
|
});
|
|
57105
57040
|
}
|
|
57106
57041
|
//#endregion
|
|
@@ -57136,179 +57071,6 @@ function PipelineRuntimeSelector({ options, value, onChange }) {
|
|
|
57136
57071
|
});
|
|
57137
57072
|
}
|
|
57138
57073
|
//#endregion
|
|
57139
|
-
//#region src/composites/pipeline-tree-matrix.tsx
|
|
57140
|
-
var STEP_COL_REM = 18;
|
|
57141
|
-
function QuickToggle({ enabled, onChange, disabled }) {
|
|
57142
|
-
return /* @__PURE__ */ jsx("button", {
|
|
57143
|
-
type: "button",
|
|
57144
|
-
role: "switch",
|
|
57145
|
-
"aria-checked": enabled,
|
|
57146
|
-
disabled,
|
|
57147
|
-
onClick: (e) => {
|
|
57148
|
-
e.stopPropagation();
|
|
57149
|
-
onChange(!enabled);
|
|
57150
|
-
},
|
|
57151
|
-
className: cn("relative inline-flex h-3.5 w-7 shrink-0 items-center rounded-full transition-colors", enabled ? "bg-emerald-500" : "bg-foreground-subtle/30", disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"),
|
|
57152
|
-
title: enabled ? "Click to disable" : "Click to enable",
|
|
57153
|
-
children: /* @__PURE__ */ jsx("span", { className: cn("inline-block h-3 w-3 rounded-full bg-white shadow transition-transform", enabled ? "translate-x-3.5" : "translate-x-0.5") })
|
|
57154
|
-
});
|
|
57155
|
-
}
|
|
57156
|
-
function GridRow({ node, depth, agents, getCellState, onCellClick, selectedCell, toggleProps }) {
|
|
57157
|
-
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("div", {
|
|
57158
|
-
className: "sticky left-0 z-10 bg-surface px-3 py-2 border-b border-border text-xs flex items-start gap-2 min-w-0",
|
|
57159
|
-
style: { paddingLeft: `${12 + depth * 14}px` },
|
|
57160
|
-
children: [/* @__PURE__ */ jsx(StepLabel, { node }), toggleProps && /* @__PURE__ */ jsx("span", {
|
|
57161
|
-
className: "pl-2 pt-0.5 shrink-0",
|
|
57162
|
-
children: /* @__PURE__ */ jsx(QuickToggle, {
|
|
57163
|
-
enabled: toggleProps.enabled,
|
|
57164
|
-
onChange: toggleProps.onChange,
|
|
57165
|
-
disabled: toggleProps.disabled
|
|
57166
|
-
})
|
|
57167
|
-
})]
|
|
57168
|
-
}), agents.map((a) => {
|
|
57169
|
-
const state = getCellState(node.addonId, a);
|
|
57170
|
-
return /* @__PURE__ */ jsx("button", {
|
|
57171
|
-
type: "button",
|
|
57172
|
-
onClick: () => onCellClick(node.addonId, a),
|
|
57173
|
-
className: cellButtonClass(state, selectedCell !== null && selectedCell.addonId === node.addonId && agentColumnKey(selectedCell) === agentColumnKey(a), "min-w-0 overflow-hidden px-3 py-1.5 border-b border-l border-border"),
|
|
57174
|
-
children: renderCellContent(state)
|
|
57175
|
-
}, agentColumnKey(a));
|
|
57176
|
-
})] });
|
|
57177
|
-
}
|
|
57178
|
-
/**
|
|
57179
|
-
* Wide layout: horizontally self-scrolling matrix. The scroll lives INSIDE
|
|
57180
|
-
* this `overflow-auto` box (sticky first column + sticky header row) so the
|
|
57181
|
-
* page body never scrolls sideways. Column tracks are fixed px widths so the
|
|
57182
|
-
* grid is static regardless of content.
|
|
57183
|
-
*/
|
|
57184
|
-
function MatrixGrid({ rows, agents, getCellState, onCellClick, selectedCell, onToggleEnabled }) {
|
|
57185
|
-
const gridTemplate = `${STEP_COL_REM}rem repeat(${agents.length}, 13rem)`;
|
|
57186
|
-
const showToggle = onToggleEnabled !== void 0 && agents.length === 1;
|
|
57187
|
-
const onlyAgent = agents[0];
|
|
57188
|
-
const groups = groupAgentColumns(agents);
|
|
57189
|
-
return /* @__PURE__ */ jsx("div", {
|
|
57190
|
-
className: "overflow-auto border border-border rounded",
|
|
57191
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
57192
|
-
className: "grid w-max",
|
|
57193
|
-
style: { gridTemplateColumns: gridTemplate },
|
|
57194
|
-
children: [
|
|
57195
|
-
/* @__PURE__ */ jsx("div", {
|
|
57196
|
-
className: "sticky top-0 left-0 z-20 bg-muted/60 px-3 py-2 text-[10px] uppercase tracking-widest text-foreground-subtle border-b border-border",
|
|
57197
|
-
children: "Step"
|
|
57198
|
-
}),
|
|
57199
|
-
groups.map((group) => group.grouped ? /* @__PURE__ */ jsx(GroupedAgentHeader, { group }, group.agentNodeId) : group.columns.map((col) => /* @__PURE__ */ jsxs("div", {
|
|
57200
|
-
className: "sticky top-0 z-10 min-w-0 bg-muted/60 px-3 py-2 border-b border-l border-border",
|
|
57201
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
57202
|
-
className: "text-xs font-semibold text-foreground truncate",
|
|
57203
|
-
children: col.agentNodeId
|
|
57204
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
57205
|
-
className: "text-[10px] text-foreground-subtle truncate",
|
|
57206
|
-
children: col.engineLabel
|
|
57207
|
-
})]
|
|
57208
|
-
}, agentColumnKey(col)))),
|
|
57209
|
-
rows.map(({ node, depth }) => {
|
|
57210
|
-
const cellState = showToggle && onlyAgent !== void 0 ? getCellState(node.addonId, onlyAgent) : null;
|
|
57211
|
-
return /* @__PURE__ */ jsx(GridRow, {
|
|
57212
|
-
node,
|
|
57213
|
-
depth,
|
|
57214
|
-
agents,
|
|
57215
|
-
getCellState,
|
|
57216
|
-
onCellClick,
|
|
57217
|
-
selectedCell,
|
|
57218
|
-
toggleProps: showToggle && cellState !== null ? {
|
|
57219
|
-
enabled: cellState.kind === "enabled",
|
|
57220
|
-
onChange: (next) => onToggleEnabled?.(node.addonId, next),
|
|
57221
|
-
disabled: cellState.kind === "na"
|
|
57222
|
-
} : void 0
|
|
57223
|
-
}, node.addonId);
|
|
57224
|
-
})
|
|
57225
|
-
]
|
|
57226
|
-
})
|
|
57227
|
-
});
|
|
57228
|
-
}
|
|
57229
|
-
/**
|
|
57230
|
-
* Narrow layout: one card per agent column, each listing every step stacked
|
|
57231
|
-
* vertically. Feature-parity with the matrix — same `onCellClick`, same
|
|
57232
|
-
* `renderCellContent`, same single-agent `onToggleEnabled`.
|
|
57233
|
-
*/
|
|
57234
|
-
function StackedCards({ rows, agents, getCellState, onCellClick, selectedCell, onToggleEnabled }) {
|
|
57235
|
-
const showToggle = onToggleEnabled !== void 0 && agents.length === 1;
|
|
57236
|
-
return /* @__PURE__ */ jsx("div", {
|
|
57237
|
-
className: "space-y-3",
|
|
57238
|
-
children: agents.map((a) => /* @__PURE__ */ jsxs("div", {
|
|
57239
|
-
className: "border border-border rounded overflow-hidden",
|
|
57240
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
57241
|
-
className: "bg-muted/60 px-3 py-2 border-b border-border",
|
|
57242
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
57243
|
-
className: "text-xs font-semibold text-foreground truncate",
|
|
57244
|
-
children: a.deviceLabel ? `${a.agentNodeId} · ${a.deviceLabel}` : a.agentNodeId
|
|
57245
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
57246
|
-
className: "text-[10px] text-foreground-subtle truncate",
|
|
57247
|
-
children: a.engineLabel
|
|
57248
|
-
})]
|
|
57249
|
-
}), /* @__PURE__ */ jsx("ul", { children: rows.map(({ node, depth }) => {
|
|
57250
|
-
const state = getCellState(node.addonId, a);
|
|
57251
|
-
const isSelected = selectedCell !== null && selectedCell.addonId === node.addonId && agentColumnKey(selectedCell) === agentColumnKey(a);
|
|
57252
|
-
const toggleProps = showToggle && state !== null ? {
|
|
57253
|
-
enabled: state.kind === "enabled",
|
|
57254
|
-
onChange: (next) => onToggleEnabled?.(node.addonId, next),
|
|
57255
|
-
disabled: state.kind === "na"
|
|
57256
|
-
} : void 0;
|
|
57257
|
-
return /* @__PURE__ */ jsx("li", {
|
|
57258
|
-
className: "border-b border-border last:border-b-0",
|
|
57259
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
57260
|
-
className: "flex items-center gap-2",
|
|
57261
|
-
children: [/* @__PURE__ */ jsxs("button", {
|
|
57262
|
-
type: "button",
|
|
57263
|
-
onClick: () => onCellClick(node.addonId, a),
|
|
57264
|
-
className: cellButtonClass(state, isSelected, "flex flex-1 min-w-0 items-start justify-between gap-3 px-3 py-2"),
|
|
57265
|
-
style: { paddingLeft: `${12 + depth * 14}px` },
|
|
57266
|
-
children: [/* @__PURE__ */ jsx(StepLabel, { node }), /* @__PURE__ */ jsx("span", {
|
|
57267
|
-
className: "shrink-0 max-w-[45%] pt-0.5",
|
|
57268
|
-
children: renderCellContent(state)
|
|
57269
|
-
})]
|
|
57270
|
-
}), toggleProps && /* @__PURE__ */ jsx("span", {
|
|
57271
|
-
className: "pr-3 shrink-0",
|
|
57272
|
-
children: /* @__PURE__ */ jsx(QuickToggle, {
|
|
57273
|
-
enabled: toggleProps.enabled,
|
|
57274
|
-
onChange: toggleProps.onChange,
|
|
57275
|
-
disabled: toggleProps.disabled
|
|
57276
|
-
})
|
|
57277
|
-
})]
|
|
57278
|
-
})
|
|
57279
|
-
}, node.addonId);
|
|
57280
|
-
}) })]
|
|
57281
|
-
}, agentColumnKey(a)))
|
|
57282
|
-
});
|
|
57283
|
-
}
|
|
57284
|
-
function PipelineTreeMatrix({ tree, agents, getCellState, onCellClick, selectedCell, onToggleEnabled }) {
|
|
57285
|
-
const rows = useMemo(() => flattenTree(tree), [tree]);
|
|
57286
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
57287
|
-
className: "@container/matrix w-full",
|
|
57288
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
57289
|
-
className: "@2xl/matrix:hidden",
|
|
57290
|
-
children: /* @__PURE__ */ jsx(StackedCards, {
|
|
57291
|
-
rows,
|
|
57292
|
-
agents,
|
|
57293
|
-
getCellState,
|
|
57294
|
-
onCellClick,
|
|
57295
|
-
selectedCell,
|
|
57296
|
-
onToggleEnabled
|
|
57297
|
-
})
|
|
57298
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
57299
|
-
className: "hidden @2xl/matrix:block",
|
|
57300
|
-
children: /* @__PURE__ */ jsx(MatrixGrid, {
|
|
57301
|
-
rows,
|
|
57302
|
-
agents,
|
|
57303
|
-
getCellState,
|
|
57304
|
-
onCellClick,
|
|
57305
|
-
selectedCell,
|
|
57306
|
-
onToggleEnabled
|
|
57307
|
-
})
|
|
57308
|
-
})]
|
|
57309
|
-
});
|
|
57310
|
-
}
|
|
57311
|
-
//#endregion
|
|
57312
57074
|
//#region src/composites/provider-badge.tsx
|
|
57313
57075
|
var providerConfig = {
|
|
57314
57076
|
onvif: {
|
|
@@ -57752,89 +57514,6 @@ function validateSelector(selector) {
|
|
|
57752
57514
|
}
|
|
57753
57515
|
}
|
|
57754
57516
|
//#endregion
|
|
57755
|
-
//#region src/composites/slide-over-panel.tsx
|
|
57756
|
-
/**
|
|
57757
|
-
* SlideOverPanel — a detail surface anchored to context on desktop and to the
|
|
57758
|
-
* viewport on mobile.
|
|
57759
|
-
*
|
|
57760
|
-
* - **Desktop (`md+`):** an in-container, NON-modal slide-over pinned to the
|
|
57761
|
-
* right edge of the nearest positioned ancestor. The host reserves space with
|
|
57762
|
-
* a matching `md:pr-*` so the panel sits beside its content (e.g. the
|
|
57763
|
-
* multi-node pipeline matrix), not over it.
|
|
57764
|
-
* - **Mobile (`< md`):** a MODAL bottom sheet pinned to the viewport
|
|
57765
|
-
* (`position: fixed`). It never derives its size from the surrounding
|
|
57766
|
-
* container, so it can't stretch across a horizontally-laid-out node matrix
|
|
57767
|
-
* and overflow the page — the previous behaviour when it was a fixed-width
|
|
57768
|
-
* `absolute` panel anchored to the wide matrix wrapper.
|
|
57769
|
-
*
|
|
57770
|
-
* The whole desktop⇄mobile transform is pure Tailwind responsive classes on one
|
|
57771
|
-
* element — no layout-shift on hydration, no portal. JS is used only to lock
|
|
57772
|
-
* body scroll behind the mobile sheet and to wire Escape-to-close.
|
|
57773
|
-
*/
|
|
57774
|
-
function SlideOverPanel({ open, onClose, title, subtitle, footer, children, widthClass = "md:w-[360px]" }) {
|
|
57775
|
-
const isMobile = useIsMobile();
|
|
57776
|
-
useEffect(() => {
|
|
57777
|
-
if (!open) return;
|
|
57778
|
-
const onEsc = (e) => {
|
|
57779
|
-
if (e.key === "Escape") onClose();
|
|
57780
|
-
};
|
|
57781
|
-
window.addEventListener("keydown", onEsc);
|
|
57782
|
-
return () => window.removeEventListener("keydown", onEsc);
|
|
57783
|
-
}, [open, onClose]);
|
|
57784
|
-
useEffect(() => {
|
|
57785
|
-
if (!open || !isMobile) return;
|
|
57786
|
-
const previous = document.body.style.overflow;
|
|
57787
|
-
document.body.style.overflow = "hidden";
|
|
57788
|
-
return () => {
|
|
57789
|
-
document.body.style.overflow = previous;
|
|
57790
|
-
};
|
|
57791
|
-
}, [open, isMobile]);
|
|
57792
|
-
if (!open) return null;
|
|
57793
|
-
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
|
|
57794
|
-
className: "fixed inset-0 z-40 bg-black/50 md:hidden",
|
|
57795
|
-
onClick: onClose,
|
|
57796
|
-
"aria-hidden": "true"
|
|
57797
|
-
}), /* @__PURE__ */ jsxs("aside", {
|
|
57798
|
-
className: cn("fixed inset-x-0 bottom-0 z-50 flex flex-col", "max-h-[85dvh] rounded-t-2xl border-t border-border", "bg-surface shadow-2xl pb-[env(safe-area-inset-bottom)]", "md:absolute md:inset-x-auto md:top-0 md:right-0 md:bottom-0 md:z-20", "md:max-h-none md:rounded-none md:border-t-0 md:border-l md:pb-0", widthClass),
|
|
57799
|
-
role: "dialog",
|
|
57800
|
-
"aria-modal": isMobile ? "true" : "false",
|
|
57801
|
-
children: [
|
|
57802
|
-
/* @__PURE__ */ jsx("div", {
|
|
57803
|
-
className: "flex shrink-0 justify-center pt-2 pb-1 md:hidden",
|
|
57804
|
-
"aria-hidden": "true",
|
|
57805
|
-
children: /* @__PURE__ */ jsx("div", { className: "h-1 w-9 rounded-full bg-foreground-subtle/30" })
|
|
57806
|
-
}),
|
|
57807
|
-
/* @__PURE__ */ jsxs("header", {
|
|
57808
|
-
className: "flex shrink-0 items-start justify-between gap-2 px-4 py-3 border-b border-border",
|
|
57809
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
57810
|
-
className: "min-w-0",
|
|
57811
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
57812
|
-
className: "text-sm font-semibold text-foreground truncate",
|
|
57813
|
-
children: title
|
|
57814
|
-
}), subtitle !== void 0 && /* @__PURE__ */ jsx("div", {
|
|
57815
|
-
className: "text-[11px] text-foreground-subtle mt-0.5 truncate",
|
|
57816
|
-
children: subtitle
|
|
57817
|
-
})]
|
|
57818
|
-
}), /* @__PURE__ */ jsx("button", {
|
|
57819
|
-
type: "button",
|
|
57820
|
-
onClick: onClose,
|
|
57821
|
-
className: "p-1 rounded hover:bg-muted text-foreground-subtle hover:text-foreground",
|
|
57822
|
-
"aria-label": "Close panel",
|
|
57823
|
-
children: /* @__PURE__ */ jsx(X, { className: "w-4 h-4" })
|
|
57824
|
-
})]
|
|
57825
|
-
}),
|
|
57826
|
-
/* @__PURE__ */ jsx("div", {
|
|
57827
|
-
className: "flex-1 min-h-0 overflow-y-auto overscroll-contain px-4 py-3",
|
|
57828
|
-
children
|
|
57829
|
-
}),
|
|
57830
|
-
footer !== void 0 && /* @__PURE__ */ jsx("footer", {
|
|
57831
|
-
className: "flex shrink-0 items-center gap-2 justify-end px-4 py-3 border-t border-border",
|
|
57832
|
-
children: footer
|
|
57833
|
-
})
|
|
57834
|
-
]
|
|
57835
|
-
})] });
|
|
57836
|
-
}
|
|
57837
|
-
//#endregion
|
|
57838
57517
|
//#region src/composites/snapshot-button.tsx
|
|
57839
57518
|
/**
|
|
57840
57519
|
* SnapshotButton — operator-facing manual snapshot trigger.
|
|
@@ -58020,51 +57699,501 @@ function StepTimings({ timings, totalMs, className }) {
|
|
|
58020
57699
|
});
|
|
58021
57700
|
}
|
|
58022
57701
|
//#endregion
|
|
58023
|
-
//#region src/composites/step-
|
|
58024
|
-
|
|
58025
|
-
|
|
58026
|
-
|
|
58027
|
-
|
|
58028
|
-
|
|
58029
|
-
|
|
58030
|
-
|
|
58031
|
-
|
|
58032
|
-
|
|
58033
|
-
|
|
57702
|
+
//#region src/composites/step-inspector/accelerator-tabs.tsx
|
|
57703
|
+
function AcceleratorTabs({ items, selectedId, onSelect }) {
|
|
57704
|
+
const onKeyDown = (e, index) => {
|
|
57705
|
+
const delta = e.key === "ArrowRight" ? 1 : e.key === "ArrowLeft" ? -1 : 0;
|
|
57706
|
+
if (delta === 0) return;
|
|
57707
|
+
e.preventDefault();
|
|
57708
|
+
const next = items[(index + delta + items.length) % items.length];
|
|
57709
|
+
if (next !== void 0) onSelect(next.id);
|
|
57710
|
+
};
|
|
57711
|
+
return /* @__PURE__ */ jsx("div", {
|
|
57712
|
+
role: "tablist",
|
|
57713
|
+
"aria-label": "Accelerator",
|
|
57714
|
+
className: "-mx-1 flex min-w-0 flex-nowrap gap-1 overflow-x-auto px-1 pb-0.5",
|
|
57715
|
+
children: items.map((item, index) => {
|
|
57716
|
+
const selected = item.id === selectedId;
|
|
57717
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
57718
|
+
type: "button",
|
|
57719
|
+
role: "tab",
|
|
57720
|
+
"aria-selected": selected,
|
|
57721
|
+
"aria-label": item.marked ? `${item.label} (camera override)` : item.label,
|
|
57722
|
+
tabIndex: selected ? 0 : -1,
|
|
57723
|
+
onClick: () => onSelect(item.id),
|
|
57724
|
+
onKeyDown: (e) => onKeyDown(e, index),
|
|
57725
|
+
className: cn("inline-flex h-9 shrink-0 items-center gap-1 whitespace-nowrap rounded-md border px-2.5 text-[11px] font-medium transition-colors md:h-7", selected ? "border-primary/50 bg-primary/15 text-primary" : "border-border text-foreground-subtle hover:bg-surface-hover hover:text-foreground"),
|
|
57726
|
+
children: [item.label, item.marked && /* @__PURE__ */ jsx("span", {
|
|
57727
|
+
className: "h-1.5 w-1.5 rounded-full bg-amber-500",
|
|
57728
|
+
"aria-hidden": true
|
|
57729
|
+
})]
|
|
57730
|
+
}, item.id);
|
|
57731
|
+
})
|
|
57732
|
+
});
|
|
57733
|
+
}
|
|
57734
|
+
//#endregion
|
|
57735
|
+
//#region src/composites/step-inspector/gate-control.tsx
|
|
57736
|
+
/**
|
|
57737
|
+
* GateControl — whether ONE camera runs a step: Auto (the catalog default) /
|
|
57738
|
+
* On / Off. A per-camera, node-independent switch, written at once (it is not
|
|
57739
|
+
* part of the inspector's draft). `package-detection` is driven by package
|
|
57740
|
+
* zones and shows a badge instead.
|
|
57741
|
+
*
|
|
57742
|
+
* Segments are 36 px tall on a phone and 32 px from `md` up — the matrix this
|
|
57743
|
+
* replaced drew 26 px ones.
|
|
57744
|
+
*/
|
|
57745
|
+
function activeChoice(gate) {
|
|
57746
|
+
if (!gate.explicit) return "auto";
|
|
57747
|
+
return gate.effectiveOn ? "on" : "off";
|
|
57748
|
+
}
|
|
57749
|
+
function GateControl({ gate, busy = false, onSet }) {
|
|
57750
|
+
if (gate.kind === "zone-driven") return /* @__PURE__ */ jsx("span", {
|
|
57751
|
+
className: "inline-flex items-center rounded-md border border-violet-500/40 bg-violet-500/10 px-2 py-1 text-[11px] font-medium text-violet-400",
|
|
57752
|
+
title: "Runs where this camera has package zones — set on the Zones tab",
|
|
57753
|
+
children: "Zones"
|
|
57754
|
+
});
|
|
57755
|
+
const active = activeChoice(gate);
|
|
57756
|
+
const segment = (choice, label, value, on) => /* @__PURE__ */ jsx("button", {
|
|
58034
57757
|
type: "button",
|
|
58035
|
-
|
|
58036
|
-
|
|
58037
|
-
|
|
58038
|
-
|
|
58039
|
-
|
|
58040
|
-
|
|
58041
|
-
|
|
58042
|
-
|
|
58043
|
-
|
|
58044
|
-
|
|
58045
|
-
|
|
58046
|
-
|
|
57758
|
+
role: "radio",
|
|
57759
|
+
"aria-checked": active === choice,
|
|
57760
|
+
disabled: busy,
|
|
57761
|
+
onClick: () => onSet(value),
|
|
57762
|
+
className: cn("h-9 min-w-12 px-3 text-xs font-medium transition-colors md:h-8", active === choice ? on : "text-foreground-subtle hover:bg-muted/60", busy && "cursor-not-allowed opacity-50"),
|
|
57763
|
+
children: label
|
|
57764
|
+
});
|
|
57765
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
57766
|
+
className: "flex items-center gap-2",
|
|
57767
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
57768
|
+
role: "radiogroup",
|
|
57769
|
+
"aria-label": "Runs on this camera",
|
|
57770
|
+
title: `Catalog default: ${gate.defaultOn ? "on" : "off"}`,
|
|
57771
|
+
className: "inline-flex overflow-hidden rounded-md border border-border",
|
|
57772
|
+
children: [
|
|
57773
|
+
segment("auto", "Auto", null, "bg-primary/15 text-primary"),
|
|
57774
|
+
/* @__PURE__ */ jsx("span", {
|
|
57775
|
+
className: "w-px self-stretch bg-border",
|
|
57776
|
+
"aria-hidden": true
|
|
57777
|
+
}),
|
|
57778
|
+
segment("on", "On", true, "bg-emerald-500 text-white"),
|
|
57779
|
+
/* @__PURE__ */ jsx("span", {
|
|
57780
|
+
className: "w-px self-stretch bg-border",
|
|
57781
|
+
"aria-hidden": true
|
|
57782
|
+
}),
|
|
57783
|
+
segment("off", "Off", false, "bg-foreground-subtle/70 text-white")
|
|
57784
|
+
]
|
|
57785
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
57786
|
+
className: "hidden text-[10px] text-foreground-subtle @3xl/inspector:inline",
|
|
57787
|
+
children: ["default: ", gate.defaultOn ? "on" : "off"]
|
|
58047
57788
|
})]
|
|
58048
|
-
})
|
|
58049
|
-
|
|
58050
|
-
|
|
58051
|
-
|
|
58052
|
-
|
|
58053
|
-
|
|
58054
|
-
|
|
57789
|
+
});
|
|
57790
|
+
}
|
|
57791
|
+
/** The gate as a short list-row badge. */
|
|
57792
|
+
function GateBadge({ gate }) {
|
|
57793
|
+
if (gate.kind === "zone-driven") return /* @__PURE__ */ jsx("span", {
|
|
57794
|
+
className: "shrink-0 text-[9px] font-semibold uppercase text-violet-400",
|
|
57795
|
+
children: "zones"
|
|
57796
|
+
});
|
|
57797
|
+
const on = gate.effectiveOn;
|
|
57798
|
+
return /* @__PURE__ */ jsx("span", {
|
|
57799
|
+
className: cn("shrink-0 rounded px-1.5 py-px text-[9px] font-semibold uppercase", on ? "bg-emerald-500/15 text-emerald-500" : "bg-muted text-foreground-subtle", gate.explicit && "ring-1 ring-inset ring-current"),
|
|
57800
|
+
title: gate.explicit ? "Set for this camera" : "Catalog default",
|
|
57801
|
+
children: on ? "on" : "off"
|
|
57802
|
+
});
|
|
58055
57803
|
}
|
|
58056
|
-
|
|
57804
|
+
//#endregion
|
|
57805
|
+
//#region src/composites/step-inspector/segmented-choice.tsx
|
|
57806
|
+
/**
|
|
57807
|
+
* SegmentedChoice — a small, labelled single-choice group (a radiogroup of
|
|
57808
|
+
* buttons): which layer the inspector's settings edit ("All accelerators" /
|
|
57809
|
+
* "Only hub · NPU"). 36 px tall on a phone, 28 px from `md` up.
|
|
57810
|
+
*/
|
|
57811
|
+
function SegmentedChoice({ label, options, value, onChange }) {
|
|
57812
|
+
return /* @__PURE__ */ jsx("div", {
|
|
57813
|
+
role: "radiogroup",
|
|
57814
|
+
"aria-label": label,
|
|
57815
|
+
className: "flex flex-wrap items-center gap-1",
|
|
57816
|
+
children: options.map((option) => /* @__PURE__ */ jsx("button", {
|
|
57817
|
+
type: "button",
|
|
57818
|
+
role: "radio",
|
|
57819
|
+
"aria-checked": value === option.value,
|
|
57820
|
+
onClick: () => onChange(option.value),
|
|
57821
|
+
className: cn("h-9 rounded-md border px-2.5 text-[11px] font-medium transition-colors md:h-7", value === option.value ? "border-primary/50 bg-primary/15 text-primary" : "border-border text-foreground-subtle hover:bg-surface-hover hover:text-foreground"),
|
|
57822
|
+
children: option.label
|
|
57823
|
+
}, option.value))
|
|
57824
|
+
});
|
|
57825
|
+
}
|
|
57826
|
+
//#endregion
|
|
57827
|
+
//#region src/composites/step-inspector/step-detail-dock.tsx
|
|
57828
|
+
/**
|
|
57829
|
+
* StepDetailDock — where a step's settings open from the step matrix
|
|
57830
|
+
* (D757): docked to the page's scroll container, never inside the scrolling
|
|
57831
|
+
* content.
|
|
57832
|
+
*
|
|
57833
|
+
* Desktop: a side panel `position: fixed` over the RIGHT edge of the nearest
|
|
57834
|
+
* scroll container (its top, bottom and right are measured from that box), so
|
|
57835
|
+
* it stays where it is while the matrix scrolls under it, and its header and
|
|
57836
|
+
* save bar are always on screen. It overlays — it never reserves width, so the
|
|
57837
|
+
* matrix does not reflow (the slide-over before D756 reserved 360 px, the
|
|
57838
|
+
* matrix re-measured into a single-node layout, and the clicked cell slid
|
|
57839
|
+
* under the panel). The matrix uses {@link STEP_DOCK_WIDTH_PX} to scroll the
|
|
57840
|
+
* selected column clear of it.
|
|
57841
|
+
*
|
|
57842
|
+
* Phone: a full-screen `Dialog` sheet.
|
|
57843
|
+
*/
|
|
57844
|
+
/** Width of the desktop dock — what the matrix keeps clear of it. */
|
|
57845
|
+
var STEP_DOCK_WIDTH_PX = 432;
|
|
57846
|
+
/** The dock's viewport box, from its scroll container's box. */
|
|
57847
|
+
function dockBox(input) {
|
|
57848
|
+
const right = Math.max(0, input.viewportWidth - input.scroller.right);
|
|
57849
|
+
const width = Math.min(input.widthPx, input.scroller.right);
|
|
57850
|
+
return {
|
|
57851
|
+
top: Math.max(0, input.scroller.top),
|
|
57852
|
+
height: Math.max(0, input.scroller.bottom - Math.max(0, input.scroller.top)),
|
|
57853
|
+
right,
|
|
57854
|
+
width
|
|
57855
|
+
};
|
|
57856
|
+
}
|
|
57857
|
+
function scrollParentOf(el) {
|
|
57858
|
+
for (let p = el?.parentElement ?? null; p !== null; p = p.parentElement) {
|
|
57859
|
+
const { overflowY } = getComputedStyle(p);
|
|
57860
|
+
if (overflowY === "auto" || overflowY === "scroll") return p;
|
|
57861
|
+
}
|
|
57862
|
+
return null;
|
|
57863
|
+
}
|
|
57864
|
+
function useDockBox(anchor, enabled) {
|
|
57865
|
+
const [box, setBox] = useState(null);
|
|
57866
|
+
useLayoutEffect(() => {
|
|
57867
|
+
if (!enabled) return;
|
|
57868
|
+
const scroller = scrollParentOf(anchor.current);
|
|
57869
|
+
const measure = () => {
|
|
57870
|
+
setBox(dockBox({
|
|
57871
|
+
scroller: scroller?.getBoundingClientRect() ?? {
|
|
57872
|
+
top: 0,
|
|
57873
|
+
bottom: window.innerHeight,
|
|
57874
|
+
right: window.innerWidth
|
|
57875
|
+
},
|
|
57876
|
+
viewportWidth: window.innerWidth,
|
|
57877
|
+
widthPx: 432
|
|
57878
|
+
}));
|
|
57879
|
+
};
|
|
57880
|
+
measure();
|
|
57881
|
+
const RO = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(measure);
|
|
57882
|
+
if (scroller) RO?.observe(scroller);
|
|
57883
|
+
window.addEventListener("resize", measure);
|
|
57884
|
+
return () => {
|
|
57885
|
+
RO?.disconnect();
|
|
57886
|
+
window.removeEventListener("resize", measure);
|
|
57887
|
+
};
|
|
57888
|
+
}, [anchor, enabled]);
|
|
57889
|
+
return box;
|
|
57890
|
+
}
|
|
57891
|
+
function StepDetailDock({ open, anchor, onClose, label, children }) {
|
|
57892
|
+
const isMobile = useIsMobile();
|
|
57893
|
+
const box = useDockBox(anchor, open && !isMobile);
|
|
57894
|
+
if (isMobile) return /* @__PURE__ */ jsx(Dialog, {
|
|
57895
|
+
open,
|
|
57896
|
+
onOpenChange: (next) => !next && onClose(),
|
|
57897
|
+
children: /* @__PURE__ */ jsx(DialogContent, {
|
|
57898
|
+
placement: "sheet-on-mobile",
|
|
57899
|
+
scroll: "body",
|
|
57900
|
+
"aria-label": label,
|
|
57901
|
+
className: "h-[100dvh] max-h-none w-full max-w-full rounded-none border-0 p-0 pt-[env(safe-area-inset-top)] pb-[env(safe-area-inset-bottom)]",
|
|
57902
|
+
children: open && children
|
|
57903
|
+
})
|
|
57904
|
+
});
|
|
57905
|
+
if (!open) return null;
|
|
57906
|
+
return /* @__PURE__ */ jsx("aside", {
|
|
57907
|
+
"aria-label": label,
|
|
57908
|
+
"data-step-dock": true,
|
|
57909
|
+
className: "fixed z-30 flex flex-col border-l border-border bg-surface shadow-2xl",
|
|
57910
|
+
style: box !== null ? {
|
|
57911
|
+
top: box.top,
|
|
57912
|
+
height: box.height,
|
|
57913
|
+
right: box.right,
|
|
57914
|
+
width: box.width
|
|
57915
|
+
} : {
|
|
57916
|
+
top: 0,
|
|
57917
|
+
bottom: 0,
|
|
57918
|
+
right: 0,
|
|
57919
|
+
width: 432
|
|
57920
|
+
},
|
|
57921
|
+
children
|
|
57922
|
+
});
|
|
57923
|
+
}
|
|
57924
|
+
/** "‹ Steps" — the phone sheet's way back to the matrix. */
|
|
57925
|
+
function BackToStepsButton({ onClick }) {
|
|
57926
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
57927
|
+
type: "button",
|
|
57928
|
+
onClick,
|
|
57929
|
+
className: "inline-flex h-9 items-center gap-0.5 rounded-md border border-border px-2 text-xs text-foreground hover:bg-surface-hover",
|
|
57930
|
+
children: [/* @__PURE__ */ jsx(ChevronLeft, {
|
|
57931
|
+
className: "h-3.5 w-3.5",
|
|
57932
|
+
"aria-hidden": true
|
|
57933
|
+
}), "Steps"]
|
|
57934
|
+
});
|
|
57935
|
+
}
|
|
57936
|
+
//#endregion
|
|
57937
|
+
//#region src/composites/step-inspector/step-inspector-panel.tsx
|
|
57938
|
+
/**
|
|
57939
|
+
* StepInspectorPanel — the detail pane of the step inspector: a pinned header
|
|
57940
|
+
* (the step, its gate, the accelerator tabs), ONE scrolling body, and a pinned
|
|
57941
|
+
* save bar. Nothing in it depends on the page's scroll position — the slide-over
|
|
57942
|
+
* it replaced was anchored to the matrix block and scrolled away with it.
|
|
57943
|
+
*/
|
|
57944
|
+
function SaveBar({ dirtyCount, saving, status, error, onSave, onDiscard }) {
|
|
57945
|
+
const dirty = dirtyCount > 0;
|
|
57946
|
+
const message = saving ? "Saving…" : dirty ? `${dirtyCount} unsaved change${dirtyCount === 1 ? "" : "s"}` : status === "saved" ? "Saved" : status === "error" ? error ?? "Save failed" : "No unsaved changes";
|
|
57947
|
+
return /* @__PURE__ */ jsxs("footer", {
|
|
57948
|
+
className: "flex shrink-0 items-center gap-2 border-t border-border bg-surface px-4 py-2 pb-[max(0.5rem,env(safe-area-inset-bottom))] md:pb-2",
|
|
57949
|
+
children: [
|
|
57950
|
+
/* @__PURE__ */ jsx("span", {
|
|
57951
|
+
role: "status",
|
|
57952
|
+
className: cn("min-w-0 flex-1 truncate text-[11px]", status === "error" && !dirty ? "text-danger" : dirty ? "text-amber-500" : "text-foreground-subtle"),
|
|
57953
|
+
children: message
|
|
57954
|
+
}),
|
|
57955
|
+
/* @__PURE__ */ jsx(Button, {
|
|
57956
|
+
variant: "outline",
|
|
57957
|
+
size: "md",
|
|
57958
|
+
disabled: !dirty || saving,
|
|
57959
|
+
onClick: onDiscard,
|
|
57960
|
+
children: "Discard"
|
|
57961
|
+
}),
|
|
57962
|
+
/* @__PURE__ */ jsx(Button, {
|
|
57963
|
+
variant: "primary",
|
|
57964
|
+
size: "md",
|
|
57965
|
+
disabled: !dirty || saving,
|
|
57966
|
+
onClick: onSave,
|
|
57967
|
+
children: "Save"
|
|
57968
|
+
})
|
|
57969
|
+
]
|
|
57970
|
+
});
|
|
57971
|
+
}
|
|
57972
|
+
var StepInspectorPanel = forwardRef(function StepInspectorPanel({ title, subtitle, headerActions, headerExtra, leading, saveBar, onEscape, children, className }, headingRef) {
|
|
57973
|
+
const headingId = useId();
|
|
57974
|
+
const onKeyDown = (e) => {
|
|
57975
|
+
if (e.key !== "Escape" || onEscape === void 0) return;
|
|
57976
|
+
e.stopPropagation();
|
|
57977
|
+
onEscape();
|
|
57978
|
+
};
|
|
57979
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
57980
|
+
"aria-labelledby": headingId,
|
|
57981
|
+
onKeyDown,
|
|
57982
|
+
className: cn("flex min-h-0 flex-1 flex-col overflow-hidden bg-surface", className),
|
|
57983
|
+
children: [
|
|
57984
|
+
/* @__PURE__ */ jsxs("header", {
|
|
57985
|
+
className: "shrink-0 space-y-2 border-b border-border px-4 py-2.5",
|
|
57986
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
57987
|
+
className: "flex flex-wrap items-start gap-x-3 gap-y-2",
|
|
57988
|
+
children: [
|
|
57989
|
+
leading,
|
|
57990
|
+
/* @__PURE__ */ jsxs("div", {
|
|
57991
|
+
className: "min-w-[9rem] flex-1",
|
|
57992
|
+
children: [/* @__PURE__ */ jsx("h2", {
|
|
57993
|
+
id: headingId,
|
|
57994
|
+
ref: headingRef,
|
|
57995
|
+
tabIndex: -1,
|
|
57996
|
+
className: "truncate text-sm font-semibold text-foreground outline-none focus-visible:ring-2 focus-visible:ring-primary rounded",
|
|
57997
|
+
children: title
|
|
57998
|
+
}), subtitle !== void 0 && /* @__PURE__ */ jsx("div", {
|
|
57999
|
+
className: "mt-0.5 text-[11px] text-foreground-subtle",
|
|
58000
|
+
children: subtitle
|
|
58001
|
+
})]
|
|
58002
|
+
}),
|
|
58003
|
+
headerActions
|
|
58004
|
+
]
|
|
58005
|
+
}), headerExtra]
|
|
58006
|
+
}),
|
|
58007
|
+
/* @__PURE__ */ jsx("div", {
|
|
58008
|
+
"data-inspector-body": true,
|
|
58009
|
+
className: "min-h-0 flex-1 overflow-y-auto overscroll-contain px-4 py-3",
|
|
58010
|
+
children
|
|
58011
|
+
}),
|
|
58012
|
+
saveBar !== void 0 && /* @__PURE__ */ jsx(SaveBar, { ...saveBar })
|
|
58013
|
+
]
|
|
58014
|
+
});
|
|
58015
|
+
});
|
|
58016
|
+
//#endregion
|
|
58017
|
+
//#region src/composites/step-inspector/step-model-row.tsx
|
|
58018
|
+
var SOURCE_TONE = {
|
|
58019
|
+
camera: "border-primary/40 bg-primary/10 text-primary",
|
|
58020
|
+
node: "border-border bg-muted/40 text-foreground",
|
|
58021
|
+
default: "border-border/60 text-foreground-subtle",
|
|
58022
|
+
cluster: "border-primary/40 bg-primary/5 text-primary"
|
|
58023
|
+
};
|
|
58024
|
+
function StepModelRow({ label, format, modelId, source, sourceLabel, models, defaultModelId, expanded, onToggle, onChangeModel, onReset, resetLabel = "Reset", note, extra, changed = false, disabled = false }) {
|
|
58025
|
+
const pickable = models.length > 0 && note === void 0;
|
|
58026
|
+
const canExpand = pickable || extra !== void 0;
|
|
58027
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
58028
|
+
className: cn("rounded-md border border-border", expanded && "bg-muted/10"),
|
|
58029
|
+
children: [
|
|
58030
|
+
/* @__PURE__ */ jsxs("div", {
|
|
58031
|
+
className: cn(LIST_ROW, "space-y-1"),
|
|
58032
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
58033
|
+
className: "flex flex-wrap items-center gap-x-2 gap-y-1 text-xs",
|
|
58034
|
+
children: [
|
|
58035
|
+
/* @__PURE__ */ jsx("span", {
|
|
58036
|
+
className: "font-medium text-foreground",
|
|
58037
|
+
children: label
|
|
58038
|
+
}),
|
|
58039
|
+
/* @__PURE__ */ jsx("span", {
|
|
58040
|
+
className: "text-[10px] text-foreground-subtle",
|
|
58041
|
+
children: format
|
|
58042
|
+
}),
|
|
58043
|
+
/* @__PURE__ */ jsx("span", {
|
|
58044
|
+
className: cn("ml-auto rounded border px-1.5 py-px text-[10px] font-medium", SOURCE_TONE[source]),
|
|
58045
|
+
children: sourceLabel
|
|
58046
|
+
})
|
|
58047
|
+
]
|
|
58048
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
58049
|
+
className: "flex items-center gap-2",
|
|
58050
|
+
children: [
|
|
58051
|
+
/* @__PURE__ */ jsxs("span", {
|
|
58052
|
+
className: "min-w-0 flex-1 truncate font-mono text-xs text-foreground",
|
|
58053
|
+
children: [modelId ?? "—", changed && /* @__PURE__ */ jsx("span", {
|
|
58054
|
+
className: "ml-1 text-amber-500",
|
|
58055
|
+
children: "•"
|
|
58056
|
+
})]
|
|
58057
|
+
}),
|
|
58058
|
+
onReset !== void 0 && /* @__PURE__ */ jsx("button", {
|
|
58059
|
+
type: "button",
|
|
58060
|
+
className: "inline-flex items-center justify-center gap-1 rounded border border-border bg-surface px-1.5 py-0.5 sm:px-2 sm:py-1 text-[10px] sm:text-[11px] font-medium text-foreground hover:bg-surface-hover transition-colors disabled:opacity-40",
|
|
58061
|
+
disabled,
|
|
58062
|
+
onClick: onReset,
|
|
58063
|
+
children: resetLabel
|
|
58064
|
+
}),
|
|
58065
|
+
canExpand && /* @__PURE__ */ jsx("button", {
|
|
58066
|
+
type: "button",
|
|
58067
|
+
className: cn("inline-flex items-center justify-center gap-1 rounded border border-border bg-surface px-1.5 py-0.5 sm:px-2 sm:py-1 text-[10px] sm:text-[11px] font-medium text-foreground hover:bg-surface-hover transition-colors disabled:opacity-40", "min-h-9 md:min-h-0"),
|
|
58068
|
+
"aria-expanded": expanded,
|
|
58069
|
+
"aria-label": `Change model for ${label}`,
|
|
58070
|
+
disabled,
|
|
58071
|
+
onClick: onToggle,
|
|
58072
|
+
children: expanded ? "Done" : pickable ? "Change" : "Route"
|
|
58073
|
+
})
|
|
58074
|
+
]
|
|
58075
|
+
})]
|
|
58076
|
+
}),
|
|
58077
|
+
note !== void 0 && /* @__PURE__ */ jsx("div", {
|
|
58078
|
+
className: "border-t border-border/60 px-3 py-1.5 text-[10px] leading-snug text-foreground-subtle",
|
|
58079
|
+
children: note
|
|
58080
|
+
}),
|
|
58081
|
+
expanded && canExpand && /* @__PURE__ */ jsxs("div", {
|
|
58082
|
+
className: "space-y-3 border-t border-border/60 px-3 py-3",
|
|
58083
|
+
children: [pickable && /* @__PURE__ */ jsx(ModelPicker, {
|
|
58084
|
+
models,
|
|
58085
|
+
value: modelId ?? "",
|
|
58086
|
+
defaultModelId,
|
|
58087
|
+
disabled,
|
|
58088
|
+
onChange: onChangeModel
|
|
58089
|
+
}), extra]
|
|
58090
|
+
})
|
|
58091
|
+
]
|
|
58092
|
+
});
|
|
58093
|
+
}
|
|
58094
|
+
//#endregion
|
|
58095
|
+
//#region src/composites/step-inspector/step-model-list.tsx
|
|
58096
|
+
/**
|
|
58097
|
+
* StepModelList — the model section of the step inspector.
|
|
58098
|
+
*
|
|
58099
|
+
* While nothing is pinned, edited or worth a note, the accelerators are
|
|
58100
|
+
* summarised by model — one line per distinct model, naming the accelerators
|
|
58101
|
+
* that run it ("yolov9m-320-int8 · hub iGPU, hub NPU, little-unraid iGPU") —
|
|
58102
|
+
* with "Per accelerator" to open one `StepModelRow` each. Four near-identical
|
|
58103
|
+
* rows pushed the settings, the thing most edits are about, below the fold.
|
|
58104
|
+
* A pin, a pending change or a note (no build here, root-supplied) shows every
|
|
58105
|
+
* row, so nothing that differs from the default is ever folded away.
|
|
58106
|
+
*/
|
|
58107
|
+
/** True when the rows can be summarised: nothing pinned here, edited, or noted. */
|
|
58108
|
+
function modelRowsAreFoldable(rows) {
|
|
58109
|
+
return rows.length >= 2 && rows.every((r) => r.note === void 0 && r.onReset === void 0 && r.changed !== true && !r.expanded);
|
|
58110
|
+
}
|
|
58111
|
+
function groupByModel(rows) {
|
|
58112
|
+
const groups = [];
|
|
58113
|
+
for (const row of rows) {
|
|
58114
|
+
const modelId = row.modelId ?? "—";
|
|
58115
|
+
const index = groups.findIndex((g) => g.modelId === modelId && g.sourceLabel === row.sourceLabel);
|
|
58116
|
+
const existing = groups[index];
|
|
58117
|
+
if (existing !== void 0) groups[index] = {
|
|
58118
|
+
...existing,
|
|
58119
|
+
labels: [...existing.labels, row.label]
|
|
58120
|
+
};
|
|
58121
|
+
else groups.push({
|
|
58122
|
+
modelId,
|
|
58123
|
+
labels: [row.label],
|
|
58124
|
+
sourceLabel: row.sourceLabel
|
|
58125
|
+
});
|
|
58126
|
+
}
|
|
58127
|
+
return groups;
|
|
58128
|
+
}
|
|
58129
|
+
function StepModelList({ rows }) {
|
|
58130
|
+
const [open, setOpen] = useState(false);
|
|
58131
|
+
if (!open && modelRowsAreFoldable(rows)) {
|
|
58132
|
+
const groups = groupByModel(rows);
|
|
58133
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
58134
|
+
className: cn("rounded-md border border-border", LIST_ROW),
|
|
58135
|
+
children: [/* @__PURE__ */ jsx("ul", {
|
|
58136
|
+
className: "space-y-1",
|
|
58137
|
+
children: groups.map((g) => /* @__PURE__ */ jsxs("li", {
|
|
58138
|
+
className: "flex flex-wrap items-baseline gap-x-2 text-xs",
|
|
58139
|
+
children: [
|
|
58140
|
+
/* @__PURE__ */ jsx("span", {
|
|
58141
|
+
className: "font-mono text-foreground",
|
|
58142
|
+
children: g.modelId
|
|
58143
|
+
}),
|
|
58144
|
+
/* @__PURE__ */ jsx("span", {
|
|
58145
|
+
className: "min-w-0 flex-1 text-[11px] text-foreground-subtle",
|
|
58146
|
+
children: g.labels.length === rows.length ? `all ${rows.length} accelerators` : g.labels.join(", ")
|
|
58147
|
+
}),
|
|
58148
|
+
/* @__PURE__ */ jsx("span", {
|
|
58149
|
+
className: "rounded border border-border px-1.5 py-px text-[10px] font-medium text-foreground-subtle",
|
|
58150
|
+
children: g.sourceLabel
|
|
58151
|
+
})
|
|
58152
|
+
]
|
|
58153
|
+
}, `${g.modelId}|${g.sourceLabel}`))
|
|
58154
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
58155
|
+
className: "mt-1.5 flex justify-end",
|
|
58156
|
+
children: /* @__PURE__ */ jsx("button", {
|
|
58157
|
+
type: "button",
|
|
58158
|
+
className: cn(BTN_COMPACT, "min-h-9 md:min-h-0"),
|
|
58159
|
+
"aria-expanded": false,
|
|
58160
|
+
onClick: () => setOpen(true),
|
|
58161
|
+
children: "Per accelerator"
|
|
58162
|
+
})
|
|
58163
|
+
})]
|
|
58164
|
+
});
|
|
58165
|
+
}
|
|
58057
58166
|
return /* @__PURE__ */ jsx("div", {
|
|
58058
|
-
className:
|
|
58059
|
-
children:
|
|
58060
|
-
node,
|
|
58061
|
-
depth: 0,
|
|
58062
|
-
selectedAddonId,
|
|
58063
|
-
onSelect,
|
|
58064
|
-
agentDots
|
|
58065
|
-
}, node.addonId))
|
|
58167
|
+
className: "space-y-2",
|
|
58168
|
+
children: rows.map(({ id, ...row }) => /* @__PURE__ */ jsx(StepModelRow, { ...row }, id))
|
|
58066
58169
|
});
|
|
58067
58170
|
}
|
|
58171
|
+
//#endregion
|
|
58172
|
+
//#region src/composites/step-inspector/step-search.ts
|
|
58173
|
+
function matches(text, tokens) {
|
|
58174
|
+
const lower = text.toLowerCase();
|
|
58175
|
+
return tokens.every((t) => lower.includes(t));
|
|
58176
|
+
}
|
|
58177
|
+
/** Steps matching `query` (all tokens in the name, or all in one field label). Empty query = all. */
|
|
58178
|
+
function searchSteps(rows, query) {
|
|
58179
|
+
const tokens = query.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
58180
|
+
if (tokens.length === 0) return rows.map((row) => ({ addonId: row.addonId }));
|
|
58181
|
+
const hits = [];
|
|
58182
|
+
for (const row of rows) {
|
|
58183
|
+
if (matches(row.name, tokens)) {
|
|
58184
|
+
hits.push({ addonId: row.addonId });
|
|
58185
|
+
continue;
|
|
58186
|
+
}
|
|
58187
|
+
const field = row.fieldLabels.find((l) => matches(l, tokens));
|
|
58188
|
+
if (field !== void 0) hits.push({
|
|
58189
|
+
addonId: row.addonId,
|
|
58190
|
+
matchedField: field
|
|
58191
|
+
});
|
|
58192
|
+
}
|
|
58193
|
+
return hits;
|
|
58194
|
+
}
|
|
58195
|
+
//#endregion
|
|
58196
|
+
//#region src/composites/step-tree.ts
|
|
58068
58197
|
/**
|
|
58069
58198
|
* Helper: build a StepTreeNode[] from a `PipelineSchema` by chaining on
|
|
58070
58199
|
* `inputClasses` ⇔ `outputClasses` compatibility. Mirrors the orchestrator
|
|
@@ -61009,4 +61138,4 @@ var SceneMonitorEditor = lazy(() => import("./SceneMonitorEditor-vfWTm6qv.js").t
|
|
|
61009
61138
|
/** Lazy-wrapped `PrivacyMaskSettings` — code-split off the main bundle. */
|
|
61010
61139
|
var PrivacyMaskSettings = lazy(() => import("./PrivacyMaskSettings-DMkchqO1.js").then((m) => ({ default: m.PrivacyMaskSettings })));
|
|
61011
61140
|
//#endregion
|
|
61012
|
-
export { AddonGlobalSettingsForm, AdminLinkQuickAction, AgentStepEditor, AlarmHeroCard, AlarmInlineControl as AlarmPanelInlineControl, AppShell, ArcKnob, AudioClassificationList, AudioLevelWaveform, AudioWaveform, AutomationHeroCard, AutomationInlineControl, AutotrackSection, BTN_COMPACT, BTN_COMPACT_DANGER, BTN_COMPACT_PRIMARY, BTN_COMPACT_WARNING, Badge, BatteryBadge, BottomSheet, Breadcrumb, BrightnessPanel, Button, ButtonControl, ButtonHeroCard, CARD_MODE_MIN_COLUMNS, CENTER, CHIP_ACTIVE, CHIP_BASE, CHIP_INACTIVE, CLASS_COLORS, COLUMN_BREAKPOINT_CLASS, COLUMN_PRIORITY, COMMIT_DEDUPE_TOLERANCE_MS, COMMIT_DEDUPE_WINDOW_MS, CONTROL_CAP_NAMES, CONTROL_FILLS, CameraStreamPlayer, Card, Checkbox, ChildSectionAccordion, ClimatePanel, CodeBlock, CollapsibleCard, ConfigFormBuilder, FormField as ConfigFormField, ConfigNotificationTargetMultiSelectFieldView, ConfigNotificationTargetSelectFieldView, ConfigSchemaField, ConfirmActionButton, ConfirmDialogProvider, ConsumablesPanel, ContainerChildrenProvider, ContainerPrimaryHero, ControlColumn, ControlHeroCard, ControlInlineControl, ControlPanel, CopyButton, CoverHeroCard, CoverInlineControl, CoverPanel, CustomFieldRenderersProvider, DEFAULT_COLOR, DEVICE_COLUMNS, DEVICE_LIST_PAGE_SIZE_KEY, DEVICE_LIST_PAGE_SIZE_OPTIONS, DEVICE_PICKER_GROUP_STORAGE_KEY, DEVICE_ROLE_META, DEVICE_TYPE_CONTROL, DEVICE_TYPE_META, DISPLAY_ICON_REGISTRY, DataTable, DataTableFilterBar, DetectionCanvas, DetectionOverlay, DetectionResultTree, DevShell, DeviceActivityPanel, DeviceBatchToolbar, DeviceCard, DeviceContextProvider, DeviceExportPanel, DeviceFilterBar, DeviceGrid, DeviceItem, DeviceList, DeviceMultiSelectField, DevicePicker, DeviceQuickDetailProvider, DeviceSelectField, DeviceSelectorPicker, DeviceStepMatrix, DevicesFailedLine, DevicesLoadingLine, DevicesWidenWarning, Dialog, DialogBody, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, DiscoveryPanel, DoorbellRecentPanel, Dropdown, DropdownContent, DropdownItem, DropdownTrigger, DummyHeroCard, DummyInline, EMPTY_DATA_TABLE_FILTER, EVENT_KIND_ICONS, EmptyState, EndpointResultsCard, EndpointTestCard, ErrorBox, EventKindGlyph, EventStream, ExtensionsPanel, FILL, FLEET_LIST_GC_TIME_MS, FLEET_LIST_QUERY_KEY, FLEET_LIST_STALE_TIME_MS, FanHeroCard, FanInlineControl, FanPanel, FilterBar, FloatingEventStream, FloatingLogStream, FloatingPanel, FormField$1 as FormField, GRID_GAP, GRID_PAIRED, GRID_QUICK_STATS, GripTrack, GroupedModelSelector, HOST_WIDGETS, HUB_SESSION_RUN_MS, HlsVideo, HoverZoomImage, HubSessionTestCard, HumidifierHeroCard, HumidifierInlineControl, INPUT_COMPACT, INPUT_SHELL, IconAction, IconButton, IconPicker, ImageHeroCard, ImageInlineControl, ImageSelector, InferenceConfigSelector, Input, KebabMenu, KeyValueList, LIST_ROW, Label, LawnMowerHeroCard, LawnMowerInlineControl, LightHeroCard, LightInlineControl, LockHeroCard, LockInlineControl, LockPanel, LogStream, LoginForm, MODE_COLOR, MaskShapeCanvas, MediaPlayerHeroCard, MediaPlayerInlineControl, MediaPlayerPanel, MobileDrawer, ModelPicker, MotionZonesSettings, NAVIGATION_DRIVE_INTERVAL_MS, NatResultCard, NavigationPanel, NetworkLinkBadge, NodeMultiSelectField, NodePicker, NodeSelectField, NotificationTargetSelectField, NotificationTargetsField, OPTION_SELECT_SEARCH_MIN_OPTIONS, OfflineBadge, OptionSelect, PHASE_CONFIG, PICKER_CHIP_LIMIT, PICKER_DEFAULT_GROUP_BY, PICKER_GROUP_BY_MODES, PICKER_GROUP_COLLAPSE_AT, PICKER_NONE_KEY, PICKER_NOUN_PLURAL, PICKER_NO_FILTERS, PICKER_PAGE_SIZE, PICKER_SEARCH_DEBOUNCE_MS, PICKER_WINDOW, PRIORITY, PTZOverlay, PageHeader, PhaseIcon, PipelineBuilder, PipelineRuntimeSelector, PipelineStep, PipelineTreeMatrix, PlaceholderChipField, PlayerOverlaysProvider, Popover, PopoverContent, PopoverRowAction, PopoverTrigger, PrimaryChildPicker, PrivacyMaskSettings, ProviderBadge, PtzPanel, QrCode, RECONNECT_POLICY, RECORDED_PLAYBACK_MODES, RIGHT, ROI_AREA_WARN_FRACTION, ROLE_DESCRIPTOR, RadialGauge, RecordedPlaybackProvider, RecordingPanel, ResponseLog, RoleDisplayDefaultsFromServer, RoleDisplayDefaultsProvider, RunReport, SCENE_CAPTURE_VARIANTS, SECTION_BODY, SECTION_CARD, SECTION_HEADER, SETTING_ROW, SETTING_ROW_LABEL, SETTING_ROW_STACK_BREAKPOINT, SETTING_ROW_VALUE, SETTING_ROW_VALUE_TEXT, SNAPSHOT_MEDIA_PATH, SPLIT_PANEL_OUTER, SPLIT_PANEL_SIDE, STACK_GAP, STATE_COLOR, SceneMonitorEditor, ScopePicker, ScriptHeroCard, ScriptInlineControl, ScrollArea, SectionCard, Select, SelectedChip, SemanticBadge, SensorHeroCard, SensorInlineControl, SensorValueAtom, Separator, SettingRow, Sidebar, SidebarItem, Skeleton, SlideOverPanel, SlideToggle, SnapshotButton, SortHeaderButton, StatCard, StateValuesStream, StatusBadge, StepTimings, StepTreeMaster, Stepper, StreamBrokerSelector, StreamDebugOverlay, StreamPanel, Switch, SwitchHeroCard, SwitchInlineControl, SwitchPanel, SystemProvider, TABLE_SCROLL_MAX_H, TEXT_FIELD_LABEL, TEXT_HINT, TEXT_METRIC, TEXT_SECTION_LABEL, TEXT_VALUE, TIMEZONES, Tabs, TabsContent, TabsList, TabsTrigger, TapToggle, ThemeProvider, ThermostatHeroCard, ThermostatInlineControl, TimezoneSelector, Tooltip, TooltipContent, TooltipTrigger, UnitPicker, VacuumHeroCard, VacuumInlineControl, ValueReadout, ValveHeroCard, ValveInlineControl, VersionBadge, VodPlaybackProvider, WaterHeaterHeroCard, WaterHeaterInlineControl, WeatherHeroCard, WeatherInlineControl, WidgetMetricCard, WidgetPanel, WidgetRegistryProvider, WidgetSlot, ZoneEditingProvider, MicOff as a, agentColumnKey, allDeviceTypeFilterOptions, applyFleetQueryDefaults, applyPickerFilters, ariaSortForColumn, badgeFor, buildPeerConnectionConfig, buildStepTreeFromSchema, EyeOff as c, catalogHasDraft, childEntityId, childListName, chipOverflow, classifyAddressScope, classifyCapability, classifySessionVerdict, clearPickerGroup, cn, columnsForContext, compareSrflxMappings, containerChildToRef, countableDevices, coverHighlight, coverageLine, createSharedContext, createTheme, cursorFractionFor, darkColors, dataTableFacets, defaultTheme, deriveDeviceKind, deriveWebrtcDebugStats, describeDeviceSelector, deviceIntegrationResolver, deviceListStateOf, deviceMatchesFilter, deviceOptionLabel, deviceRoleMeta, deviceRoleMetaOf, deviceTypeLabel, deviceTypeMeta, deviceTypeMetaOf, devicesToOptions, draftFromQuery, emptyDevicesWidens, emptySessionRun, ensureMfHostInit, eventKindLabel, filterDataTableRows, filterDeviceOptions, filterOptions as filterOptionSelectOptions, filterPickerDevices, finalizeSessionRun, findTimezone, flattenPickerGrouping, flattenPickerRows, fleetViewOf, formatControlDateTime, formatLastSeen, formatNumeric, freezeVerdict, fuzzyMatch, getClassColor, getPhaseVisual, groupAgentColumns, groupChildrenByLayout, groupPickerDevices, groupPickerDevicesBy, hardwareLabel, hubOrigin, hubPath, hubUrl, hubWsUrl, humanDuration, humidifierTint, Mic as i, initialScrubState, insertAtSelection, isAbsentProvider, isDataTableFilterActive, isFieldVisible, isGroupExpanded, Camera as l, lawnMowerActivityMeta, lightColors, loadRemoteBundle, makeScrubBridge, metadataEntries, metadataString, mirror, mountAddonPage, mountPath, Square as n, nextReconnectAction, nextSort, nextSortDirection, nextTableSort, normalizeForSearch, ImageOff as o, offListSelections, openTopLayer, optionSearchText as optionSelectSearchText, orphanDeviceLabel, overrideEntityIdFromLink, pageRows, parentDetailOf, parseIceCandidate, parsePickerGroupBy, parseRecordedServerMessage, partitionSelected as partitionOptionSelectSelected, partitionSuggested, pickerFacetFilterShown, pickerFacetKey, pickerFacetOptions, pickerFiltersActive, pickerGroupKey, pickerHiddenSelectedCount, pickerLocationKey, pickerQueryTokens, pickerRowFacts, pickerSearchText, pickerZoneFilterSuspended, pinnedStreamChoices, providerIcons, RotateCcw as r, readStoredGroupBy, reduceSessionRun, resetHubMountForTests, resetPickerFilters, resolveContainerPrimary, resolveControlAlign, resolveDeviceControl, resolveDeviceIntegration, resolveDisplayIcon, resolveEffectiveDefaultModel, resolveEffectiveStepModel, resolveEventKindIcon, resolveSearchable as resolveOptionSelectSearchable, resolveParentNames, resolvePrimaryChild, resolveSelectedDevices, resolveSensorDisplay, resolveStepDefaultModel, resolveTableLayout, roiTooLarge, rootSourceState, routerBasename, Grid2x2 as s, sameLocationSuggestions, scrubReducer, selectPickerGroup, selectedDeviceOptions, serializeRecordedCommand, shouldCommit, shouldEmit, shouldShowAddNewFooter, shouldShowUseQueryRow, shouldUseSingleNode, showsNoCamerasHint, sortRows, sortRowsByColumn, statusIcons, statusLine, stepHasModelForFormat, stepModelOptions, stripParentNamePrefix, summarizeHubCandidates, Trash2 as t, tabForSelector, tankAlert, themeToCss, toStationaryOverlayBox, toggleDataTableFacet, togglePickerDevice, togglePickerKey, trpc, typeLabel, createLucideIcon as u, useAccessoriesGetStatus, useAccessoriesSetChildHidden, useAddonPagesListPages, useAddonSettingsGetDeviceSettings, useAddonSettingsGetGlobalSettings, useAddonSettingsGetIntegrationSettings, useAddonSettingsUpdateDeviceSettings, useAddonSettingsUpdateGlobalSettings, useAddonWidgetsListWidgets, useAddonsApplyAutoUpdateToAll, useAddonsCancelJob, useAddonsCustom, useAddonsForceRefresh, useAddonsGetAddonAutoUpdate, useAddonsGetAutoUpdateSettings, useAddonsGetJob, useAddonsGetLastRestart, useAddonsGetLogs, useAddonsGetVersions, useAddonsInstallFromWorkspace, useAddonsInstallPackage, useAddonsIsWorkspaceAvailable, useAddonsList, useAddonsListCapabilityProviders, useAddonsListFrameworkPackages, useAddonsListJobs, useAddonsListPackages, useAddonsListUpdates, useAddonsListWorkspacePackages, useAddonsOnAddonLogs, useAddonsReloadPackages, useAddonsRestartAddon, useAddonsRestartServer, useAddonsRetryLoad, useAddonsRollbackPackage, useAddonsSearchAvailable, useAddonsSetAddonAutoUpdate, useAddonsSetAutoUpdateSettings, useAddonsSetCapabilityProviderEnabled, useAddonsStartJob, useAddonsUninstallPackage, useAddonsUpdatePackage, useAirQualitySensorGetStatus, useAlarmPanelArm, useAlarmPanelDisarm, useAlarmPanelGetStatus, useAlarmPanelTrigger, useAlert, useAlertsDismiss, useAlertsEmit, useAlertsGetUnreadCount, useAlertsList, useAlertsMarkAllRead, useAlertsMarkRead, useAlertsUpdate, useAllWidgets, useAmbientLightSensorGetStatus, useAudioAnalysisApplyDeviceSettingsPatch, useAudioAnalysisGetDeviceLiveContribution, useAudioAnalysisGetDeviceSettingsContribution, useAudioAnalysisResolveDeviceSettings, useAudioAnalyzerAnalyseChunk, useAudioAnalyzerAttachDevice, useAudioAnalyzerClassify, useAudioAnalyzerDetachDevice, useAudioAnalyzerDispose, useAudioAnalyzerIsReady, useAudioAnalyzerReprobeAudioEngine, useAudioCodecCanHandle, useAudioCodecCloseSession, useAudioCodecCreateDecodeSession, useAudioCodecCreateEncodeSession, useAudioCodecFlushEncode, useAudioCodecListActiveSessions, useAudioCodecListSupportedCodecs, useAudioCodecPullEncoded, useAudioCodecPullPcm, useAudioCodecPushEncodedFrame, useAudioCodecPushPcm, useAudioMetricsGetCurrentSnapshot, useAudioMetricsGetHistory, useAutomationControlDisable, useAutomationControlEnable, useAutomationControlGetStatus, useAutomationControlTrigger, useBackupCancel, useBackupDelete, useBackupDeleteSchedule, useBackupGetEntries, useBackupList, useBackupListArchives, useBackupListDestinations, useBackupListLocations, useBackupListRuns, useBackupListSchedules, useBackupPreviewSchedule, useBackupRestore, useBackupTrigger, useBackupUpsertDestinationPolicy, useBackupUpsertSchedule, useBatteryGetStatus, useBatteryWakeForStream, useBinaryGetStatus, useBrightnessGetStatus, useBrightnessSetBrightness, useBrokerAdd, useBrokerGet, useBrokerGetBrokerConfig, useBrokerGetSettings, useBrokerGetSettingsSchema, useBrokerGetState, useBrokerGetStatus, useBrokerList, useBrokerListProviders, useBrokerPublish, useBrokerRemove, useBrokerSetSettings, useBrokerSubscribe, useBrokerTestConnection, useBrokerTestSettings, useBrokerUnsubscribe, useButtonPress, useCalendarsGetPreferences, useCalendarsListCalendars, useCalendarsListEvents, useCalendarsSetCalendarPreference, useCameraCredentialsGetCredentials, useCameraCredentialsGetStatus, useCameraGridLayoutApplyDeviceSettingsPatch, useCameraGridLayoutGetDeviceLiveContribution, useCameraGridLayoutGetDeviceSettingsContribution, useCameraGridLayoutGetLayout, useCameraGridLayoutSaveLayout, useCameraPipelineConfigApplyDeviceSettingsPatch, useCameraPipelineConfigGetDeviceLiveContribution, useCameraPipelineConfigGetDeviceSettingsContribution, useCameraStreamsGetBrokerStreams, useCameraStreamsGetCameraStreams, useCameraStreamsGetProfileRtspEntries, useCameraStreamsGetRtspEntries, useCameraStreamsPickStream, useCapabilityPresence, useCarbonMonoxideGetStatus, useClimateControlGetStatus, useClimateControlSetFanMode, useClimateControlSetMode, useClimateControlSetPreset, useClimateControlSetSwingHorizontal, useClimateControlSetSwingVertical, useClimateControlSetTarget, useClimateControlSetTargetHumidity, useClimateControlSetTargetRange, useClusterNodes, useClusterTopology, useColorGetStatus, useColorSetColor, useConfirm, useConnectionTestDescribeTest, useConnectionTestTestSettings, useConnectivityGetStatus, useConsumablesGetStatus, useConsumablesReset, useContactGetStatus, useContainerChildren, useControlGetStatus, useControlSetValue, useCoreBlocksCompile, useCoreBlocksCreate, useCoreBlocksCreateComposition, useCoreBlocksDelete, useCoreBlocksGet, useCoreBlocksGetBlockSettings, useCoreBlocksGetComposition, useCoreBlocksGetCustomization, useCoreBlocksGetTypeDefs, useCoreBlocksList, useCoreBlocksListComposableCaps, useCoreBlocksListCompositions, useCoreBlocksRestart, useCoreBlocksSetEnabled, useCoreBlocksUpdate, useCoreBlocksUpdateBlockSettings, useCoreBlocksUpdateComposition, useCoreBlocksValidateComposition, useCoverClose, useCoverGetStatus, useCoverOpen, useCoverSetPosition, useCoverSetTiltPosition, useCoverStop, useCustomFieldRenderer, useDataTableFilter, useDayNightGetOptions, useDayNightGetStatus, useDayNightSetSettings, useDebouncedString, useDecoderCreateSession, useDecoderDestroySession, useDecoderGetFrame, useDecoderGetInfo, useDecoderGetShmStats, useDecoderGetStats, useDecoderListActiveSessions, useDecoderOpenStream, useDecoderPullFrames, useDecoderPullHandles, useDecoderPushPacket, useDecoderReprobeHwaccel, useDecoderSupportsCodec, useDecoderUpdateConfig, useDetectionPipelineApplyDeviceSettingsPatch, useDetectionPipelineGetDeviceLiveContribution, useDetectionPipelineGetDeviceSettingsContribution, useDevShell, useDevice, useDeviceAdminLink, useDeviceAdminLinkGetAdminLink, useDeviceAdoptionAdopt, useDeviceAdoptionGetCandidate, useDeviceAdoptionGetStatus, useDeviceAdoptionListCandidateFilters, useDeviceAdoptionListCandidates, useDeviceAdoptionRefresh, useDeviceAdoptionRelease, useDeviceAdoptionResync, useDeviceAutotrack, useDeviceBattery, useDeviceCapSlice, useDeviceCapability, useDeviceDetections, useDeviceDiscoveryAdoptDevice, useDeviceDiscoveryGetStatus, useDeviceDiscoveryListDiscovered, useDeviceDiscoveryRefreshDiscovery, useDeviceDiscoveryReleaseDevice, useDeviceExportApplyDeviceSettingsPatch, useDeviceExportExposeDevice, useDeviceExportGetDeviceLiveContribution, useDeviceExportGetDeviceSettingsContribution, useDeviceExportGetStatus, useDeviceExportListExposedDevices, useDeviceExportListSupportedDeviceKinds, useDeviceExportUnexposeDevice, useDeviceExtensionListCandidates, useDeviceExtensionListSlots, useDeviceExtensionListSources, useDeviceExtensionSetSlot, useDeviceId, useDeviceListPageSize, useDeviceManagerAddLocation, useDeviceManagerAdoptDevice, useDeviceManagerAdoptionAdopt, useDeviceManagerAdoptionCancelJob, useDeviceManagerAdoptionListCandidateFilters, useDeviceManagerAdoptionListCandidates, useDeviceManagerAdoptionListJobs, useDeviceManagerAdoptionRefresh, useDeviceManagerAdoptionRelease, useDeviceManagerAdoptionResync, useDeviceManagerAdoptionStartJob, useDeviceManagerAllocateDeviceId, useDeviceManagerApplyInitialMeta, useDeviceManagerCreateDevice, useDeviceManagerDisable, useDeviceManagerDiscoverAllProviders, useDeviceManagerDiscoverDevices, useDeviceManagerDiscoverProvider, useDeviceManagerDiscoveryProviders, useDeviceManagerEnable, useDeviceManagerGetAllBindings, useDeviceManagerGetBindings, useDeviceManagerGetBindingsBatch, useDeviceManagerGetChildren, useDeviceManagerGetChildrenBatch, useDeviceManagerGetConfigSchema, useDeviceManagerGetCreationSchema, useDeviceManagerGetDevice, useDeviceManagerGetDeviceAggregate, useDeviceManagerGetDeviceLiveInfoAggregate, useDeviceManagerGetDeviceSettingsAggregate, useDeviceManagerGetDeviceStatusAggregate, useDeviceManagerGetDeviceStatusAggregateBatch, useDeviceManagerGetLinkedDevices, useDeviceManagerGetLinkedDevicesBatch, useDeviceManagerGetRoleDisplayDefaults, useDeviceManagerGetSettingsSchema, useDeviceManagerGetStreamProfileMap, useDeviceManagerGetStreamSources, useDeviceManagerGetWireableFields, useDeviceManagerGetWrapperActivation, useDeviceManagerListAll, useDeviceManagerListBindableCapsForDeviceType, useDeviceManagerListDeviceIdsByCaps, useDeviceManagerListLocationDescriptions, useDeviceManagerListLocationIcons, useDeviceManagerListLocations, useDeviceManagerListPersistedByAddon, useDeviceManagerListSiteZones, useDeviceManagerListWrappersForCap, useDeviceManagerLoadConfig, useDeviceManagerLoadMeta, useDeviceManagerLoadRuntimeState, useDeviceManagerMigrateDevice, useDeviceManagerPersistConfig, useDeviceManagerProbeStreams, useDeviceManagerProviderCreationType, useDeviceManagerProviderDiscoveryParamsSchema, useDeviceManagerRegisterDevice, useDeviceManagerRemove, useDeviceManagerRemoveByIntegration, useDeviceManagerRemoveDevice, useDeviceManagerRemoveLocation, useDeviceManagerRemoveSiteZone, useDeviceManagerRenameLocation, useDeviceManagerRenameSiteZone, useDeviceManagerRunDeviceAction, useDeviceManagerSetChildLayout, useDeviceManagerSetDisabled, useDeviceManagerSetDisplay, useDeviceManagerSetIntegrationId, useDeviceManagerSetLinkDeviceId, useDeviceManagerSetLocation, useDeviceManagerSetLocationDescription, useDeviceManagerSetLocationIcon, useDeviceManagerSetLocationZone, useDeviceManagerSetMetadata, useDeviceManagerSetName, useDeviceManagerSetPrimaryChildEntityId, useDeviceManagerSetRole, useDeviceManagerSetRoleDisplayDefaults, useDeviceManagerSetSiteZone, useDeviceManagerSetStreamProfileMap, useDeviceManagerSetType, useDeviceManagerSetWrapperActive, useDeviceManagerTestCreationField, useDeviceManagerTestField, useDeviceManagerUpdateConfig, useDeviceManagerUpdateDeviceField, useDeviceManagerUpdateDeviceFieldsBatch, useDeviceNetworkLink, useDeviceOpsGetConfigEntries, useDeviceOpsGetRawState, useDeviceOpsGetSettingsSchema, useDeviceOpsGetStreamSources, useDeviceOpsRemoveDevice, useDeviceOpsRunAction, useDeviceOpsSetConfig, useDeviceProviderAdoptDiscoveredDevice, useDeviceProviderCreateDevice, useDeviceProviderDiscoverDevices, useDeviceProviderGetChildCreationSchema, useDeviceProviderGetDevices, useDeviceProviderGetDiscoveryParamsSchema, useDeviceProviderGetManualCreationType, useDeviceProviderGetStatus, useDeviceProviderReloadDevice, useDeviceProviderStart, useDeviceProviderStop, useDeviceProviderSupportsDiscovery, useDeviceProviderSupportsManualCreation, useDeviceProviderTestCreationField, useDeviceProxy, useDeviceQuickDetailOpen, useDeviceSnapshot, useDeviceSnapshotImage, useDeviceState, useDeviceStateClaimFields, useDeviceStateGetAllSnapshots, useDeviceStateGetCapSlice, useDeviceStateGetNativeCapSlice, useDeviceStateGetSnapshot, useDeviceStateListClaims, useDeviceStatePatchOwnedFields, useDeviceStateReleaseClaim, useDeviceStateSetCapSlice, useDeviceStateSlice, useDeviceStatusGetStatus, useDeviceWebrtc, useDevices, useDoorbellEvents, useDoorbellGetStatus, useEnumSensorGetStatus, useEventEmitterGetStatus, useEventInvalidation, useEventStreamLatest, useEventStreamMap, useFaceGalleryAssignFace, useFaceGalleryAssignFaces, useFaceGalleryAuditIdentitySamples, useFaceGalleryCreateIdentity, useFaceGalleryDeleteFace, useFaceGalleryDeleteIdentity, useFaceGalleryGetFaceByTrack, useFaceGalleryGetFaceMedia, useFaceGalleryListIdentities, useFaceGalleryListIdentitySamples, useFaceGalleryListRecentFaces, useFaceGalleryRemoveSample, useFaceGalleryRenameIdentity, useFaceGallerySuggestFaceClusters, useFaceGalleryUnassignFace, useFaceGalleryUnassignFaces, useFanControlGetStatus, useFanControlSetDirection, useFanControlSetOscillating, useFanControlSetPercentage, useFanControlSetPreset, useFeatureProbeGetStatus, useFloodGetStatus, useGasGetStatus, useHumidifierGetStatus, useHumidifierSetMode, useHumidifierSetOn, useHumidifierSetTargetHumidity, useHumiditySensorGetStatus, useImageGetStatus, useImageSettingsGetOptions, useImageSettingsGetStatus, useImageSettingsSetSettings, useIntegrationsCreate, useIntegrationsDelete, useIntegrationsGet, useIntegrationsGetAvailableTypes, useIntegrationsGetByAddonId, useIntegrationsGetSettings, useIntegrationsList, useIntegrationsSetSettings, useIntegrationsTestConnection, useIntegrationsUpdate, useIntercomEndTalkSession, useIntercomGetStatus, useIntercomHandleAnswer, useIntercomPushTalkAudio, useIntercomStartSession, useIntercomStartTalkSession, useIntercomStopSession, useIsMidWidth, useIsMobile, useLawnMowerControlDock, useLawnMowerControlGetStatus, useLawnMowerControlPause, useLawnMowerControlStartMowing, useLiveBuffer, useLiveEvent, useLlmCancel, useLlmDeleteModel, useLlmDeleteProfile, useLlmGenerate, useLlmGenerateVision, useLlmGetDefaults, useLlmGetRuntimeStatus, useLlmGetUsage, useLlmInstallModel, useLlmListModelCatalog, useLlmListModels, useLlmListNodeModels, useLlmListProfileKinds, useLlmListProfiles, useLlmListRuntimeNodes, useLlmResolveModelRef, useLlmSetDefault, useLlmStartRuntime, useLlmStopRuntime, useLlmTestProfile, useLlmUpsertProfile, useLocalNetworkAddCustomAddress, useLocalNetworkDownloadCa, useLocalNetworkGetAddresses, useLocalNetworkGetAllowedAddresses, useLocalNetworkGetConnectionEndpoints, useLocalNetworkGetHubAddresses, useLocalNetworkGetNotificationEndpoint, useLocalNetworkGetPreferred, useLocalNetworkGetTlsStatus, useLocalNetworkGetViewerEndpoints, useLocalNetworkList, useLocalNetworkRegenerateCertificate, useLocalNetworkRemoveCustomAddress, useLocalNetworkResetAllowlistToBestMatch, useLocalNetworkRevertToGeneratedCertificate, useLocalNetworkSetAddressRole, useLocalNetworkSetAllowedAddresses, useLocalNetworkSetNotificationEndpoint, useLocalNetworkSetViewerEndpoints, useLocalNetworkUploadCertificate, useLockControlGetStatus, useLockControlLock, useLockControlOpen, useLockControlUnlock, useMediaPlayerGetStatus, useMediaPlayerNext, useMediaPlayerPause, useMediaPlayerPlay, useMediaPlayerPlayMedia, useMediaPlayerPrevious, useMediaPlayerSeek, useMediaPlayerSelectSource, useMediaPlayerSetMute, useMediaPlayerSetRepeat, useMediaPlayerSetShuffle, useMediaPlayerSetVolume, useMediaPlayerStop, useMeshNetworkGetStatus, useMeshNetworkJoin, useMeshNetworkLeave, useMeshNetworkListPeers, useMeshNetworkLogout, useMeshNetworkStartLogin, useMeshNetworkTestConnection, useMetricsProviderCollectSnapshot, useMetricsProviderGetAddonStats, useMetricsProviderGetCached, useMetricsProviderGetCpuTemperature, useMetricsProviderGetCurrent, useMetricsProviderGetDiskSpace, useMetricsProviderGetGpuInfo, useMetricsProviderGetLoadSeries, useMetricsProviderGetProcessStats, useMetricsProviderListAddonInstances, useMetricsProviderListNodeProcesses, useMotionDetectionAnalyze, useMotionDetectionApplyDeviceSettingsPatch, useMotionDetectionGetDeviceLiveContribution, useMotionDetectionGetDeviceSettingsContribution, useMotionDetectionRemoveCamera, useMotionDetectionReset, useMotionGetStatus, useMotionIsDetected, useMotionTriggerGetStatus, useMotionTriggerSetMotionTrigger, useMotionZonesGetOptions, useMotionZonesGetStatus, useMotionZonesSetZone, useMqttBrokerAddBroker, useMqttBrokerGetBrokerConfig, useMqttBrokerGetStatus, useMqttBrokerListBrokers, useMqttBrokerRemoveBroker, useMqttBrokerStartEmbeddedBroker, useMqttBrokerStopEmbeddedBroker, useMqttBrokerTestConnection, useNativeObjectDetectionGetOptions, useNativeObjectDetectionGetStatus, useNativeObjectDetectionSetEnabled, useNativeObjectDetectionSetSettings, useNavigation, useNavigationGetFeatures, useNavigationGetStatus, useNavigationGoToPoint, useNavigationListActions, useNavigationMove, useNavigationPlaySound, useNavigationRunAction, useNavigationSetLightLevel, useNavigationSetLightMode, useNavigationSetLightOn, useNavigationStop, useNetworkAccessGetEndpoint, useNetworkAccessGetStatus, useNetworkAccessListEndpoints, useNetworkAccessStart, useNetworkAccessStop, useNetworkLinkGetStatus, useNetworkQualityGetAllStats, useNetworkQualityGetDeviceStats, useNetworkQualityReportClientStats, useNodesClusterAddonStatus, useNodesDeployAddon, useNodesDirectory, useNodesExecuteQuery, useNodesGetCapUsageGraph, useNodesGetNodeAddons, useNodesRenameNode, useNodesRestartAddon, useNodesRestartNode, useNodesRestartProcess, useNodesSetProcessLogLevel, useNodesShutdownNode, useNodesTopology, useNodesUndeployAddon, useNotificationOutputDeleteTarget, useNotificationOutputDiscoverTargets, useNotificationOutputGetTarget, useNotificationOutputListTargetKinds, useNotificationOutputListTargets, useNotificationOutputProbeTargetConfig, useNotificationOutputSend, useNotificationOutputSetTargetEnabled, useNotificationOutputTestTarget, useNotificationOutputUpsertTarget, useNotificationRulesActivateAlarmProfile, useNotificationRulesCancelSnooze, useNotificationRulesCreateAlarmProfile, useNotificationRulesCreateRule, useNotificationRulesCreateSequence, useNotificationRulesCreateSnooze, useNotificationRulesDeleteAlarmProfile, useNotificationRulesDeleteRule, useNotificationRulesDeleteSequence, useNotificationRulesGetAlarmConfig, useNotificationRulesGetAlarmSensors, useNotificationRulesGetClipRetentionAsks, useNotificationRulesGetConditionCatalog, useNotificationRulesGetHistory, useNotificationRulesGetRule, useNotificationRulesGetRuleLastRuns, useNotificationRulesGetSequence, useNotificationRulesGetTemplateCatalog, useNotificationRulesListDeviceMutes, useNotificationRulesListRules, useNotificationRulesListSequences, useNotificationRulesListSnoozes, useNotificationRulesPreviewStateSummary, useNotificationRulesPreviewTemplate, useNotificationRulesRenameAlarmProfile, useNotificationRulesResolveArtifactUrl, useNotificationRulesSetAlarmConfig, useNotificationRulesSetDeviceMuted, useNotificationRulesSetRuleEnabled, useNotificationRulesTestRule, useNotificationRulesUpdateRule, useNotificationRulesUpdateSequence, useNotifierCancel, useNotifierGetStatus, useNotifierSend, useNumericSensorGetStatus, useOptimisticSlice, useOptionalSystem, useOptionalWidgetRegistry, useOsdGetStatus, useOsdManagerClearSlotBinding, useOsdManagerCopyDeviceConfiguration, useOsdManagerDeleteTemplate, useOsdManagerGetConditionSupport, useOsdManagerGetDeviceOsd, useOsdManagerGetSourceCatalog, useOsdManagerListTemplates, useOsdManagerPreviewSlot, useOsdManagerRenderDevice, useOsdManagerSetSlotBinding, useOsdManagerUpsertTemplate, useOsdSetOverlay, usePTZ, usePetFeederCallPet, usePetFeederCancelFeed, usePetFeederFeed, usePetFeederGetStatus, usePetFeederMarkFoodReplenished, usePetFeederPlaySound, usePetFeederResetDesiccant, usePetFeederSetChildLock, usePetFeederSetFeedSound, usePetFeederSetIndicatorLight, usePetFeederSetVolume, usePickerSiteZones, usePipelineAnalyticsApplyDeviceSettingsPatch, usePipelineAnalyticsCancelRelocateMedia, usePipelineAnalyticsCancelStorageMigrationMove, usePipelineAnalyticsClearTrackRelation, usePipelineAnalyticsClearTracks, usePipelineAnalyticsCompleteRetrainTrack, usePipelineAnalyticsCountRelocatableMedia, usePipelineAnalyticsCountUnstampedEventMedia, usePipelineAnalyticsDeleteDeviceEvents, usePipelineAnalyticsDeleteTracks, usePipelineAnalyticsDeselectRetrainFrame, usePipelineAnalyticsGetActiveTracks, usePipelineAnalyticsGetAudioEvents, usePipelineAnalyticsGetDeviceLiveContribution, usePipelineAnalyticsGetDeviceSettingsContribution, usePipelineAnalyticsGetEventDensity, usePipelineAnalyticsGetEventDensityBatch, usePipelineAnalyticsGetEventMedia, usePipelineAnalyticsGetEventMediaFootprintByKind, usePipelineAnalyticsGetEventStoreFootprint, usePipelineAnalyticsGetKeyEvents, usePipelineAnalyticsGetKeyEventsBatch, usePipelineAnalyticsGetMediaReclaimStatus, usePipelineAnalyticsGetMotionEvents, usePipelineAnalyticsGetObjectEmbeddingRebuildStatus, usePipelineAnalyticsGetObjectEvents, usePipelineAnalyticsGetRetrainExportUrl, usePipelineAnalyticsGetRetrainFrameImage, usePipelineAnalyticsGetSensorEvents, usePipelineAnalyticsGetStorageMigrationMoveStatus, usePipelineAnalyticsGetTrack, usePipelineAnalyticsGetTrackMedia, usePipelineAnalyticsGetTrainingExportSummary, usePipelineAnalyticsGetTrainingExportUrl, usePipelineAnalyticsListArchivedDebugNotes, usePipelineAnalyticsListBirthDecisions, usePipelineAnalyticsListEventKinds, usePipelineAnalyticsListEventKindsBatch, usePipelineAnalyticsListEventMedia, usePipelineAnalyticsListOpsLog, usePipelineAnalyticsListRecentTracks, usePipelineAnalyticsListRelocateMediaJobs, usePipelineAnalyticsListRetrainAnnotations, usePipelineAnalyticsListRetrainFrames, usePipelineAnalyticsListRetrainStaging, usePipelineAnalyticsListTrackMedia, usePipelineAnalyticsListTrackRelations, usePipelineAnalyticsListTracks, usePipelineAnalyticsOwnersWithMedia, usePipelineAnalyticsPauseForStorageMigration, usePipelineAnalyticsProposeRetrainAnnotations, usePipelineAnalyticsPruneEvents, usePipelineAnalyticsPruneEventsBefore, usePipelineAnalyticsPruneTracksBefore, usePipelineAnalyticsReadLongTermSeries, usePipelineAnalyticsRebuildObjectEmbeddings, usePipelineAnalyticsReclaimDebugMedia, usePipelineAnalyticsReconcileFromDisk, usePipelineAnalyticsRefreshStorageLocationsForMigration, usePipelineAnalyticsRelocateMedia, usePipelineAnalyticsRestageRetrainTrack, usePipelineAnalyticsResumeForStorageMigration, usePipelineAnalyticsSaveRetrainAnnotations, usePipelineAnalyticsSearchObjectEvents, usePipelineAnalyticsSelectRetrainFrames, usePipelineAnalyticsSetTrackFlags, usePipelineAnalyticsSetTrackPurity, usePipelineAnalyticsSetTrackRelation, usePipelineAnalyticsStartStorageMigrationMove, usePipelineAnalyticsWipeAllAnalytics, usePipelineAnalyticsWipeObjectEmbeddings, usePipelineExecutorCacheFrameInPool, usePipelineExecutorClearDeviceOverrides, usePipelineExecutorClearModelBoundDeviceOverrides, usePipelineExecutorDeleteModel, usePipelineExecutorDeleteTemplate, usePipelineExecutorDownloadModel, usePipelineExecutorGetAddonModels, usePipelineExecutorGetAudioCapabilities, usePipelineExecutorGetAvailableEngines, usePipelineExecutorGetCapabilities, usePipelineExecutorGetDefaultSteps, usePipelineExecutorGetDetectionConfigSchema, usePipelineExecutorGetEffectiveTuning, usePipelineExecutorGetEngineProvisioning, usePipelineExecutorGetGlobalPipelineConfig, usePipelineExecutorGetGlobalSteps, usePipelineExecutorGetInferenceDeviceHealth, usePipelineExecutorGetOrchestratorConfigSchema, usePipelineExecutorGetReferenceAudio, usePipelineExecutorGetReferenceAudioFiles, usePipelineExecutorGetReferenceImage, usePipelineExecutorGetSchema, usePipelineExecutorGetSelectedEngine, usePipelineExecutorGetVideoPipelineSteps, usePipelineExecutorInferCached, usePipelineExecutorKillEngine, usePipelineExecutorListLoadedEngines, usePipelineExecutorListReferenceImages, usePipelineExecutorListTemplates, usePipelineExecutorRearmInferenceDevice, usePipelineExecutorRunAudioTest, usePipelineExecutorRunPipeline, usePipelineExecutorRunPipelineBatch, usePipelineExecutorSaveTemplate, usePipelineExecutorSetVideoPipelineSteps, usePipelineExecutorSpinEngine, usePipelineExecutorUncacheFrame, usePipelineExecutorUpdateTemplate, usePipelineExecutorValidatePipeline, usePipelineOrchestratorApplyAutoTune, usePipelineOrchestratorApplyDeviceSettingsPatch, usePipelineOrchestratorAssignAudio, usePipelineOrchestratorAssignPipeline, usePipelineOrchestratorDeleteTemplate, usePipelineOrchestratorGetAgentLoad, usePipelineOrchestratorGetAgentSettings, usePipelineOrchestratorGetAudioAssignment, usePipelineOrchestratorGetAudioAssignments, usePipelineOrchestratorGetAudioNodeLoad, usePipelineOrchestratorGetCameraMetrics, usePipelineOrchestratorGetCameraSettings, usePipelineOrchestratorGetCameraStatus, usePipelineOrchestratorGetCameraStatuses, usePipelineOrchestratorGetCameraStepOverrides, usePipelineOrchestratorGetCameraSwitches, usePipelineOrchestratorGetCapabilityBindings, usePipelineOrchestratorGetClusterModelChoice, usePipelineOrchestratorGetDeviceLiveContribution, usePipelineOrchestratorGetDeviceSettingsContribution, usePipelineOrchestratorGetEffectiveShares, usePipelineOrchestratorGetGlobalMetrics, usePipelineOrchestratorGetIngestOwner, usePipelineOrchestratorGetNodeInferenceDevices, usePipelineOrchestratorGetPipelineAssignment, usePipelineOrchestratorGetPipelineAssignments, usePipelineOrchestratorGetPipelineDevicePin, usePipelineOrchestratorGetPlacementStats, usePipelineOrchestratorGetReconcileFromDiskStatus, usePipelineOrchestratorListAgentSettings, usePipelineOrchestratorListTemplates, usePipelineOrchestratorPauseForStorageMigration, usePipelineOrchestratorPlanAutoTune, usePipelineOrchestratorRebalance, usePipelineOrchestratorReconcileFromDisk, usePipelineOrchestratorRemoveAgentSettings, usePipelineOrchestratorRequestOccupancyLook, usePipelineOrchestratorResetNodePipelineDefaults, usePipelineOrchestratorResolvePipeline, usePipelineOrchestratorResumeForStorageMigration, usePipelineOrchestratorSaveTemplate, usePipelineOrchestratorSetAgentCapabilities, usePipelineOrchestratorSetAgentDecodeLimits, usePipelineOrchestratorSetAgentInferenceDevices, usePipelineOrchestratorSetAgentMaxCameras, usePipelineOrchestratorSetAgentReachableHost, usePipelineOrchestratorSetCameraPipelineForAgent, usePipelineOrchestratorSetCameraSensors, usePipelineOrchestratorSetCameraStepOverride, usePipelineOrchestratorSetCameraStepSettings, usePipelineOrchestratorSetCameraStepToggle, usePipelineOrchestratorSetCameraSwitch, usePipelineOrchestratorSetCapabilityBinding, usePipelineOrchestratorSetLoadBalancingShares, usePipelineOrchestratorSetPipelineDevicePin, usePipelineOrchestratorSetShareSource, usePipelineOrchestratorSuggestShares, usePipelineOrchestratorUnassignAudio, usePipelineOrchestratorUnassignPipeline, usePipelineOrchestratorUpdateTemplate, usePipelineRunnerAttachCamera, usePipelineRunnerDetachCamera, usePipelineRunnerGetAllCameraMetrics, usePipelineRunnerGetCameraMetrics, usePipelineRunnerGetLocalCameras, usePipelineRunnerGetLocalLoad, usePipelineRunnerGetLocalMetrics, usePipelineRunnerGetNativeCrop, usePipelineRunnerGetParkedTrackFrame, usePipelineRunnerParkTrackFrame, usePipelineRunnerReleaseParkedTrackFrames, usePipelineRunnerReportMotion, usePipelineRunnerRequestOccupancyBurst, usePipelineRunnerRunDetailSubtree, usePipelineRunnerRunStatelessStep, usePlateGalleryAssignPlate, usePlateGalleryAssignPlates, usePlateGalleryCorrectPlateText, usePlateGalleryCreateVehicle, usePlateGalleryDeletePlate, usePlateGalleryDeleteVehicle, usePlateGalleryGetPlateByTrack, usePlateGalleryGetPlateMedia, usePlateGalleryListPlates, usePlateGalleryListVehicleSamples, usePlateGalleryListVehicles, usePlateGalleryRemoveVehicleSample, usePlateGalleryRenameVehicle, usePlateGallerySearchPlates, usePlateGallerySuggestPlateClusters, usePlateGalleryUnassignPlate, usePlateGalleryUnassignPlates, usePlayerOverlayLayer, usePlayerOverlayLayers, usePlayerToolbarButton, usePlayerToolbarButtons, usePowerMeterGetStatus, usePresenceGetStatus, usePressureSensorGetStatus, usePrivacyMaskGetOptions, usePrivacyMaskGetStatus, usePrivacyMaskSetAudioEnabled, usePrivacyMaskSetMask, usePrompt, usePtzAutotrackGetSettings, usePtzAutotrackGetStatus, usePtzAutotrackSetEnabled, usePtzAutotrackSetSettings, usePtzCaptureHomeHere, usePtzContinuousMove, usePtzDeletePreset, usePtzGetHomePreset, usePtzGetHomeReturn, usePtzGetOptions, usePtzGetPosition, usePtzGetPresets, usePtzGetStatus, usePtzGoHome, usePtzGoToPreset, usePtzMove, usePtzSavePreset, usePtzSetAutofocus, usePtzSetHomePreset, usePtzSetHomeReturn, usePtzStop, useRebootReboot, useRecordedPlayback, useRecordingArchiveApplyDeviceSettingsPatch, useRecordingArchiveCancelRelocateJob, useRecordingArchiveCancelStorageMigrationMove, useRecordingArchiveDeleteFootprint, useRecordingArchiveGetAvailabilityBatch, useRecordingArchiveGetDaysWithRecordingsBatch, useRecordingArchiveGetDeviceConfig, useRecordingArchiveGetDeviceLiveContribution, useRecordingArchiveGetDeviceSettingsContribution, useRecordingArchiveGetPlacement, useRecordingArchiveGetRelocateResidue, useRecordingArchiveGetStatus, useRecordingArchiveGetStorageMigrationMoveStatus, useRecordingArchiveGetStorageUsage, useRecordingArchiveListOpsLog, useRecordingArchiveListRelocateJobs, useRecordingArchiveLocateSegment, useRecordingArchivePauseForStorageMigration, useRecordingArchivePlanStorageRebalance, useRecordingArchivePruneFootage, useRecordingArchiveReadGopBytes, useRecordingArchiveReadSegmentBytes, useRecordingArchiveReadWindowBytes, useRecordingArchiveReconcileLedgerAgainstDisk, useRecordingArchiveRefreshStorageLocationsForMigration, useRecordingArchiveRelocateFootage, useRecordingArchiveRenderClip, useRecordingArchiveRenderGif, useRecordingArchiveRescanStorage, useRecordingArchiveResumeForStorageMigration, useRecordingArchiveSetDeviceConfig, useRecordingArchiveSetDevicePlacement, useRecordingArchiveStartStorageMigrationMove, useRecordingArchiveStartStorageRebalance, useRecordingExportCancelExport, useRecordingExportCreateExport, useRecordingExportDeleteExport, useRecordingExportGetDownloadUrl, useRecordingExportGetExport, useRecordingExportListExports, useRecordingExportReadExportBytes, useRecordingGetAvailability, useRecordingGetDaysWithRecordings, useRecordingGetPlayback, useRecordingGetPlaybackOptions, useRecordingListSources, useRecordingOnboardGetOptions, useRecordingOnboardGetStatus, useRecordingOnboardSetSettings, useRecordingSignalGetStatus, useRemoteComponent, useRoleDisplayDefaults, useSceneMonitorCaptureReference, useSceneMonitorCreateScene, useSceneMonitorDeleteReference, useSceneMonitorDeleteScene, useSceneMonitorGetStatus, useSceneMonitorListScenes, useSceneMonitorListScenesBatch, useSceneMonitorRecheckNow, useSceneMonitorResetScene, useSceneMonitorUpdateScene, useScriptRunnerGetStatus, useScriptRunnerRun, useScriptRunnerStop, useScrubController, useServerManagementApplyServerUpdate, useServerManagementCheckServerUpdate, useServerManagementGetServerPackageStatus, useServerManagementRestartServer, useServerManagementRollbackServerUpdate, useSettingsStoreAggregate, useSettingsStoreCount, useSettingsStoreDeclareCollection, useSettingsStoreDelete, useSettingsStoreDeleteWhere, useSettingsStoreGet, useSettingsStoreHistogram, useSettingsStoreInsert, useSettingsStoreInsertMany, useSettingsStoreIsEmpty, useSettingsStoreQuery, useSettingsStoreSet, useSettingsStoreUpdate, useSettingsStoreUpdateWhere, useSettingsStoreUpsert, useSmokeGetStatus, useSnapshotApplyDeviceSettingsPatch, useSnapshotGetDebugState, useSnapshotGetDeviceLiveContribution, useSnapshotGetDeviceSettingsContribution, useSnapshotGetSnapshot, useSnapshotGetSnapshotLinks, useSnapshotGetSnapshotOverview, useSnapshotGetStatus, useSnapshotInvalidateCache, useStationaryOverlay, useStorageAbortUpload, useStorageBeginDownload, useStorageBeginUpload, useStorageDelete, useStorageDeleteLocation, useStorageEndDownload, useStorageExists, useStorageFinalizeUpload, useStorageGetAvailableSpace, useStorageList, useStorageListDrainProgress, useStorageListLocationDeclarations, useStorageListLocations, useStorageListProviders, useStorageMigrationCancel, useStorageMigrationCleanupCancel, useStorageMigrationCleanupStart, useStorageMigrationCleanupStatus, useStorageMigrationDrain, useStorageMigrationHistory, useStorageMigrationMovers, useStorageMigrationPlan, useStorageMigrationResidue, useStorageMigrationStart, useStorageMigrationStatus, useStorageRead, useStorageReadChunk, useStorageResolve, useStorageTestConfig, useStorageTestLocation, useStorageUpsertLocation, useStorageWrite, useStorageWriteChunk, useStoredGroupBy, useStreamBrokerAcquireEgressTranscode, useStreamBrokerApplyDeviceSettingsPatch, useStreamBrokerAssignProfile, useStreamBrokerFetchEventMedia, useStreamBrokerForgetDeviceHardware, useStreamBrokerGetAllRtspEntries, useStreamBrokerGetBrokerStats, useStreamBrokerGetDeviceAudioMute, useStreamBrokerGetDeviceLiveContribution, useStreamBrokerGetDeviceSettingsContribution, useStreamBrokerGetPreBufferInfo, useStreamBrokerGetRtspEntry, useStreamBrokerGetRtspPort, useStreamBrokerGetStreamUrl, useStreamBrokerGetStreamWithCodec, useStreamBrokerIsRtspEnabled, useStreamBrokerKillClient, useStreamBrokerListAllCameraStreams, useStreamBrokerListAllProfileSlots, useStreamBrokerListClients, useStreamBrokerProbeStream, useStreamBrokerProduceEventMedia, useStreamBrokerPublishCameraStream, useStreamBrokerPullAudioChunks, useStreamBrokerPullFrameHandles, useStreamBrokerRegenerateRtspToken, useStreamBrokerReleaseEgressTranscode, useStreamBrokerReleaseStreamWithCodec, useStreamBrokerRenderPreBufferClip, useStreamBrokerReportStreamSignal, useStreamBrokerRestartProfile, useStreamBrokerRetractCameraStream, useStreamBrokerSetDeviceAudioMute, useStreamBrokerSetPreBufferDuration, useStreamBrokerSetRtspEnabled, useStreamBrokerSubscribeAudioChunks, useStreamBrokerSubscribeFrames, useStreamBrokerUnassignProfile, useStreamBrokerUnsubscribeAudioChunks, useStreamBrokerUnsubscribeFrames, useStreamCatalogGetCatalog, useStreamParamsGetConfigSchema, useStreamParamsGetOptions, useStreamParamsGetStatus, useStreamParamsSetProfile, useStreamSignalsListSignals, useSwitchGetStatus, useSwitchSetState, useSystem, useSystemDetectSiteLocation, useSystemFeatureFlags, useSystemForceRetentionCleanup, useSystemGetFailureContributions, useSystemGetLoadContributions, useSystemGetLoggingSettings, useSystemGetRequestCensus, useSystemGetRetentionConfig, useSystemGetSiteLocation, useSystemHealth, useSystemInfo, useSystemMutation, useSystemNetworkAddresses, useSystemQuery, useSystemSetLoggingSettings, useSystemSetRetentionConfig, useSystemSetSiteLocation, useTamperGetStatus, useTemperatureSensorGetStatus, useTerminalSessionAdoptLegacyMonitor, useTerminalSessionClose, useTerminalSessionCreateInstance, useTerminalSessionDeleteInstance, useTerminalSessionListInstances, useTerminalSessionListLegacyCameras, useTerminalSessionListProfiles, useTerminalSessionListSessions, useTerminalSessionOpenSession, useTerminalSessionPullOutput, useTerminalSessionResize, useTerminalSessionSetInstanceEnabled, useTerminalSessionUpdateInstance, useTerminalSessionWriteInput, useThemeMode, useToastOnToast, useTurnProviderGetTurnServers, useUpdateGetStatus, useUpdateInstallUpdate, useUrlQueryParam, useUserManagementConfirmTotp, useUserManagementCreateApiKey, useUserManagementCreateScopedToken, useUserManagementCreateUser, useUserManagementDeleteUser, useUserManagementDisableTotp, useUserManagementGetTotpStatus, useUserManagementListApiKeys, useUserManagementListOauthSessions, useUserManagementListScopedTokens, useUserManagementListUsers, useUserManagementOauthExchangeCode, useUserManagementOauthIssueCode, useUserManagementOauthRefresh, useUserManagementOauthVerifyAccessToken, useUserManagementResetPassword, useUserManagementRevokeApiKey, useUserManagementRevokeOauthSession, useUserManagementRevokeScopedToken, useUserManagementSetUserScopes, useUserManagementSetupTotp, useUserManagementUpdateUser, useUserManagementValidateApiKey, useUserManagementValidateCredentials, useUserManagementValidateScopedToken, useUserManagementVerifyTotp, useVacuumControlGetStatus, useVacuumControlLocate, useVacuumControlPause, useVacuumControlReturnToBase, useVacuumControlSetFanSpeed, useVacuumControlStart, useVacuumControlStop, useValveClose, useValveGetStatus, useValveOpen, useValveSetPosition, useValveStop, useVibrationGetStatus, useVideoclipsDialClipStream, useVideoclipsGetClipPlayback, useVideoclipsGetPlaybackOptions, useVideoclipsListClips, useVideoclipsListSources, useVideoclipsOfferClipBytes, useVideoclipsReadClipBytes, useVodPlayback, useWaterHeaterGetStatus, useWaterHeaterSetAway, useWaterHeaterSetOperationMode, useWaterHeaterSetTargetTemp, useWeatherGetStatus, useWebrtcSessionAddIceCandidate, useWebrtcSessionApplyDownlinkProbe, useWebrtcSessionCloseSession, useWebrtcSessionCreateSession, useWebrtcSessionGetIceCandidates, useWebrtcSessionGetSessionDebug, useWebrtcSessionGetSessionState, useWebrtcSessionHandleAnswer, useWebrtcSessionHandleOffer, useWebrtcSessionHasAdaptiveBitrate, useWebrtcSessionListStreams, useWidget, useWidgetMetadata, useWidgetRegistry, useZoneAnalyticsGetCameraHistory, useZoneAnalyticsGetCurrentSnapshot, useZoneAnalyticsGetCurrentSnapshotBatch, useZoneAnalyticsGetUnzonedHistory, useZoneAnalyticsGetZoneHistory, useZoneEditing, useZoneRulesListRules, useZoneRulesSetRules, useZonesAddZone, useZonesListZones, useZonesRemoveZone, useZonesUpdateZone, vacuumStateMeta, validateScopes, valveStateMeta, variantLabel, waterHeaterPhase, waterHeaterTint, weatherConditionMeta, weatherTint, withResolvedParentDetail, writeStoredGroupBy };
|
|
61141
|
+
export { AcceleratorTabs, AddonGlobalSettingsForm, AdminLinkQuickAction, AgentStepEditor, AlarmHeroCard, AlarmInlineControl as AlarmPanelInlineControl, AppShell, ArcKnob, AudioClassificationList, AudioLevelWaveform, AudioWaveform, AutomationHeroCard, AutomationInlineControl, AutotrackSection, BTN_COMPACT, BTN_COMPACT_DANGER, BTN_COMPACT_PRIMARY, BTN_COMPACT_WARNING, BackToStepsButton, Badge, BatteryBadge, BottomSheet, Breadcrumb, BrightnessPanel, Button, ButtonControl, ButtonHeroCard, CARD_MODE_MIN_COLUMNS, CENTER, CHIP_ACTIVE, CHIP_BASE, CHIP_INACTIVE, CLASS_COLORS, COLUMN_BREAKPOINT_CLASS, COLUMN_PRIORITY, COMMIT_DEDUPE_TOLERANCE_MS, COMMIT_DEDUPE_WINDOW_MS, CONTROL_CAP_NAMES, CONTROL_FILLS, CameraStreamPlayer, Card, Checkbox, ChildSectionAccordion, ClimatePanel, CodeBlock, CollapsibleCard, ConfigFormBuilder, FormField as ConfigFormField, ConfigNotificationTargetMultiSelectFieldView, ConfigNotificationTargetSelectFieldView, ConfigSchemaField, ConfirmActionButton, ConfirmDialogProvider, ConsumablesPanel, ContainerChildrenProvider, ContainerPrimaryHero, ControlColumn, ControlHeroCard, ControlInlineControl, ControlPanel, CopyButton, CoverHeroCard, CoverInlineControl, CoverPanel, CustomFieldRenderersProvider, DEFAULT_COLOR, DEVICE_COLUMNS, DEVICE_LIST_PAGE_SIZE_KEY, DEVICE_LIST_PAGE_SIZE_OPTIONS, DEVICE_PICKER_GROUP_STORAGE_KEY, DEVICE_ROLE_META, DEVICE_TYPE_CONTROL, DEVICE_TYPE_META, DISPLAY_ICON_REGISTRY, DataTable, DataTableFilterBar, DetectionCanvas, DetectionOverlay, DetectionResultTree, DevShell, DeviceActivityPanel, DeviceBatchToolbar, DeviceCard, DeviceContextProvider, DeviceExportPanel, DeviceFilterBar, DeviceGrid, DeviceItem, DeviceList, DeviceMultiSelectField, DevicePicker, DeviceQuickDetailProvider, DeviceSelectField, DeviceSelectorPicker, DeviceStepMatrix, DevicesFailedLine, DevicesLoadingLine, DevicesWidenWarning, Dialog, DialogBody, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, DiscoveryPanel, DoorbellRecentPanel, Dropdown, DropdownContent, DropdownItem, DropdownTrigger, DummyHeroCard, DummyInline, EMPTY_DATA_TABLE_FILTER, EVENT_KIND_ICONS, EmptyState, EndpointResultsCard, EndpointTestCard, ErrorBox, EventKindGlyph, EventStream, ExtensionsPanel, FILL, FLEET_LIST_GC_TIME_MS, FLEET_LIST_QUERY_KEY, FLEET_LIST_STALE_TIME_MS, FanHeroCard, FanInlineControl, FanPanel, FilterBar, FloatingEventStream, FloatingLogStream, FloatingPanel, FormField$1 as FormField, GRID_GAP, GRID_PAIRED, GRID_QUICK_STATS, GateBadge, GateControl, GripTrack, GroupedModelSelector, HOST_WIDGETS, HUB_SESSION_RUN_MS, HlsVideo, HoverZoomImage, HubSessionTestCard, HumidifierHeroCard, HumidifierInlineControl, INPUT_COMPACT, INPUT_SHELL, IconAction, IconButton, IconPicker, ImageHeroCard, ImageInlineControl, ImageSelector, InferenceConfigSelector, Input, KebabMenu, KeyValueList, LIST_ROW, Label, LawnMowerHeroCard, LawnMowerInlineControl, LayeredSettingsForm, LightHeroCard, LightInlineControl, LockHeroCard, LockInlineControl, LockPanel, LogStream, LoginForm, MODE_COLOR, MaskShapeCanvas, MediaPlayerHeroCard, MediaPlayerInlineControl, MediaPlayerPanel, MobileDrawer, ModelPicker, MotionZonesSettings, NAVIGATION_DRIVE_INTERVAL_MS, NatResultCard, NavigationPanel, NetworkLinkBadge, NodeMultiSelectField, NodePicker, NodeSelectField, NotificationTargetSelectField, NotificationTargetsField, OPTION_SELECT_SEARCH_MIN_OPTIONS, OfflineBadge, OptionSelect, PHASE_CONFIG, PICKER_CHIP_LIMIT, PICKER_DEFAULT_GROUP_BY, PICKER_GROUP_BY_MODES, PICKER_GROUP_COLLAPSE_AT, PICKER_NONE_KEY, PICKER_NOUN_PLURAL, PICKER_NO_FILTERS, PICKER_PAGE_SIZE, PICKER_SEARCH_DEBOUNCE_MS, PICKER_WINDOW, PRIORITY, PTZOverlay, PageHeader, PhaseIcon, PipelineBuilder, PipelineRuntimeSelector, PipelineStep, PlaceholderChipField, PlayerOverlaysProvider, Popover, PopoverContent, PopoverRowAction, PopoverTrigger, PrimaryChildPicker, PrivacyMaskSettings, ProviderBadge, PtzPanel, QrCode, RECONNECT_POLICY, RECORDED_PLAYBACK_MODES, RIGHT, ROI_AREA_WARN_FRACTION, ROLE_DESCRIPTOR, RadialGauge, RecordedPlaybackProvider, RecordingPanel, ResponseLog, RoleDisplayDefaultsFromServer, RoleDisplayDefaultsProvider, RootModelSourceControl, RootSuppliedModelNote, RunReport, SCENE_CAPTURE_VARIANTS, SECTION_BODY, SECTION_CARD, SECTION_HEADER, SETTING_ROW, SETTING_ROW_LABEL, SETTING_ROW_STACK_BREAKPOINT, SETTING_ROW_VALUE, SETTING_ROW_VALUE_TEXT, SNAPSHOT_MEDIA_PATH, SPLIT_PANEL_OUTER, SPLIT_PANEL_SIDE, STACK_GAP, STATE_COLOR, STEP_DOCK_WIDTH_PX, SceneMonitorEditor, ScopePicker, ScriptHeroCard, ScriptInlineControl, ScrollArea, SectionCard, SegmentedChoice, Select, SelectedChip, SemanticBadge, SensorHeroCard, SensorInlineControl, SensorValueAtom, Separator, SettingRow, Sidebar, SidebarItem, Skeleton, SlideToggle, SnapshotButton, SortHeaderButton, StatCard, StateValuesStream, StatusBadge, StepDetailDock, StepInspectorPanel, StepModelList, StepModelRow, StepTimings, Stepper, StreamBrokerSelector, StreamDebugOverlay, StreamPanel, Switch, SwitchHeroCard, SwitchInlineControl, SwitchPanel, SystemProvider, TABLE_SCROLL_MAX_H, TEXT_FIELD_LABEL, TEXT_HINT, TEXT_METRIC, TEXT_SECTION_LABEL, TEXT_VALUE, TIMEZONES, Tabs, TabsContent, TabsList, TabsTrigger, TapToggle, ThemeProvider, ThermostatHeroCard, ThermostatInlineControl, TimezoneSelector, Tooltip, TooltipContent, TooltipTrigger, UnitPicker, VacuumHeroCard, VacuumInlineControl, ValueReadout, ValveHeroCard, ValveInlineControl, VersionBadge, VodPlaybackProvider, WaterHeaterHeroCard, WaterHeaterInlineControl, WeatherHeroCard, WeatherInlineControl, WidgetMetricCard, WidgetPanel, WidgetRegistryProvider, WidgetSlot, ZoneEditingProvider, MicOff as a, acceleratorLabel, acceleratorShortLabel, agentColumnKey, allDeviceTypeFilterOptions, applyFleetQueryDefaults, applyPickerFilters, ariaSortForColumn, badgeFor, bindsToModel, buildPeerConnectionConfig, buildStepTreeFromSchema, EyeOff as c, catalogHasDraft, childEntityId, childListName, chipOverflow, classifyAddressScope, classifyCapability, classifySessionVerdict, clearPickerGroup, cn, columnsForContext, compareSrflxMappings, containerChildToRef, countableDevices, coverHighlight, coverageLine, createSharedContext, createTheme, cursorFractionFor, darkColors, dataTableFacets, defaultOfField, defaultTheme, deriveDeviceKind, deriveWebrtcDebugStats, describeDeviceSelector, deviceIntegrationResolver, deviceListStateOf, deviceMatchesFilter, deviceOptionLabel, deviceRoleMeta, deviceRoleMetaOf, deviceTypeLabel, deviceTypeMeta, deviceTypeMetaOf, devicesToOptions, dockBox, draftFromQuery, emptyDevicesWidens, emptySessionRun, ensureMfHostInit, eventKindLabel, filterDataTableRows, filterDeviceOptions, filterOptions as filterOptionSelectOptions, filterPickerDevices, finalizeSessionRun, findTimezone, flattenPickerGrouping, flattenPickerRows, fleetViewOf, formatControlDateTime, formatLastSeen, formatNumeric, formatSettingValue, freezeVerdict, fuzzyMatch, getClassColor, getPhaseVisual, groupAgentColumns, groupChildrenByLayout, groupPickerDevices, groupPickerDevicesBy, hardwareLabel, hubOrigin, hubPath, hubUrl, hubWsUrl, humanDuration, humidifierTint, Mic as i, initialScrubState, insertAtSelection, isAbsentProvider, isDataTableFilterActive, isFieldVisible, isGroupExpanded, isValueField, Camera as l, lawnMowerActivityMeta, lightColors, loadRemoteBundle, makeScrubBridge, metadataEntries, metadataString, mirror, modelRowsAreFoldable, mountAddonPage, mountPath, Square as n, nextGridPosition, nextReconnectAction, nextSort, nextSortDirection, nextTableSort, normalizeForSearch, ImageOff as o, offListSelections, openTopLayer, optionSearchText as optionSelectSearchText, orphanDeviceLabel, overrideEntityIdFromLink, pageRows, parentDetailOf, parseIceCandidate, parsePickerGroupBy, parseRecordedServerMessage, partitionSelected as partitionOptionSelectSelected, partitionSuggested, pickerFacetFilterShown, pickerFacetKey, pickerFacetOptions, pickerFiltersActive, pickerGroupKey, pickerHiddenSelectedCount, pickerLocationKey, pickerQueryTokens, pickerRowFacts, pickerSearchText, pickerZoneFilterSuspended, pinnedStreamChoices, providerIcons, RotateCcw as r, readStoredGroupBy, reduceSessionRun, resetHubMountForTests, resetPickerFilters, resolveContainerPrimary, resolveControlAlign, resolveDeviceControl, resolveDeviceIntegration, resolveDisplayIcon, resolveEffectiveDefaultModel, resolveEffectiveStepModel, resolveEventKindIcon, resolveSearchable as resolveOptionSelectSearchable, resolveParentNames, resolvePrimaryChild, resolveSelectedDevices, resolveSensorDisplay, resolveStepDefaultModel, resolveTableLayout, roiTooLarge, rootSourceState, routerBasename, Grid2x2 as s, sameLocationSuggestions, scrubReducer, searchSteps, selectPickerGroup, selectedDeviceOptions, serializeRecordedCommand, settingsModelIdFor, shouldCommit, shouldEmit, shouldShowAddNewFooter, shouldShowUseQueryRow, shouldUseSingleNode, showsNoCamerasHint, sortRows, sortRowsByColumn, statusIcons, statusLine, stepFieldDomId, stepHasModelForFormat, stepLocalFields, stepModelOptions, stripParentNamePrefix, summarizeHubCandidates, Trash2 as t, tabForSelector, tankAlert, themeToCss, toStationaryOverlayBox, toggleDataTableFacet, togglePickerDevice, togglePickerKey, trpc, typeLabel, createLucideIcon as u, useAccessoriesGetStatus, useAccessoriesSetChildHidden, useAddonPagesListPages, useAddonSettingsGetDeviceSettings, useAddonSettingsGetGlobalSettings, useAddonSettingsGetIntegrationSettings, useAddonSettingsUpdateDeviceSettings, useAddonSettingsUpdateGlobalSettings, useAddonWidgetsListWidgets, useAddonsApplyAutoUpdateToAll, useAddonsCancelJob, useAddonsCustom, useAddonsForceRefresh, useAddonsGetAddonAutoUpdate, useAddonsGetAutoUpdateSettings, useAddonsGetJob, useAddonsGetLastRestart, useAddonsGetLogs, useAddonsGetVersions, useAddonsInstallFromWorkspace, useAddonsInstallPackage, useAddonsIsWorkspaceAvailable, useAddonsList, useAddonsListCapabilityProviders, useAddonsListFrameworkPackages, useAddonsListJobs, useAddonsListPackages, useAddonsListUpdates, useAddonsListWorkspacePackages, useAddonsOnAddonLogs, useAddonsReloadPackages, useAddonsRestartAddon, useAddonsRestartServer, useAddonsRetryLoad, useAddonsRollbackPackage, useAddonsSearchAvailable, useAddonsSetAddonAutoUpdate, useAddonsSetAutoUpdateSettings, useAddonsSetCapabilityProviderEnabled, useAddonsStartJob, useAddonsUninstallPackage, useAddonsUpdatePackage, useAirQualitySensorGetStatus, useAlarmPanelArm, useAlarmPanelDisarm, useAlarmPanelGetStatus, useAlarmPanelTrigger, useAlert, useAlertsDismiss, useAlertsEmit, useAlertsGetUnreadCount, useAlertsList, useAlertsMarkAllRead, useAlertsMarkRead, useAlertsUpdate, useAllWidgets, useAmbientLightSensorGetStatus, useAudioAnalysisApplyDeviceSettingsPatch, useAudioAnalysisGetDeviceLiveContribution, useAudioAnalysisGetDeviceSettingsContribution, useAudioAnalysisResolveDeviceSettings, useAudioAnalyzerAnalyseChunk, useAudioAnalyzerAttachDevice, useAudioAnalyzerClassify, useAudioAnalyzerDetachDevice, useAudioAnalyzerDispose, useAudioAnalyzerIsReady, useAudioAnalyzerReprobeAudioEngine, useAudioCodecCanHandle, useAudioCodecCloseSession, useAudioCodecCreateDecodeSession, useAudioCodecCreateEncodeSession, useAudioCodecFlushEncode, useAudioCodecListActiveSessions, useAudioCodecListSupportedCodecs, useAudioCodecPullEncoded, useAudioCodecPullPcm, useAudioCodecPushEncodedFrame, useAudioCodecPushPcm, useAudioMetricsGetCurrentSnapshot, useAudioMetricsGetHistory, useAutomationControlDisable, useAutomationControlEnable, useAutomationControlGetStatus, useAutomationControlTrigger, useBackupCancel, useBackupDelete, useBackupDeleteSchedule, useBackupGetEntries, useBackupList, useBackupListArchives, useBackupListDestinations, useBackupListLocations, useBackupListRuns, useBackupListSchedules, useBackupPreviewSchedule, useBackupRestore, useBackupTrigger, useBackupUpsertDestinationPolicy, useBackupUpsertSchedule, useBatteryGetStatus, useBatteryWakeForStream, useBinaryGetStatus, useBrightnessGetStatus, useBrightnessSetBrightness, useBrokerAdd, useBrokerGet, useBrokerGetBrokerConfig, useBrokerGetSettings, useBrokerGetSettingsSchema, useBrokerGetState, useBrokerGetStatus, useBrokerList, useBrokerListProviders, useBrokerPublish, useBrokerRemove, useBrokerSetSettings, useBrokerSubscribe, useBrokerTestConnection, useBrokerTestSettings, useBrokerUnsubscribe, useButtonPress, useCalendarsGetPreferences, useCalendarsListCalendars, useCalendarsListEvents, useCalendarsSetCalendarPreference, useCameraCredentialsGetCredentials, useCameraCredentialsGetStatus, useCameraGridLayoutApplyDeviceSettingsPatch, useCameraGridLayoutGetDeviceLiveContribution, useCameraGridLayoutGetDeviceSettingsContribution, useCameraGridLayoutGetLayout, useCameraGridLayoutSaveLayout, useCameraPipelineConfigApplyDeviceSettingsPatch, useCameraPipelineConfigGetDeviceLiveContribution, useCameraPipelineConfigGetDeviceSettingsContribution, useCameraStreamsGetBrokerStreams, useCameraStreamsGetCameraStreams, useCameraStreamsGetProfileRtspEntries, useCameraStreamsGetRtspEntries, useCameraStreamsPickStream, useCapabilityPresence, useCarbonMonoxideGetStatus, useClimateControlGetStatus, useClimateControlSetFanMode, useClimateControlSetMode, useClimateControlSetPreset, useClimateControlSetSwingHorizontal, useClimateControlSetSwingVertical, useClimateControlSetTarget, useClimateControlSetTargetHumidity, useClimateControlSetTargetRange, useClusterNodes, useClusterTopology, useColorGetStatus, useColorSetColor, useConfirm, useConnectionTestDescribeTest, useConnectionTestTestSettings, useConnectivityGetStatus, useConsumablesGetStatus, useConsumablesReset, useContactGetStatus, useContainerChildren, useControlGetStatus, useControlSetValue, useCoreBlocksCompile, useCoreBlocksCreate, useCoreBlocksCreateComposition, useCoreBlocksDelete, useCoreBlocksGet, useCoreBlocksGetBlockSettings, useCoreBlocksGetComposition, useCoreBlocksGetCustomization, useCoreBlocksGetTypeDefs, useCoreBlocksList, useCoreBlocksListComposableCaps, useCoreBlocksListCompositions, useCoreBlocksRestart, useCoreBlocksSetEnabled, useCoreBlocksUpdate, useCoreBlocksUpdateBlockSettings, useCoreBlocksUpdateComposition, useCoreBlocksValidateComposition, useCoverClose, useCoverGetStatus, useCoverOpen, useCoverSetPosition, useCoverSetTiltPosition, useCoverStop, useCustomFieldRenderer, useDataTableFilter, useDayNightGetOptions, useDayNightGetStatus, useDayNightSetSettings, useDebouncedString, useDecoderCreateSession, useDecoderDestroySession, useDecoderGetFrame, useDecoderGetInfo, useDecoderGetShmStats, useDecoderGetStats, useDecoderListActiveSessions, useDecoderOpenStream, useDecoderPullFrames, useDecoderPullHandles, useDecoderPushPacket, useDecoderReprobeHwaccel, useDecoderSupportsCodec, useDecoderUpdateConfig, useDetectionPipelineApplyDeviceSettingsPatch, useDetectionPipelineGetDeviceLiveContribution, useDetectionPipelineGetDeviceSettingsContribution, useDevShell, useDevice, useDeviceAdminLink, useDeviceAdminLinkGetAdminLink, useDeviceAdoptionAdopt, useDeviceAdoptionGetCandidate, useDeviceAdoptionGetStatus, useDeviceAdoptionListCandidateFilters, useDeviceAdoptionListCandidates, useDeviceAdoptionRefresh, useDeviceAdoptionRelease, useDeviceAdoptionResync, useDeviceAutotrack, useDeviceBattery, useDeviceCapSlice, useDeviceCapability, useDeviceDetections, useDeviceDiscoveryAdoptDevice, useDeviceDiscoveryGetStatus, useDeviceDiscoveryListDiscovered, useDeviceDiscoveryRefreshDiscovery, useDeviceDiscoveryReleaseDevice, useDeviceExportApplyDeviceSettingsPatch, useDeviceExportExposeDevice, useDeviceExportGetDeviceLiveContribution, useDeviceExportGetDeviceSettingsContribution, useDeviceExportGetStatus, useDeviceExportListExposedDevices, useDeviceExportListSupportedDeviceKinds, useDeviceExportUnexposeDevice, useDeviceExtensionListCandidates, useDeviceExtensionListSlots, useDeviceExtensionListSources, useDeviceExtensionSetSlot, useDeviceId, useDeviceListPageSize, useDeviceManagerAddLocation, useDeviceManagerAdoptDevice, useDeviceManagerAdoptionAdopt, useDeviceManagerAdoptionCancelJob, useDeviceManagerAdoptionListCandidateFilters, useDeviceManagerAdoptionListCandidates, useDeviceManagerAdoptionListJobs, useDeviceManagerAdoptionRefresh, useDeviceManagerAdoptionRelease, useDeviceManagerAdoptionResync, useDeviceManagerAdoptionStartJob, useDeviceManagerAllocateDeviceId, useDeviceManagerApplyInitialMeta, useDeviceManagerCreateDevice, useDeviceManagerDisable, useDeviceManagerDiscoverAllProviders, useDeviceManagerDiscoverDevices, useDeviceManagerDiscoverProvider, useDeviceManagerDiscoveryProviders, useDeviceManagerEnable, useDeviceManagerGetAllBindings, useDeviceManagerGetBindings, useDeviceManagerGetBindingsBatch, useDeviceManagerGetChildren, useDeviceManagerGetChildrenBatch, useDeviceManagerGetConfigSchema, useDeviceManagerGetCreationSchema, useDeviceManagerGetDevice, useDeviceManagerGetDeviceAggregate, useDeviceManagerGetDeviceLiveInfoAggregate, useDeviceManagerGetDeviceSettingsAggregate, useDeviceManagerGetDeviceStatusAggregate, useDeviceManagerGetDeviceStatusAggregateBatch, useDeviceManagerGetLinkedDevices, useDeviceManagerGetLinkedDevicesBatch, useDeviceManagerGetRoleDisplayDefaults, useDeviceManagerGetSettingsSchema, useDeviceManagerGetStreamProfileMap, useDeviceManagerGetStreamSources, useDeviceManagerGetWireableFields, useDeviceManagerGetWrapperActivation, useDeviceManagerListAll, useDeviceManagerListBindableCapsForDeviceType, useDeviceManagerListDeviceIdsByCaps, useDeviceManagerListLocationDescriptions, useDeviceManagerListLocationIcons, useDeviceManagerListLocations, useDeviceManagerListPersistedByAddon, useDeviceManagerListSiteZones, useDeviceManagerListWrappersForCap, useDeviceManagerLoadConfig, useDeviceManagerLoadMeta, useDeviceManagerLoadRuntimeState, useDeviceManagerMigrateDevice, useDeviceManagerPersistConfig, useDeviceManagerProbeStreams, useDeviceManagerProviderCreationType, useDeviceManagerProviderDiscoveryParamsSchema, useDeviceManagerRegisterDevice, useDeviceManagerRemove, useDeviceManagerRemoveByIntegration, useDeviceManagerRemoveDevice, useDeviceManagerRemoveLocation, useDeviceManagerRemoveSiteZone, useDeviceManagerRenameLocation, useDeviceManagerRenameSiteZone, useDeviceManagerRunDeviceAction, useDeviceManagerSetChildLayout, useDeviceManagerSetDisabled, useDeviceManagerSetDisplay, useDeviceManagerSetIntegrationId, useDeviceManagerSetLinkDeviceId, useDeviceManagerSetLocation, useDeviceManagerSetLocationDescription, useDeviceManagerSetLocationIcon, useDeviceManagerSetLocationZone, useDeviceManagerSetMetadata, useDeviceManagerSetName, useDeviceManagerSetPrimaryChildEntityId, useDeviceManagerSetRole, useDeviceManagerSetRoleDisplayDefaults, useDeviceManagerSetSiteZone, useDeviceManagerSetStreamProfileMap, useDeviceManagerSetType, useDeviceManagerSetWrapperActive, useDeviceManagerTestCreationField, useDeviceManagerTestField, useDeviceManagerUpdateConfig, useDeviceManagerUpdateDeviceField, useDeviceManagerUpdateDeviceFieldsBatch, useDeviceNetworkLink, useDeviceOpsGetConfigEntries, useDeviceOpsGetRawState, useDeviceOpsGetSettingsSchema, useDeviceOpsGetStreamSources, useDeviceOpsRemoveDevice, useDeviceOpsRunAction, useDeviceOpsSetConfig, useDeviceProviderAdoptDiscoveredDevice, useDeviceProviderCreateDevice, useDeviceProviderDiscoverDevices, useDeviceProviderGetChildCreationSchema, useDeviceProviderGetDevices, useDeviceProviderGetDiscoveryParamsSchema, useDeviceProviderGetManualCreationType, useDeviceProviderGetStatus, useDeviceProviderReloadDevice, useDeviceProviderStart, useDeviceProviderStop, useDeviceProviderSupportsDiscovery, useDeviceProviderSupportsManualCreation, useDeviceProviderTestCreationField, useDeviceProxy, useDeviceQuickDetailOpen, useDeviceSnapshot, useDeviceSnapshotImage, useDeviceState, useDeviceStateClaimFields, useDeviceStateGetAllSnapshots, useDeviceStateGetCapSlice, useDeviceStateGetNativeCapSlice, useDeviceStateGetSnapshot, useDeviceStateListClaims, useDeviceStatePatchOwnedFields, useDeviceStateReleaseClaim, useDeviceStateSetCapSlice, useDeviceStateSlice, useDeviceStatusGetStatus, useDeviceWebrtc, useDevices, useDoorbellEvents, useDoorbellGetStatus, useEnumSensorGetStatus, useEventEmitterGetStatus, useEventInvalidation, useEventStreamLatest, useEventStreamMap, useFaceGalleryAssignFace, useFaceGalleryAssignFaces, useFaceGalleryAuditIdentitySamples, useFaceGalleryCreateIdentity, useFaceGalleryDeleteFace, useFaceGalleryDeleteIdentity, useFaceGalleryGetFaceByTrack, useFaceGalleryGetFaceMedia, useFaceGalleryListIdentities, useFaceGalleryListIdentitySamples, useFaceGalleryListRecentFaces, useFaceGalleryRemoveSample, useFaceGalleryRenameIdentity, useFaceGallerySuggestFaceClusters, useFaceGalleryUnassignFace, useFaceGalleryUnassignFaces, useFanControlGetStatus, useFanControlSetDirection, useFanControlSetOscillating, useFanControlSetPercentage, useFanControlSetPreset, useFeatureProbeGetStatus, useFloodGetStatus, useGasGetStatus, useHumidifierGetStatus, useHumidifierSetMode, useHumidifierSetOn, useHumidifierSetTargetHumidity, useHumiditySensorGetStatus, useImageGetStatus, useImageSettingsGetOptions, useImageSettingsGetStatus, useImageSettingsSetSettings, useIntegrationsCreate, useIntegrationsDelete, useIntegrationsGet, useIntegrationsGetAvailableTypes, useIntegrationsGetByAddonId, useIntegrationsGetSettings, useIntegrationsList, useIntegrationsSetSettings, useIntegrationsTestConnection, useIntegrationsUpdate, useIntercomEndTalkSession, useIntercomGetStatus, useIntercomHandleAnswer, useIntercomPushTalkAudio, useIntercomStartSession, useIntercomStartTalkSession, useIntercomStopSession, useIsMidWidth, useIsMobile, useLawnMowerControlDock, useLawnMowerControlGetStatus, useLawnMowerControlPause, useLawnMowerControlStartMowing, useLiveBuffer, useLiveEvent, useLlmCancel, useLlmDeleteModel, useLlmDeleteProfile, useLlmGenerate, useLlmGenerateVision, useLlmGetDefaults, useLlmGetRuntimeStatus, useLlmGetUsage, useLlmInstallModel, useLlmListModelCatalog, useLlmListModels, useLlmListNodeModels, useLlmListProfileKinds, useLlmListProfiles, useLlmListRuntimeNodes, useLlmResolveModelRef, useLlmSetDefault, useLlmStartRuntime, useLlmStopRuntime, useLlmTestProfile, useLlmUpsertProfile, useLocalNetworkAddCustomAddress, useLocalNetworkDownloadCa, useLocalNetworkGetAddresses, useLocalNetworkGetAllowedAddresses, useLocalNetworkGetConnectionEndpoints, useLocalNetworkGetHubAddresses, useLocalNetworkGetNotificationEndpoint, useLocalNetworkGetPreferred, useLocalNetworkGetTlsStatus, useLocalNetworkGetViewerEndpoints, useLocalNetworkList, useLocalNetworkRegenerateCertificate, useLocalNetworkRemoveCustomAddress, useLocalNetworkResetAllowlistToBestMatch, useLocalNetworkRevertToGeneratedCertificate, useLocalNetworkSetAddressRole, useLocalNetworkSetAllowedAddresses, useLocalNetworkSetNotificationEndpoint, useLocalNetworkSetViewerEndpoints, useLocalNetworkUploadCertificate, useLockControlGetStatus, useLockControlLock, useLockControlOpen, useLockControlUnlock, useMediaPlayerGetStatus, useMediaPlayerNext, useMediaPlayerPause, useMediaPlayerPlay, useMediaPlayerPlayMedia, useMediaPlayerPrevious, useMediaPlayerSeek, useMediaPlayerSelectSource, useMediaPlayerSetMute, useMediaPlayerSetRepeat, useMediaPlayerSetShuffle, useMediaPlayerSetVolume, useMediaPlayerStop, useMeshNetworkGetStatus, useMeshNetworkJoin, useMeshNetworkLeave, useMeshNetworkListPeers, useMeshNetworkLogout, useMeshNetworkStartLogin, useMeshNetworkTestConnection, useMetricsProviderCollectSnapshot, useMetricsProviderGetAddonStats, useMetricsProviderGetCached, useMetricsProviderGetCpuTemperature, useMetricsProviderGetCurrent, useMetricsProviderGetDiskSpace, useMetricsProviderGetGpuInfo, useMetricsProviderGetLoadSeries, useMetricsProviderGetProcessStats, useMetricsProviderListAddonInstances, useMetricsProviderListNodeProcesses, useMotionDetectionAnalyze, useMotionDetectionApplyDeviceSettingsPatch, useMotionDetectionGetDeviceLiveContribution, useMotionDetectionGetDeviceSettingsContribution, useMotionDetectionRemoveCamera, useMotionDetectionReset, useMotionGetStatus, useMotionIsDetected, useMotionTriggerGetStatus, useMotionTriggerSetMotionTrigger, useMotionZonesGetOptions, useMotionZonesGetStatus, useMotionZonesSetZone, useMqttBrokerAddBroker, useMqttBrokerGetBrokerConfig, useMqttBrokerGetStatus, useMqttBrokerListBrokers, useMqttBrokerRemoveBroker, useMqttBrokerStartEmbeddedBroker, useMqttBrokerStopEmbeddedBroker, useMqttBrokerTestConnection, useNativeObjectDetectionGetOptions, useNativeObjectDetectionGetStatus, useNativeObjectDetectionSetEnabled, useNativeObjectDetectionSetSettings, useNavigation, useNavigationGetFeatures, useNavigationGetStatus, useNavigationGoToPoint, useNavigationListActions, useNavigationMove, useNavigationPlaySound, useNavigationRunAction, useNavigationSetLightLevel, useNavigationSetLightMode, useNavigationSetLightOn, useNavigationStop, useNetworkAccessGetEndpoint, useNetworkAccessGetStatus, useNetworkAccessListEndpoints, useNetworkAccessStart, useNetworkAccessStop, useNetworkLinkGetStatus, useNetworkQualityGetAllStats, useNetworkQualityGetDeviceStats, useNetworkQualityReportClientStats, useNodesClusterAddonStatus, useNodesDeployAddon, useNodesDirectory, useNodesExecuteQuery, useNodesGetCapUsageGraph, useNodesGetNodeAddons, useNodesRenameNode, useNodesRestartAddon, useNodesRestartNode, useNodesRestartProcess, useNodesSetProcessLogLevel, useNodesShutdownNode, useNodesTopology, useNodesUndeployAddon, useNotificationOutputDeleteTarget, useNotificationOutputDiscoverTargets, useNotificationOutputGetTarget, useNotificationOutputListTargetKinds, useNotificationOutputListTargets, useNotificationOutputProbeTargetConfig, useNotificationOutputSend, useNotificationOutputSetTargetEnabled, useNotificationOutputTestTarget, useNotificationOutputUpsertTarget, useNotificationRulesActivateAlarmProfile, useNotificationRulesCancelSnooze, useNotificationRulesCreateAlarmProfile, useNotificationRulesCreateRule, useNotificationRulesCreateSequence, useNotificationRulesCreateSnooze, useNotificationRulesDeleteAlarmProfile, useNotificationRulesDeleteRule, useNotificationRulesDeleteSequence, useNotificationRulesGetAlarmConfig, useNotificationRulesGetAlarmSensors, useNotificationRulesGetClipRetentionAsks, useNotificationRulesGetConditionCatalog, useNotificationRulesGetHistory, useNotificationRulesGetRule, useNotificationRulesGetRuleLastRuns, useNotificationRulesGetSequence, useNotificationRulesGetTemplateCatalog, useNotificationRulesListDeviceMutes, useNotificationRulesListRules, useNotificationRulesListSequences, useNotificationRulesListSnoozes, useNotificationRulesPreviewStateSummary, useNotificationRulesPreviewTemplate, useNotificationRulesRenameAlarmProfile, useNotificationRulesResolveArtifactUrl, useNotificationRulesSetAlarmConfig, useNotificationRulesSetDeviceMuted, useNotificationRulesSetRuleEnabled, useNotificationRulesTestRule, useNotificationRulesUpdateRule, useNotificationRulesUpdateSequence, useNotifierCancel, useNotifierGetStatus, useNotifierSend, useNumericSensorGetStatus, useOptimisticSlice, useOptionalSystem, useOptionalWidgetRegistry, useOsdGetStatus, useOsdManagerClearSlotBinding, useOsdManagerCopyDeviceConfiguration, useOsdManagerDeleteTemplate, useOsdManagerGetConditionSupport, useOsdManagerGetDeviceOsd, useOsdManagerGetSourceCatalog, useOsdManagerListTemplates, useOsdManagerPreviewSlot, useOsdManagerRenderDevice, useOsdManagerSetSlotBinding, useOsdManagerUpsertTemplate, useOsdSetOverlay, usePTZ, usePetFeederCallPet, usePetFeederCancelFeed, usePetFeederFeed, usePetFeederGetStatus, usePetFeederMarkFoodReplenished, usePetFeederPlaySound, usePetFeederResetDesiccant, usePetFeederSetChildLock, usePetFeederSetFeedSound, usePetFeederSetIndicatorLight, usePetFeederSetVolume, usePickerSiteZones, usePipelineAnalyticsApplyDeviceSettingsPatch, usePipelineAnalyticsCancelRelocateMedia, usePipelineAnalyticsCancelStorageMigrationMove, usePipelineAnalyticsClearTrackRelation, usePipelineAnalyticsClearTracks, usePipelineAnalyticsCompleteRetrainTrack, usePipelineAnalyticsCountRelocatableMedia, usePipelineAnalyticsCountUnstampedEventMedia, usePipelineAnalyticsDeleteDeviceEvents, usePipelineAnalyticsDeleteTracks, usePipelineAnalyticsDeselectRetrainFrame, usePipelineAnalyticsGetActiveTracks, usePipelineAnalyticsGetAudioEvents, usePipelineAnalyticsGetDeviceLiveContribution, usePipelineAnalyticsGetDeviceSettingsContribution, usePipelineAnalyticsGetEventDensity, usePipelineAnalyticsGetEventDensityBatch, usePipelineAnalyticsGetEventMedia, usePipelineAnalyticsGetEventMediaFootprintByKind, usePipelineAnalyticsGetEventStoreFootprint, usePipelineAnalyticsGetKeyEvents, usePipelineAnalyticsGetKeyEventsBatch, usePipelineAnalyticsGetMediaReclaimStatus, usePipelineAnalyticsGetMotionEvents, usePipelineAnalyticsGetObjectEmbeddingRebuildStatus, usePipelineAnalyticsGetObjectEvents, usePipelineAnalyticsGetRetrainExportUrl, usePipelineAnalyticsGetRetrainFrameImage, usePipelineAnalyticsGetSensorEvents, usePipelineAnalyticsGetStorageMigrationMoveStatus, usePipelineAnalyticsGetTrack, usePipelineAnalyticsGetTrackMedia, usePipelineAnalyticsGetTrainingExportSummary, usePipelineAnalyticsGetTrainingExportUrl, usePipelineAnalyticsListArchivedDebugNotes, usePipelineAnalyticsListBirthDecisions, usePipelineAnalyticsListEventKinds, usePipelineAnalyticsListEventKindsBatch, usePipelineAnalyticsListEventMedia, usePipelineAnalyticsListOpsLog, usePipelineAnalyticsListRecentTracks, usePipelineAnalyticsListRelocateMediaJobs, usePipelineAnalyticsListRetrainAnnotations, usePipelineAnalyticsListRetrainFrames, usePipelineAnalyticsListRetrainStaging, usePipelineAnalyticsListTrackMedia, usePipelineAnalyticsListTrackRelations, usePipelineAnalyticsListTracks, usePipelineAnalyticsOwnersWithMedia, usePipelineAnalyticsPauseForStorageMigration, usePipelineAnalyticsProposeRetrainAnnotations, usePipelineAnalyticsPruneEvents, usePipelineAnalyticsPruneEventsBefore, usePipelineAnalyticsPruneTracksBefore, usePipelineAnalyticsReadLongTermSeries, usePipelineAnalyticsRebuildObjectEmbeddings, usePipelineAnalyticsReclaimDebugMedia, usePipelineAnalyticsReconcileFromDisk, usePipelineAnalyticsRefreshStorageLocationsForMigration, usePipelineAnalyticsRelocateMedia, usePipelineAnalyticsRestageRetrainTrack, usePipelineAnalyticsResumeForStorageMigration, usePipelineAnalyticsSaveRetrainAnnotations, usePipelineAnalyticsSearchObjectEvents, usePipelineAnalyticsSelectRetrainFrames, usePipelineAnalyticsSetTrackFlags, usePipelineAnalyticsSetTrackPurity, usePipelineAnalyticsSetTrackRelation, usePipelineAnalyticsStartStorageMigrationMove, usePipelineAnalyticsWipeAllAnalytics, usePipelineAnalyticsWipeObjectEmbeddings, usePipelineExecutorCacheFrameInPool, usePipelineExecutorClearDeviceOverrides, usePipelineExecutorClearModelBoundDeviceOverrides, usePipelineExecutorDeleteModel, usePipelineExecutorDownloadModel, usePipelineExecutorGetAddonModels, usePipelineExecutorGetAudioCapabilities, usePipelineExecutorGetAvailableEngines, usePipelineExecutorGetCapabilities, usePipelineExecutorGetDefaultSteps, usePipelineExecutorGetDetectionConfigSchema, usePipelineExecutorGetEffectiveTuning, usePipelineExecutorGetEngineProvisioning, usePipelineExecutorGetGlobalPipelineConfig, usePipelineExecutorGetGlobalSteps, usePipelineExecutorGetInferenceDeviceHealth, usePipelineExecutorGetOrchestratorConfigSchema, usePipelineExecutorGetReferenceAudio, usePipelineExecutorGetReferenceAudioFiles, usePipelineExecutorGetReferenceImage, usePipelineExecutorGetSchema, usePipelineExecutorGetSelectedEngine, usePipelineExecutorGetVideoPipelineSteps, usePipelineExecutorInferCached, usePipelineExecutorKillEngine, usePipelineExecutorListLoadedEngines, usePipelineExecutorListReferenceImages, usePipelineExecutorRearmInferenceDevice, usePipelineExecutorRunAudioTest, usePipelineExecutorRunPipeline, usePipelineExecutorRunPipelineBatch, usePipelineExecutorSetVideoPipelineSteps, usePipelineExecutorSpinEngine, usePipelineExecutorUncacheFrame, usePipelineExecutorValidatePipeline, usePipelineOrchestratorApplyAutoTune, usePipelineOrchestratorApplyDeviceSettingsPatch, usePipelineOrchestratorAssignAudio, usePipelineOrchestratorAssignPipeline, usePipelineOrchestratorGetAgentLoad, usePipelineOrchestratorGetAgentSettings, usePipelineOrchestratorGetAudioAssignment, usePipelineOrchestratorGetAudioAssignments, usePipelineOrchestratorGetAudioNodeLoad, usePipelineOrchestratorGetCameraMetrics, usePipelineOrchestratorGetCameraSettings, usePipelineOrchestratorGetCameraStatus, usePipelineOrchestratorGetCameraStatuses, usePipelineOrchestratorGetCameraStepOverrides, usePipelineOrchestratorGetCameraSwitches, usePipelineOrchestratorGetCapabilityBindings, usePipelineOrchestratorGetClusterModelChoice, usePipelineOrchestratorGetDeviceLiveContribution, usePipelineOrchestratorGetDeviceSettingsContribution, usePipelineOrchestratorGetEffectiveShares, usePipelineOrchestratorGetGlobalMetrics, usePipelineOrchestratorGetIngestOwner, usePipelineOrchestratorGetNodeInferenceDevices, usePipelineOrchestratorGetPipelineAssignment, usePipelineOrchestratorGetPipelineAssignments, usePipelineOrchestratorGetPipelineDevicePin, usePipelineOrchestratorGetPlacementStats, usePipelineOrchestratorGetReconcileFromDiskStatus, usePipelineOrchestratorListAgentSettings, usePipelineOrchestratorPauseForStorageMigration, usePipelineOrchestratorPlanAutoTune, usePipelineOrchestratorRebalance, usePipelineOrchestratorReconcileFromDisk, usePipelineOrchestratorRemoveAgentSettings, usePipelineOrchestratorRequestOccupancyLook, usePipelineOrchestratorResetNodePipelineDefaults, usePipelineOrchestratorResolvePipeline, usePipelineOrchestratorResumeForStorageMigration, usePipelineOrchestratorSetAgentCapabilities, usePipelineOrchestratorSetAgentDecodeLimits, usePipelineOrchestratorSetAgentInferenceDevices, usePipelineOrchestratorSetAgentMaxCameras, usePipelineOrchestratorSetAgentReachableHost, usePipelineOrchestratorSetCameraPipelineForAgent, usePipelineOrchestratorSetCameraSensors, usePipelineOrchestratorSetCameraStepOverride, usePipelineOrchestratorSetCameraStepSettings, usePipelineOrchestratorSetCameraStepToggle, usePipelineOrchestratorSetCameraSwitch, usePipelineOrchestratorSetCapabilityBinding, usePipelineOrchestratorSetLoadBalancingShares, usePipelineOrchestratorSetPipelineDevicePin, usePipelineOrchestratorSetShareSource, usePipelineOrchestratorSuggestShares, usePipelineOrchestratorUnassignAudio, usePipelineOrchestratorUnassignPipeline, usePipelineRunnerAttachCamera, usePipelineRunnerDetachCamera, usePipelineRunnerGetAllCameraMetrics, usePipelineRunnerGetCameraMetrics, usePipelineRunnerGetLocalCameras, usePipelineRunnerGetLocalLoad, usePipelineRunnerGetLocalMetrics, usePipelineRunnerGetNativeCrop, usePipelineRunnerGetParkedTrackFrame, usePipelineRunnerParkTrackFrame, usePipelineRunnerReleaseParkedTrackFrames, usePipelineRunnerReportMotion, usePipelineRunnerRequestOccupancyBurst, usePipelineRunnerRunDetailSubtree, usePipelineRunnerRunStatelessStep, usePlateGalleryAssignPlate, usePlateGalleryAssignPlates, usePlateGalleryCorrectPlateText, usePlateGalleryCreateVehicle, usePlateGalleryDeletePlate, usePlateGalleryDeleteVehicle, usePlateGalleryGetPlateByTrack, usePlateGalleryGetPlateMedia, usePlateGalleryListPlates, usePlateGalleryListVehicleSamples, usePlateGalleryListVehicles, usePlateGalleryRemoveVehicleSample, usePlateGalleryRenameVehicle, usePlateGallerySearchPlates, usePlateGallerySuggestPlateClusters, usePlateGalleryUnassignPlate, usePlateGalleryUnassignPlates, usePlayerOverlayLayer, usePlayerOverlayLayers, usePlayerToolbarButton, usePlayerToolbarButtons, usePowerMeterGetStatus, usePresenceGetStatus, usePressureSensorGetStatus, usePrivacyMaskGetOptions, usePrivacyMaskGetStatus, usePrivacyMaskSetAudioEnabled, usePrivacyMaskSetMask, usePrompt, usePtzAutotrackGetSettings, usePtzAutotrackGetStatus, usePtzAutotrackSetEnabled, usePtzAutotrackSetSettings, usePtzCaptureHomeHere, usePtzContinuousMove, usePtzDeletePreset, usePtzGetHomePreset, usePtzGetHomeReturn, usePtzGetOptions, usePtzGetPosition, usePtzGetPresets, usePtzGetStatus, usePtzGoHome, usePtzGoToPreset, usePtzMove, usePtzSavePreset, usePtzSetAutofocus, usePtzSetHomePreset, usePtzSetHomeReturn, usePtzStop, useRebootReboot, useRecordedPlayback, useRecordingArchiveApplyDeviceSettingsPatch, useRecordingArchiveCancelRelocateJob, useRecordingArchiveCancelStorageMigrationMove, useRecordingArchiveDeleteFootprint, useRecordingArchiveGetAvailabilityBatch, useRecordingArchiveGetDaysWithRecordingsBatch, useRecordingArchiveGetDeviceConfig, useRecordingArchiveGetDeviceLiveContribution, useRecordingArchiveGetDeviceSettingsContribution, useRecordingArchiveGetPlacement, useRecordingArchiveGetRelocateResidue, useRecordingArchiveGetStatus, useRecordingArchiveGetStorageMigrationMoveStatus, useRecordingArchiveGetStorageUsage, useRecordingArchiveListOpsLog, useRecordingArchiveListRelocateJobs, useRecordingArchiveLocateSegment, useRecordingArchivePauseForStorageMigration, useRecordingArchivePlanStorageRebalance, useRecordingArchivePruneFootage, useRecordingArchiveReadGopBytes, useRecordingArchiveReadSegmentBytes, useRecordingArchiveReadWindowBytes, useRecordingArchiveReconcileLedgerAgainstDisk, useRecordingArchiveRefreshStorageLocationsForMigration, useRecordingArchiveRelocateFootage, useRecordingArchiveRenderClip, useRecordingArchiveRenderGif, useRecordingArchiveRescanStorage, useRecordingArchiveResumeForStorageMigration, useRecordingArchiveSetDeviceConfig, useRecordingArchiveSetDevicePlacement, useRecordingArchiveStartStorageMigrationMove, useRecordingArchiveStartStorageRebalance, useRecordingExportCancelExport, useRecordingExportCreateExport, useRecordingExportDeleteExport, useRecordingExportGetDownloadUrl, useRecordingExportGetExport, useRecordingExportListExports, useRecordingExportReadExportBytes, useRecordingGetAvailability, useRecordingGetDaysWithRecordings, useRecordingGetPlayback, useRecordingGetPlaybackOptions, useRecordingListSources, useRecordingOnboardGetOptions, useRecordingOnboardGetStatus, useRecordingOnboardSetSettings, useRecordingSignalGetStatus, useRemoteComponent, useRoleDisplayDefaults, useSceneMonitorCaptureReference, useSceneMonitorCreateScene, useSceneMonitorDeleteReference, useSceneMonitorDeleteScene, useSceneMonitorGetStatus, useSceneMonitorListScenes, useSceneMonitorListScenesBatch, useSceneMonitorRecheckNow, useSceneMonitorResetScene, useSceneMonitorUpdateScene, useScriptRunnerGetStatus, useScriptRunnerRun, useScriptRunnerStop, useScrubController, useServerManagementApplyServerUpdate, useServerManagementCheckServerUpdate, useServerManagementGetServerPackageStatus, useServerManagementRestartServer, useServerManagementRollbackServerUpdate, useSettingsStoreAggregate, useSettingsStoreCount, useSettingsStoreDeclareCollection, useSettingsStoreDelete, useSettingsStoreDeleteWhere, useSettingsStoreGet, useSettingsStoreHistogram, useSettingsStoreInsert, useSettingsStoreInsertMany, useSettingsStoreIsEmpty, useSettingsStoreQuery, useSettingsStoreSet, useSettingsStoreUpdate, useSettingsStoreUpdateWhere, useSettingsStoreUpsert, useSmokeGetStatus, useSnapshotApplyDeviceSettingsPatch, useSnapshotGetDebugState, useSnapshotGetDeviceLiveContribution, useSnapshotGetDeviceSettingsContribution, useSnapshotGetSnapshot, useSnapshotGetSnapshotLinks, useSnapshotGetSnapshotOverview, useSnapshotGetStatus, useSnapshotInvalidateCache, useStationaryOverlay, useStorageAbortUpload, useStorageBeginDownload, useStorageBeginUpload, useStorageDelete, useStorageDeleteLocation, useStorageEndDownload, useStorageExists, useStorageFinalizeUpload, useStorageGetAvailableSpace, useStorageList, useStorageListDrainProgress, useStorageListLocationDeclarations, useStorageListLocations, useStorageListProviders, useStorageMigrationCancel, useStorageMigrationCleanupCancel, useStorageMigrationCleanupStart, useStorageMigrationCleanupStatus, useStorageMigrationDrain, useStorageMigrationHistory, useStorageMigrationMovers, useStorageMigrationPlan, useStorageMigrationResidue, useStorageMigrationStart, useStorageMigrationStatus, useStorageRead, useStorageReadChunk, useStorageResolve, useStorageTestConfig, useStorageTestLocation, useStorageUpsertLocation, useStorageWrite, useStorageWriteChunk, useStoredGroupBy, useStreamBrokerAcquireEgressTranscode, useStreamBrokerApplyDeviceSettingsPatch, useStreamBrokerAssignProfile, useStreamBrokerFetchEventMedia, useStreamBrokerForgetDeviceHardware, useStreamBrokerGetAllRtspEntries, useStreamBrokerGetBrokerStats, useStreamBrokerGetDeviceAudioMute, useStreamBrokerGetDeviceLiveContribution, useStreamBrokerGetDeviceSettingsContribution, useStreamBrokerGetPreBufferInfo, useStreamBrokerGetRtspEntry, useStreamBrokerGetRtspPort, useStreamBrokerGetStreamUrl, useStreamBrokerGetStreamWithCodec, useStreamBrokerIsRtspEnabled, useStreamBrokerKillClient, useStreamBrokerListAllCameraStreams, useStreamBrokerListAllProfileSlots, useStreamBrokerListClients, useStreamBrokerProbeStream, useStreamBrokerProduceEventMedia, useStreamBrokerPublishCameraStream, useStreamBrokerPullAudioChunks, useStreamBrokerPullFrameHandles, useStreamBrokerRegenerateRtspToken, useStreamBrokerReleaseEgressTranscode, useStreamBrokerReleaseStreamWithCodec, useStreamBrokerRenderPreBufferClip, useStreamBrokerReportStreamSignal, useStreamBrokerRestartProfile, useStreamBrokerRetractCameraStream, useStreamBrokerSetDeviceAudioMute, useStreamBrokerSetPreBufferDuration, useStreamBrokerSetRtspEnabled, useStreamBrokerSubscribeAudioChunks, useStreamBrokerSubscribeFrames, useStreamBrokerUnassignProfile, useStreamBrokerUnsubscribeAudioChunks, useStreamBrokerUnsubscribeFrames, useStreamCatalogGetCatalog, useStreamParamsGetConfigSchema, useStreamParamsGetOptions, useStreamParamsGetStatus, useStreamParamsSetProfile, useStreamSignalsListSignals, useSwitchGetStatus, useSwitchSetState, useSystem, useSystemDetectSiteLocation, useSystemFeatureFlags, useSystemForceRetentionCleanup, useSystemGetFailureContributions, useSystemGetLoadContributions, useSystemGetLoggingSettings, useSystemGetRequestCensus, useSystemGetRetentionConfig, useSystemGetSiteLocation, useSystemHealth, useSystemInfo, useSystemMutation, useSystemNetworkAddresses, useSystemQuery, useSystemSetLoggingSettings, useSystemSetRetentionConfig, useSystemSetSiteLocation, useTamperGetStatus, useTemperatureSensorGetStatus, useTerminalSessionAdoptLegacyMonitor, useTerminalSessionClose, useTerminalSessionCreateInstance, useTerminalSessionDeleteInstance, useTerminalSessionListInstances, useTerminalSessionListLegacyCameras, useTerminalSessionListProfiles, useTerminalSessionListSessions, useTerminalSessionOpenSession, useTerminalSessionPullOutput, useTerminalSessionResize, useTerminalSessionSetInstanceEnabled, useTerminalSessionUpdateInstance, useTerminalSessionWriteInput, useThemeMode, useToastOnToast, useTurnProviderGetTurnServers, useUpdateGetStatus, useUpdateInstallUpdate, useUrlQueryParam, useUserManagementConfirmTotp, useUserManagementCreateApiKey, useUserManagementCreateScopedToken, useUserManagementCreateUser, useUserManagementDeleteUser, useUserManagementDisableTotp, useUserManagementGetTotpStatus, useUserManagementListApiKeys, useUserManagementListOauthSessions, useUserManagementListScopedTokens, useUserManagementListUsers, useUserManagementOauthExchangeCode, useUserManagementOauthIssueCode, useUserManagementOauthRefresh, useUserManagementOauthVerifyAccessToken, useUserManagementResetPassword, useUserManagementRevokeApiKey, useUserManagementRevokeOauthSession, useUserManagementRevokeScopedToken, useUserManagementSetUserScopes, useUserManagementSetupTotp, useUserManagementUpdateUser, useUserManagementValidateApiKey, useUserManagementValidateCredentials, useUserManagementValidateScopedToken, useUserManagementVerifyTotp, useVacuumControlGetStatus, useVacuumControlLocate, useVacuumControlPause, useVacuumControlReturnToBase, useVacuumControlSetFanSpeed, useVacuumControlStart, useVacuumControlStop, useValveClose, useValveGetStatus, useValveOpen, useValveSetPosition, useValveStop, useVibrationGetStatus, useVideoclipsDialClipStream, useVideoclipsGetClipPlayback, useVideoclipsGetPlaybackOptions, useVideoclipsListClips, useVideoclipsListSources, useVideoclipsOfferClipBytes, useVideoclipsReadClipBytes, useVodPlayback, useWaterHeaterGetStatus, useWaterHeaterSetAway, useWaterHeaterSetOperationMode, useWaterHeaterSetTargetTemp, useWeatherGetStatus, useWebrtcSessionAddIceCandidate, useWebrtcSessionApplyDownlinkProbe, useWebrtcSessionCloseSession, useWebrtcSessionCreateSession, useWebrtcSessionGetIceCandidates, useWebrtcSessionGetSessionDebug, useWebrtcSessionGetSessionState, useWebrtcSessionHandleAnswer, useWebrtcSessionHandleOffer, useWebrtcSessionHasAdaptiveBitrate, useWebrtcSessionListStreams, useWidget, useWidgetMetadata, useWidgetRegistry, useZoneAnalyticsGetCameraHistory, useZoneAnalyticsGetCurrentSnapshot, useZoneAnalyticsGetCurrentSnapshotBatch, useZoneAnalyticsGetUnzonedHistory, useZoneAnalyticsGetZoneHistory, useZoneEditing, useZoneRulesListRules, useZoneRulesSetRules, useZonesAddZone, useZonesListZones, useZonesRemoveZone, useZonesUpdateZone, vacuumStateMeta, validateScopes, valveStateMeta, variantLabel, waterHeaterPhase, waterHeaterTint, weatherConditionMeta, weatherTint, withResolvedParentDetail, withUseRootModel, writeStoredGroupBy };
|