@camstack/ui-library 0.1.49 → 0.1.51

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/index.cjs CHANGED
@@ -1,29 +1,30 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  //#region \0rolldown/runtime.js
3
3
  var __create = Object.create;
4
- var __defProp = Object.defineProperty;
4
+ var __defProp$1 = Object.defineProperty;
5
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __getProtoOf = Object.getPrototypeOf;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
9
9
  var __copyProps = (to, from, except, desc) => {
10
10
  if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
11
  key = keys[i];
12
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ if (!__hasOwnProp$1.call(to, key) && key !== except) __defProp$1(to, key, {
13
13
  get: ((k) => from[k]).bind(null, key),
14
14
  enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
15
  });
16
16
  }
17
17
  return to;
18
18
  };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp$1(target, "default", {
20
20
  value: mod,
21
21
  enumerable: true
22
22
  }) : target, mod));
23
23
  //#endregion
24
24
  const require_theme_index = require("./theme/index.cjs");
25
25
  let react = require("react");
26
- react = __toESM(react, 1);
26
+ let react$1 = __toESM(react, 1);
27
+ react = __toESM(react);
27
28
  let react_jsx_runtime = require("react/jsx-runtime");
28
29
  react_jsx_runtime = __toESM(react_jsx_runtime, 1);
29
30
  let react_dom = require("react-dom");
@@ -38,6 +39,7 @@ let _trpc_react_query = require("@trpc/react-query");
38
39
  _trpc_react_query = __toESM(_trpc_react_query, 1);
39
40
  let _camstack_types = require("@camstack/types");
40
41
  let _camstack_sdk = require("@camstack/sdk");
42
+ let zod = require("zod");
41
43
  //#region ../../node_modules/clsx/dist/clsx.mjs
42
44
  function r(e) {
43
45
  var t, f, n = "";
@@ -3590,13 +3592,13 @@ function getPhaseVisual(phase) {
3590
3592
  * the Map is typed as `Context<unknown>`).
3591
3593
  */
3592
3594
  function createSharedContext(name, defaultValue) {
3593
- if (typeof globalThis === "undefined") return (0, react.createContext)(defaultValue);
3595
+ if (typeof globalThis === "undefined") return (0, react$1.createContext)(defaultValue);
3594
3596
  const existingMap = globalThis.__camstackSharedContexts;
3595
3597
  const map = existingMap ?? /* @__PURE__ */ new Map();
3596
3598
  if (!existingMap) globalThis.__camstackSharedContexts = map;
3597
3599
  const existing = map.get(name);
3598
3600
  if (existing) return existing;
3599
- const ctx = (0, react.createContext)(defaultValue);
3601
+ const ctx = (0, react$1.createContext)(defaultValue);
3600
3602
  map.set(name, ctx);
3601
3603
  return ctx;
3602
3604
  }
@@ -6866,7 +6868,7 @@ function getModuleCache() {
6866
6868
  }
6867
6869
  function populateShareCache() {
6868
6870
  const cache = getModuleCache();
6869
- cache.share["react"] ??= react;
6871
+ cache.share["react"] ??= react$1;
6870
6872
  cache.share["react-dom"] ??= react_dom;
6871
6873
  cache.share["react-dom/client"] ??= react_dom_client;
6872
6874
  cache.share["react/jsx-runtime"] ??= react_jsx_runtime;
@@ -6884,7 +6886,7 @@ function ensureMfHostInit() {
6884
6886
  name: "admin_ui_host",
6885
6887
  remotes: [],
6886
6888
  shared: {
6887
- "react": npmShared(() => react),
6889
+ "react": npmShared(() => react$1),
6888
6890
  "react-dom": npmShared(() => react_dom),
6889
6891
  "react-dom/client": npmShared(() => react_dom_client),
6890
6892
  "react/jsx-runtime": npmShared(() => react_jsx_runtime),
@@ -7991,6 +7993,68 @@ var PowerOff = createLucideIcon("power-off", [
7991
7993
  key: "1ooewy"
7992
7994
  }]
7993
7995
  ]);
7996
+ var QrCode$1 = createLucideIcon("qr-code", [
7997
+ ["rect", {
7998
+ width: "5",
7999
+ height: "5",
8000
+ x: "3",
8001
+ y: "3",
8002
+ rx: "1",
8003
+ key: "1tu5fj"
8004
+ }],
8005
+ ["rect", {
8006
+ width: "5",
8007
+ height: "5",
8008
+ x: "16",
8009
+ y: "3",
8010
+ rx: "1",
8011
+ key: "1v8r4q"
8012
+ }],
8013
+ ["rect", {
8014
+ width: "5",
8015
+ height: "5",
8016
+ x: "3",
8017
+ y: "16",
8018
+ rx: "1",
8019
+ key: "1x03jg"
8020
+ }],
8021
+ ["path", {
8022
+ d: "M21 16h-3a2 2 0 0 0-2 2v3",
8023
+ key: "177gqh"
8024
+ }],
8025
+ ["path", {
8026
+ d: "M21 21v.01",
8027
+ key: "ents32"
8028
+ }],
8029
+ ["path", {
8030
+ d: "M12 7v3a2 2 0 0 1-2 2H7",
8031
+ key: "8crl2c"
8032
+ }],
8033
+ ["path", {
8034
+ d: "M3 12h.01",
8035
+ key: "nlz23k"
8036
+ }],
8037
+ ["path", {
8038
+ d: "M12 3h.01",
8039
+ key: "n36tog"
8040
+ }],
8041
+ ["path", {
8042
+ d: "M12 16v.01",
8043
+ key: "133mhm"
8044
+ }],
8045
+ ["path", {
8046
+ d: "M16 12h1",
8047
+ key: "1slzba"
8048
+ }],
8049
+ ["path", {
8050
+ d: "M21 12v.01",
8051
+ key: "1lwtk9"
8052
+ }],
8053
+ ["path", {
8054
+ d: "M12 21v-1",
8055
+ key: "1880an"
8056
+ }]
8057
+ ]);
7994
8058
  var Radar = createLucideIcon("radar", [
7995
8059
  ["path", {
7996
8060
  d: "M19.07 4.93A10 10 0 0 0 6.99 3.34",
@@ -8176,6 +8240,40 @@ var Server = createLucideIcon("server", [
8176
8240
  key: "nzw8ys"
8177
8241
  }]
8178
8242
  ]);
8243
+ var Share2 = createLucideIcon("share-2", [
8244
+ ["circle", {
8245
+ cx: "18",
8246
+ cy: "5",
8247
+ r: "3",
8248
+ key: "gq8acd"
8249
+ }],
8250
+ ["circle", {
8251
+ cx: "6",
8252
+ cy: "12",
8253
+ r: "3",
8254
+ key: "w7nqdw"
8255
+ }],
8256
+ ["circle", {
8257
+ cx: "18",
8258
+ cy: "19",
8259
+ r: "3",
8260
+ key: "1xt0gg"
8261
+ }],
8262
+ ["line", {
8263
+ x1: "8.59",
8264
+ x2: "15.42",
8265
+ y1: "13.51",
8266
+ y2: "17.49",
8267
+ key: "47mynk"
8268
+ }],
8269
+ ["line", {
8270
+ x1: "15.41",
8271
+ x2: "8.59",
8272
+ y1: "6.51",
8273
+ y2: "10.49",
8274
+ key: "1n3mei"
8275
+ }]
8276
+ ]);
8179
8277
  var Shield = createLucideIcon("shield", [["path", {
8180
8278
  d: "M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",
8181
8279
  key: "oel41y"
@@ -8383,6 +8481,10 @@ var TriangleAlert = createLucideIcon("triangle-alert", [
8383
8481
  key: "p32p05"
8384
8482
  }]
8385
8483
  ]);
8484
+ var Unlink2 = createLucideIcon("unlink-2", [["path", {
8485
+ d: "M15 7h2a5 5 0 0 1 0 10h-2m-6 0H7A5 5 0 0 1 7 7h2",
8486
+ key: "1re2ne"
8487
+ }]]);
8386
8488
  var Upload = createLucideIcon("upload", [
8387
8489
  ["path", {
8388
8490
  d: "M12 3v12",
@@ -8603,7 +8705,7 @@ var buttonVariants = cva("inline-flex items-center justify-center rounded-md fon
8603
8705
  size: "sm"
8604
8706
  }
8605
8707
  });
8606
- var Button = (0, react.forwardRef)(({ className, variant, size, ...props }, ref) => {
8708
+ var Button = (0, react$1.forwardRef)(({ className, variant, size, ...props }, ref) => {
8607
8709
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8608
8710
  ref,
8609
8711
  className: cn(buttonVariants({
@@ -8636,7 +8738,7 @@ var iconButtonVariants = cva("inline-flex items-center justify-center rounded-md
8636
8738
  size: "sm"
8637
8739
  }
8638
8740
  });
8639
- var IconButton = (0, react.forwardRef)(({ className, variant, size, icon: Icon, ...props }, ref) => {
8741
+ var IconButton = (0, react$1.forwardRef)(({ className, variant, size, icon: Icon, ...props }, ref) => {
8640
8742
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8641
8743
  ref,
8642
8744
  className: cn(iconButtonVariants({
@@ -8669,7 +8771,7 @@ var badgeVariants = cva("inline-flex items-center rounded-full text-xs font-medi
8669
8771
  styleVariant: "solid"
8670
8772
  }
8671
8773
  });
8672
- var Badge = (0, react.forwardRef)(({ className, variant, style, ...props }, ref) => {
8774
+ var Badge = (0, react$1.forwardRef)(({ className, variant, style, ...props }, ref) => {
8673
8775
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8674
8776
  ref,
8675
8777
  className: cn(badgeVariants({
@@ -8689,7 +8791,7 @@ var cardVariants = cva("rounded-lg p-3", {
8689
8791
  } },
8690
8792
  defaultVariants: { variant: "bordered" }
8691
8793
  });
8692
- var Card = (0, react.forwardRef)(({ className, variant, ...props }, ref) => {
8794
+ var Card = (0, react$1.forwardRef)(({ className, variant, ...props }, ref) => {
8693
8795
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8694
8796
  ref,
8695
8797
  className: cn(cardVariants({ variant }), className),
@@ -8725,7 +8827,7 @@ function CollapsibleCard({ expanded, onExpandedChange, header, children, dimmed
8725
8827
  }
8726
8828
  //#endregion
8727
8829
  //#region src/primitives/label.tsx
8728
- var Label = (0, react.forwardRef)(({ className, ...props }, ref) => {
8830
+ var Label = (0, react$1.forwardRef)(({ className, ...props }, ref) => {
8729
8831
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
8730
8832
  ref,
8731
8833
  className: cn("text-[10px] uppercase tracking-wider text-foreground-muted font-medium", className),
@@ -8742,7 +8844,7 @@ var separatorVariants = cva("", {
8742
8844
  } },
8743
8845
  defaultVariants: { orientation: "horizontal" }
8744
8846
  });
8745
- var Separator = (0, react.forwardRef)(({ className, orientation, ...props }, ref) => {
8847
+ var Separator = (0, react$1.forwardRef)(({ className, orientation, ...props }, ref) => {
8746
8848
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8747
8849
  ref,
8748
8850
  role: "separator",
@@ -8753,7 +8855,7 @@ var Separator = (0, react.forwardRef)(({ className, orientation, ...props }, ref
8753
8855
  Separator.displayName = "Separator";
8754
8856
  //#endregion
8755
8857
  //#region src/primitives/skeleton.tsx
8756
- var Skeleton = (0, react.forwardRef)(({ className, ...props }, ref) => {
8858
+ var Skeleton = (0, react$1.forwardRef)(({ className, ...props }, ref) => {
8757
8859
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8758
8860
  ref,
8759
8861
  className: cn("animate-pulse bg-surface-hover rounded-md h-4 w-full", className),
@@ -8770,7 +8872,7 @@ var inputVariants = cva("h-7 w-full px-2.5 text-xs bg-surface border rounded-md
8770
8872
  } },
8771
8873
  defaultVariants: { state: "default" }
8772
8874
  });
8773
- var Input = (0, react.forwardRef)(({ className, state, leftSlot, rightSlot, ...props }, ref) => {
8875
+ var Input = (0, react$1.forwardRef)(({ className, state, leftSlot, rightSlot, ...props }, ref) => {
8774
8876
  if (leftSlot || rightSlot) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8775
8877
  className: "relative flex items-center w-full",
8776
8878
  children: [
@@ -8798,7 +8900,7 @@ var Input = (0, react.forwardRef)(({ className, state, leftSlot, rightSlot, ...p
8798
8900
  Input.displayName = "Input";
8799
8901
  //#endregion
8800
8902
  //#region src/primitives/select.tsx
8801
- var Select = (0, react.forwardRef)(({ className, options, ...props }, ref) => {
8903
+ var Select = (0, react$1.forwardRef)(({ className, options, ...props }, ref) => {
8802
8904
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8803
8905
  className: "relative w-full",
8804
8906
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
@@ -8818,7 +8920,7 @@ var Select = (0, react.forwardRef)(({ className, options, ...props }, ref) => {
8818
8920
  Select.displayName = "Select";
8819
8921
  //#endregion
8820
8922
  //#region src/primitives/checkbox.tsx
8821
- var Checkbox = (0, react.forwardRef)(({ className, ...props }, ref) => {
8923
+ var Checkbox = (0, react$1.forwardRef)(({ className, ...props }, ref) => {
8822
8924
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
8823
8925
  ref,
8824
8926
  type: "checkbox",
@@ -8829,7 +8931,7 @@ var Checkbox = (0, react.forwardRef)(({ className, ...props }, ref) => {
8829
8931
  Checkbox.displayName = "Checkbox";
8830
8932
  //#endregion
8831
8933
  //#region src/primitives/switch.tsx
8832
- var Switch = (0, react.forwardRef)(({ className, checked, onCheckedChange, label, ...props }, ref) => {
8934
+ var Switch = (0, react$1.forwardRef)(({ className, checked, onCheckedChange, label, ...props }, ref) => {
8833
8935
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
8834
8936
  ref,
8835
8937
  role: "switch",
@@ -8850,17 +8952,17 @@ var Switch = (0, react.forwardRef)(({ className, checked, onCheckedChange, label
8850
8952
  Switch.displayName = "Switch";
8851
8953
  //#endregion
8852
8954
  //#region src/primitives/dialog.tsx
8853
- var DialogContext = (0, react.createContext)(null);
8955
+ var DialogContext = (0, react$1.createContext)(null);
8854
8956
  function useDialogContext() {
8855
- const ctx = (0, react.useContext)(DialogContext);
8957
+ const ctx = (0, react$1.useContext)(DialogContext);
8856
8958
  if (!ctx) throw new Error("Dialog compound components must be used within <Dialog>");
8857
8959
  return ctx;
8858
8960
  }
8859
8961
  function Dialog({ children, open: controlledOpen, onOpenChange }) {
8860
- const [uncontrolledOpen, setUncontrolledOpen] = (0, react.useState)(false);
8962
+ const [uncontrolledOpen, setUncontrolledOpen] = (0, react$1.useState)(false);
8861
8963
  const open = controlledOpen ?? uncontrolledOpen;
8862
- const contentId = (0, react.useId)();
8863
- const setOpen = (0, react.useCallback)((next) => {
8964
+ const contentId = (0, react$1.useId)();
8965
+ const setOpen = (0, react$1.useCallback)((next) => {
8864
8966
  onOpenChange?.(next);
8865
8967
  if (controlledOpen === void 0) setUncontrolledOpen(next);
8866
8968
  }, [controlledOpen, onOpenChange]);
@@ -8890,11 +8992,11 @@ var contentVariants = cva("bg-background-elevated border border-border rounded-l
8890
8992
  } },
8891
8993
  defaultVariants: { width: "md" }
8892
8994
  });
8893
- var DialogContent = (0, react.forwardRef)(({ className, width, children, ...props }, ref) => {
8995
+ var DialogContent = (0, react$1.forwardRef)(({ className, width, children, ...props }, ref) => {
8894
8996
  const { open, setOpen, contentId } = useDialogContext();
8895
- const innerRef = (0, react.useRef)(null);
8997
+ const innerRef = (0, react$1.useRef)(null);
8896
8998
  const dialogRef = ref ?? innerRef;
8897
- (0, react.useEffect)(() => {
8999
+ (0, react$1.useEffect)(() => {
8898
9000
  const el = dialogRef.current;
8899
9001
  if (!el) return;
8900
9002
  if (open && !el.open) el.showModal();
@@ -8940,17 +9042,17 @@ function DialogDescription({ className, ...props }) {
8940
9042
  }
8941
9043
  //#endregion
8942
9044
  //#region src/primitives/dropdown.tsx
8943
- var DropdownContext = (0, react.createContext)(null);
9045
+ var DropdownContext = (0, react$1.createContext)(null);
8944
9046
  function useDropdownContext() {
8945
- const ctx = (0, react.useContext)(DropdownContext);
9047
+ const ctx = (0, react$1.useContext)(DropdownContext);
8946
9048
  if (!ctx) throw new Error("Dropdown compound components must be used within <Dropdown>");
8947
9049
  return ctx;
8948
9050
  }
8949
9051
  function Dropdown({ children }) {
8950
- const [open, setOpen] = (0, react.useState)(false);
8951
- const triggerId = (0, react.useId)();
8952
- const contentId = (0, react.useId)();
8953
- const triggerRef = (0, react.useRef)(null);
9052
+ const [open, setOpen] = (0, react$1.useState)(false);
9053
+ const triggerId = (0, react$1.useId)();
9054
+ const contentId = (0, react$1.useId)();
9055
+ const triggerRef = (0, react$1.useRef)(null);
8954
9056
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DropdownContext.Provider, {
8955
9057
  value: {
8956
9058
  open,
@@ -8981,9 +9083,9 @@ function DropdownTrigger({ children, ...props }) {
8981
9083
  }
8982
9084
  function DropdownContent({ className, children, align = "start", offset = 4, ...props }) {
8983
9085
  const { open, setOpen, contentId, triggerId, triggerRef } = useDropdownContext();
8984
- const ref = (0, react.useRef)(null);
8985
- const [coords, setCoords] = (0, react.useState)(null);
8986
- (0, react.useLayoutEffect)(() => {
9086
+ const ref = (0, react$1.useRef)(null);
9087
+ const [coords, setCoords] = (0, react$1.useState)(null);
9088
+ (0, react$1.useLayoutEffect)(() => {
8987
9089
  if (!open) {
8988
9090
  setCoords(null);
8989
9091
  return;
@@ -9012,7 +9114,7 @@ function DropdownContent({ className, children, align = "start", offset = 4, ...
9012
9114
  offset,
9013
9115
  triggerRef
9014
9116
  ]);
9015
- (0, react.useEffect)(() => {
9117
+ (0, react$1.useEffect)(() => {
9016
9118
  if (!open) return;
9017
9119
  const handler = (e) => {
9018
9120
  const el = ref.current;
@@ -9052,7 +9154,7 @@ function DropdownContent({ className, children, align = "start", offset = 4, ...
9052
9154
  }
9053
9155
  function DropdownItem({ className, icon: Icon, variant = "default", children, onClick, ...props }) {
9054
9156
  const { setOpen } = useDropdownContext();
9055
- const handleClick = (0, react.useCallback)((e) => {
9157
+ const handleClick = (0, react$1.useCallback)((e) => {
9056
9158
  onClick?.(e);
9057
9159
  setOpen(false);
9058
9160
  }, [onClick, setOpen]);
@@ -9067,16 +9169,16 @@ function DropdownItem({ className, icon: Icon, variant = "default", children, on
9067
9169
  }
9068
9170
  //#endregion
9069
9171
  //#region src/primitives/tooltip.tsx
9070
- var TooltipContext = (0, react.createContext)(null);
9172
+ var TooltipContext = (0, react$1.createContext)(null);
9071
9173
  function useTooltipContext() {
9072
- const ctx = (0, react.useContext)(TooltipContext);
9174
+ const ctx = (0, react$1.useContext)(TooltipContext);
9073
9175
  if (!ctx) throw new Error("Tooltip compound components must be used within <Tooltip>");
9074
9176
  return ctx;
9075
9177
  }
9076
9178
  function Tooltip({ children }) {
9077
- const [open, setOpen] = (0, react.useState)(false);
9078
- const timerRef = (0, react.useRef)(null);
9079
- const tooltipId = (0, react.useId)();
9179
+ const [open, setOpen] = (0, react$1.useState)(false);
9180
+ const timerRef = (0, react$1.useRef)(null);
9181
+ const tooltipId = (0, react$1.useId)();
9080
9182
  const show = () => {
9081
9183
  timerRef.current = setTimeout(() => setOpen(true), 300);
9082
9184
  };
@@ -9143,7 +9245,7 @@ function getServerSnapshot() {
9143
9245
  return false;
9144
9246
  }
9145
9247
  function useIsMobile() {
9146
- return (0, react.useSyncExternalStore)(subscribeQuery(MOBILE_QUERY), getSnapshot(MOBILE_QUERY), getServerSnapshot);
9248
+ return (0, react$1.useSyncExternalStore)(subscribeQuery(MOBILE_QUERY), getSnapshot(MOBILE_QUERY), getServerSnapshot);
9147
9249
  }
9148
9250
  /**
9149
9251
  * True when the viewport is in the medium (`md`) Tailwind range —
@@ -9152,12 +9254,12 @@ function useIsMobile() {
9152
9254
  * sidebar rail, narrower stat tiles).
9153
9255
  */
9154
9256
  function useIsMidWidth() {
9155
- return (0, react.useSyncExternalStore)(subscribeQuery(MID_QUERY), getSnapshot(MID_QUERY), getServerSnapshot);
9257
+ return (0, react$1.useSyncExternalStore)(subscribeQuery(MID_QUERY), getSnapshot(MID_QUERY), getServerSnapshot);
9156
9258
  }
9157
9259
  //#endregion
9158
9260
  //#region src/primitives/bottom-sheet.tsx
9159
9261
  function BottomSheet({ open, onClose, title, children, className }) {
9160
- (0, react.useEffect)(() => {
9262
+ (0, react$1.useEffect)(() => {
9161
9263
  if (!open) return;
9162
9264
  const handleKeyDown = (e) => {
9163
9265
  if (e.key === "Escape") onClose();
@@ -9202,18 +9304,18 @@ function BottomSheet({ open, onClose, title, children, className }) {
9202
9304
  }
9203
9305
  //#endregion
9204
9306
  //#region src/primitives/popover.tsx
9205
- var PopoverContext = (0, react.createContext)(null);
9307
+ var PopoverContext = (0, react$1.createContext)(null);
9206
9308
  function usePopoverContext() {
9207
- const ctx = (0, react.useContext)(PopoverContext);
9309
+ const ctx = (0, react$1.useContext)(PopoverContext);
9208
9310
  if (!ctx) throw new Error("Popover compound components must be used within <Popover>");
9209
9311
  return ctx;
9210
9312
  }
9211
9313
  function Popover({ children, open: controlledOpen, onOpenChange }) {
9212
- const [uncontrolledOpen, setUncontrolledOpen] = (0, react.useState)(false);
9314
+ const [uncontrolledOpen, setUncontrolledOpen] = (0, react$1.useState)(false);
9213
9315
  const open = controlledOpen ?? uncontrolledOpen;
9214
- const triggerId = (0, react.useId)();
9215
- const contentId = (0, react.useId)();
9216
- const setOpen = (0, react.useCallback)((next) => {
9316
+ const triggerId = (0, react$1.useId)();
9317
+ const contentId = (0, react$1.useId)();
9318
+ const setOpen = (0, react$1.useCallback)((next) => {
9217
9319
  onOpenChange?.(next);
9218
9320
  if (controlledOpen === void 0) setUncontrolledOpen(next);
9219
9321
  }, [controlledOpen, onOpenChange]);
@@ -9246,8 +9348,8 @@ function PopoverTrigger({ children, ...props }) {
9246
9348
  function PopoverContent({ className, children, ...props }) {
9247
9349
  const { open, setOpen, contentId, triggerId } = usePopoverContext();
9248
9350
  const isMobile = useIsMobile();
9249
- const ref = (0, react.useRef)(null);
9250
- (0, react.useEffect)(() => {
9351
+ const ref = (0, react$1.useRef)(null);
9352
+ (0, react$1.useEffect)(() => {
9251
9353
  if (!open || isMobile) return;
9252
9354
  const handler = (e) => {
9253
9355
  const el = ref.current;
@@ -9287,16 +9389,16 @@ function PopoverContent({ className, children, ...props }) {
9287
9389
  }
9288
9390
  //#endregion
9289
9391
  //#region src/primitives/tabs.tsx
9290
- var TabsContext = (0, react.createContext)(null);
9392
+ var TabsContext = (0, react$1.createContext)(null);
9291
9393
  function useTabsContext() {
9292
- const ctx = (0, react.useContext)(TabsContext);
9394
+ const ctx = (0, react$1.useContext)(TabsContext);
9293
9395
  if (!ctx) throw new Error("Tabs compound components must be used within <Tabs>");
9294
9396
  return ctx;
9295
9397
  }
9296
9398
  function Tabs({ value: controlledValue, onValueChange, defaultValue = "", className, ...props }) {
9297
- const [uncontrolledValue, setUncontrolledValue] = (0, react.useState)(defaultValue);
9399
+ const [uncontrolledValue, setUncontrolledValue] = (0, react$1.useState)(defaultValue);
9298
9400
  const value = controlledValue ?? uncontrolledValue;
9299
- const setValue = (0, react.useCallback)((next) => {
9401
+ const setValue = (0, react$1.useCallback)((next) => {
9300
9402
  onValueChange?.(next);
9301
9403
  if (controlledValue === void 0) setUncontrolledValue(next);
9302
9404
  }, [controlledValue, onValueChange]);
@@ -9344,7 +9446,7 @@ function TabsContent({ value, className, ...props }) {
9344
9446
  }
9345
9447
  //#endregion
9346
9448
  //#region src/primitives/scroll-area.tsx
9347
- var ScrollArea = (0, react.forwardRef)(({ className, ...props }, ref) => {
9449
+ var ScrollArea = (0, react$1.forwardRef)(({ className, ...props }, ref) => {
9348
9450
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9349
9451
  ref,
9350
9452
  className: cn("overflow-auto [&::-webkit-scrollbar]:w-1 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:bg-surface-hover [&::-webkit-scrollbar-thumb]:rounded-full", className),
@@ -9355,23 +9457,23 @@ ScrollArea.displayName = "ScrollArea";
9355
9457
  //#endregion
9356
9458
  //#region src/primitives/floating-panel.tsx
9357
9459
  function FloatingPanel({ title, onClose, children, defaultWidth = 360, defaultHeight = 280, minWidth = 280, minHeight = 160, offsetIndex = 0, className }) {
9358
- const [pos, setPos] = (0, react.useState)({
9460
+ const [pos, setPos] = (0, react$1.useState)({
9359
9461
  x: 80 + offsetIndex * 30,
9360
9462
  y: 80 + offsetIndex * 30
9361
9463
  });
9362
- const [size, setSize] = (0, react.useState)({
9464
+ const [size, setSize] = (0, react$1.useState)({
9363
9465
  w: defaultWidth,
9364
9466
  h: defaultHeight
9365
9467
  });
9366
- const [minimized, setMinimized] = (0, react.useState)(false);
9367
- const dragging = (0, react.useRef)(false);
9368
- const resizing = (0, react.useRef)(false);
9369
- const offset = (0, react.useRef)({
9468
+ const [minimized, setMinimized] = (0, react$1.useState)(false);
9469
+ const dragging = (0, react$1.useRef)(false);
9470
+ const resizing = (0, react$1.useRef)(false);
9471
+ const offset = (0, react$1.useRef)({
9370
9472
  x: 0,
9371
9473
  y: 0
9372
9474
  });
9373
9475
  const isMobile = useIsMobile();
9374
- const onDragStart = (0, react.useCallback)((e) => {
9476
+ const onDragStart = (0, react$1.useCallback)((e) => {
9375
9477
  e.preventDefault();
9376
9478
  dragging.current = true;
9377
9479
  offset.current = {
@@ -9379,7 +9481,7 @@ function FloatingPanel({ title, onClose, children, defaultWidth = 360, defaultHe
9379
9481
  y: e.clientY - pos.y
9380
9482
  };
9381
9483
  }, [pos]);
9382
- const onResizeStart = (0, react.useCallback)((e) => {
9484
+ const onResizeStart = (0, react$1.useCallback)((e) => {
9383
9485
  e.preventDefault();
9384
9486
  e.stopPropagation();
9385
9487
  resizing.current = true;
@@ -9388,7 +9490,7 @@ function FloatingPanel({ title, onClose, children, defaultWidth = 360, defaultHe
9388
9490
  y: e.clientY
9389
9491
  };
9390
9492
  }, []);
9391
- (0, react.useEffect)(() => {
9493
+ (0, react$1.useEffect)(() => {
9392
9494
  const onMouseMove = (e) => {
9393
9495
  if (dragging.current) setPos({
9394
9496
  x: e.clientX - offset.current.x,
@@ -9493,8 +9595,8 @@ function FloatingPanel({ title, onClose, children, defaultWidth = 360, defaultHe
9493
9595
  //#endregion
9494
9596
  //#region src/primitives/mobile-drawer.tsx
9495
9597
  function MobileDrawer({ open, onClose, children, className, width = "w-64" }) {
9496
- const drawerRef = (0, react.useRef)(null);
9497
- (0, react.useEffect)(() => {
9598
+ const drawerRef = (0, react$1.useRef)(null);
9599
+ (0, react$1.useEffect)(() => {
9498
9600
  if (!open) return;
9499
9601
  const handleKeyDown = (e) => {
9500
9602
  if (e.key === "Escape") onClose();
@@ -9538,7 +9640,7 @@ function Breadcrumb({ items, className }) {
9538
9640
  children: items.map((item, i) => {
9539
9641
  const isLast = i === items.length - 1;
9540
9642
  const isClickable = !isLast && (item.onClick || item.href);
9541
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react.default.Fragment, { children: [i > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronRight, { className: "h-3 w-3 flex-shrink-0" }), isClickable ? item.onClick ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
9643
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react$1.default.Fragment, { children: [i > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronRight, { className: "h-3 w-3 flex-shrink-0" }), isClickable ? item.onClick ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
9542
9644
  type: "button",
9543
9645
  onClick: item.onClick,
9544
9646
  className: "hover:text-foreground transition-colors",
@@ -9614,7 +9716,7 @@ function DataTable({ columns, rows, rowKey, onRowClick, minWidthPx = 480, emptyM
9614
9716
  //#endregion
9615
9717
  //#region src/composites/slide-over-panel.tsx
9616
9718
  function SlideOverPanel({ open, onClose, title, subtitle, footer, children, widthClass = "w-[360px]" }) {
9617
- (0, react.useEffect)(() => {
9719
+ (0, react$1.useEffect)(() => {
9618
9720
  if (!open) return;
9619
9721
  const onEsc = (e) => {
9620
9722
  if (e.key === "Escape") onClose();
@@ -9757,7 +9859,7 @@ function modelsForStep(schema) {
9757
9859
  }));
9758
9860
  }
9759
9861
  function PipelineStep({ step, schema, allSchemas: _allSchemas, depth: _depth = 0, onChange, onDelete: _onDelete, readOnly = false, toggleMode = "simple", overrideState = null, onOverrideChange, inheritedEnabled, hideModelAndSettings = false }) {
9760
- const [expanded, setExpanded] = (0, react.useState)(false);
9862
+ const [expanded, setExpanded] = (0, react$1.useState)(false);
9761
9863
  const models = modelsForStep(schema);
9762
9864
  if (models.length > 0 && !models.some((m) => m.id === step.modelId) && !readOnly) {
9763
9865
  const fallback = (schema?.defaultModelId ? models.find((m) => m.id === schema.defaultModelId) : null) ?? models[0];
@@ -10308,7 +10410,7 @@ function DeviceModeEditor({ addon, agentDefault, agentNodeId, currentPatch, mode
10308
10410
  }
10309
10411
  function AgentStepEditor(props) {
10310
10412
  const { mode, addon, agentDefault, agentNodeId, currentPatch, onChangeAgentConfig, onChangePatch, engineFormat } = props;
10311
- const modelsForFormat = (0, react.useMemo)(() => addon.models.filter((m) => Boolean(m.formats[engineFormat])), [addon.models, engineFormat]);
10413
+ const modelsForFormat = (0, react$1.useMemo)(() => addon.models.filter((m) => Boolean(m.formats[engineFormat])), [addon.models, engineFormat]);
10312
10414
  if (mode === "agent") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AgentModeEditor, {
10313
10415
  addon,
10314
10416
  agentDefault,
@@ -10458,7 +10560,7 @@ function Row({ node, depth, agents, getCellState, onCellClick, selectedCell, tog
10458
10560
  })] });
10459
10561
  }
10460
10562
  function PipelineTreeMatrix({ tree, agents, getCellState, onCellClick, selectedCell, onToggleEnabled }) {
10461
- const rows = (0, react.useMemo)(() => flattenTree(tree), [tree]);
10563
+ const rows = (0, react$1.useMemo)(() => flattenTree(tree), [tree]);
10462
10564
  const gridTemplate = `minmax(320px, 1fr) repeat(${agents.length}, minmax(160px, 220px))`;
10463
10565
  const showToggle = onToggleEnabled !== void 0 && agents.length === 1;
10464
10566
  const onlyAgent = agents[0]?.agentNodeId;
@@ -10564,7 +10666,7 @@ function SystemProvider({ system, children }) {
10564
10666
  * relies on the system, so a clear error beats a silent null.
10565
10667
  */
10566
10668
  function useSystem() {
10567
- const sys = (0, react.useContext)(SystemContext);
10669
+ const sys = (0, react$1.useContext)(SystemContext);
10568
10670
  if (!sys) throw new Error("useSystem(): no <SystemProvider> in tree");
10569
10671
  return sys;
10570
10672
  }
@@ -10574,7 +10676,7 @@ function useSystem() {
10574
10676
  * (boot-time splash screens etc.).
10575
10677
  */
10576
10678
  function useOptionalSystem() {
10577
- return (0, react.useContext)(SystemContext);
10679
+ return (0, react$1.useContext)(SystemContext);
10578
10680
  }
10579
10681
  //#endregion
10580
10682
  //#region src/hooks/use-live-event.ts
@@ -10590,15 +10692,15 @@ function useOptionalSystem() {
10590
10692
  */
10591
10693
  function useLiveEvent(category, cb) {
10592
10694
  const system = useSystem();
10593
- const cbRef = (0, react.useRef)(cb);
10695
+ const cbRef = (0, react$1.useRef)(cb);
10594
10696
  cbRef.current = cb;
10595
- const [tick, setTick] = (0, react.useState)(system.connectionVersion);
10596
- (0, react.useEffect)(() => {
10697
+ const [tick, setTick] = (0, react$1.useState)(system.connectionVersion);
10698
+ (0, react$1.useEffect)(() => {
10597
10699
  return system.subscribeConnectionEvents((state, version) => {
10598
10700
  if (state === "connected") setTick(version);
10599
10701
  });
10600
10702
  }, [system]);
10601
- (0, react.useEffect)(() => {
10703
+ (0, react$1.useEffect)(() => {
10602
10704
  return system.subscribeEvent(category, (evt) => {
10603
10705
  cbRef.current(evt);
10604
10706
  });
@@ -10617,12 +10719,12 @@ function useLiveEvent(category, cb) {
10617
10719
  * useEventStreamMap — same but accumulates per-key payloads into a map.
10618
10720
  */
10619
10721
  function useFreshRef(value) {
10620
- const ref = (0, react.useRef)(value);
10722
+ const ref = (0, react$1.useRef)(value);
10621
10723
  ref.current = value;
10622
10724
  return ref;
10623
10725
  }
10624
10726
  function useEventStreamLatest(category, filter) {
10625
- const [data, setData] = (0, react.useState)(null);
10727
+ const [data, setData] = (0, react$1.useState)(null);
10626
10728
  const filterRef = useFreshRef(filter);
10627
10729
  useLiveEvent(category, (evt) => {
10628
10730
  const payload = evt.data;
@@ -10633,7 +10735,7 @@ function useEventStreamLatest(category, filter) {
10633
10735
  return data;
10634
10736
  }
10635
10737
  function useEventStreamMap(category, keyOf, filter) {
10636
- const [map, setMap] = (0, react.useState)(() => /* @__PURE__ */ new Map());
10738
+ const [map, setMap] = (0, react$1.useState)(() => /* @__PURE__ */ new Map());
10637
10739
  const keyOfRef = useFreshRef(keyOf);
10638
10740
  const filterRef = useFreshRef(filter);
10639
10741
  useLiveEvent(category, (evt) => {
@@ -10649,7 +10751,7 @@ function useEventStreamMap(category, keyOf, filter) {
10649
10751
  });
10650
10752
  return {
10651
10753
  map,
10652
- values: (0, react.useMemo)(() => Array.from(map.values()), [map])
10754
+ values: (0, react$1.useMemo)(() => Array.from(map.values()), [map])
10653
10755
  };
10654
10756
  }
10655
10757
  //#endregion
@@ -10669,7 +10771,7 @@ function useClusterNodes() {
10669
10771
  const { data: bootstrapTopology, isLoading } = trpc.nodes.topology.useQuery(void 0, { staleTime: 6e4 });
10670
10772
  const sourceNodes = useEventStreamLatest("cluster.topology-snapshot")?.nodes ?? bootstrapTopology;
10671
10773
  return {
10672
- nodes: (0, react.useMemo)(() => {
10774
+ nodes: (0, react$1.useMemo)(() => {
10673
10775
  const list = [];
10674
10776
  for (const n of sourceNodes ?? []) list.push({
10675
10777
  id: String(n.id ?? ""),
@@ -10803,7 +10905,7 @@ function ProviderBadge({ provider, showLabel = true, className }) {
10803
10905
  }
10804
10906
  //#endregion
10805
10907
  //#region src/composites/version-badge.tsx
10806
- var VARIANT_STYLES = {
10908
+ var VARIANT_STYLES$1 = {
10807
10909
  success: "bg-emerald-400 text-emerald-950",
10808
10910
  warning: "bg-amber-400 text-amber-950",
10809
10911
  danger: "bg-red-400 text-red-950",
@@ -10816,7 +10918,7 @@ var VARIANT_STYLES = {
10816
10918
  */
10817
10919
  function SemanticBadge({ children, variant = "neutral", mono, className }) {
10818
10920
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
10819
- className: cn("inline-flex items-center rounded-md px-2 py-0.5 text-[11px] font-bold leading-tight", mono && "font-mono", VARIANT_STYLES[variant], className),
10921
+ className: cn("inline-flex items-center rounded-md px-2 py-0.5 text-[11px] font-bold leading-tight", mono && "font-mono", VARIANT_STYLES$1[variant], className),
10820
10922
  children
10821
10923
  });
10822
10924
  }
@@ -10905,16 +11007,65 @@ function EmptyState({ icon: Icon, title, description, action, className }) {
10905
11007
  });
10906
11008
  }
10907
11009
  //#endregion
11010
+ //#region src/composites/error-box.tsx
11011
+ var VARIANT_STYLES = {
11012
+ danger: {
11013
+ box: "border-danger/40 bg-danger/10",
11014
+ icon: "text-danger",
11015
+ title: "text-danger",
11016
+ message: "text-danger"
11017
+ },
11018
+ warning: {
11019
+ box: "border-amber-500/40 bg-amber-500/10",
11020
+ icon: "text-amber-600 dark:text-amber-400",
11021
+ title: "text-amber-700 dark:text-amber-300",
11022
+ message: "text-amber-700 dark:text-amber-300"
11023
+ }
11024
+ };
11025
+ function ErrorBox({ message, title, onRetry, action, variant = "danger", className }) {
11026
+ const styles = VARIANT_STYLES[variant];
11027
+ const Icon = variant === "warning" ? TriangleAlert : CircleAlert;
11028
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11029
+ role: "alert",
11030
+ className: cn("flex items-start gap-2.5 rounded border px-3 py-2.5", styles.box, className),
11031
+ children: [
11032
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
11033
+ className: cn("h-4 w-4 mt-0.5 shrink-0", styles.icon),
11034
+ "aria-hidden": "true"
11035
+ }),
11036
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11037
+ className: "flex-1 min-w-0",
11038
+ children: [title && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
11039
+ className: cn("text-xs font-semibold", styles.title),
11040
+ children: title
11041
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
11042
+ className: cn("text-xs break-words", styles.message, title ? "mt-0.5" : ""),
11043
+ children: message
11044
+ })]
11045
+ }),
11046
+ action ?? (onRetry && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
11047
+ type: "button",
11048
+ onClick: onRetry,
11049
+ className: cn("shrink-0 inline-flex items-center gap-1 rounded px-2 py-1 text-[11px] font-medium", "border border-current/30 hover:bg-current/10 transition-colors", styles.message),
11050
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(RefreshCw, {
11051
+ className: "h-3 w-3",
11052
+ "aria-hidden": "true"
11053
+ }), "Retry"]
11054
+ }))
11055
+ ]
11056
+ });
11057
+ }
11058
+ //#endregion
10908
11059
  //#region src/composites/confirm-dialog.tsx
10909
11060
  var ConfirmContext = createSharedContext("camstack:confirm-dialog", null);
10910
11061
  function useConfirm() {
10911
- const ctx = (0, react.useContext)(ConfirmContext);
11062
+ const ctx = (0, react$1.useContext)(ConfirmContext);
10912
11063
  if (!ctx) throw new Error("useConfirm must be used within ConfirmDialogProvider");
10913
11064
  return ctx.confirm;
10914
11065
  }
10915
11066
  function ConfirmDialogProvider({ children }) {
10916
- const [dialog, setDialog] = (0, react.useState)(null);
10917
- const confirm = (0, react.useCallback)((options) => {
11067
+ const [dialog, setDialog] = (0, react$1.useState)(null);
11068
+ const confirm = (0, react$1.useCallback)((options) => {
10918
11069
  return new Promise((resolve) => {
10919
11070
  setDialog({
10920
11071
  ...options,
@@ -11026,8 +11177,8 @@ function KeyValueList({ items, className }) {
11026
11177
  //#endregion
11027
11178
  //#region src/composites/code-block.tsx
11028
11179
  function CodeBlock({ children, maxHeight = 300, className }) {
11029
- const [copied, setCopied] = (0, react.useState)(false);
11030
- const handleCopy = (0, react.useCallback)(() => {
11180
+ const [copied, setCopied] = (0, react$1.useState)(false);
11181
+ const handleCopy = (0, react$1.useCallback)(() => {
11031
11182
  navigator.clipboard.writeText(children).then(() => {
11032
11183
  setCopied(true);
11033
11184
  setTimeout(() => setCopied(false), 2e3);
@@ -11057,7 +11208,7 @@ function CodeBlock({ children, maxHeight = 300, className }) {
11057
11208
  //#region src/composites/filter-bar.tsx
11058
11209
  function FilterBar({ filters, values, onChange, className }) {
11059
11210
  const isMobile = useIsMobile();
11060
- const [sheetOpen, setSheetOpen] = (0, react.useState)(false);
11211
+ const [sheetOpen, setSheetOpen] = (0, react$1.useState)(false);
11061
11212
  const handleChange = (key, value) => {
11062
11213
  onChange({
11063
11214
  ...values,
@@ -11222,7 +11373,7 @@ function Sidebar({ logo, sections, footer, onNavigate, className }) {
11222
11373
  //#region src/composites/app-shell/app-shell.tsx
11223
11374
  function AppShell({ sidebar, header, mobileLogo, mobileActions, children, className }) {
11224
11375
  const isMobile = useIsMobile();
11225
- const [drawerOpen, setDrawerOpen] = (0, react.useState)(false);
11376
+ const [drawerOpen, setDrawerOpen] = (0, react$1.useState)(false);
11226
11377
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11227
11378
  className: cn("flex h-screen", className),
11228
11379
  children: [
@@ -11408,8 +11559,8 @@ var BINDING_CHANGED_CATEGORY = "capability.binding-changed";
11408
11559
  * when `deviceId` is null. Re-rendered when bindings change.
11409
11560
  */
11410
11561
  function useDeviceProxy(trpc, deviceId) {
11411
- const [binding, setBinding] = (0, react.useState)(null);
11412
- (0, react.useEffect)(() => {
11562
+ const [binding, setBinding] = (0, react$1.useState)(null);
11563
+ (0, react$1.useEffect)(() => {
11413
11564
  if (deviceId === null) {
11414
11565
  setBinding(null);
11415
11566
  return;
@@ -11437,7 +11588,7 @@ function useDeviceProxy(trpc, deviceId) {
11437
11588
  sub?.unsubscribe();
11438
11589
  };
11439
11590
  }, [trpc, deviceId]);
11440
- return (0, react.useMemo)(() => {
11591
+ return (0, react$1.useMemo)(() => {
11441
11592
  if (!binding) return null;
11442
11593
  return (0, _camstack_types.createDeviceProxy)(trpc, binding);
11443
11594
  }, [trpc, binding]);
@@ -11461,12 +11612,12 @@ function useDeviceProxy(trpc, deviceId) {
11461
11612
  * de-dups identical pushes).
11462
11613
  */
11463
11614
  function useDeviceStateSlice(handle) {
11464
- const subscribe = (0, react.useCallback)((notify) => {
11615
+ const subscribe = (0, react$1.useCallback)((notify) => {
11465
11616
  if (!handle) return () => void 0;
11466
11617
  return handle.subscribe(() => notify());
11467
11618
  }, [handle]);
11468
- const getSnapshot = (0, react.useCallback)(() => handle?.value, [handle]);
11469
- return (0, react.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
11619
+ const getSnapshot = (0, react$1.useCallback)(() => handle?.value, [handle]);
11620
+ return (0, react$1.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
11470
11621
  }
11471
11622
  /**
11472
11623
  * One-line combinator — collapse the common
@@ -11751,7 +11902,7 @@ function ChildSwitchToggle({ trpc, deviceId }) {
11751
11902
  cap: (d) => d.switch,
11752
11903
  slice: (d) => d.state.switch
11753
11904
  });
11754
- const [pending, setPending] = (0, react.useState)(false);
11905
+ const [pending, setPending] = (0, react$1.useState)(false);
11755
11906
  if (dev !== null && !cap) return null;
11756
11907
  const on = slice?.on === true;
11757
11908
  const knobStyle = { transform: on ? "translateX(14px)" : "translateX(2px)" };
@@ -11789,7 +11940,7 @@ function ChildMotionTriggerToggle({ trpc, deviceId, features }) {
11789
11940
  requireFeature: "motion-trigger",
11790
11941
  deviceFeatures: features
11791
11942
  });
11792
- const [pending, setPending] = (0, react.useState)(false);
11943
+ const [pending, setPending] = (0, react$1.useState)(false);
11793
11944
  if (dev !== null && !cap) return null;
11794
11945
  const on = slice?.enabled === true;
11795
11946
  const handleClick = async (e) => {
@@ -11867,7 +12018,7 @@ function SwitchToggle({ trpc, deviceId }) {
11867
12018
  cap: (d) => d.switch,
11868
12019
  slice: (d) => d.state.switch
11869
12020
  });
11870
- const [pending, setPending] = (0, react.useState)(false);
12021
+ const [pending, setPending] = (0, react$1.useState)(false);
11871
12022
  if (dev !== null && !cap) return null;
11872
12023
  const on = slice?.on === true;
11873
12024
  const knobStyle = { transform: on ? "translateX(14px)" : "translateX(2px)" };
@@ -11905,7 +12056,7 @@ function OnMotionToggle({ trpc, deviceId, features }) {
11905
12056
  requireFeature: "motion-trigger",
11906
12057
  deviceFeatures: features
11907
12058
  });
11908
- const [pending, setPending] = (0, react.useState)(false);
12059
+ const [pending, setPending] = (0, react$1.useState)(false);
11909
12060
  if (dev !== null && !cap) return null;
11910
12061
  const on = slice?.enabled === true;
11911
12062
  const handleClick = async (e) => {
@@ -11939,10 +12090,10 @@ function MoreActionsMenu({ trpc, deviceId }) {
11939
12090
  cap: (d) => d.reboot,
11940
12091
  slice: () => void 0
11941
12092
  });
11942
- const triggerRef = (0, react.useRef)(null);
11943
- const menuRef = (0, react.useRef)(null);
11944
- const [position, setPosition] = (0, react.useState)(null);
11945
- const [pending, setPending] = (0, react.useState)(false);
12093
+ const triggerRef = (0, react$1.useRef)(null);
12094
+ const menuRef = (0, react$1.useRef)(null);
12095
+ const [position, setPosition] = (0, react$1.useState)(null);
12096
+ const [pending, setPending] = (0, react$1.useState)(false);
11946
12097
  const ready = dev !== null && cap !== void 0 && cap !== null;
11947
12098
  const isOpen = position !== null;
11948
12099
  const close = () => setPosition(null);
@@ -11957,7 +12108,7 @@ function MoreActionsMenu({ trpc, deviceId }) {
11957
12108
  left
11958
12109
  });
11959
12110
  };
11960
- (0, react.useEffect)(() => {
12111
+ (0, react$1.useEffect)(() => {
11961
12112
  if (!isOpen) return;
11962
12113
  const onMouseDown = (e) => {
11963
12114
  const trg = triggerRef.current;
@@ -12095,10 +12246,10 @@ function buildResolved(rawFeatures, binding) {
12095
12246
  return out;
12096
12247
  }
12097
12248
  function useDeviceFeatures(trpc, deviceId, rawFeatures) {
12098
- const [binding, setBinding] = (0, react.useState)(null);
12099
- const [errored, setErrored] = (0, react.useState)(false);
12100
- const [loading, setLoading] = (0, react.useState)(true);
12101
- (0, react.useEffect)(() => {
12249
+ const [binding, setBinding] = (0, react$1.useState)(null);
12250
+ const [errored, setErrored] = (0, react$1.useState)(false);
12251
+ const [loading, setLoading] = (0, react$1.useState)(true);
12252
+ (0, react$1.useEffect)(() => {
12102
12253
  if (deviceId === null) {
12103
12254
  setBinding(null);
12104
12255
  setErrored(false);
@@ -12196,8 +12347,8 @@ function ChildrenCountBadge({ accessoryCount, adoptedCount }) {
12196
12347
  var POPOVER_WIDTH$1 = 240;
12197
12348
  var POPOVER_MIN_HEIGHT = 200;
12198
12349
  function FeatureRow({ resolved }) {
12199
- const triggerRef = (0, react.useRef)(null);
12200
- const [position, setPosition] = (0, react.useState)(null);
12350
+ const triggerRef = (0, react$1.useRef)(null);
12351
+ const [position, setPosition] = (0, react$1.useState)(null);
12201
12352
  const open = () => {
12202
12353
  const el = triggerRef.current;
12203
12354
  if (!el) return;
@@ -12390,7 +12541,7 @@ function useDeviceBattery(trpc, deviceId) {
12390
12541
  */
12391
12542
  function useDeviceSnapshotImage(trpc, deviceId) {
12392
12543
  const dev = useDeviceProxy(trpc, deviceId);
12393
- const forceRef = (0, react.useRef)(false);
12544
+ const forceRef = (0, react$1.useRef)(false);
12394
12545
  const { data, isLoading, isFetching, refetch } = (0, _tanstack_react_query.useQuery)({
12395
12546
  queryKey: [
12396
12547
  "device",
@@ -12507,8 +12658,8 @@ var POPOVER_WIDTH = 288;
12507
12658
  var POPOVER_HEIGHT = 196;
12508
12659
  var TRIGGER_GAP = 8;
12509
12660
  function SnapshotPopoverInline({ deviceName, snapshotUrl, status }) {
12510
- const triggerRef = (0, react.useRef)(null);
12511
- const [position, setPosition] = (0, react.useState)(null);
12661
+ const triggerRef = (0, react$1.useRef)(null);
12662
+ const [position, setPosition] = (0, react$1.useState)(null);
12512
12663
  const offline = status === "offline" || status === "disabled";
12513
12664
  const open = () => {
12514
12665
  const el = triggerRef.current;
@@ -12598,7 +12749,7 @@ function DeviceItem(props) {
12598
12749
  const accessoryChildren = childrenList.filter(isAccessoryChild);
12599
12750
  const adoptedChildren = childrenList.filter((c) => !isAccessoryChild(c));
12600
12751
  const hasChildren = childrenList.length > 0;
12601
- const [localExpanded, setLocalExpanded] = (0, react.useState)(false);
12752
+ const [localExpanded, setLocalExpanded] = (0, react$1.useState)(false);
12602
12753
  const expanded = props.expanded ?? localExpanded;
12603
12754
  const onToggleExpand = props.onToggleExpand ?? (() => setLocalExpanded((v) => !v));
12604
12755
  const navigate = (id) => {
@@ -12748,8 +12899,8 @@ function DeviceItemTableRow(props) {
12748
12899
  * (caller's `useState`); this hook produces a debounced derivation.
12749
12900
  */
12750
12901
  function useDebouncedString(value, delayMs) {
12751
- const [debounced, setDebounced] = (0, react.useState)(value);
12752
- (0, react.useEffect)(() => {
12902
+ const [debounced, setDebounced] = (0, react$1.useState)(value);
12903
+ (0, react$1.useEffect)(() => {
12753
12904
  const t = setTimeout(() => setDebounced(value), delayMs);
12754
12905
  return () => clearTimeout(t);
12755
12906
  }, [value, delayMs]);
@@ -13050,12 +13201,12 @@ function writeUrlState(scope, next, defaultView) {
13050
13201
  }
13051
13202
  function useDeviceListUrlState(options) {
13052
13203
  const { scope, defaultView, lsKey } = options;
13053
- const [state, setState] = (0, react.useState)(() => {
13204
+ const [state, setState] = (0, react$1.useState)(() => {
13054
13205
  return readUrlState(scope, defaultView, readFromLS(lsKey));
13055
13206
  });
13056
- const stateRef = (0, react.useRef)(state);
13207
+ const stateRef = (0, react$1.useRef)(state);
13057
13208
  stateRef.current = state;
13058
- (0, react.useEffect)(() => {
13209
+ (0, react$1.useEffect)(() => {
13059
13210
  const handler = () => {
13060
13211
  const next = readUrlState(scope, defaultView, readFromLS(lsKey));
13061
13212
  stateRef.current = next;
@@ -13068,7 +13219,7 @@ function useDeviceListUrlState(options) {
13068
13219
  defaultView,
13069
13220
  lsKey
13070
13221
  ]);
13071
- const apply = (0, react.useCallback)((mutate) => {
13222
+ const apply = (0, react$1.useCallback)((mutate) => {
13072
13223
  const next = mutate(stateRef.current);
13073
13224
  stateRef.current = next;
13074
13225
  setState(next);
@@ -13086,30 +13237,30 @@ function useDeviceListUrlState(options) {
13086
13237
  ]);
13087
13238
  return {
13088
13239
  state,
13089
- setView: (0, react.useCallback)((view) => apply((s) => ({
13240
+ setView: (0, react$1.useCallback)((view) => apply((s) => ({
13090
13241
  ...s,
13091
13242
  view
13092
13243
  })), [apply]),
13093
- setPage: (0, react.useCallback)((page) => apply((s) => ({
13244
+ setPage: (0, react$1.useCallback)((page) => apply((s) => ({
13094
13245
  ...s,
13095
13246
  page
13096
13247
  })), [apply]),
13097
- setAddon: (0, react.useCallback)((addon) => apply((s) => ({
13248
+ setAddon: (0, react$1.useCallback)((addon) => apply((s) => ({
13098
13249
  ...s,
13099
13250
  addon,
13100
13251
  page: 1
13101
13252
  })), [apply]),
13102
- setType: (0, react.useCallback)((type) => apply((s) => ({
13253
+ setType: (0, react$1.useCallback)((type) => apply((s) => ({
13103
13254
  ...s,
13104
13255
  type,
13105
13256
  page: 1
13106
13257
  })), [apply]),
13107
- setQ: (0, react.useCallback)((q) => apply((s) => ({
13258
+ setQ: (0, react$1.useCallback)((q) => apply((s) => ({
13108
13259
  ...s,
13109
13260
  q,
13110
13261
  page: 1
13111
13262
  })), [apply]),
13112
- clearFilters: (0, react.useCallback)(() => apply((s) => ({
13263
+ clearFilters: (0, react$1.useCallback)(() => apply((s) => ({
13113
13264
  ...s,
13114
13265
  addon: null,
13115
13266
  type: null,
@@ -13149,13 +13300,13 @@ function DeviceList(props) {
13149
13300
  });
13150
13301
  const view = url.state.view;
13151
13302
  const currentPageSize = view === "cards" ? pageSize.cards : pageSize.table;
13152
- const [searchInput, setSearchInput] = (0, react.useState)(url.state.q);
13303
+ const [searchInput, setSearchInput] = (0, react$1.useState)(url.state.q);
13153
13304
  const debouncedSearch = useDebouncedString(searchInput, 300);
13154
- (0, react.useEffect)(() => {
13305
+ (0, react$1.useEffect)(() => {
13155
13306
  if (debouncedSearch !== url.state.q) url.setQ(debouncedSearch);
13156
13307
  }, [debouncedSearch]);
13157
13308
  const effectiveAddon = forceAddon ?? url.state.addon;
13158
- const filtered = (0, react.useMemo)(() => {
13309
+ const filtered = (0, react$1.useMemo)(() => {
13159
13310
  const q = url.state.q.toLowerCase().trim();
13160
13311
  return devices.filter((d) => {
13161
13312
  if (effectiveAddon && d.addonId !== effectiveAddon) return false;
@@ -13169,8 +13320,8 @@ function DeviceList(props) {
13169
13320
  url.state.type,
13170
13321
  url.state.q
13171
13322
  ]);
13172
- const grouped = (0, react.useMemo)(() => groupTopLevelAndAccessories(filtered), [filtered]);
13173
- const autoExpandedParents = (0, react.useMemo)(() => {
13323
+ const grouped = (0, react$1.useMemo)(() => groupTopLevelAndAccessories(filtered), [filtered]);
13324
+ const autoExpandedParents = (0, react$1.useMemo)(() => {
13174
13325
  if (url.state.q.trim() === "") return /* @__PURE__ */ new Set();
13175
13326
  const q = url.state.q.toLowerCase().trim();
13176
13327
  const matching = /* @__PURE__ */ new Set();
@@ -13182,7 +13333,7 @@ function DeviceList(props) {
13182
13333
  const safePage = Math.min(url.state.page, totalPages);
13183
13334
  const startIdx = (safePage - 1) * currentPageSize;
13184
13335
  const pageRows = grouped.topLevel.slice(startIdx, startIdx + currentPageSize);
13185
- (0, react.useEffect)(() => {
13336
+ (0, react$1.useEffect)(() => {
13186
13337
  if (safePage !== url.state.page) url.setPage(safePage);
13187
13338
  }, [safePage]);
13188
13339
  useDeviceListRealtimeSync();
@@ -13287,7 +13438,7 @@ function topLevelIndentLevel(device, parentType) {
13287
13438
  return 0;
13288
13439
  }
13289
13440
  function TableLayout({ rows, accessoriesByParent, autoExpandedParents, devices, trpc, resolveIntegrationIcon, resolveParent, onNavigate }) {
13290
- const parentTypeById = (0, react.useMemo)(() => {
13441
+ const parentTypeById = (0, react$1.useMemo)(() => {
13291
13442
  const m = /* @__PURE__ */ new Map();
13292
13443
  for (const d of devices) m.set(d.id, d.type);
13293
13444
  return m;
@@ -13342,9 +13493,9 @@ function TableLayout({ rows, accessoriesByParent, autoExpandedParents, devices,
13342
13493
  });
13343
13494
  }
13344
13495
  function TableRowGroup({ parent, accessories, hasAccessories, forceExpanded, trpc, integrationIcon, parentRowParent, indentLevel, onNavigate }) {
13345
- const [expanded, setExpanded] = (0, react.useState)(forceExpanded);
13346
- const prevForce = (0, react.useRef)(forceExpanded);
13347
- (0, react.useEffect)(() => {
13496
+ const [expanded, setExpanded] = (0, react$1.useState)(forceExpanded);
13497
+ const prevForce = (0, react$1.useRef)(forceExpanded);
13498
+ (0, react$1.useEffect)(() => {
13348
13499
  if (prevForce.current !== forceExpanded) {
13349
13500
  setExpanded(forceExpanded);
13350
13501
  prevForce.current = forceExpanded;
@@ -13508,9 +13659,9 @@ function PipelineBuilder({ schema, steps, onChange, templates, selectedTemplateI
13508
13659
  inheritedEnabled: inheritedEnabledByAddon[addonId]
13509
13660
  } : {}
13510
13661
  });
13511
- const excluded = (0, react.useMemo)(() => new Set(excludeAddons), [excludeAddons]);
13512
- const schemaMap = (0, react.useMemo)(() => buildSchemaMap(schema), [schema]);
13513
- const [warnings, setWarnings] = (0, react.useState)([]);
13662
+ const excluded = (0, react$1.useMemo)(() => new Set(excludeAddons), [excludeAddons]);
13663
+ const schemaMap = (0, react$1.useMemo)(() => buildSchemaMap(schema), [schema]);
13664
+ const [warnings, setWarnings] = (0, react$1.useState)([]);
13514
13665
  const dirty = selectedTemplateId ? JSON.stringify(steps) !== JSON.stringify(templates.find((t) => t.id === selectedTemplateId)?.steps) : false;
13515
13666
  function handleSelectTemplate(e) {
13516
13667
  const id = e.target.value || null;
@@ -13965,8 +14116,8 @@ function BoundingBox({ detection, imageWidth, imageHeight, color, showConfidence
13965
14116
  }
13966
14117
  /** Renders a segmentation mask as a semi-transparent colored canvas overlay */
13967
14118
  function MaskOverlay({ mask, maskWidth, maskHeight, bbox, imageWidth, imageHeight, color }) {
13968
- const canvasRef = (0, react.useRef)(null);
13969
- (0, react.useEffect)(() => {
14119
+ const canvasRef = (0, react$1.useRef)(null);
14120
+ (0, react$1.useEffect)(() => {
13970
14121
  const canvas = canvasRef.current;
13971
14122
  if (!canvas) return;
13972
14123
  const ctx = canvas.getContext("2d");
@@ -14278,7 +14429,7 @@ function ChildrenTree({ items, colors, hiddenKeys, onToggleVisibility }) {
14278
14429
  });
14279
14430
  }
14280
14431
  function AlternateLabelsSection({ alternateLabels, colors }) {
14281
- const [expanded, setExpanded] = (0, react.useState)(false);
14432
+ const [expanded, setExpanded] = (0, react$1.useState)(false);
14282
14433
  const sources = Object.keys(alternateLabels);
14283
14434
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
14284
14435
  className: "mt-1",
@@ -15184,11 +15335,11 @@ function SpinnerIcon({ className }) {
15184
15335
  });
15185
15336
  }
15186
15337
  function LoginForm({ onLogin, serverUrl, logoSrc, error: externalError, className }) {
15187
- const [username, setUsername] = (0, react.useState)("");
15188
- const [password, setPassword] = (0, react.useState)("");
15189
- const [showPassword, setShowPassword] = (0, react.useState)(false);
15190
- const [submitting, setSubmitting] = (0, react.useState)(false);
15191
- const [internalError, setInternalError] = (0, react.useState)(null);
15338
+ const [username, setUsername] = (0, react$1.useState)("");
15339
+ const [password, setPassword] = (0, react$1.useState)("");
15340
+ const [showPassword, setShowPassword] = (0, react$1.useState)(false);
15341
+ const [submitting, setSubmitting] = (0, react$1.useState)(false);
15342
+ const [internalError, setInternalError] = (0, react$1.useState)(null);
15192
15343
  const error = externalError ?? internalError;
15193
15344
  const handleSubmit = async (e) => {
15194
15345
  e.preventDefault();
@@ -15280,9 +15431,9 @@ function LoginForm({ onLogin, serverUrl, logoSrc, error: externalError, classNam
15280
15431
  //#endregion
15281
15432
  //#region src/composites/dev-shell.tsx
15282
15433
  var STORAGE_KEY = "camstack_dev_token";
15283
- var DevShellContext = (0, react.createContext)(null);
15434
+ var DevShellContext = (0, react$1.createContext)(null);
15284
15435
  function useDevShell() {
15285
- const ctx = (0, react.useContext)(DevShellContext);
15436
+ const ctx = (0, react$1.useContext)(DevShellContext);
15286
15437
  if (!ctx) throw new Error("useDevShell must be used within a DevShell");
15287
15438
  return ctx;
15288
15439
  }
@@ -15332,7 +15483,7 @@ function MoonIcon({ className }) {
15332
15483
  }
15333
15484
  function DevShellInner({ children, serverUrl, title, token, onLogout }) {
15334
15485
  const theme = require_theme_index.useThemeMode$1();
15335
- const links = (0, react.useMemo)(() => {
15486
+ const links = (0, react$1.useMemo)(() => {
15336
15487
  return [(0, _trpc_client.splitLink)({
15337
15488
  condition: (op) => op.type === "subscription",
15338
15489
  true: (0, _trpc_client.wsLink)({
@@ -15349,20 +15500,20 @@ function DevShellInner({ children, serverUrl, title, token, onLogout }) {
15349
15500
  })
15350
15501
  })];
15351
15502
  }, [serverUrl, token]);
15352
- const trpc$1 = (0, react.useMemo)(() => (0, _trpc_client.createTRPCClient)({ links }), [links]);
15353
- const trpcReactClient = (0, react.useMemo)(() => trpc.createClient({ links }), [links]);
15354
- const system = (0, react.useMemo)(() => (0, _camstack_sdk.createSystem)({
15503
+ const trpc$1 = (0, react$1.useMemo)(() => (0, _trpc_client.createTRPCClient)({ links }), [links]);
15504
+ const trpcReactClient = (0, react$1.useMemo)(() => trpc.createClient({ links }), [links]);
15505
+ const system = (0, react$1.useMemo)(() => (0, _camstack_sdk.createSystem)({
15355
15506
  serverUrl,
15356
15507
  token
15357
15508
  }), [serverUrl, token]);
15358
- (0, react.useEffect)(() => {
15509
+ (0, react$1.useEffect)(() => {
15359
15510
  system.init().catch(() => void 0);
15360
15511
  return () => {
15361
15512
  system.close();
15362
15513
  };
15363
15514
  }, [system]);
15364
- const queryClient = (0, react.useMemo)(() => new _tanstack_react_query.QueryClient(), []);
15365
- const contextValue = (0, react.useMemo)(() => ({
15515
+ const queryClient = (0, react$1.useMemo)(() => new _tanstack_react_query.QueryClient(), []);
15516
+ const contextValue = (0, react$1.useMemo)(() => ({
15366
15517
  trpc: trpc$1,
15367
15518
  token,
15368
15519
  logout: onLogout
@@ -15429,8 +15580,8 @@ function DevShellInner({ children, serverUrl, title, token, onLogout }) {
15429
15580
  });
15430
15581
  }
15431
15582
  function DevShell({ children, serverUrl = "https://localhost:4443", title }) {
15432
- const [token, setToken] = (0, react.useState)(getStoredToken);
15433
- const handleLogin = (0, react.useCallback)(async (username, password) => {
15583
+ const [token, setToken] = (0, react$1.useState)(getStoredToken);
15584
+ const handleLogin = (0, react$1.useCallback)(async (username, password) => {
15434
15585
  const loginResult = await (0, _trpc_client.createTRPCClient)({ links: [(0, _trpc_client.httpLink)({
15435
15586
  url: `${serverUrl}/trpc`,
15436
15587
  transformer: SuperJSON
@@ -15442,7 +15593,7 @@ function DevShell({ children, serverUrl = "https://localhost:4443", title }) {
15442
15593
  localStorage.setItem(STORAGE_KEY, loginResult.token);
15443
15594
  setToken(loginResult.token);
15444
15595
  }, [serverUrl]);
15445
- const handleLogout = (0, react.useCallback)(() => {
15596
+ const handleLogout = (0, react$1.useCallback)(() => {
15446
15597
  localStorage.removeItem(STORAGE_KEY);
15447
15598
  setToken(null);
15448
15599
  }, []);
@@ -15491,10 +15642,10 @@ function mountAddonPage(PageComponent, options = {}) {
15491
15642
  console.error(`[mountAddonPage] Element #${rootId} not found`);
15492
15643
  return;
15493
15644
  }
15494
- (0, react_dom_client.createRoot)(root).render((0, react.createElement)(DevShell, {
15645
+ (0, react_dom_client.createRoot)(root).render((0, react$1.createElement)(DevShell, {
15495
15646
  serverUrl,
15496
15647
  title,
15497
- children: ({ trpc, theme }) => (0, react.createElement)(PageComponent, {
15648
+ children: ({ trpc, theme }) => (0, react$1.createElement)(PageComponent, {
15498
15649
  trpc,
15499
15650
  theme: { isDark: theme.resolvedMode === "dark" },
15500
15651
  navigate: (path) => {
@@ -15554,7 +15705,7 @@ function CustomFieldRenderersProvider({ renderers, children }) {
15554
15705
  * (or renders nothing).
15555
15706
  */
15556
15707
  function useCustomFieldRenderer(type) {
15557
- return (0, react.useContext)(CustomFieldRenderersContext)[type] ?? null;
15708
+ return (0, react$1.useContext)(CustomFieldRenderersContext)[type] ?? null;
15558
15709
  }
15559
15710
  //#endregion
15560
15711
  //#region src/contexts/device-context.tsx
@@ -15591,11 +15742,11 @@ function DeviceContextProvider({ deviceId, device, children }) {
15591
15742
  }
15592
15743
  /** @returns the device id of the current page subtree, or null if outside any provider. */
15593
15744
  function useDeviceId() {
15594
- return (0, react.useContext)(DeviceContext)?.deviceId ?? null;
15745
+ return (0, react$1.useContext)(DeviceContext)?.deviceId ?? null;
15595
15746
  }
15596
15747
  /** @returns the cached device snapshot, or null when no snapshot is provided. */
15597
15748
  function useDeviceSnapshot() {
15598
- return (0, react.useContext)(DeviceContext)?.device ?? null;
15749
+ return (0, react$1.useContext)(DeviceContext)?.device ?? null;
15599
15750
  }
15600
15751
  //#endregion
15601
15752
  //#region src/generated/system-hooks.ts
@@ -15649,6 +15800,14 @@ var useAddonsRollbackPackage = trpc.addons.rollbackPackage.useMutation;
15649
15800
  var useAddonsForceRefresh = trpc.addons.forceRefresh.useMutation;
15650
15801
  /** Generated alias around `trpc.addons.restartServer.useMutation`. */
15651
15802
  var useAddonsRestartServer = trpc.addons.restartServer.useMutation;
15803
+ /** Generated alias around `trpc.addons.getLastRestart.useQuery`. */
15804
+ var useAddonsGetLastRestart = trpc.addons.getLastRestart.useQuery;
15805
+ /** Generated alias around `trpc.addons.listFrameworkPackages.useQuery`. */
15806
+ var useAddonsListFrameworkPackages = trpc.addons.listFrameworkPackages.useQuery;
15807
+ /** Generated alias around `trpc.addons.listCapabilityProviders.useQuery`. */
15808
+ var useAddonsListCapabilityProviders = trpc.addons.listCapabilityProviders.useQuery;
15809
+ /** Generated alias around `trpc.addons.updateFrameworkPackage.useMutation`. */
15810
+ var useAddonsUpdateFrameworkPackage = trpc.addons.updateFrameworkPackage.useMutation;
15652
15811
  /** Generated alias around `trpc.addons.getVersions.useQuery`. */
15653
15812
  var useAddonsGetVersions = trpc.addons.getVersions.useQuery;
15654
15813
  /** Generated alias around `trpc.addons.restartAddon.useMutation`. */
@@ -16027,6 +16186,8 @@ var useMeshNetworkJoin = trpc.meshNetwork.join.useMutation;
16027
16186
  var useMeshNetworkStartLogin = trpc.meshNetwork.startLogin.useMutation;
16028
16187
  /** Generated alias around `trpc.meshNetwork.leave.useMutation`. */
16029
16188
  var useMeshNetworkLeave = trpc.meshNetwork.leave.useMutation;
16189
+ /** Generated alias around `trpc.meshNetwork.logout.useMutation`. */
16190
+ var useMeshNetworkLogout = trpc.meshNetwork.logout.useMutation;
16030
16191
  /** Generated alias around `trpc.meshNetwork.listPeers.useQuery`. */
16031
16192
  var useMeshNetworkListPeers = trpc.meshNetwork.listPeers.useQuery;
16032
16193
  /** Generated alias around `trpc.meshNetwork.testConnection.useMutation`. */
@@ -16037,6 +16198,12 @@ var useMeshOrchestratorListProviders = trpc.meshOrchestrator.listProviders.useQu
16037
16198
  var useMeshOrchestratorJoinProvider = trpc.meshOrchestrator.joinProvider.useMutation;
16038
16199
  /** Generated alias around `trpc.meshOrchestrator.leaveProvider.useMutation`. */
16039
16200
  var useMeshOrchestratorLeaveProvider = trpc.meshOrchestrator.leaveProvider.useMutation;
16201
+ /** Generated alias around `trpc.meshOrchestrator.startLoginProvider.useMutation`. */
16202
+ var useMeshOrchestratorStartLoginProvider = trpc.meshOrchestrator.startLoginProvider.useMutation;
16203
+ /** Generated alias around `trpc.meshOrchestrator.logoutProvider.useMutation`. */
16204
+ var useMeshOrchestratorLogoutProvider = trpc.meshOrchestrator.logoutProvider.useMutation;
16205
+ /** Generated alias around `trpc.meshOrchestrator.listProviderPeers.useQuery`. */
16206
+ var useMeshOrchestratorListProviderPeers = trpc.meshOrchestrator.listProviderPeers.useQuery;
16040
16207
  /** Generated alias around `trpc.metricsProvider.collectSnapshot.useQuery`. */
16041
16208
  var useMetricsProviderCollectSnapshot = trpc.metricsProvider.collectSnapshot.useQuery;
16042
16209
  /** Generated alias around `trpc.metricsProvider.getCached.useQuery`. */
@@ -16121,6 +16288,8 @@ var useNodesShutdownNode = trpc.nodes.shutdownNode.useMutation;
16121
16288
  var useNodesRenameNode = trpc.nodes.renameNode.useMutation;
16122
16289
  /** Generated alias around `trpc.nodes.clusterAddonStatus.useQuery`. */
16123
16290
  var useNodesClusterAddonStatus = trpc.nodes.clusterAddonStatus.useQuery;
16291
+ /** Generated alias around `trpc.nodes.getNodeAddons.useQuery`. */
16292
+ var useNodesGetNodeAddons = trpc.nodes.getNodeAddons.useQuery;
16124
16293
  /** Generated alias around `trpc.nodes.setProcessLogLevel.useMutation`. */
16125
16294
  var useNodesSetProcessLogLevel = trpc.nodes.setProcessLogLevel.useMutation;
16126
16295
  /** Generated alias around `trpc.nodes.executeQuery.useMutation`. */
@@ -16738,7 +16907,7 @@ var BOOT_WINDOW_MS = 3e4;
16738
16907
  var POLL_INTERVAL_MS = 2e3;
16739
16908
  function WidgetRegistryProvider({ children }) {
16740
16909
  const queryClient = (0, _tanstack_react_query.useQueryClient)();
16741
- const mountedAtRef = (0, react.useRef)(Date.now());
16910
+ const mountedAtRef = (0, react$1.useRef)(Date.now());
16742
16911
  const { data: rawWidgets } = useAddonWidgetsListWidgets(void 0, {
16743
16912
  staleTime: 0,
16744
16913
  refetchOnMount: "always",
@@ -16752,8 +16921,8 @@ function WidgetRegistryProvider({ children }) {
16752
16921
  useLiveEvent("addon.widget-ready", () => {
16753
16922
  queryClient.invalidateQueries({ queryKey: [["addonWidgets", "listWidgets"]] });
16754
16923
  });
16755
- const [resolvedTick, setResolvedTick] = (0, react.useState)(0);
16756
- (0, react.useEffect)(() => {
16924
+ const [resolvedTick, setResolvedTick] = (0, react$1.useState)(0);
16925
+ (0, react$1.useEffect)(() => {
16757
16926
  if (!rawWidgets) return;
16758
16927
  let cancelled = false;
16759
16928
  const seenRemotes = /* @__PURE__ */ new Set();
@@ -16777,7 +16946,7 @@ function WidgetRegistryProvider({ children }) {
16777
16946
  cancelled = true;
16778
16947
  };
16779
16948
  }, [rawWidgets]);
16780
- const registry = (0, react.useMemo)(() => {
16949
+ const registry = (0, react$1.useMemo)(() => {
16781
16950
  const widgets = rawWidgets ?? [];
16782
16951
  const byId = /* @__PURE__ */ new Map();
16783
16952
  for (const w of widgets) byId.set(`${w.addonId}/${w.stableId}`, w);
@@ -16849,7 +17018,7 @@ function useOptionalWidgetRegistry() {
16849
17018
  return useContextSafe(WidgetRegistryContext);
16850
17019
  }
16851
17020
  function useContextSafe(ctx) {
16852
- return (0, react.useContext)(ctx);
17021
+ return (0, react$1.useContext)(ctx);
16853
17022
  }
16854
17023
  //#endregion
16855
17024
  //#region src/composites/widget-slot.tsx
@@ -16873,7 +17042,7 @@ function WidgetSlot(props) {
16873
17042
  const { widgetId, host = "device-tab", config, deviceId, integrationId, instanceId, size, columns, rows } = props;
16874
17043
  const Component = useWidget(widgetId);
16875
17044
  const metadata = useWidgetMetadata(widgetId);
16876
- const resolvedInstanceId = (0, react.useMemo)(() => instanceId ?? widgetId, [instanceId, widgetId]);
17045
+ const resolvedInstanceId = (0, react$1.useMemo)(() => instanceId ?? widgetId, [instanceId, widgetId]);
16877
17046
  if (Component === void 0 && metadata === void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WidgetMissingError, {
16878
17047
  widgetId,
16879
17048
  reason: "unknown"
@@ -16967,9 +17136,9 @@ function TextField({ field, value, onChange, disabled, translationFn }) {
16967
17136
  });
16968
17137
  }
16969
17138
  function NumberField({ field, value, onChange, disabled, translationFn }) {
16970
- const [local, setLocal] = (0, react.useState)(value === void 0 || value === null ? "" : String(value));
16971
- const focusedRef = (0, react.useRef)(false);
16972
- (0, react.useEffect)(() => {
17139
+ const [local, setLocal] = (0, react$1.useState)(value === void 0 || value === null ? "" : String(value));
17140
+ const focusedRef = (0, react$1.useRef)(false);
17141
+ (0, react$1.useEffect)(() => {
16973
17142
  if (focusedRef.current) return;
16974
17143
  setLocal(value === void 0 || value === null ? "" : String(value));
16975
17144
  }, [value]);
@@ -17135,7 +17304,7 @@ function MultiSelectField({ field, value, onChange, disabled, translationFn }) {
17135
17304
  });
17136
17305
  }
17137
17306
  function PasswordField({ field, value, onChange, disabled, translationFn }) {
17138
- const [show, setShow] = (0, react.useState)(false);
17307
+ const [show, setShow] = (0, react$1.useState)(false);
17139
17308
  const showToggle = field.showToggle !== false;
17140
17309
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FieldWrapper, {
17141
17310
  label: field.label,
@@ -17302,9 +17471,9 @@ function SliderField({ field, value, onChange, disabled, translationFn }) {
17302
17471
  }
17303
17472
  function TagsField({ field, value, onChange, disabled, translationFn }) {
17304
17473
  const tags = Array.isArray(value) ? value : [];
17305
- const [input, setInput] = (0, react.useState)("");
17306
- const inputRef = (0, react.useRef)(null);
17307
- const addTag = (0, react.useCallback)((tag) => {
17474
+ const [input, setInput] = (0, react$1.useState)("");
17475
+ const inputRef = (0, react$1.useRef)(null);
17476
+ const addTag = (0, react$1.useCallback)((tag) => {
17308
17477
  const trimmed = tag.trim();
17309
17478
  if (!trimmed || tags.includes(trimmed)) return;
17310
17479
  if (field.maxTags !== void 0 && tags.length >= field.maxTags) return;
@@ -17463,12 +17632,12 @@ function ColorField({ field, value, onChange, disabled, translationFn }) {
17463
17632
  });
17464
17633
  }
17465
17634
  function ProbeField({ field, value, onChange, disabled, translationFn, onTestField, onAction, externalProbe }) {
17466
- const [localStatus, setLocalStatus] = (0, react.useState)("idle");
17467
- const [localResult, setLocalResult] = (0, react.useState)(null);
17635
+ const [localStatus, setLocalStatus] = (0, react$1.useState)("idle");
17636
+ const [localResult, setLocalResult] = (0, react$1.useState)(null);
17468
17637
  const probeStatus = externalProbe?.status ?? localStatus;
17469
17638
  const probeResult = externalProbe?.result ?? localResult;
17470
17639
  const hasTestHandler = !!onTestField || !!onAction;
17471
- const handleTest = (0, react.useCallback)(async () => {
17640
+ const handleTest = (0, react$1.useCallback)(async () => {
17472
17641
  if (!hasTestHandler) return;
17473
17642
  setLocalStatus("probing");
17474
17643
  setLocalResult(null);
@@ -17547,7 +17716,7 @@ function ProbeField({ field, value, onChange, disabled, translationFn, onTestFie
17547
17716
  });
17548
17717
  }
17549
17718
  function GroupField({ field, values, onChange, disabled, translationFn, onTestField }) {
17550
- const [collapsed, setCollapsed] = (0, react.useState)(field.defaultCollapsed ?? false);
17719
+ const [collapsed, setCollapsed] = (0, react$1.useState)(field.defaultCollapsed ?? false);
17551
17720
  const isAccordion = field.style === "accordion";
17552
17721
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
17553
17722
  className: field.span === 2 ? "col-span-2" : field.span === 3 ? "col-span-3" : field.span === 4 ? "col-span-4" : "col-span-1",
@@ -17578,7 +17747,7 @@ function GroupField({ field, values, onChange, disabled, translationFn, onTestFi
17578
17747
  });
17579
17748
  }
17580
17749
  function SubTabsField({ field, values, onChange, disabled, translationFn, onTestField, onAction }) {
17581
- const [active, setActive] = (0, react.useState)(field.tabs[0]?.id ?? "");
17750
+ const [active, setActive] = (0, react$1.useState)(field.tabs[0]?.id ?? "");
17582
17751
  const colSpanClass = field.span === 2 ? "col-span-2" : field.span === 3 ? "col-span-3" : field.span === 4 ? "col-span-4" : "col-span-1";
17583
17752
  if (field.tabs.length === 0) return null;
17584
17753
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -17919,7 +18088,7 @@ function EditableArrayField({ field, value, onChange, disabled, translationFn, o
17919
18088
  });
17920
18089
  }
17921
18090
  function ButtonField({ field, disabled, onAction }) {
17922
- const [loading, setLoading] = (0, react.useState)(false);
18091
+ const [loading, setLoading] = (0, react$1.useState)(false);
17923
18092
  const confirm = useConfirm();
17924
18093
  const handleClick = async () => {
17925
18094
  if (field.confirmMessage) {
@@ -17965,12 +18134,12 @@ function resolveActionParams(field, values) {
17965
18134
  return params;
17966
18135
  }
17967
18136
  function AddonActionSelectField({ field, value, values, onChange, disabled, onAction }) {
17968
- const [loading, setLoading] = (0, react.useState)(false);
17969
- const [error, setError] = (0, react.useState)(null);
17970
- const [options, setOptions] = (0, react.useState)(null);
18137
+ const [loading, setLoading] = (0, react$1.useState)(false);
18138
+ const [error, setError] = (0, react$1.useState)(null);
18139
+ const [options, setOptions] = (0, react$1.useState)(null);
17971
18140
  const params = resolveActionParams(field, values);
17972
18141
  const missingParam = Object.keys(field.paramsFromForm ?? {}).some((k) => params[k] === void 0);
17973
- (0, react.useEffect)(() => {
18142
+ (0, react$1.useEffect)(() => {
17974
18143
  if (!onAction || missingParam) {
17975
18144
  setOptions(null);
17976
18145
  setError(null);
@@ -18056,8 +18225,8 @@ function AddonActionSelectField({ field, value, values, onChange, disabled, onAc
18056
18225
  });
18057
18226
  }
18058
18227
  function AddonActionButtonField({ field, values, disabled, onAction }) {
18059
- const [loading, setLoading] = (0, react.useState)(false);
18060
- const [status, setStatus] = (0, react.useState)(null);
18228
+ const [loading, setLoading] = (0, react$1.useState)(false);
18229
+ const [status, setStatus] = (0, react$1.useState)(null);
18061
18230
  const confirm = useConfirm();
18062
18231
  const handleClick = async () => {
18063
18232
  if (field.confirmMessage) {
@@ -18202,7 +18371,7 @@ function InlineIconGlyph({ name }) {
18202
18371
  */
18203
18372
  function InlineActionIcon({ action, fieldKey, value, onAction }) {
18204
18373
  const confirm = useConfirm();
18205
- const [loading, setLoading] = (0, react.useState)(false);
18374
+ const [loading, setLoading] = (0, react$1.useState)(false);
18206
18375
  const variantClass = action.variant === "danger" ? "text-danger hover:bg-danger/10 border-danger/30" : action.variant === "primary" ? "text-primary hover:bg-primary/10 border-primary/30" : "text-foreground-subtle hover:text-foreground hover:bg-surface-hover border-border";
18207
18376
  const handleClick = async () => {
18208
18377
  if (action.confirmMessage) {
@@ -18550,7 +18719,7 @@ function resolveLabel(value, t) {
18550
18719
  return value;
18551
18720
  }
18552
18721
  function SectionCard({ section, values, onChange, disabled, translationFn, onTestField, probeResults }) {
18553
- const [collapsed, setCollapsed] = (0, react.useState)(section.defaultCollapsed ?? false);
18722
+ const [collapsed, setCollapsed] = (0, react$1.useState)(section.defaultCollapsed ?? false);
18554
18723
  const isAccordion = section.style === "accordion";
18555
18724
  const columns = section.columns ?? 2;
18556
18725
  const gridClass = columns === 1 ? "grid-cols-1" : columns === 3 ? "grid-cols-1 @[480px]:grid-cols-2 @[880px]:grid-cols-3" : columns === 4 ? "grid-cols-1 @[480px]:grid-cols-2 @[1140px]:grid-cols-4" : "grid-cols-1 @[640px]:grid-cols-2";
@@ -18655,14 +18824,14 @@ function stripValues(schema) {
18655
18824
  }
18656
18825
  function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAfterChange, refreshToken, collapsible, defaultOpen, mode, onOverrideChange }) {
18657
18826
  const effectiveMode = mode ?? "persist";
18658
- const [hydrated, setHydrated] = (0, react.useState)(null);
18659
- const [loading, setLoading] = (0, react.useState)(true);
18660
- const [error, setError] = (0, react.useState)(null);
18661
- const [saving, setSaving] = (0, react.useState)(false);
18662
- const [open, setOpen] = (0, react.useState)(defaultOpen ?? false);
18663
- const [overrideValues, setOverrideValues] = (0, react.useState)({});
18664
- const [baseValues, setBaseValues] = (0, react.useState)(null);
18665
- (0, react.useEffect)(() => {
18827
+ const [hydrated, setHydrated] = (0, react$1.useState)(null);
18828
+ const [loading, setLoading] = (0, react$1.useState)(true);
18829
+ const [error, setError] = (0, react$1.useState)(null);
18830
+ const [saving, setSaving] = (0, react$1.useState)(false);
18831
+ const [open, setOpen] = (0, react$1.useState)(defaultOpen ?? false);
18832
+ const [overrideValues, setOverrideValues] = (0, react$1.useState)({});
18833
+ const [baseValues, setBaseValues] = (0, react$1.useState)(null);
18834
+ (0, react$1.useEffect)(() => {
18666
18835
  setBaseValues(null);
18667
18836
  setOverrideValues({});
18668
18837
  }, [
@@ -18672,7 +18841,7 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
18672
18841
  refreshToken,
18673
18842
  effectiveMode
18674
18843
  ]);
18675
- (0, react.useEffect)(() => {
18844
+ (0, react$1.useEffect)(() => {
18676
18845
  let cancelled = false;
18677
18846
  setLoading(true);
18678
18847
  setError(null);
@@ -18702,8 +18871,8 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
18702
18871
  effectiveMode,
18703
18872
  JSON.stringify(overrideValues)
18704
18873
  ]);
18705
- const values = (0, react.useMemo)(() => extractValues(hydrated), [hydrated]);
18706
- const schemaNoValues = (0, react.useMemo)(() => hydrated ? stripValues(hydrated) : null, [hydrated]);
18874
+ const values = (0, react$1.useMemo)(() => extractValues(hydrated), [hydrated]);
18875
+ const schemaNoValues = (0, react$1.useMemo)(() => hydrated ? stripValues(hydrated) : null, [hydrated]);
18707
18876
  const handleChange = async (nextValues) => {
18708
18877
  if (effectiveMode === "override") {
18709
18878
  const ref = baseValues ?? values;
@@ -18950,30 +19119,30 @@ function computeClientHints(container) {
18950
19119
  var RECONNECT_DELAY_MS = 3e3;
18951
19120
  var MAX_RECONNECT_ATTEMPTS = 5;
18952
19121
  function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, muted: initialMuted = true, showControls = true, className = "", onStateChange, onError, overlay, createSession, sendAnswer, closeSession, hintsOverride }) {
18953
- const videoRef = (0, react.useRef)(null);
18954
- const containerRef = (0, react.useRef)(null);
18955
- const pcRef = (0, react.useRef)(null);
19122
+ const videoRef = (0, react$1.useRef)(null);
19123
+ const containerRef = (0, react$1.useRef)(null);
19124
+ const pcRef = (0, react$1.useRef)(null);
18956
19125
  /** All session IDs created during this player's lifetime — closed on cleanup */
18957
- const sessionIdsRef = (0, react.useRef)(/* @__PURE__ */ new Set());
19126
+ const sessionIdsRef = (0, react$1.useRef)(/* @__PURE__ */ new Set());
18958
19127
  /** Abort controller to cancel in-flight connection attempts on cleanup */
18959
- const connectAbortRef = (0, react.useRef)(null);
18960
- const reconnectTimerRef = (0, react.useRef)(null);
18961
- const reconnectAttemptsRef = (0, react.useRef)(0);
18962
- const mountedRef = (0, react.useRef)(true);
18963
- const [state, setState] = (0, react.useState)("idle");
18964
- const [errorMessage, setErrorMessage] = (0, react.useState)("");
18965
- const [isMuted, setIsMuted] = (0, react.useState)(initialMuted);
18966
- const [isFullscreen, setIsFullscreen] = (0, react.useState)(false);
18967
- const [showToolbar, setShowToolbar] = (0, react.useState)(false);
18968
- const hideTimerRef = (0, react.useRef)(null);
18969
- const serverOfferModeRef = (0, react.useRef)(false);
19128
+ const connectAbortRef = (0, react$1.useRef)(null);
19129
+ const reconnectTimerRef = (0, react$1.useRef)(null);
19130
+ const reconnectAttemptsRef = (0, react$1.useRef)(0);
19131
+ const mountedRef = (0, react$1.useRef)(true);
19132
+ const [state, setState] = (0, react$1.useState)("idle");
19133
+ const [errorMessage, setErrorMessage] = (0, react$1.useState)("");
19134
+ const [isMuted, setIsMuted] = (0, react$1.useState)(initialMuted);
19135
+ const [isFullscreen, setIsFullscreen] = (0, react$1.useState)(false);
19136
+ const [showToolbar, setShowToolbar] = (0, react$1.useState)(false);
19137
+ const hideTimerRef = (0, react$1.useRef)(null);
19138
+ const serverOfferModeRef = (0, react$1.useRef)(false);
18970
19139
  if (sendAnswer || createSession) serverOfferModeRef.current = true;
18971
19140
  const useServerOffer = serverOfferModeRef.current;
18972
- const updateState = (0, react.useCallback)((s) => {
19141
+ const updateState = (0, react$1.useCallback)((s) => {
18973
19142
  setState(s);
18974
19143
  onStateChange?.(s);
18975
19144
  }, [onStateChange]);
18976
- const cleanup = (0, react.useCallback)(() => {
19145
+ const cleanup = (0, react$1.useCallback)(() => {
18977
19146
  connectAbortRef.current?.abort();
18978
19147
  connectAbortRef.current = null;
18979
19148
  if (reconnectTimerRef.current) {
@@ -18990,7 +19159,7 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
18990
19159
  }
18991
19160
  if (videoRef.current) videoRef.current.srcObject = null;
18992
19161
  }, [closeSession]);
18993
- const connectServerOffer = (0, react.useCallback)(async () => {
19162
+ const connectServerOffer = (0, react$1.useCallback)(async () => {
18994
19163
  if (!mountedRef.current || !createSession || !sendAnswer) return;
18995
19164
  cleanup();
18996
19165
  updateState("connecting");
@@ -19081,7 +19250,7 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
19081
19250
  onError,
19082
19251
  hintsOverride
19083
19252
  ]);
19084
- const connectWhep = (0, react.useCallback)(async () => {
19253
+ const connectWhep = (0, react$1.useCallback)(async () => {
19085
19254
  if (!mountedRef.current) return;
19086
19255
  cleanup();
19087
19256
  updateState("connecting");
@@ -19142,9 +19311,9 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
19142
19311
  onError
19143
19312
  ]);
19144
19313
  const connect = useServerOffer ? connectServerOffer : connectWhep;
19145
- const connectRef = (0, react.useRef)(() => {});
19314
+ const connectRef = (0, react$1.useRef)(() => {});
19146
19315
  connectRef.current = connect;
19147
- const scheduleReconnect = (0, react.useCallback)(() => {
19316
+ const scheduleReconnect = (0, react$1.useCallback)(() => {
19148
19317
  if (!mountedRef.current) return;
19149
19318
  if (reconnectAttemptsRef.current >= MAX_RECONNECT_ATTEMPTS) return;
19150
19319
  reconnectAttemptsRef.current += 1;
@@ -19152,7 +19321,7 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
19152
19321
  if (mountedRef.current) connectRef.current();
19153
19322
  }, RECONNECT_DELAY_MS);
19154
19323
  }, []);
19155
- (0, react.useEffect)(() => {
19324
+ (0, react$1.useEffect)(() => {
19156
19325
  mountedRef.current = true;
19157
19326
  reconnectAttemptsRef.current = 0;
19158
19327
  if (autoPlay) connect();
@@ -19161,8 +19330,8 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
19161
19330
  cleanup();
19162
19331
  };
19163
19332
  }, [serverUrl, streamKey]);
19164
- const hasSignaledRef = (0, react.useRef)(false);
19165
- (0, react.useEffect)(() => {
19333
+ const hasSignaledRef = (0, react$1.useRef)(false);
19334
+ (0, react$1.useEffect)(() => {
19166
19335
  if (!autoPlay || !useServerOffer) return;
19167
19336
  if (!createSession || !sendAnswer) return;
19168
19337
  if (hasSignaledRef.current) return;
@@ -19208,7 +19377,7 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
19208
19377
  link.href = canvas.toDataURL("image/jpeg", .92);
19209
19378
  link.click();
19210
19379
  };
19211
- (0, react.useEffect)(() => {
19380
+ (0, react$1.useEffect)(() => {
19212
19381
  const handler = () => setIsFullscreen(!!document.fullscreenElement);
19213
19382
  document.addEventListener("fullscreenchange", handler);
19214
19383
  return () => document.removeEventListener("fullscreenchange", handler);
@@ -19432,16 +19601,16 @@ async function waitForIceGathering(pc) {
19432
19601
  var PlayerOverlaysStateContext = createSharedContext("camstack:player-overlays-state", null);
19433
19602
  var PlayerOverlaysActionsContext = createSharedContext("camstack:player-overlays-actions", null);
19434
19603
  function PlayerOverlaysProvider({ children }) {
19435
- const [layers, setLayers] = (0, react.useState)(() => /* @__PURE__ */ new Map());
19436
- const [buttons, setButtons] = (0, react.useState)(() => /* @__PURE__ */ new Map());
19437
- const setLayer = (0, react.useCallback)((layer) => {
19604
+ const [layers, setLayers] = (0, react$1.useState)(() => /* @__PURE__ */ new Map());
19605
+ const [buttons, setButtons] = (0, react$1.useState)(() => /* @__PURE__ */ new Map());
19606
+ const setLayer = (0, react$1.useCallback)((layer) => {
19438
19607
  setLayers((prev) => {
19439
19608
  const next = new Map(prev);
19440
19609
  next.set(layer.id, layer);
19441
19610
  return next;
19442
19611
  });
19443
19612
  }, []);
19444
- const removeLayer = (0, react.useCallback)((id) => {
19613
+ const removeLayer = (0, react$1.useCallback)((id) => {
19445
19614
  setLayers((prev) => {
19446
19615
  if (!prev.has(id)) return prev;
19447
19616
  const next = new Map(prev);
@@ -19449,14 +19618,14 @@ function PlayerOverlaysProvider({ children }) {
19449
19618
  return next;
19450
19619
  });
19451
19620
  }, []);
19452
- const setButton = (0, react.useCallback)((button) => {
19621
+ const setButton = (0, react$1.useCallback)((button) => {
19453
19622
  setButtons((prev) => {
19454
19623
  const next = new Map(prev);
19455
19624
  next.set(button.id, button);
19456
19625
  return next;
19457
19626
  });
19458
19627
  }, []);
19459
- const removeButton = (0, react.useCallback)((id) => {
19628
+ const removeButton = (0, react$1.useCallback)((id) => {
19460
19629
  setButtons((prev) => {
19461
19630
  if (!prev.has(id)) return prev;
19462
19631
  const next = new Map(prev);
@@ -19464,11 +19633,11 @@ function PlayerOverlaysProvider({ children }) {
19464
19633
  return next;
19465
19634
  });
19466
19635
  }, []);
19467
- const stateValue = (0, react.useMemo)(() => ({
19636
+ const stateValue = (0, react$1.useMemo)(() => ({
19468
19637
  layers,
19469
19638
  buttons
19470
19639
  }), [layers, buttons]);
19471
- const actionsValue = (0, react.useMemo)(() => ({
19640
+ const actionsValue = (0, react$1.useMemo)(() => ({
19472
19641
  setLayer,
19473
19642
  removeLayer,
19474
19643
  setButton,
@@ -19491,16 +19660,16 @@ function PlayerOverlaysProvider({ children }) {
19491
19660
  * by insertion order of the underlying Map). Returns `[]` outside a
19492
19661
  * provider. */
19493
19662
  function usePlayerOverlayLayers() {
19494
- const state = (0, react.useContext)(PlayerOverlaysStateContext);
19495
- return (0, react.useMemo)(() => {
19663
+ const state = (0, react$1.useContext)(PlayerOverlaysStateContext);
19664
+ return (0, react$1.useMemo)(() => {
19496
19665
  if (!state) return [];
19497
19666
  return [...state.layers.values()].sort((a, b) => a.order - b.order);
19498
19667
  }, [state]);
19499
19668
  }
19500
19669
  /** Snapshot of registered toolbar buttons, ordered by `order` (asc). */
19501
19670
  function usePlayerToolbarButtons() {
19502
- const state = (0, react.useContext)(PlayerOverlaysStateContext);
19503
- return (0, react.useMemo)(() => {
19671
+ const state = (0, react$1.useContext)(PlayerOverlaysStateContext);
19672
+ return (0, react$1.useMemo)(() => {
19504
19673
  if (!state) return [];
19505
19674
  return [...state.buttons.values()].sort((a, b) => a.order - b.order);
19506
19675
  }, [state]);
@@ -19517,8 +19686,8 @@ function usePlayerToolbarButtons() {
19517
19686
  * effects depend on referential equality of the spec object.
19518
19687
  */
19519
19688
  function usePlayerOverlayLayer(spec) {
19520
- const actions = (0, react.useContext)(PlayerOverlaysActionsContext);
19521
- (0, react.useEffect)(() => {
19689
+ const actions = (0, react$1.useContext)(PlayerOverlaysActionsContext);
19690
+ (0, react$1.useEffect)(() => {
19522
19691
  if (!actions || !spec) return void 0;
19523
19692
  actions.setLayer(spec);
19524
19693
  return () => actions.removeLayer(spec.id);
@@ -19526,8 +19695,8 @@ function usePlayerOverlayLayer(spec) {
19526
19695
  }
19527
19696
  /** Same shape as `usePlayerOverlayLayer`, scoped to toolbar buttons. */
19528
19697
  function usePlayerToolbarButton(spec) {
19529
- const actions = (0, react.useContext)(PlayerOverlaysActionsContext);
19530
- (0, react.useEffect)(() => {
19698
+ const actions = (0, react$1.useContext)(PlayerOverlaysActionsContext);
19699
+ (0, react$1.useEffect)(() => {
19531
19700
  if (!actions || !spec) return void 0;
19532
19701
  actions.setButton(spec);
19533
19702
  return () => actions.removeButton(spec.id);
@@ -19696,13 +19865,13 @@ function ImageOffIcon({ className }) {
19696
19865
  }
19697
19866
  function StreamPanel({ serverUrl, createSession, sendAnswer, closeSession, streams, activeStreamId: controlledStreamId, onStreamChange, deviceName, phase, pipelineMetrics, detections, defaultShowDetections = true, defaultShowMotion = false, streamStats, autoPlay = false, showPlayStop = false, snapshotSrc, snapshotLoading = false, onRefreshSnapshot, showStreamStats = false, children, extraOverlay, ptzAvailable = false, ptzShown = false, ptzOverlay, onPtzToggle, intercomAvailable = false, intercomShown = false, onIntercomToggle, chromeless = false, className }) {
19698
19867
  const registeredButtons = usePlayerToolbarButtons();
19699
- const [isPlaying, setIsPlaying] = (0, react.useState)(autoPlay);
19700
- const [showDetections, setShowDetections] = (0, react.useState)(defaultShowDetections);
19701
- const [showMotion, setShowMotion] = (0, react.useState)(defaultShowMotion);
19702
- const [internalStreamId, setInternalStreamId] = (0, react.useState)(null);
19703
- const [menuOpen, setMenuOpen] = (0, react.useState)(false);
19704
- const menuRef = (0, react.useRef)(null);
19705
- (0, react.useEffect)(() => {
19868
+ const [isPlaying, setIsPlaying] = (0, react$1.useState)(autoPlay);
19869
+ const [showDetections, setShowDetections] = (0, react$1.useState)(defaultShowDetections);
19870
+ const [showMotion, setShowMotion] = (0, react$1.useState)(defaultShowMotion);
19871
+ const [internalStreamId, setInternalStreamId] = (0, react$1.useState)(null);
19872
+ const [menuOpen, setMenuOpen] = (0, react$1.useState)(false);
19873
+ const menuRef = (0, react$1.useRef)(null);
19874
+ (0, react$1.useEffect)(() => {
19706
19875
  if (!menuOpen) return;
19707
19876
  function onClick(e) {
19708
19877
  if (menuRef.current && !menuRef.current.contains(e.target)) setMenuOpen(false);
@@ -19725,7 +19894,7 @@ function StreamPanel({ serverUrl, createSession, sendAnswer, closeSession, strea
19725
19894
  setTimeout(() => setIsPlaying(true), 50);
19726
19895
  }
19727
19896
  };
19728
- const playerCreateSession = (0, react.useMemo)(() => {
19897
+ const playerCreateSession = (0, react$1.useMemo)(() => {
19729
19898
  const target = selectedChoice?.target;
19730
19899
  if (!target) return void 0;
19731
19900
  return (hints) => createSession(target, hints);
@@ -20048,10 +20217,10 @@ function profileLabel(streamId) {
20048
20217
  return streamId.charAt(0).toUpperCase() + streamId.slice(1);
20049
20218
  }
20050
20219
  function StreamBrokerSelector({ deviceId, value, onChange, disabled, label, className }) {
20051
- const labelId = (0, react.useId)();
20220
+ const labelId = (0, react$1.useId)();
20052
20221
  const query = useCameraStreamsGetRtspEntries({ deviceId }, { refetchOnWindowFocus: false });
20053
- const [options, setOptions] = (0, react.useState)([AUTO_OPTION]);
20054
- (0, react.useEffect)(() => {
20222
+ const [options, setOptions] = (0, react$1.useState)([AUTO_OPTION]);
20223
+ (0, react$1.useEffect)(() => {
20055
20224
  if (!query.data) return;
20056
20225
  const prefix = `${deviceId}/`;
20057
20226
  const next = [AUTO_OPTION];
@@ -20090,6 +20259,1479 @@ function StreamBrokerSelector({ deviceId, value, onChange, disabled, label, clas
20090
20259
  });
20091
20260
  }
20092
20261
  //#endregion
20262
+ //#region ../../node_modules/qrcode.react/lib/esm/index.js
20263
+ var __defProp = Object.defineProperty;
20264
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
20265
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
20266
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
20267
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
20268
+ enumerable: true,
20269
+ configurable: true,
20270
+ writable: true,
20271
+ value
20272
+ }) : obj[key] = value;
20273
+ var __spreadValues = (a, b) => {
20274
+ for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]);
20275
+ if (__getOwnPropSymbols) {
20276
+ for (var prop of __getOwnPropSymbols(b)) if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]);
20277
+ }
20278
+ return a;
20279
+ };
20280
+ var __objRest = (source, exclude) => {
20281
+ var target = {};
20282
+ for (var prop in source) if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0) target[prop] = source[prop];
20283
+ if (source != null && __getOwnPropSymbols) {
20284
+ for (var prop of __getOwnPropSymbols(source)) if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop)) target[prop] = source[prop];
20285
+ }
20286
+ return target;
20287
+ };
20288
+ /**
20289
+ * @license QR Code generator library (TypeScript)
20290
+ * Copyright (c) Project Nayuki.
20291
+ * SPDX-License-Identifier: MIT
20292
+ */
20293
+ var qrcodegen;
20294
+ ((qrcodegen2) => {
20295
+ const _QrCode = class _QrCode {
20296
+ constructor(version, errorCorrectionLevel, dataCodewords, msk) {
20297
+ this.version = version;
20298
+ this.errorCorrectionLevel = errorCorrectionLevel;
20299
+ this.modules = [];
20300
+ this.isFunction = [];
20301
+ if (version < _QrCode.MIN_VERSION || version > _QrCode.MAX_VERSION) throw new RangeError("Version value out of range");
20302
+ if (msk < -1 || msk > 7) throw new RangeError("Mask value out of range");
20303
+ this.size = version * 4 + 17;
20304
+ let row = [];
20305
+ for (let i = 0; i < this.size; i++) row.push(false);
20306
+ for (let i = 0; i < this.size; i++) {
20307
+ this.modules.push(row.slice());
20308
+ this.isFunction.push(row.slice());
20309
+ }
20310
+ this.drawFunctionPatterns();
20311
+ const allCodewords = this.addEccAndInterleave(dataCodewords);
20312
+ this.drawCodewords(allCodewords);
20313
+ if (msk == -1) {
20314
+ let minPenalty = 1e9;
20315
+ for (let i = 0; i < 8; i++) {
20316
+ this.applyMask(i);
20317
+ this.drawFormatBits(i);
20318
+ const penalty = this.getPenaltyScore();
20319
+ if (penalty < minPenalty) {
20320
+ msk = i;
20321
+ minPenalty = penalty;
20322
+ }
20323
+ this.applyMask(i);
20324
+ }
20325
+ }
20326
+ assert(0 <= msk && msk <= 7);
20327
+ this.mask = msk;
20328
+ this.applyMask(msk);
20329
+ this.drawFormatBits(msk);
20330
+ this.isFunction = [];
20331
+ }
20332
+ static encodeText(text, ecl) {
20333
+ const segs = qrcodegen2.QrSegment.makeSegments(text);
20334
+ return _QrCode.encodeSegments(segs, ecl);
20335
+ }
20336
+ static encodeBinary(data, ecl) {
20337
+ const seg = qrcodegen2.QrSegment.makeBytes(data);
20338
+ return _QrCode.encodeSegments([seg], ecl);
20339
+ }
20340
+ static encodeSegments(segs, ecl, minVersion = 1, maxVersion = 40, mask = -1, boostEcl = true) {
20341
+ if (!(_QrCode.MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= _QrCode.MAX_VERSION) || mask < -1 || mask > 7) throw new RangeError("Invalid value");
20342
+ let version;
20343
+ let dataUsedBits;
20344
+ for (version = minVersion;; version++) {
20345
+ const dataCapacityBits2 = _QrCode.getNumDataCodewords(version, ecl) * 8;
20346
+ const usedBits = QrSegment.getTotalBits(segs, version);
20347
+ if (usedBits <= dataCapacityBits2) {
20348
+ dataUsedBits = usedBits;
20349
+ break;
20350
+ }
20351
+ if (version >= maxVersion) throw new RangeError("Data too long");
20352
+ }
20353
+ for (const newEcl of [
20354
+ _QrCode.Ecc.MEDIUM,
20355
+ _QrCode.Ecc.QUARTILE,
20356
+ _QrCode.Ecc.HIGH
20357
+ ]) if (boostEcl && dataUsedBits <= _QrCode.getNumDataCodewords(version, newEcl) * 8) ecl = newEcl;
20358
+ let bb = [];
20359
+ for (const seg of segs) {
20360
+ appendBits(seg.mode.modeBits, 4, bb);
20361
+ appendBits(seg.numChars, seg.mode.numCharCountBits(version), bb);
20362
+ for (const b of seg.getData()) bb.push(b);
20363
+ }
20364
+ assert(bb.length == dataUsedBits);
20365
+ const dataCapacityBits = _QrCode.getNumDataCodewords(version, ecl) * 8;
20366
+ assert(bb.length <= dataCapacityBits);
20367
+ appendBits(0, Math.min(4, dataCapacityBits - bb.length), bb);
20368
+ appendBits(0, (8 - bb.length % 8) % 8, bb);
20369
+ assert(bb.length % 8 == 0);
20370
+ for (let padByte = 236; bb.length < dataCapacityBits; padByte ^= 253) appendBits(padByte, 8, bb);
20371
+ let dataCodewords = [];
20372
+ while (dataCodewords.length * 8 < bb.length) dataCodewords.push(0);
20373
+ bb.forEach((b, i) => dataCodewords[i >>> 3] |= b << 7 - (i & 7));
20374
+ return new _QrCode(version, ecl, dataCodewords, mask);
20375
+ }
20376
+ getModule(x, y) {
20377
+ return 0 <= x && x < this.size && 0 <= y && y < this.size && this.modules[y][x];
20378
+ }
20379
+ getModules() {
20380
+ return this.modules;
20381
+ }
20382
+ drawFunctionPatterns() {
20383
+ for (let i = 0; i < this.size; i++) {
20384
+ this.setFunctionModule(6, i, i % 2 == 0);
20385
+ this.setFunctionModule(i, 6, i % 2 == 0);
20386
+ }
20387
+ this.drawFinderPattern(3, 3);
20388
+ this.drawFinderPattern(this.size - 4, 3);
20389
+ this.drawFinderPattern(3, this.size - 4);
20390
+ const alignPatPos = this.getAlignmentPatternPositions();
20391
+ const numAlign = alignPatPos.length;
20392
+ for (let i = 0; i < numAlign; i++) for (let j = 0; j < numAlign; j++) if (!(i == 0 && j == 0 || i == 0 && j == numAlign - 1 || i == numAlign - 1 && j == 0)) this.drawAlignmentPattern(alignPatPos[i], alignPatPos[j]);
20393
+ this.drawFormatBits(0);
20394
+ this.drawVersion();
20395
+ }
20396
+ drawFormatBits(mask) {
20397
+ const data = this.errorCorrectionLevel.formatBits << 3 | mask;
20398
+ let rem = data;
20399
+ for (let i = 0; i < 10; i++) rem = rem << 1 ^ (rem >>> 9) * 1335;
20400
+ const bits = (data << 10 | rem) ^ 21522;
20401
+ assert(bits >>> 15 == 0);
20402
+ for (let i = 0; i <= 5; i++) this.setFunctionModule(8, i, getBit(bits, i));
20403
+ this.setFunctionModule(8, 7, getBit(bits, 6));
20404
+ this.setFunctionModule(8, 8, getBit(bits, 7));
20405
+ this.setFunctionModule(7, 8, getBit(bits, 8));
20406
+ for (let i = 9; i < 15; i++) this.setFunctionModule(14 - i, 8, getBit(bits, i));
20407
+ for (let i = 0; i < 8; i++) this.setFunctionModule(this.size - 1 - i, 8, getBit(bits, i));
20408
+ for (let i = 8; i < 15; i++) this.setFunctionModule(8, this.size - 15 + i, getBit(bits, i));
20409
+ this.setFunctionModule(8, this.size - 8, true);
20410
+ }
20411
+ drawVersion() {
20412
+ if (this.version < 7) return;
20413
+ let rem = this.version;
20414
+ for (let i = 0; i < 12; i++) rem = rem << 1 ^ (rem >>> 11) * 7973;
20415
+ const bits = this.version << 12 | rem;
20416
+ assert(bits >>> 18 == 0);
20417
+ for (let i = 0; i < 18; i++) {
20418
+ const color = getBit(bits, i);
20419
+ const a = this.size - 11 + i % 3;
20420
+ const b = Math.floor(i / 3);
20421
+ this.setFunctionModule(a, b, color);
20422
+ this.setFunctionModule(b, a, color);
20423
+ }
20424
+ }
20425
+ drawFinderPattern(x, y) {
20426
+ for (let dy = -4; dy <= 4; dy++) for (let dx = -4; dx <= 4; dx++) {
20427
+ const dist = Math.max(Math.abs(dx), Math.abs(dy));
20428
+ const xx = x + dx;
20429
+ const yy = y + dy;
20430
+ if (0 <= xx && xx < this.size && 0 <= yy && yy < this.size) this.setFunctionModule(xx, yy, dist != 2 && dist != 4);
20431
+ }
20432
+ }
20433
+ drawAlignmentPattern(x, y) {
20434
+ for (let dy = -2; dy <= 2; dy++) for (let dx = -2; dx <= 2; dx++) this.setFunctionModule(x + dx, y + dy, Math.max(Math.abs(dx), Math.abs(dy)) != 1);
20435
+ }
20436
+ setFunctionModule(x, y, isDark) {
20437
+ this.modules[y][x] = isDark;
20438
+ this.isFunction[y][x] = true;
20439
+ }
20440
+ addEccAndInterleave(data) {
20441
+ const ver = this.version;
20442
+ const ecl = this.errorCorrectionLevel;
20443
+ if (data.length != _QrCode.getNumDataCodewords(ver, ecl)) throw new RangeError("Invalid argument");
20444
+ const numBlocks = _QrCode.NUM_ERROR_CORRECTION_BLOCKS[ecl.ordinal][ver];
20445
+ const blockEccLen = _QrCode.ECC_CODEWORDS_PER_BLOCK[ecl.ordinal][ver];
20446
+ const rawCodewords = Math.floor(_QrCode.getNumRawDataModules(ver) / 8);
20447
+ const numShortBlocks = numBlocks - rawCodewords % numBlocks;
20448
+ const shortBlockLen = Math.floor(rawCodewords / numBlocks);
20449
+ let blocks = [];
20450
+ const rsDiv = _QrCode.reedSolomonComputeDivisor(blockEccLen);
20451
+ for (let i = 0, k = 0; i < numBlocks; i++) {
20452
+ let dat = data.slice(k, k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1));
20453
+ k += dat.length;
20454
+ const ecc = _QrCode.reedSolomonComputeRemainder(dat, rsDiv);
20455
+ if (i < numShortBlocks) dat.push(0);
20456
+ blocks.push(dat.concat(ecc));
20457
+ }
20458
+ let result = [];
20459
+ for (let i = 0; i < blocks[0].length; i++) blocks.forEach((block, j) => {
20460
+ if (i != shortBlockLen - blockEccLen || j >= numShortBlocks) result.push(block[i]);
20461
+ });
20462
+ assert(result.length == rawCodewords);
20463
+ return result;
20464
+ }
20465
+ drawCodewords(data) {
20466
+ if (data.length != Math.floor(_QrCode.getNumRawDataModules(this.version) / 8)) throw new RangeError("Invalid argument");
20467
+ let i = 0;
20468
+ for (let right = this.size - 1; right >= 1; right -= 2) {
20469
+ if (right == 6) right = 5;
20470
+ for (let vert = 0; vert < this.size; vert++) for (let j = 0; j < 2; j++) {
20471
+ const x = right - j;
20472
+ const y = (right + 1 & 2) == 0 ? this.size - 1 - vert : vert;
20473
+ if (!this.isFunction[y][x] && i < data.length * 8) {
20474
+ this.modules[y][x] = getBit(data[i >>> 3], 7 - (i & 7));
20475
+ i++;
20476
+ }
20477
+ }
20478
+ }
20479
+ assert(i == data.length * 8);
20480
+ }
20481
+ applyMask(mask) {
20482
+ if (mask < 0 || mask > 7) throw new RangeError("Mask value out of range");
20483
+ for (let y = 0; y < this.size; y++) for (let x = 0; x < this.size; x++) {
20484
+ let invert;
20485
+ switch (mask) {
20486
+ case 0:
20487
+ invert = (x + y) % 2 == 0;
20488
+ break;
20489
+ case 1:
20490
+ invert = y % 2 == 0;
20491
+ break;
20492
+ case 2:
20493
+ invert = x % 3 == 0;
20494
+ break;
20495
+ case 3:
20496
+ invert = (x + y) % 3 == 0;
20497
+ break;
20498
+ case 4:
20499
+ invert = (Math.floor(x / 3) + Math.floor(y / 2)) % 2 == 0;
20500
+ break;
20501
+ case 5:
20502
+ invert = x * y % 2 + x * y % 3 == 0;
20503
+ break;
20504
+ case 6:
20505
+ invert = (x * y % 2 + x * y % 3) % 2 == 0;
20506
+ break;
20507
+ case 7:
20508
+ invert = ((x + y) % 2 + x * y % 3) % 2 == 0;
20509
+ break;
20510
+ default: throw new Error("Unreachable");
20511
+ }
20512
+ if (!this.isFunction[y][x] && invert) this.modules[y][x] = !this.modules[y][x];
20513
+ }
20514
+ }
20515
+ getPenaltyScore() {
20516
+ let result = 0;
20517
+ for (let y = 0; y < this.size; y++) {
20518
+ let runColor = false;
20519
+ let runX = 0;
20520
+ let runHistory = [
20521
+ 0,
20522
+ 0,
20523
+ 0,
20524
+ 0,
20525
+ 0,
20526
+ 0,
20527
+ 0
20528
+ ];
20529
+ for (let x = 0; x < this.size; x++) if (this.modules[y][x] == runColor) {
20530
+ runX++;
20531
+ if (runX == 5) result += _QrCode.PENALTY_N1;
20532
+ else if (runX > 5) result++;
20533
+ } else {
20534
+ this.finderPenaltyAddHistory(runX, runHistory);
20535
+ if (!runColor) result += this.finderPenaltyCountPatterns(runHistory) * _QrCode.PENALTY_N3;
20536
+ runColor = this.modules[y][x];
20537
+ runX = 1;
20538
+ }
20539
+ result += this.finderPenaltyTerminateAndCount(runColor, runX, runHistory) * _QrCode.PENALTY_N3;
20540
+ }
20541
+ for (let x = 0; x < this.size; x++) {
20542
+ let runColor = false;
20543
+ let runY = 0;
20544
+ let runHistory = [
20545
+ 0,
20546
+ 0,
20547
+ 0,
20548
+ 0,
20549
+ 0,
20550
+ 0,
20551
+ 0
20552
+ ];
20553
+ for (let y = 0; y < this.size; y++) if (this.modules[y][x] == runColor) {
20554
+ runY++;
20555
+ if (runY == 5) result += _QrCode.PENALTY_N1;
20556
+ else if (runY > 5) result++;
20557
+ } else {
20558
+ this.finderPenaltyAddHistory(runY, runHistory);
20559
+ if (!runColor) result += this.finderPenaltyCountPatterns(runHistory) * _QrCode.PENALTY_N3;
20560
+ runColor = this.modules[y][x];
20561
+ runY = 1;
20562
+ }
20563
+ result += this.finderPenaltyTerminateAndCount(runColor, runY, runHistory) * _QrCode.PENALTY_N3;
20564
+ }
20565
+ for (let y = 0; y < this.size - 1; y++) for (let x = 0; x < this.size - 1; x++) {
20566
+ const color = this.modules[y][x];
20567
+ if (color == this.modules[y][x + 1] && color == this.modules[y + 1][x] && color == this.modules[y + 1][x + 1]) result += _QrCode.PENALTY_N2;
20568
+ }
20569
+ let dark = 0;
20570
+ for (const row of this.modules) dark = row.reduce((sum, color) => sum + (color ? 1 : 0), dark);
20571
+ const total = this.size * this.size;
20572
+ const k = Math.ceil(Math.abs(dark * 20 - total * 10) / total) - 1;
20573
+ assert(0 <= k && k <= 9);
20574
+ result += k * _QrCode.PENALTY_N4;
20575
+ assert(0 <= result && result <= 2568888);
20576
+ return result;
20577
+ }
20578
+ getAlignmentPatternPositions() {
20579
+ if (this.version == 1) return [];
20580
+ else {
20581
+ const numAlign = Math.floor(this.version / 7) + 2;
20582
+ const step = this.version == 32 ? 26 : Math.ceil((this.version * 4 + 4) / (numAlign * 2 - 2)) * 2;
20583
+ let result = [6];
20584
+ for (let pos = this.size - 7; result.length < numAlign; pos -= step) result.splice(1, 0, pos);
20585
+ return result;
20586
+ }
20587
+ }
20588
+ static getNumRawDataModules(ver) {
20589
+ if (ver < _QrCode.MIN_VERSION || ver > _QrCode.MAX_VERSION) throw new RangeError("Version number out of range");
20590
+ let result = (16 * ver + 128) * ver + 64;
20591
+ if (ver >= 2) {
20592
+ const numAlign = Math.floor(ver / 7) + 2;
20593
+ result -= (25 * numAlign - 10) * numAlign - 55;
20594
+ if (ver >= 7) result -= 36;
20595
+ }
20596
+ assert(208 <= result && result <= 29648);
20597
+ return result;
20598
+ }
20599
+ static getNumDataCodewords(ver, ecl) {
20600
+ return Math.floor(_QrCode.getNumRawDataModules(ver) / 8) - _QrCode.ECC_CODEWORDS_PER_BLOCK[ecl.ordinal][ver] * _QrCode.NUM_ERROR_CORRECTION_BLOCKS[ecl.ordinal][ver];
20601
+ }
20602
+ static reedSolomonComputeDivisor(degree) {
20603
+ if (degree < 1 || degree > 255) throw new RangeError("Degree out of range");
20604
+ let result = [];
20605
+ for (let i = 0; i < degree - 1; i++) result.push(0);
20606
+ result.push(1);
20607
+ let root = 1;
20608
+ for (let i = 0; i < degree; i++) {
20609
+ for (let j = 0; j < result.length; j++) {
20610
+ result[j] = _QrCode.reedSolomonMultiply(result[j], root);
20611
+ if (j + 1 < result.length) result[j] ^= result[j + 1];
20612
+ }
20613
+ root = _QrCode.reedSolomonMultiply(root, 2);
20614
+ }
20615
+ return result;
20616
+ }
20617
+ static reedSolomonComputeRemainder(data, divisor) {
20618
+ let result = divisor.map((_) => 0);
20619
+ for (const b of data) {
20620
+ const factor = b ^ result.shift();
20621
+ result.push(0);
20622
+ divisor.forEach((coef, i) => result[i] ^= _QrCode.reedSolomonMultiply(coef, factor));
20623
+ }
20624
+ return result;
20625
+ }
20626
+ static reedSolomonMultiply(x, y) {
20627
+ if (x >>> 8 != 0 || y >>> 8 != 0) throw new RangeError("Byte out of range");
20628
+ let z = 0;
20629
+ for (let i = 7; i >= 0; i--) {
20630
+ z = z << 1 ^ (z >>> 7) * 285;
20631
+ z ^= (y >>> i & 1) * x;
20632
+ }
20633
+ assert(z >>> 8 == 0);
20634
+ return z;
20635
+ }
20636
+ finderPenaltyCountPatterns(runHistory) {
20637
+ const n = runHistory[1];
20638
+ assert(n <= this.size * 3);
20639
+ const core = n > 0 && runHistory[2] == n && runHistory[3] == n * 3 && runHistory[4] == n && runHistory[5] == n;
20640
+ return (core && runHistory[0] >= n * 4 && runHistory[6] >= n ? 1 : 0) + (core && runHistory[6] >= n * 4 && runHistory[0] >= n ? 1 : 0);
20641
+ }
20642
+ finderPenaltyTerminateAndCount(currentRunColor, currentRunLength, runHistory) {
20643
+ if (currentRunColor) {
20644
+ this.finderPenaltyAddHistory(currentRunLength, runHistory);
20645
+ currentRunLength = 0;
20646
+ }
20647
+ currentRunLength += this.size;
20648
+ this.finderPenaltyAddHistory(currentRunLength, runHistory);
20649
+ return this.finderPenaltyCountPatterns(runHistory);
20650
+ }
20651
+ finderPenaltyAddHistory(currentRunLength, runHistory) {
20652
+ if (runHistory[0] == 0) currentRunLength += this.size;
20653
+ runHistory.pop();
20654
+ runHistory.unshift(currentRunLength);
20655
+ }
20656
+ };
20657
+ _QrCode.MIN_VERSION = 1;
20658
+ _QrCode.MAX_VERSION = 40;
20659
+ _QrCode.PENALTY_N1 = 3;
20660
+ _QrCode.PENALTY_N2 = 3;
20661
+ _QrCode.PENALTY_N3 = 40;
20662
+ _QrCode.PENALTY_N4 = 10;
20663
+ _QrCode.ECC_CODEWORDS_PER_BLOCK = [
20664
+ [
20665
+ -1,
20666
+ 7,
20667
+ 10,
20668
+ 15,
20669
+ 20,
20670
+ 26,
20671
+ 18,
20672
+ 20,
20673
+ 24,
20674
+ 30,
20675
+ 18,
20676
+ 20,
20677
+ 24,
20678
+ 26,
20679
+ 30,
20680
+ 22,
20681
+ 24,
20682
+ 28,
20683
+ 30,
20684
+ 28,
20685
+ 28,
20686
+ 28,
20687
+ 28,
20688
+ 30,
20689
+ 30,
20690
+ 26,
20691
+ 28,
20692
+ 30,
20693
+ 30,
20694
+ 30,
20695
+ 30,
20696
+ 30,
20697
+ 30,
20698
+ 30,
20699
+ 30,
20700
+ 30,
20701
+ 30,
20702
+ 30,
20703
+ 30,
20704
+ 30,
20705
+ 30
20706
+ ],
20707
+ [
20708
+ -1,
20709
+ 10,
20710
+ 16,
20711
+ 26,
20712
+ 18,
20713
+ 24,
20714
+ 16,
20715
+ 18,
20716
+ 22,
20717
+ 22,
20718
+ 26,
20719
+ 30,
20720
+ 22,
20721
+ 22,
20722
+ 24,
20723
+ 24,
20724
+ 28,
20725
+ 28,
20726
+ 26,
20727
+ 26,
20728
+ 26,
20729
+ 26,
20730
+ 28,
20731
+ 28,
20732
+ 28,
20733
+ 28,
20734
+ 28,
20735
+ 28,
20736
+ 28,
20737
+ 28,
20738
+ 28,
20739
+ 28,
20740
+ 28,
20741
+ 28,
20742
+ 28,
20743
+ 28,
20744
+ 28,
20745
+ 28,
20746
+ 28,
20747
+ 28,
20748
+ 28
20749
+ ],
20750
+ [
20751
+ -1,
20752
+ 13,
20753
+ 22,
20754
+ 18,
20755
+ 26,
20756
+ 18,
20757
+ 24,
20758
+ 18,
20759
+ 22,
20760
+ 20,
20761
+ 24,
20762
+ 28,
20763
+ 26,
20764
+ 24,
20765
+ 20,
20766
+ 30,
20767
+ 24,
20768
+ 28,
20769
+ 28,
20770
+ 26,
20771
+ 30,
20772
+ 28,
20773
+ 30,
20774
+ 30,
20775
+ 30,
20776
+ 30,
20777
+ 28,
20778
+ 30,
20779
+ 30,
20780
+ 30,
20781
+ 30,
20782
+ 30,
20783
+ 30,
20784
+ 30,
20785
+ 30,
20786
+ 30,
20787
+ 30,
20788
+ 30,
20789
+ 30,
20790
+ 30,
20791
+ 30
20792
+ ],
20793
+ [
20794
+ -1,
20795
+ 17,
20796
+ 28,
20797
+ 22,
20798
+ 16,
20799
+ 22,
20800
+ 28,
20801
+ 26,
20802
+ 26,
20803
+ 24,
20804
+ 28,
20805
+ 24,
20806
+ 28,
20807
+ 22,
20808
+ 24,
20809
+ 24,
20810
+ 30,
20811
+ 28,
20812
+ 28,
20813
+ 26,
20814
+ 28,
20815
+ 30,
20816
+ 24,
20817
+ 30,
20818
+ 30,
20819
+ 30,
20820
+ 30,
20821
+ 30,
20822
+ 30,
20823
+ 30,
20824
+ 30,
20825
+ 30,
20826
+ 30,
20827
+ 30,
20828
+ 30,
20829
+ 30,
20830
+ 30,
20831
+ 30,
20832
+ 30,
20833
+ 30,
20834
+ 30
20835
+ ]
20836
+ ];
20837
+ _QrCode.NUM_ERROR_CORRECTION_BLOCKS = [
20838
+ [
20839
+ -1,
20840
+ 1,
20841
+ 1,
20842
+ 1,
20843
+ 1,
20844
+ 1,
20845
+ 2,
20846
+ 2,
20847
+ 2,
20848
+ 2,
20849
+ 4,
20850
+ 4,
20851
+ 4,
20852
+ 4,
20853
+ 4,
20854
+ 6,
20855
+ 6,
20856
+ 6,
20857
+ 6,
20858
+ 7,
20859
+ 8,
20860
+ 8,
20861
+ 9,
20862
+ 9,
20863
+ 10,
20864
+ 12,
20865
+ 12,
20866
+ 12,
20867
+ 13,
20868
+ 14,
20869
+ 15,
20870
+ 16,
20871
+ 17,
20872
+ 18,
20873
+ 19,
20874
+ 19,
20875
+ 20,
20876
+ 21,
20877
+ 22,
20878
+ 24,
20879
+ 25
20880
+ ],
20881
+ [
20882
+ -1,
20883
+ 1,
20884
+ 1,
20885
+ 1,
20886
+ 2,
20887
+ 2,
20888
+ 4,
20889
+ 4,
20890
+ 4,
20891
+ 5,
20892
+ 5,
20893
+ 5,
20894
+ 8,
20895
+ 9,
20896
+ 9,
20897
+ 10,
20898
+ 10,
20899
+ 11,
20900
+ 13,
20901
+ 14,
20902
+ 16,
20903
+ 17,
20904
+ 17,
20905
+ 18,
20906
+ 20,
20907
+ 21,
20908
+ 23,
20909
+ 25,
20910
+ 26,
20911
+ 28,
20912
+ 29,
20913
+ 31,
20914
+ 33,
20915
+ 35,
20916
+ 37,
20917
+ 38,
20918
+ 40,
20919
+ 43,
20920
+ 45,
20921
+ 47,
20922
+ 49
20923
+ ],
20924
+ [
20925
+ -1,
20926
+ 1,
20927
+ 1,
20928
+ 2,
20929
+ 2,
20930
+ 4,
20931
+ 4,
20932
+ 6,
20933
+ 6,
20934
+ 8,
20935
+ 8,
20936
+ 8,
20937
+ 10,
20938
+ 12,
20939
+ 16,
20940
+ 12,
20941
+ 17,
20942
+ 16,
20943
+ 18,
20944
+ 21,
20945
+ 20,
20946
+ 23,
20947
+ 23,
20948
+ 25,
20949
+ 27,
20950
+ 29,
20951
+ 34,
20952
+ 34,
20953
+ 35,
20954
+ 38,
20955
+ 40,
20956
+ 43,
20957
+ 45,
20958
+ 48,
20959
+ 51,
20960
+ 53,
20961
+ 56,
20962
+ 59,
20963
+ 62,
20964
+ 65,
20965
+ 68
20966
+ ],
20967
+ [
20968
+ -1,
20969
+ 1,
20970
+ 1,
20971
+ 2,
20972
+ 4,
20973
+ 4,
20974
+ 4,
20975
+ 5,
20976
+ 6,
20977
+ 8,
20978
+ 8,
20979
+ 11,
20980
+ 11,
20981
+ 16,
20982
+ 16,
20983
+ 18,
20984
+ 16,
20985
+ 19,
20986
+ 21,
20987
+ 25,
20988
+ 25,
20989
+ 25,
20990
+ 34,
20991
+ 30,
20992
+ 32,
20993
+ 35,
20994
+ 37,
20995
+ 40,
20996
+ 42,
20997
+ 45,
20998
+ 48,
20999
+ 51,
21000
+ 54,
21001
+ 57,
21002
+ 60,
21003
+ 63,
21004
+ 66,
21005
+ 70,
21006
+ 74,
21007
+ 77,
21008
+ 81
21009
+ ]
21010
+ ];
21011
+ qrcodegen2.QrCode = _QrCode;
21012
+ function appendBits(val, len, bb) {
21013
+ if (len < 0 || len > 31 || val >>> len != 0) throw new RangeError("Value out of range");
21014
+ for (let i = len - 1; i >= 0; i--) bb.push(val >>> i & 1);
21015
+ }
21016
+ function getBit(x, i) {
21017
+ return (x >>> i & 1) != 0;
21018
+ }
21019
+ function assert(cond) {
21020
+ if (!cond) throw new Error("Assertion error");
21021
+ }
21022
+ const _QrSegment = class _QrSegment {
21023
+ constructor(mode, numChars, bitData) {
21024
+ this.mode = mode;
21025
+ this.numChars = numChars;
21026
+ this.bitData = bitData;
21027
+ if (numChars < 0) throw new RangeError("Invalid argument");
21028
+ this.bitData = bitData.slice();
21029
+ }
21030
+ static makeBytes(data) {
21031
+ let bb = [];
21032
+ for (const b of data) appendBits(b, 8, bb);
21033
+ return new _QrSegment(_QrSegment.Mode.BYTE, data.length, bb);
21034
+ }
21035
+ static makeNumeric(digits) {
21036
+ if (!_QrSegment.isNumeric(digits)) throw new RangeError("String contains non-numeric characters");
21037
+ let bb = [];
21038
+ for (let i = 0; i < digits.length;) {
21039
+ const n = Math.min(digits.length - i, 3);
21040
+ appendBits(parseInt(digits.substring(i, i + n), 10), n * 3 + 1, bb);
21041
+ i += n;
21042
+ }
21043
+ return new _QrSegment(_QrSegment.Mode.NUMERIC, digits.length, bb);
21044
+ }
21045
+ static makeAlphanumeric(text) {
21046
+ if (!_QrSegment.isAlphanumeric(text)) throw new RangeError("String contains unencodable characters in alphanumeric mode");
21047
+ let bb = [];
21048
+ let i;
21049
+ for (i = 0; i + 2 <= text.length; i += 2) {
21050
+ let temp = _QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)) * 45;
21051
+ temp += _QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i + 1));
21052
+ appendBits(temp, 11, bb);
21053
+ }
21054
+ if (i < text.length) appendBits(_QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)), 6, bb);
21055
+ return new _QrSegment(_QrSegment.Mode.ALPHANUMERIC, text.length, bb);
21056
+ }
21057
+ static makeSegments(text) {
21058
+ if (text == "") return [];
21059
+ else if (_QrSegment.isNumeric(text)) return [_QrSegment.makeNumeric(text)];
21060
+ else if (_QrSegment.isAlphanumeric(text)) return [_QrSegment.makeAlphanumeric(text)];
21061
+ else return [_QrSegment.makeBytes(_QrSegment.toUtf8ByteArray(text))];
21062
+ }
21063
+ static makeEci(assignVal) {
21064
+ let bb = [];
21065
+ if (assignVal < 0) throw new RangeError("ECI assignment value out of range");
21066
+ else if (assignVal < 128) appendBits(assignVal, 8, bb);
21067
+ else if (assignVal < 16384) {
21068
+ appendBits(2, 2, bb);
21069
+ appendBits(assignVal, 14, bb);
21070
+ } else if (assignVal < 1e6) {
21071
+ appendBits(6, 3, bb);
21072
+ appendBits(assignVal, 21, bb);
21073
+ } else throw new RangeError("ECI assignment value out of range");
21074
+ return new _QrSegment(_QrSegment.Mode.ECI, 0, bb);
21075
+ }
21076
+ static isNumeric(text) {
21077
+ return _QrSegment.NUMERIC_REGEX.test(text);
21078
+ }
21079
+ static isAlphanumeric(text) {
21080
+ return _QrSegment.ALPHANUMERIC_REGEX.test(text);
21081
+ }
21082
+ getData() {
21083
+ return this.bitData.slice();
21084
+ }
21085
+ static getTotalBits(segs, version) {
21086
+ let result = 0;
21087
+ for (const seg of segs) {
21088
+ const ccbits = seg.mode.numCharCountBits(version);
21089
+ if (seg.numChars >= 1 << ccbits) return Infinity;
21090
+ result += 4 + ccbits + seg.bitData.length;
21091
+ }
21092
+ return result;
21093
+ }
21094
+ static toUtf8ByteArray(str) {
21095
+ str = encodeURI(str);
21096
+ let result = [];
21097
+ for (let i = 0; i < str.length; i++) if (str.charAt(i) != "%") result.push(str.charCodeAt(i));
21098
+ else {
21099
+ result.push(parseInt(str.substring(i + 1, i + 3), 16));
21100
+ i += 2;
21101
+ }
21102
+ return result;
21103
+ }
21104
+ };
21105
+ _QrSegment.NUMERIC_REGEX = /^[0-9]*$/;
21106
+ _QrSegment.ALPHANUMERIC_REGEX = /^[A-Z0-9 $%*+.\/:-]*$/;
21107
+ _QrSegment.ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
21108
+ let QrSegment = _QrSegment;
21109
+ qrcodegen2.QrSegment = _QrSegment;
21110
+ })(qrcodegen || (qrcodegen = {}));
21111
+ ((qrcodegen2) => {
21112
+ ((QrCode2) => {
21113
+ const _Ecc = class _Ecc {
21114
+ constructor(ordinal, formatBits) {
21115
+ this.ordinal = ordinal;
21116
+ this.formatBits = formatBits;
21117
+ }
21118
+ };
21119
+ _Ecc.LOW = new _Ecc(0, 1);
21120
+ _Ecc.MEDIUM = new _Ecc(1, 0);
21121
+ _Ecc.QUARTILE = new _Ecc(2, 3);
21122
+ _Ecc.HIGH = new _Ecc(3, 2);
21123
+ QrCode2.Ecc = _Ecc;
21124
+ })(qrcodegen2.QrCode || (qrcodegen2.QrCode = {}));
21125
+ })(qrcodegen || (qrcodegen = {}));
21126
+ ((qrcodegen2) => {
21127
+ ((QrSegment2) => {
21128
+ const _Mode = class _Mode {
21129
+ constructor(modeBits, numBitsCharCount) {
21130
+ this.modeBits = modeBits;
21131
+ this.numBitsCharCount = numBitsCharCount;
21132
+ }
21133
+ numCharCountBits(ver) {
21134
+ return this.numBitsCharCount[Math.floor((ver + 7) / 17)];
21135
+ }
21136
+ };
21137
+ _Mode.NUMERIC = new _Mode(1, [
21138
+ 10,
21139
+ 12,
21140
+ 14
21141
+ ]);
21142
+ _Mode.ALPHANUMERIC = new _Mode(2, [
21143
+ 9,
21144
+ 11,
21145
+ 13
21146
+ ]);
21147
+ _Mode.BYTE = new _Mode(4, [
21148
+ 8,
21149
+ 16,
21150
+ 16
21151
+ ]);
21152
+ _Mode.KANJI = new _Mode(8, [
21153
+ 8,
21154
+ 10,
21155
+ 12
21156
+ ]);
21157
+ _Mode.ECI = new _Mode(7, [
21158
+ 0,
21159
+ 0,
21160
+ 0
21161
+ ]);
21162
+ QrSegment2.Mode = _Mode;
21163
+ })(qrcodegen2.QrSegment || (qrcodegen2.QrSegment = {}));
21164
+ })(qrcodegen || (qrcodegen = {}));
21165
+ var qrcodegen_default = qrcodegen;
21166
+ /**
21167
+ * @license qrcode.react
21168
+ * Copyright (c) Paul O'Shannessy
21169
+ * SPDX-License-Identifier: ISC
21170
+ */
21171
+ var ERROR_LEVEL_MAP = {
21172
+ L: qrcodegen_default.QrCode.Ecc.LOW,
21173
+ M: qrcodegen_default.QrCode.Ecc.MEDIUM,
21174
+ Q: qrcodegen_default.QrCode.Ecc.QUARTILE,
21175
+ H: qrcodegen_default.QrCode.Ecc.HIGH
21176
+ };
21177
+ var DEFAULT_SIZE$1 = 128;
21178
+ var DEFAULT_LEVEL = "L";
21179
+ var DEFAULT_BGCOLOR = "#FFFFFF";
21180
+ var DEFAULT_FGCOLOR = "#000000";
21181
+ var DEFAULT_INCLUDEMARGIN = false;
21182
+ var DEFAULT_MINVERSION = 1;
21183
+ var SPEC_MARGIN_SIZE = 4;
21184
+ var DEFAULT_MARGIN_SIZE = 0;
21185
+ var DEFAULT_IMG_SCALE = .1;
21186
+ function generatePath(modules, margin = 0) {
21187
+ const ops = [];
21188
+ modules.forEach(function(row, y) {
21189
+ let start = null;
21190
+ row.forEach(function(cell, x) {
21191
+ if (!cell && start !== null) {
21192
+ ops.push(`M${start + margin} ${y + margin}h${x - start}v1H${start + margin}z`);
21193
+ start = null;
21194
+ return;
21195
+ }
21196
+ if (x === row.length - 1) {
21197
+ if (!cell) return;
21198
+ if (start === null) ops.push(`M${x + margin},${y + margin} h1v1H${x + margin}z`);
21199
+ else ops.push(`M${start + margin},${y + margin} h${x + 1 - start}v1H${start + margin}z`);
21200
+ return;
21201
+ }
21202
+ if (cell && start === null) start = x;
21203
+ });
21204
+ });
21205
+ return ops.join("");
21206
+ }
21207
+ function excavateModules(modules, excavation) {
21208
+ return modules.slice().map((row, y) => {
21209
+ if (y < excavation.y || y >= excavation.y + excavation.h) return row;
21210
+ return row.map((cell, x) => {
21211
+ if (x < excavation.x || x >= excavation.x + excavation.w) return cell;
21212
+ return false;
21213
+ });
21214
+ });
21215
+ }
21216
+ function getImageSettings(cells, size, margin, imageSettings) {
21217
+ if (imageSettings == null) return null;
21218
+ const numCells = cells.length + margin * 2;
21219
+ const defaultSize = Math.floor(size * DEFAULT_IMG_SCALE);
21220
+ const scale = numCells / size;
21221
+ const w = (imageSettings.width || defaultSize) * scale;
21222
+ const h = (imageSettings.height || defaultSize) * scale;
21223
+ const x = imageSettings.x == null ? cells.length / 2 - w / 2 : imageSettings.x * scale;
21224
+ const y = imageSettings.y == null ? cells.length / 2 - h / 2 : imageSettings.y * scale;
21225
+ const opacity = imageSettings.opacity == null ? 1 : imageSettings.opacity;
21226
+ let excavation = null;
21227
+ if (imageSettings.excavate) {
21228
+ let floorX = Math.floor(x);
21229
+ let floorY = Math.floor(y);
21230
+ excavation = {
21231
+ x: floorX,
21232
+ y: floorY,
21233
+ w: Math.ceil(w + x - floorX),
21234
+ h: Math.ceil(h + y - floorY)
21235
+ };
21236
+ }
21237
+ const crossOrigin = imageSettings.crossOrigin;
21238
+ return {
21239
+ x,
21240
+ y,
21241
+ h,
21242
+ w,
21243
+ excavation,
21244
+ opacity,
21245
+ crossOrigin
21246
+ };
21247
+ }
21248
+ function getMarginSize(includeMargin, marginSize) {
21249
+ if (marginSize != null) return Math.max(Math.floor(marginSize), 0);
21250
+ return includeMargin ? SPEC_MARGIN_SIZE : DEFAULT_MARGIN_SIZE;
21251
+ }
21252
+ function useQRCode({ value, level, minVersion, includeMargin, marginSize, imageSettings, size, boostLevel }) {
21253
+ let qrcode = react.default.useMemo(() => {
21254
+ const segments = (Array.isArray(value) ? value : [value]).reduce((accum, v) => {
21255
+ accum.push(...qrcodegen_default.QrSegment.makeSegments(v));
21256
+ return accum;
21257
+ }, []);
21258
+ return qrcodegen_default.QrCode.encodeSegments(segments, ERROR_LEVEL_MAP[level], minVersion, void 0, void 0, boostLevel);
21259
+ }, [
21260
+ value,
21261
+ level,
21262
+ minVersion,
21263
+ boostLevel
21264
+ ]);
21265
+ const { cells, margin, numCells, calculatedImageSettings } = react.default.useMemo(() => {
21266
+ let cells2 = qrcode.getModules();
21267
+ const margin2 = getMarginSize(includeMargin, marginSize);
21268
+ return {
21269
+ cells: cells2,
21270
+ margin: margin2,
21271
+ numCells: cells2.length + margin2 * 2,
21272
+ calculatedImageSettings: getImageSettings(cells2, size, margin2, imageSettings)
21273
+ };
21274
+ }, [
21275
+ qrcode,
21276
+ size,
21277
+ imageSettings,
21278
+ includeMargin,
21279
+ marginSize
21280
+ ]);
21281
+ return {
21282
+ qrcode,
21283
+ margin,
21284
+ cells,
21285
+ numCells,
21286
+ calculatedImageSettings
21287
+ };
21288
+ }
21289
+ var SUPPORTS_PATH2D = function() {
21290
+ try {
21291
+ new Path2D().addPath(new Path2D());
21292
+ } catch (e) {
21293
+ return false;
21294
+ }
21295
+ return true;
21296
+ }();
21297
+ var QRCodeCanvas = react.default.forwardRef(function QRCodeCanvas2(props, forwardedRef) {
21298
+ const _a = props, { value, size = DEFAULT_SIZE$1, level = DEFAULT_LEVEL, bgColor = DEFAULT_BGCOLOR, fgColor = DEFAULT_FGCOLOR, includeMargin = DEFAULT_INCLUDEMARGIN, minVersion = DEFAULT_MINVERSION, boostLevel, marginSize, imageSettings } = _a;
21299
+ const _b = __objRest(_a, [
21300
+ "value",
21301
+ "size",
21302
+ "level",
21303
+ "bgColor",
21304
+ "fgColor",
21305
+ "includeMargin",
21306
+ "minVersion",
21307
+ "boostLevel",
21308
+ "marginSize",
21309
+ "imageSettings"
21310
+ ]), { style } = _b, otherProps = __objRest(_b, ["style"]);
21311
+ const imgSrc = imageSettings == null ? void 0 : imageSettings.src;
21312
+ const _canvas = react.default.useRef(null);
21313
+ const _image = react.default.useRef(null);
21314
+ const setCanvasRef = react.default.useCallback((node) => {
21315
+ _canvas.current = node;
21316
+ if (typeof forwardedRef === "function") forwardedRef(node);
21317
+ else if (forwardedRef) forwardedRef.current = node;
21318
+ }, [forwardedRef]);
21319
+ const [isImgLoaded, setIsImageLoaded] = react.default.useState(false);
21320
+ const { margin, cells, numCells, calculatedImageSettings } = useQRCode({
21321
+ value,
21322
+ level,
21323
+ minVersion,
21324
+ boostLevel,
21325
+ includeMargin,
21326
+ marginSize,
21327
+ imageSettings,
21328
+ size
21329
+ });
21330
+ react.default.useEffect(() => {
21331
+ if (_canvas.current != null) {
21332
+ const canvas = _canvas.current;
21333
+ const ctx = canvas.getContext("2d");
21334
+ if (!ctx) return;
21335
+ let cellsToDraw = cells;
21336
+ const image = _image.current;
21337
+ const haveImageToRender = calculatedImageSettings != null && image !== null && image.complete && image.naturalHeight !== 0 && image.naturalWidth !== 0;
21338
+ if (haveImageToRender) {
21339
+ if (calculatedImageSettings.excavation != null) cellsToDraw = excavateModules(cells, calculatedImageSettings.excavation);
21340
+ }
21341
+ const pixelRatio = window.devicePixelRatio || 1;
21342
+ canvas.height = canvas.width = size * pixelRatio;
21343
+ const scale = size / numCells * pixelRatio;
21344
+ ctx.scale(scale, scale);
21345
+ ctx.fillStyle = bgColor;
21346
+ ctx.fillRect(0, 0, numCells, numCells);
21347
+ ctx.fillStyle = fgColor;
21348
+ if (SUPPORTS_PATH2D) ctx.fill(new Path2D(generatePath(cellsToDraw, margin)));
21349
+ else cells.forEach(function(row, rdx) {
21350
+ row.forEach(function(cell, cdx) {
21351
+ if (cell) ctx.fillRect(cdx + margin, rdx + margin, 1, 1);
21352
+ });
21353
+ });
21354
+ if (calculatedImageSettings) ctx.globalAlpha = calculatedImageSettings.opacity;
21355
+ if (haveImageToRender) ctx.drawImage(image, calculatedImageSettings.x + margin, calculatedImageSettings.y + margin, calculatedImageSettings.w, calculatedImageSettings.h);
21356
+ }
21357
+ });
21358
+ react.default.useEffect(() => {
21359
+ setIsImageLoaded(false);
21360
+ }, [imgSrc]);
21361
+ const canvasStyle = __spreadValues({
21362
+ height: size,
21363
+ width: size
21364
+ }, style);
21365
+ let img = null;
21366
+ if (imgSrc != null) img = /* @__PURE__ */ react.default.createElement("img", {
21367
+ src: imgSrc,
21368
+ key: imgSrc,
21369
+ style: { display: "none" },
21370
+ onLoad: () => {
21371
+ setIsImageLoaded(true);
21372
+ },
21373
+ ref: _image,
21374
+ crossOrigin: calculatedImageSettings == null ? void 0 : calculatedImageSettings.crossOrigin
21375
+ });
21376
+ return /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, /* @__PURE__ */ react.default.createElement("canvas", __spreadValues({
21377
+ style: canvasStyle,
21378
+ height: size,
21379
+ width: size,
21380
+ ref: setCanvasRef,
21381
+ role: "img"
21382
+ }, otherProps)), img);
21383
+ });
21384
+ QRCodeCanvas.displayName = "QRCodeCanvas";
21385
+ var QRCodeSVG = react.default.forwardRef(function QRCodeSVG2(props, forwardedRef) {
21386
+ const _a = props, { value, size = DEFAULT_SIZE$1, level = DEFAULT_LEVEL, bgColor = DEFAULT_BGCOLOR, fgColor = DEFAULT_FGCOLOR, includeMargin = DEFAULT_INCLUDEMARGIN, minVersion = DEFAULT_MINVERSION, boostLevel, title, marginSize, imageSettings } = _a, otherProps = __objRest(_a, [
21387
+ "value",
21388
+ "size",
21389
+ "level",
21390
+ "bgColor",
21391
+ "fgColor",
21392
+ "includeMargin",
21393
+ "minVersion",
21394
+ "boostLevel",
21395
+ "title",
21396
+ "marginSize",
21397
+ "imageSettings"
21398
+ ]);
21399
+ const { margin, cells, numCells, calculatedImageSettings } = useQRCode({
21400
+ value,
21401
+ level,
21402
+ minVersion,
21403
+ boostLevel,
21404
+ includeMargin,
21405
+ marginSize,
21406
+ imageSettings,
21407
+ size
21408
+ });
21409
+ let cellsToDraw = cells;
21410
+ let image = null;
21411
+ if (imageSettings != null && calculatedImageSettings != null) {
21412
+ if (calculatedImageSettings.excavation != null) cellsToDraw = excavateModules(cells, calculatedImageSettings.excavation);
21413
+ image = /* @__PURE__ */ react.default.createElement("image", {
21414
+ href: imageSettings.src,
21415
+ height: calculatedImageSettings.h,
21416
+ width: calculatedImageSettings.w,
21417
+ x: calculatedImageSettings.x + margin,
21418
+ y: calculatedImageSettings.y + margin,
21419
+ preserveAspectRatio: "none",
21420
+ opacity: calculatedImageSettings.opacity,
21421
+ crossOrigin: calculatedImageSettings.crossOrigin
21422
+ });
21423
+ }
21424
+ const fgPath = generatePath(cellsToDraw, margin);
21425
+ return /* @__PURE__ */ react.default.createElement("svg", __spreadValues({
21426
+ height: size,
21427
+ width: size,
21428
+ viewBox: `0 0 ${numCells} ${numCells}`,
21429
+ ref: forwardedRef,
21430
+ role: "img"
21431
+ }, otherProps), !!title && /* @__PURE__ */ react.default.createElement("title", null, title), /* @__PURE__ */ react.default.createElement("path", {
21432
+ fill: bgColor,
21433
+ d: `M0,0 h${numCells}v${numCells}H0z`,
21434
+ shapeRendering: "crispEdges"
21435
+ }), /* @__PURE__ */ react.default.createElement("path", {
21436
+ fill: fgColor,
21437
+ d: fgPath,
21438
+ shapeRendering: "crispEdges"
21439
+ }), image);
21440
+ });
21441
+ QRCodeSVG.displayName = "QRCodeSVG";
21442
+ //#endregion
21443
+ //#region src/composites/qr-code.tsx
21444
+ var DEFAULT_SIZE = 192;
21445
+ function QrCode({ value, size = DEFAULT_SIZE, className, alt }) {
21446
+ const trimmed = value.trim();
21447
+ if (trimmed.length === 0) return null;
21448
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
21449
+ className: cn("inline-flex rounded-md bg-white p-2", className),
21450
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QRCodeSVG, {
21451
+ value: trimmed,
21452
+ size,
21453
+ marginSize: 1,
21454
+ title: alt ?? "QR code"
21455
+ })
21456
+ });
21457
+ }
21458
+ //#endregion
21459
+ //#region src/composites/copy-button.tsx
21460
+ /**
21461
+ * `CopyButton` — a compact button that copies a string `value` to the
21462
+ * clipboard via `navigator.clipboard.writeText`, showing a brief
21463
+ * "copied" check state. Addon-agnostic; used wherever a secret / URL
21464
+ * needs a one-click copy affordance (export setup panels, etc.).
21465
+ */
21466
+ var COPIED_RESET_MS = 2e3;
21467
+ function CopyButton({ value, label, className, disabled }) {
21468
+ const [copied, setCopied] = (0, react$1.useState)(false);
21469
+ const handleCopy = (0, react$1.useCallback)(() => {
21470
+ if (!value) return;
21471
+ navigator.clipboard.writeText(value).then(() => {
21472
+ setCopied(true);
21473
+ setTimeout(() => setCopied(false), COPIED_RESET_MS);
21474
+ });
21475
+ }, [value]);
21476
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Button, {
21477
+ size: "sm",
21478
+ variant: "ghost",
21479
+ type: "button",
21480
+ disabled: disabled || value.length === 0,
21481
+ onClick: handleCopy,
21482
+ className: cn(className),
21483
+ "aria-label": copied ? "Copied" : `Copy ${label ?? "value"}`,
21484
+ children: [copied ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Check, { className: "h-3.5 w-3.5 text-success" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Copy, { className: "h-3.5 w-3.5" }), label ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
21485
+ className: "ml-1",
21486
+ children: copied ? "Copied" : label
21487
+ }) : null]
21488
+ });
21489
+ }
21490
+ //#endregion
21491
+ //#region src/composites/device-export-panel.tsx
21492
+ /**
21493
+ * DeviceExportPanel — generic, addon-agnostic surface for the
21494
+ * `device-export` capability.
21495
+ *
21496
+ * Renders the COMMON device-export surface for a single export addon
21497
+ * (HomeAssistant via MQTT, HomeKit/HAP, Alexa Smart Home, …):
21498
+ *
21499
+ * - a link-state status badge + exposed-device count from `getStatus`,
21500
+ * - the exposed-devices table from `listExposedDevices` (device name,
21501
+ * status, stream preference) with a per-row unexpose action
21502
+ * (`unexposeDevice`),
21503
+ * - an empty state directing the operator to the device-details page.
21504
+ *
21505
+ * This composite is the reusable replacement for the per-addon
21506
+ * Module-Federation overview tables that each export addon used to
21507
+ * ship. It is driven entirely by the `device-export` cap — there are no
21508
+ * Alexa / HAP / MQTT specifics here. Mount it next to an export addon's
21509
+ * standard settings form (e.g. in the addon-settings modal).
21510
+ *
21511
+ * Routing note: `device-export` is a collection cap; the codegen'd
21512
+ * router resolves `{ nodeId }` to the first registered provider. Export
21513
+ * addons are all `hub-only`, so the panel queries `nodeId: 'hub'`. When
21514
+ * multiple device-export addons are co-installed the cap-router today
21515
+ * resolves to the first provider only (per-provider routing is a
21516
+ * separate follow-up) — identical behaviour to the pages it replaces.
21517
+ */
21518
+ var ExposedDeviceArraySchema = zod.z.array(_camstack_types.ExposedDeviceSchema);
21519
+ var STATUS_POLL_INTERVAL_MS = 1e4;
21520
+ function statusVariant(state) {
21521
+ if (state === "linked") return "success";
21522
+ if (state === "error") return "danger";
21523
+ return "warning";
21524
+ }
21525
+ function capitaliseLinkState(state) {
21526
+ if (state === "linked") return "Linked";
21527
+ if (state === "unlinked") return "Unlinked";
21528
+ if (state === "error") return "Error";
21529
+ return state;
21530
+ }
21531
+ /**
21532
+ * A single label/value row in the Setup section. `secret` rows mask the
21533
+ * value behind a reveal toggle; every row gets a copy button.
21534
+ */
21535
+ function SetupFieldRow({ field }) {
21536
+ const [revealed, setRevealed] = (0, react$1.useState)(false);
21537
+ const isSecret = field.secret === true;
21538
+ const displayValue = isSecret && !revealed ? "•".repeat(Math.min(field.value.length, 24)) : field.value;
21539
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
21540
+ className: "flex items-center gap-2 py-1.5",
21541
+ children: [
21542
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
21543
+ className: "text-[11px] text-foreground-subtle w-32 shrink-0",
21544
+ children: field.label
21545
+ }),
21546
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
21547
+ className: "flex-1 min-w-0 truncate font-mono text-xs text-foreground",
21548
+ children: displayValue || "—"
21549
+ }),
21550
+ isSecret && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
21551
+ size: "sm",
21552
+ variant: "ghost",
21553
+ type: "button",
21554
+ "aria-label": revealed ? "Hide value" : "Reveal value",
21555
+ onClick: () => setRevealed((v) => !v),
21556
+ children: revealed ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EyeOff, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Eye, { className: "h-3.5 w-3.5" })
21557
+ }),
21558
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopyButton, {
21559
+ value: field.value,
21560
+ label: field.label
21561
+ })
21562
+ ]
21563
+ });
21564
+ }
21565
+ /**
21566
+ * Generic "Setup" section — pairing QR + copyable label/value rows +
21567
+ * operator note. Driven entirely by the cap's `setup` block; renders
21568
+ * nothing addon-specific.
21569
+ */
21570
+ function SetupSection({ setup }) {
21571
+ const fields = setup.fields ?? [];
21572
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
21573
+ className: "border-b border-border bg-surface-hover/10",
21574
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
21575
+ className: "flex items-center gap-2 px-4 py-2 border-b border-border",
21576
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(QrCode$1, { className: "h-3.5 w-3.5 text-foreground-subtle shrink-0" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
21577
+ className: "text-[11px] font-semibold text-foreground-subtle uppercase tracking-wide",
21578
+ children: "Setup"
21579
+ })]
21580
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
21581
+ className: "flex flex-col gap-3 p-4 sm:flex-row sm:items-start",
21582
+ children: [setup.qr && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
21583
+ className: "shrink-0",
21584
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QrCode, {
21585
+ value: setup.qr,
21586
+ alt: "Pairing QR code"
21587
+ })
21588
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
21589
+ className: "flex-1 min-w-0",
21590
+ children: [setup.note && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
21591
+ className: "text-xs text-foreground-muted whitespace-pre-line mb-2",
21592
+ children: setup.note
21593
+ }), fields.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
21594
+ className: "divide-y divide-border-subtle",
21595
+ children: fields.map((field) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SetupFieldRow, { field }, field.label))
21596
+ })]
21597
+ })]
21598
+ })]
21599
+ });
21600
+ }
21601
+ /**
21602
+ * Generic device-export panel. Addon-agnostic — only the `device-export`
21603
+ * cap drives it.
21604
+ */
21605
+ function DeviceExportPanel({ addonId, onOpenDevice }) {
21606
+ const queryClient = (0, _tanstack_react_query.useQueryClient)();
21607
+ const statusQuery = useDeviceExportGetStatus({ nodeId: "hub" }, {
21608
+ refetchInterval: STATUS_POLL_INTERVAL_MS,
21609
+ retry: false
21610
+ });
21611
+ const exposedQuery = useDeviceExportListExposedDevices({ nodeId: "hub" }, {
21612
+ refetchInterval: STATUS_POLL_INTERVAL_MS,
21613
+ retry: false
21614
+ });
21615
+ const unexposeMutation = useDeviceExportUnexposeDevice({ onSuccess: () => {
21616
+ queryClient.invalidateQueries({ queryKey: [["deviceExport"]] });
21617
+ } });
21618
+ const status = (0, react$1.useMemo)(() => {
21619
+ const parsed = _camstack_types.DeviceExportStatusSchema.safeParse(statusQuery.data);
21620
+ return parsed.success ? parsed.data : null;
21621
+ }, [statusQuery.data]);
21622
+ const exposed = (0, react$1.useMemo)(() => {
21623
+ const parsed = ExposedDeviceArraySchema.safeParse(exposedQuery.data);
21624
+ return parsed.success ? parsed.data : [];
21625
+ }, [exposedQuery.data]);
21626
+ const linkState = status?.linkState ?? "unlinked";
21627
+ const rows = (0, react$1.useMemo)(() => exposed.map((entry) => ({
21628
+ deviceId: entry.deviceId,
21629
+ displayName: entry.exposedAs ?? `Device ${entry.deviceId}`,
21630
+ streamPreference: "auto",
21631
+ linkState
21632
+ })), [exposed, linkState]);
21633
+ const loading = statusQuery.isLoading || exposedQuery.isLoading;
21634
+ const exposedCount = status?.exposedDeviceCount ?? rows.length;
21635
+ const columns = (0, react$1.useMemo)(() => [
21636
+ {
21637
+ key: "device",
21638
+ header: "Device",
21639
+ render: (row) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
21640
+ className: "flex flex-col",
21641
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
21642
+ className: "text-foreground font-medium",
21643
+ children: row.displayName
21644
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
21645
+ className: "text-foreground-subtle text-xs font-mono",
21646
+ children: ["#", row.deviceId]
21647
+ })]
21648
+ })
21649
+ },
21650
+ {
21651
+ key: "status",
21652
+ header: "Status",
21653
+ render: (row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Badge, {
21654
+ variant: statusVariant(row.linkState),
21655
+ children: capitaliseLinkState(row.linkState)
21656
+ })
21657
+ },
21658
+ {
21659
+ key: "stream",
21660
+ header: "Stream",
21661
+ render: (row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
21662
+ className: "text-xs text-foreground-subtle font-mono",
21663
+ children: row.streamPreference === "auto" ? "Auto" : row.streamPreference
21664
+ })
21665
+ },
21666
+ {
21667
+ key: "actions",
21668
+ header: "",
21669
+ align: "right",
21670
+ render: (row) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
21671
+ className: "flex items-center justify-end gap-2",
21672
+ children: [onOpenDevice && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Button, {
21673
+ size: "sm",
21674
+ variant: "ghost",
21675
+ onClick: () => onOpenDevice(row.deviceId),
21676
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ExternalLink, { className: "h-3.5 w-3.5 mr-1" }), "Open"]
21677
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Button, {
21678
+ size: "sm",
21679
+ variant: "ghost",
21680
+ disabled: unexposeMutation.isPending,
21681
+ onClick: () => unexposeMutation.mutate({
21682
+ deviceId: row.deviceId,
21683
+ nodeId: "hub"
21684
+ }),
21685
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Unlink2, { className: "h-3.5 w-3.5 mr-1" }), "Unexpose"]
21686
+ })]
21687
+ })
21688
+ }
21689
+ ], [onOpenDevice, unexposeMutation]);
21690
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
21691
+ className: "rounded-lg border border-border bg-surface overflow-hidden",
21692
+ children: [
21693
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
21694
+ className: "flex items-center justify-between gap-3 px-4 py-2.5 border-b border-border bg-surface-hover/20",
21695
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
21696
+ className: "flex items-center gap-2 min-w-0",
21697
+ children: [
21698
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Share2, { className: "h-3.5 w-3.5 text-foreground-subtle shrink-0" }),
21699
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
21700
+ className: "text-[11px] font-semibold text-foreground-subtle uppercase tracking-wide",
21701
+ children: "Exported devices"
21702
+ }),
21703
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Badge, {
21704
+ variant: statusVariant(linkState),
21705
+ children: capitaliseLinkState(linkState)
21706
+ }),
21707
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
21708
+ className: "text-[11px] text-foreground-subtle",
21709
+ children: [exposedCount, " exposed"]
21710
+ })
21711
+ ]
21712
+ }), loading && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LoaderCircle, { className: "h-3.5 w-3.5 animate-spin text-foreground-subtle" })]
21713
+ }),
21714
+ status?.error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
21715
+ className: "px-4 py-3 border-b border-border",
21716
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ErrorBox, { message: status.error })
21717
+ }),
21718
+ status?.setup && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SetupSection, { setup: status.setup }),
21719
+ rows.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmptyState, {
21720
+ icon: Share2,
21721
+ title: "No devices exposed",
21722
+ description: `Expose a camera to "${addonId}" from its device-details page to surface it in the connected ecosystem.`
21723
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
21724
+ className: "p-3",
21725
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DataTable, {
21726
+ columns,
21727
+ rows,
21728
+ rowKey: (row) => row.deviceId
21729
+ })
21730
+ })
21731
+ ]
21732
+ });
21733
+ }
21734
+ //#endregion
20093
21735
  //#region src/composites/audio-waveform.tsx
20094
21736
  /**
20095
21737
  * Canvas-based audio waveform visualization.
@@ -20097,9 +21739,9 @@ function StreamBrokerSelector({ deviceId, value, onChange, disabled, label, clas
20097
21739
  * Downsamples to pixel resolution for performance.
20098
21740
  */
20099
21741
  function AudioWaveform({ samples, sampleRate = 16e3, height = 96, className = "", color = "#3b82f6", bgColor = "transparent" }) {
20100
- const canvasRef = (0, react.useRef)(null);
20101
- const containerRef = (0, react.useRef)(null);
20102
- const draw = (0, react.useCallback)(() => {
21742
+ const canvasRef = (0, react$1.useRef)(null);
21743
+ const containerRef = (0, react$1.useRef)(null);
21744
+ const draw = (0, react$1.useCallback)(() => {
20103
21745
  const canvas = canvasRef.current;
20104
21746
  const container = containerRef.current;
20105
21747
  if (!canvas || !container || !samples || samples.length === 0) return;
@@ -20151,10 +21793,10 @@ function AudioWaveform({ samples, sampleRate = 16e3, height = 96, className = ""
20151
21793
  color,
20152
21794
  bgColor
20153
21795
  ]);
20154
- (0, react.useEffect)(() => {
21796
+ (0, react$1.useEffect)(() => {
20155
21797
  draw();
20156
21798
  }, [draw]);
20157
- (0, react.useEffect)(() => {
21799
+ (0, react$1.useEffect)(() => {
20158
21800
  const observer = new ResizeObserver(() => draw());
20159
21801
  const el = containerRef.current;
20160
21802
  if (el) observer.observe(el);
@@ -20193,10 +21835,10 @@ function AudioWaveform({ samples, sampleRate = 16e3, height = 96, className = ""
20193
21835
  * (each chunk, ~0.5s, produces one sample via `frame.level.dbfs`).
20194
21836
  */
20195
21837
  function AudioLevelWaveform({ currentDbfs, durationSec = 30, maxSamples = 120, height = 64, className = "", color = "#10b981", clipColor = "#ef4444", clipThreshold = -6, minDbfs = -96 }) {
20196
- const canvasRef = (0, react.useRef)(null);
20197
- const containerRef = (0, react.useRef)(null);
20198
- const [samples, setSamples] = (0, react.useState)([]);
20199
- (0, react.useEffect)(() => {
21838
+ const canvasRef = (0, react$1.useRef)(null);
21839
+ const containerRef = (0, react$1.useRef)(null);
21840
+ const [samples, setSamples] = (0, react$1.useState)([]);
21841
+ (0, react$1.useEffect)(() => {
20200
21842
  if (currentDbfs === null) return;
20201
21843
  setSamples((prev) => {
20202
21844
  const next = [...prev, {
@@ -20206,7 +21848,7 @@ function AudioLevelWaveform({ currentDbfs, durationSec = 30, maxSamples = 120, h
20206
21848
  return next.length > maxSamples ? next.slice(-maxSamples) : next;
20207
21849
  });
20208
21850
  }, [currentDbfs, maxSamples]);
20209
- const draw = (0, react.useCallback)(() => {
21851
+ const draw = (0, react$1.useCallback)(() => {
20210
21852
  const canvas = canvasRef.current;
20211
21853
  const container = containerRef.current;
20212
21854
  if (!canvas || !container) return;
@@ -20259,10 +21901,10 @@ function AudioLevelWaveform({ currentDbfs, durationSec = 30, maxSamples = 120, h
20259
21901
  clipThreshold,
20260
21902
  minDbfs
20261
21903
  ]);
20262
- (0, react.useEffect)(() => {
21904
+ (0, react$1.useEffect)(() => {
20263
21905
  draw();
20264
21906
  }, [draw]);
20265
- (0, react.useEffect)(() => {
21907
+ (0, react$1.useEffect)(() => {
20266
21908
  const observer = new ResizeObserver(() => draw());
20267
21909
  const el = containerRef.current;
20268
21910
  if (el) observer.observe(el);
@@ -20384,7 +22026,7 @@ function AudioClassificationList({ classifications, processing = false, inferenc
20384
22026
  * Expandable log box showing the raw JSON response from a pipeline run.
20385
22027
  */
20386
22028
  function ResponseLog({ data, label = "Response", className = "" }) {
20387
- const [expanded, setExpanded] = (0, react.useState)(false);
22029
+ const [expanded, setExpanded] = (0, react$1.useState)(false);
20388
22030
  if (!data) return null;
20389
22031
  const json = JSON.stringify(data, null, 2);
20390
22032
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -20456,17 +22098,17 @@ function PhaseIcon({ phase, ...props }) {
20456
22098
  * keeping idle subscriptions alive.
20457
22099
  */
20458
22100
  function useLiveBuffer(max) {
20459
- const [entries, setEntries] = (0, react.useState)([]);
20460
- const append = (0, react.useCallback)((entry) => {
22101
+ const [entries, setEntries] = (0, react$1.useState)([]);
22102
+ const append = (0, react$1.useCallback)((entry) => {
20461
22103
  setEntries((prev) => {
20462
22104
  const next = [...prev, entry];
20463
22105
  return next.length > max ? next.slice(-max) : next;
20464
22106
  });
20465
22107
  }, [max]);
20466
- const reset = (0, react.useCallback)(() => {
22108
+ const reset = (0, react$1.useCallback)(() => {
20467
22109
  setEntries([]);
20468
22110
  }, []);
20469
- return (0, react.useMemo)(() => ({
22111
+ return (0, react$1.useMemo)(() => ({
20470
22112
  entries,
20471
22113
  append,
20472
22114
  reset
@@ -20540,15 +22182,15 @@ function passesLevel(logLevel, filterLevel) {
20540
22182
  return (LEVEL_SEVERITY[logLevel] ?? 0) >= (LEVEL_SEVERITY[filterLevel] ?? 0);
20541
22183
  }
20542
22184
  function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: propsDeviceId, integrationId: propsIntegrationId, requestId: propsRequestId, level: initialLevel, maxHeight = "max-h-96", showScope = false, showFilters = true, limit = 100, liveBuffer: externalBuffer, onClose, className }) {
20543
- const [localAddonId, setLocalAddonId] = (0, react.useState)("");
20544
- const [localDeviceId, setLocalDeviceId] = (0, react.useState)("");
20545
- const [levelFilter, setLevelFilter] = (0, react.useState)(initialLevel);
22185
+ const [localAddonId, setLocalAddonId] = (0, react$1.useState)("");
22186
+ const [localDeviceId, setLocalDeviceId] = (0, react$1.useState)("");
22187
+ const [levelFilter, setLevelFilter] = (0, react$1.useState)(initialLevel);
20546
22188
  const agentId = propsAgentId;
20547
22189
  const addonId = propsAddonId ?? (localAddonId || void 0);
20548
22190
  const deviceId = propsDeviceId ?? (localDeviceId ? Number(localDeviceId) : void 0);
20549
22191
  const integrationId = propsIntegrationId;
20550
22192
  const requestId = propsRequestId;
20551
- const tags = (0, react.useMemo)(() => {
22193
+ const tags = (0, react$1.useMemo)(() => {
20552
22194
  const t = {};
20553
22195
  if (agentId) t.agentId = agentId;
20554
22196
  if (addonId) t.addonId = addonId;
@@ -20566,15 +22208,15 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
20566
22208
  const fallbackBuffer = useLiveBuffer(MAX_LIVE_ENTRIES$2);
20567
22209
  const buffer = externalBuffer ?? fallbackBuffer;
20568
22210
  const liveLogs = buffer.entries;
20569
- const [clearedAt, setClearedAt] = (0, react.useState)(0);
20570
- const [autoScroll, setAutoScroll] = (0, react.useState)(false);
20571
- const [copied, setCopied] = (0, react.useState)(false);
20572
- const [expandedRows, setExpandedRows] = (0, react.useState)(/* @__PURE__ */ new Set());
20573
- const [searchText, setSearchText] = (0, react.useState)("");
20574
- const scrollRef = (0, react.useRef)(null);
22211
+ const [clearedAt, setClearedAt] = (0, react$1.useState)(0);
22212
+ const [autoScroll, setAutoScroll] = (0, react$1.useState)(false);
22213
+ const [copied, setCopied] = (0, react$1.useState)(false);
22214
+ const [expandedRows, setExpandedRows] = (0, react$1.useState)(/* @__PURE__ */ new Set());
22215
+ const [searchText, setSearchText] = (0, react$1.useState)("");
22216
+ const scrollRef = (0, react$1.useRef)(null);
20575
22217
  const scopeKey = `${agentId ?? ""}:${addonId ?? ""}:${String(deviceId ?? "")}:${integrationId ?? ""}:${requestId ?? ""}`;
20576
- const prevScopeRef = (0, react.useRef)(scopeKey);
20577
- (0, react.useEffect)(() => {
22218
+ const prevScopeRef = (0, react$1.useRef)(scopeKey);
22219
+ (0, react$1.useEffect)(() => {
20578
22220
  if (prevScopeRef.current !== scopeKey) {
20579
22221
  prevScopeRef.current = scopeKey;
20580
22222
  buffer.reset();
@@ -20589,8 +22231,8 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
20589
22231
  trpc.logs.subscribe.useSubscription({ ...tags ? { tags } : {} }, { onData: (entry) => {
20590
22232
  buffer.append(entry);
20591
22233
  } });
20592
- const prevLiveCountRef = (0, react.useRef)(liveLogs.length);
20593
- (0, react.useEffect)(() => {
22234
+ const prevLiveCountRef = (0, react$1.useRef)(liveLogs.length);
22235
+ (0, react$1.useEffect)(() => {
20594
22236
  const el = scrollRef.current;
20595
22237
  if (!el) {
20596
22238
  prevLiveCountRef.current = liveLogs.length;
@@ -20606,7 +22248,7 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
20606
22248
  el.scrollTop += rowHeight * (liveLogs.length - prevCount);
20607
22249
  }
20608
22250
  }, [liveLogs.length, autoScroll]);
20609
- const allLogs = (0, react.useMemo)(() => {
22251
+ const allLogs = (0, react$1.useMemo)(() => {
20610
22252
  const initial = (initialLogs ?? []).map((log) => ({
20611
22253
  timestamp: log.timestamp,
20612
22254
  level: log.level,
@@ -20651,7 +22293,7 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
20651
22293
  clearedAt,
20652
22294
  searchText
20653
22295
  ]);
20654
- const handleCopyAll = (0, react.useCallback)(() => {
22296
+ const handleCopyAll = (0, react$1.useCallback)(() => {
20655
22297
  const lines = allLogs.map((log) => {
20656
22298
  const time = new Date(log.timestamp).toLocaleTimeString();
20657
22299
  const tagsStr = log.tags ? " " + Object.entries(log.tags).filter(([, v]) => v).map(([k, v]) => `${k}=${v}`).join(" ") : "";
@@ -20663,7 +22305,7 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
20663
22305
  });
20664
22306
  }, [allLogs]);
20665
22307
  const clearMutation = trpc.logs.clear.useMutation();
20666
- const handleClear = (0, react.useCallback)(() => {
22308
+ const handleClear = (0, react$1.useCallback)(() => {
20667
22309
  setClearedAt(Date.now());
20668
22310
  buffer.reset();
20669
22311
  clearMutation.mutate({ ...tags ? { tags } : {} });
@@ -20672,7 +22314,7 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
20672
22314
  clearMutation,
20673
22315
  tags
20674
22316
  ]);
20675
- const toggleRow = (0, react.useCallback)((rowKey) => {
22317
+ const toggleRow = (0, react$1.useCallback)((rowKey) => {
20676
22318
  setExpandedRows((prev) => {
20677
22319
  const next = new Set(prev);
20678
22320
  if (next.has(rowKey)) next.delete(rowKey);
@@ -20680,8 +22322,8 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
20680
22322
  return next;
20681
22323
  });
20682
22324
  }, []);
20683
- const [copiedRowKey, setCopiedRowKey] = (0, react.useState)(null);
20684
- const copyOne = (0, react.useCallback)((log, key) => {
22325
+ const [copiedRowKey, setCopiedRowKey] = (0, react$1.useState)(null);
22326
+ const copyOne = (0, react$1.useCallback)((log, key) => {
20685
22327
  const time = new Date(log.timestamp).toISOString();
20686
22328
  const tagsStr = log.tags ? " " + Object.entries(log.tags).filter(([, v]) => v).map(([k, v]) => `${k}=${v}`).join(" ") : "";
20687
22329
  const metaStr = log.meta && Object.keys(log.meta).length > 0 ? ` meta=${JSON.stringify(log.meta)}` : "";
@@ -20691,7 +22333,7 @@ function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: pro
20691
22333
  setTimeout(() => setCopiedRowKey((prev) => prev === key ? null : prev), 1200);
20692
22334
  });
20693
22335
  }, []);
20694
- const rowKey = (0, react.useCallback)((log) => `${log.timestamp}|${log.level}|${log.scope ?? ""}|${log.message}`, []);
22336
+ const rowKey = (0, react$1.useCallback)((log) => `${log.timestamp}|${log.level}|${log.scope ?? ""}|${log.message}`, []);
20695
22337
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
20696
22338
  className: cn("h-full min-h-0 flex flex-col", className),
20697
22339
  onClick: (e) => e.stopPropagation(),
@@ -21256,11 +22898,11 @@ function hasContent(entry) {
21256
22898
  }
21257
22899
  var MAX_LIVE_ENTRIES$1 = 300;
21258
22900
  function EventStream({ agentId, addonId, deviceId, defaultCategories, categories: legacyCategories, category: propsCategory, maxHeight = "max-h-96", limit = 50, showCategoryFilter = true, showFilters: _showFilters = false, liveBuffer: externalBuffer, onClose, className }) {
21259
- const defaultsArray = (0, react.useMemo)(() => defaultCategories ?? legacyCategories ?? DEFAULT_EVENT_CATEGORIES, [defaultCategories, legacyCategories]);
21260
- const defaultsKey = (0, react.useMemo)(() => [...defaultsArray].sort().join(","), [defaultsArray]);
21261
- const [activeCategories, setActiveCategories] = (0, react.useState)(() => new Set(defaultsArray));
21262
- const prevDefaultsKey = (0, react.useRef)(defaultsKey);
21263
- (0, react.useEffect)(() => {
22901
+ const defaultsArray = (0, react$1.useMemo)(() => defaultCategories ?? legacyCategories ?? DEFAULT_EVENT_CATEGORIES, [defaultCategories, legacyCategories]);
22902
+ const defaultsKey = (0, react$1.useMemo)(() => [...defaultsArray].sort().join(","), [defaultsArray]);
22903
+ const [activeCategories, setActiveCategories] = (0, react$1.useState)(() => new Set(defaultsArray));
22904
+ const prevDefaultsKey = (0, react$1.useRef)(defaultsKey);
22905
+ (0, react$1.useEffect)(() => {
21264
22906
  if (prevDefaultsKey.current !== defaultsKey) {
21265
22907
  prevDefaultsKey.current = defaultsKey;
21266
22908
  setActiveCategories(new Set(defaultsArray));
@@ -21269,17 +22911,17 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
21269
22911
  const fallbackBuffer = useLiveBuffer(MAX_LIVE_ENTRIES$1);
21270
22912
  const buffer = externalBuffer ?? fallbackBuffer;
21271
22913
  const liveEvents = buffer.entries;
21272
- const [autoScroll, setAutoScroll] = (0, react.useState)(true);
21273
- const [expandedRows, setExpandedRows] = (0, react.useState)(/* @__PURE__ */ new Set());
21274
- const [searchText, setSearchText] = (0, react.useState)("");
21275
- const [filterOpen, setFilterOpen] = (0, react.useState)(false);
21276
- const [categorySearch, setCategorySearch] = (0, react.useState)("");
21277
- const [clearedAt, setClearedAt] = (0, react.useState)(0);
21278
- const scrollRef = (0, react.useRef)(null);
21279
- const filterRootRef = (0, react.useRef)(null);
22914
+ const [autoScroll, setAutoScroll] = (0, react$1.useState)(true);
22915
+ const [expandedRows, setExpandedRows] = (0, react$1.useState)(/* @__PURE__ */ new Set());
22916
+ const [searchText, setSearchText] = (0, react$1.useState)("");
22917
+ const [filterOpen, setFilterOpen] = (0, react$1.useState)(false);
22918
+ const [categorySearch, setCategorySearch] = (0, react$1.useState)("");
22919
+ const [clearedAt, setClearedAt] = (0, react$1.useState)(0);
22920
+ const scrollRef = (0, react$1.useRef)(null);
22921
+ const filterRootRef = (0, react$1.useRef)(null);
21280
22922
  const scopeKey = `${agentId ?? ""}:${addonId ?? ""}:${String(deviceId ?? "")}:${propsCategory ?? ""}`;
21281
- const prevScopeRef = (0, react.useRef)(scopeKey);
21282
- (0, react.useEffect)(() => {
22923
+ const prevScopeRef = (0, react$1.useRef)(scopeKey);
22924
+ (0, react$1.useEffect)(() => {
21283
22925
  if (prevScopeRef.current !== scopeKey) {
21284
22926
  prevScopeRef.current = scopeKey;
21285
22927
  buffer.reset();
@@ -21287,7 +22929,7 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
21287
22929
  setClearedAt(0);
21288
22930
  }
21289
22931
  }, [scopeKey, buffer]);
21290
- (0, react.useEffect)(() => {
22932
+ (0, react$1.useEffect)(() => {
21291
22933
  if (!filterOpen) return;
21292
22934
  const onDocClick = (e) => {
21293
22935
  const root = filterRootRef.current;
@@ -21298,7 +22940,7 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
21298
22940
  document.removeEventListener("mousedown", onDocClick);
21299
22941
  };
21300
22942
  }, [filterOpen]);
21301
- const scopeInput = (0, react.useMemo)(() => {
22943
+ const scopeInput = (0, react$1.useMemo)(() => {
21302
22944
  const s = {};
21303
22945
  if (agentId) s.agentId = agentId;
21304
22946
  if (addonId) s.addonId = addonId;
@@ -21311,8 +22953,8 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
21311
22953
  deviceId,
21312
22954
  propsCategory
21313
22955
  ]);
21314
- const activeArray = (0, react.useMemo)(() => [...activeCategories].sort(), [activeCategories]);
21315
- const getRecentInput = (0, react.useMemo)(() => {
22956
+ const activeArray = (0, react$1.useMemo)(() => [...activeCategories].sort(), [activeCategories]);
22957
+ const getRecentInput = (0, react$1.useMemo)(() => {
21316
22958
  const s = {
21317
22959
  ...scopeInput,
21318
22960
  limit
@@ -21322,12 +22964,12 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
21322
22964
  }, [
21323
22965
  scopeInput,
21324
22966
  limit,
21325
- (0, react.useMemo)(() => activeArray.join(","), [activeArray]),
22967
+ (0, react$1.useMemo)(() => activeArray.join(","), [activeArray]),
21326
22968
  activeArray
21327
22969
  ]);
21328
22970
  const { data: initialEvents, isLoading } = trpc.systemEvents.getRecent.useQuery(getRecentInput, { staleTime: 3e4 });
21329
- const activeCategoriesRef = (0, react.useRef)(activeCategories);
21330
- (0, react.useEffect)(() => {
22971
+ const activeCategoriesRef = (0, react$1.useRef)(activeCategories);
22972
+ (0, react$1.useEffect)(() => {
21331
22973
  activeCategoriesRef.current = activeCategories;
21332
22974
  }, [activeCategories]);
21333
22975
  const subInput = scopeInput;
@@ -21338,8 +22980,8 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
21338
22980
  if (!activeCategoriesRef.current.has(entry.category)) return;
21339
22981
  buffer.append(entry);
21340
22982
  } });
21341
- const prevLiveCountRef = (0, react.useRef)(liveEvents.length);
21342
- (0, react.useEffect)(() => {
22983
+ const prevLiveCountRef = (0, react$1.useRef)(liveEvents.length);
22984
+ (0, react$1.useEffect)(() => {
21343
22985
  const el = scrollRef.current;
21344
22986
  if (!el) {
21345
22987
  prevLiveCountRef.current = liveEvents.length;
@@ -21355,7 +22997,7 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
21355
22997
  el.scrollTop += rowHeight * (liveEvents.length - prevCount);
21356
22998
  }
21357
22999
  }, [liveEvents.length, autoScroll]);
21358
- const allEvents = (0, react.useMemo)(() => {
23000
+ const allEvents = (0, react$1.useMemo)(() => {
21359
23001
  const byId = /* @__PURE__ */ new Map();
21360
23002
  for (const e of initialEvents ?? []) byId.set(e.id, e);
21361
23003
  for (const e of liveEvents) byId.set(e.id, e);
@@ -21384,7 +23026,7 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
21384
23026
  searchText,
21385
23027
  clearedAt
21386
23028
  ]);
21387
- const toggleRow = (0, react.useCallback)((id) => {
23029
+ const toggleRow = (0, react$1.useCallback)((id) => {
21388
23030
  setExpandedRows((prev) => {
21389
23031
  const next = new Set(prev);
21390
23032
  if (next.has(id)) next.delete(id);
@@ -21392,7 +23034,7 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
21392
23034
  return next;
21393
23035
  });
21394
23036
  }, []);
21395
- const toggleCategory = (0, react.useCallback)((cat) => {
23037
+ const toggleCategory = (0, react$1.useCallback)((cat) => {
21396
23038
  setActiveCategories((prev) => {
21397
23039
  const next = new Set(prev);
21398
23040
  if (next.has(cat)) next.delete(cat);
@@ -21400,43 +23042,43 @@ function EventStream({ agentId, addonId, deviceId, defaultCategories, categories
21400
23042
  return next;
21401
23043
  });
21402
23044
  }, []);
21403
- const handleReset = (0, react.useCallback)(() => {
23045
+ const handleReset = (0, react$1.useCallback)(() => {
21404
23046
  setActiveCategories(new Set(defaultsArray));
21405
23047
  setSearchText("");
21406
23048
  setClearedAt(0);
21407
23049
  }, [defaultsArray]);
21408
- const handleClear = (0, react.useCallback)(() => {
23050
+ const handleClear = (0, react$1.useCallback)(() => {
21409
23051
  setClearedAt(Date.now());
21410
23052
  buffer.reset();
21411
23053
  }, [buffer]);
21412
- const [copiedAll, setCopiedAll] = (0, react.useState)(false);
21413
- const [copiedRowId, setCopiedRowId] = (0, react.useState)(null);
21414
- const formatEventForCopy = (0, react.useCallback)((event) => {
23054
+ const [copiedAll, setCopiedAll] = (0, react$1.useState)(false);
23055
+ const [copiedRowId, setCopiedRowId] = (0, react$1.useState)(null);
23056
+ const formatEventForCopy = (0, react$1.useCallback)((event) => {
21415
23057
  const time = new Date(event.timestamp).toISOString();
21416
23058
  const summary = summarizeEvent(event.category, event.data) ?? "";
21417
23059
  const summaryStr = summary ? ` ${summary}` : "";
21418
23060
  return `${time} [${event.category}]${summaryStr} data=${JSON.stringify(event.data)}`;
21419
23061
  }, []);
21420
- const handleCopyAll = (0, react.useCallback)(() => {
23062
+ const handleCopyAll = (0, react$1.useCallback)(() => {
21421
23063
  const lines = allEvents.map(formatEventForCopy);
21422
23064
  navigator.clipboard.writeText(lines.join("\n")).then(() => {
21423
23065
  setCopiedAll(true);
21424
23066
  setTimeout(() => setCopiedAll(false), 1500);
21425
23067
  });
21426
23068
  }, [allEvents, formatEventForCopy]);
21427
- const copyOne = (0, react.useCallback)((event) => {
23069
+ const copyOne = (0, react$1.useCallback)((event) => {
21428
23070
  navigator.clipboard.writeText(formatEventForCopy(event)).then(() => {
21429
23071
  setCopiedRowId(event.id);
21430
23072
  setTimeout(() => setCopiedRowId((prev) => prev === event.id ? null : prev), 1200);
21431
23073
  });
21432
23074
  }, [formatEventForCopy]);
21433
- const handleSelectAll = (0, react.useCallback)(() => {
23075
+ const handleSelectAll = (0, react$1.useCallback)(() => {
21434
23076
  setActiveCategories(new Set(ALL_EVENT_CATEGORIES));
21435
23077
  }, []);
21436
- const handleSelectNone = (0, react.useCallback)(() => {
23078
+ const handleSelectNone = (0, react$1.useCallback)(() => {
21437
23079
  setActiveCategories(/* @__PURE__ */ new Set());
21438
23080
  }, []);
21439
- const filteredPopoverCategories = (0, react.useMemo)(() => {
23081
+ const filteredPopoverCategories = (0, react$1.useMemo)(() => {
21440
23082
  const needle = categorySearch.trim().toLowerCase();
21441
23083
  if (!needle) return ALL_EVENT_CATEGORIES;
21442
23084
  return ALL_EVENT_CATEGORIES.filter((c) => c.toLowerCase().includes(needle));
@@ -21814,8 +23456,8 @@ function DiscoveryPanel({ deviceId, className = "", onOpenChild }) {
21814
23456
  const releaseMutation = trpc.deviceDiscovery.releaseDevice.useMutation({ onSuccess: () => {
21815
23457
  utils.deviceDiscovery.listDiscovered.invalidate({ deviceId });
21816
23458
  } });
21817
- const [busyChildId, setBusyChildId] = (0, react.useState)(null);
21818
- const { available, adopted } = (0, react.useMemo)(() => {
23459
+ const [busyChildId, setBusyChildId] = (0, react$1.useState)(null);
23460
+ const { available, adopted } = (0, react$1.useMemo)(() => {
21819
23461
  const list = listQuery.data ?? [];
21820
23462
  const sortKey = (c) => typeof c.metadata.rtspChannel === "number" ? c.metadata.rtspChannel : Number.POSITIVE_INFINITY;
21821
23463
  const byChannel = (a, b) => {
@@ -22094,20 +23736,20 @@ var MAX_LIVE_ENTRIES = 300;
22094
23736
  */
22095
23737
  var ALL_DEVICE_CAP_NAMES = Object.freeze([...new Set(_camstack_types.ALL_CAPABILITY_DEFINITIONS.filter((c) => c.scope === "device").map((c) => c.name))].sort());
22096
23738
  function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limit = 50, liveBuffer: externalBuffer, onClose, className }) {
22097
- const [activeCaps, setActiveCaps] = (0, react.useState)((0, react.useMemo)(() => new Set(defaultCaps ?? []), [defaultCaps]));
22098
- const [searchText, setSearchText] = (0, react.useState)("");
22099
- const [autoScroll, setAutoScroll] = (0, react.useState)(true);
22100
- const [expandedRows, setExpandedRows] = (0, react.useState)(/* @__PURE__ */ new Set());
22101
- const [clearedAt, setClearedAt] = (0, react.useState)(0);
22102
- const [filterOpen, setFilterOpen] = (0, react.useState)(false);
22103
- const [filterSearch, setFilterSearch] = (0, react.useState)("");
22104
- const filterRootRef = (0, react.useRef)(null);
23739
+ const [activeCaps, setActiveCaps] = (0, react$1.useState)((0, react$1.useMemo)(() => new Set(defaultCaps ?? []), [defaultCaps]));
23740
+ const [searchText, setSearchText] = (0, react$1.useState)("");
23741
+ const [autoScroll, setAutoScroll] = (0, react$1.useState)(true);
23742
+ const [expandedRows, setExpandedRows] = (0, react$1.useState)(/* @__PURE__ */ new Set());
23743
+ const [clearedAt, setClearedAt] = (0, react$1.useState)(0);
23744
+ const [filterOpen, setFilterOpen] = (0, react$1.useState)(false);
23745
+ const [filterSearch, setFilterSearch] = (0, react$1.useState)("");
23746
+ const filterRootRef = (0, react$1.useRef)(null);
22105
23747
  const fallbackBuffer = useLiveBuffer(MAX_LIVE_ENTRIES);
22106
23748
  const buffer = externalBuffer ?? fallbackBuffer;
22107
23749
  const liveEvents = buffer.entries;
22108
- const scrollRef = (0, react.useRef)(null);
22109
- const prevDeviceRef = (0, react.useRef)(deviceId);
22110
- (0, react.useEffect)(() => {
23750
+ const scrollRef = (0, react$1.useRef)(null);
23751
+ const prevDeviceRef = (0, react$1.useRef)(deviceId);
23752
+ (0, react$1.useEffect)(() => {
22111
23753
  if (prevDeviceRef.current !== deviceId) {
22112
23754
  prevDeviceRef.current = deviceId;
22113
23755
  buffer.reset();
@@ -22115,14 +23757,14 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
22115
23757
  setClearedAt(0);
22116
23758
  }
22117
23759
  }, [deviceId, buffer]);
22118
- const recentInput = (0, react.useMemo)(() => ({
23760
+ const recentInput = (0, react$1.useMemo)(() => ({
22119
23761
  deviceId,
22120
23762
  category: _camstack_types.EventCategory.DeviceStateChanged,
22121
23763
  limit
22122
23764
  }), [deviceId, limit]);
22123
23765
  const { data: initialEvents, isLoading } = trpc.systemEvents.getRecent.useQuery(recentInput, { staleTime: 3e4 });
22124
- const activeCapsRef = (0, react.useRef)(activeCaps);
22125
- (0, react.useEffect)(() => {
23766
+ const activeCapsRef = (0, react$1.useRef)(activeCaps);
23767
+ (0, react$1.useEffect)(() => {
22126
23768
  activeCapsRef.current = activeCaps;
22127
23769
  }, [activeCaps]);
22128
23770
  trpc.systemEvents.subscribe.useSubscription({
@@ -22136,8 +23778,8 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
22136
23778
  if (active.size > 0 && !active.has(entry.capName)) return;
22137
23779
  buffer.append(entry);
22138
23780
  } });
22139
- const prevLiveCountRef = (0, react.useRef)(liveEvents.length);
22140
- (0, react.useEffect)(() => {
23781
+ const prevLiveCountRef = (0, react$1.useRef)(liveEvents.length);
23782
+ (0, react$1.useEffect)(() => {
22141
23783
  const el = scrollRef.current;
22142
23784
  if (!el) {
22143
23785
  prevLiveCountRef.current = liveEvents.length;
@@ -22154,7 +23796,7 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
22154
23796
  el.scrollTop += rowHeight * newCount;
22155
23797
  }
22156
23798
  }, [liveEvents.length, autoScroll]);
22157
- const allEntries = (0, react.useMemo)(() => {
23799
+ const allEntries = (0, react$1.useMemo)(() => {
22158
23800
  const byId = /* @__PURE__ */ new Map();
22159
23801
  for (const e of initialEvents ?? []) {
22160
23802
  const entry = toEntry(e);
@@ -22186,7 +23828,7 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
22186
23828
  searchText,
22187
23829
  clearedAt
22188
23830
  ]);
22189
- const visibleCaps = (0, react.useMemo)(() => {
23831
+ const visibleCaps = (0, react$1.useMemo)(() => {
22190
23832
  const caps = new Set(ALL_DEVICE_CAP_NAMES);
22191
23833
  for (const e of initialEvents ?? []) {
22192
23834
  const entry = toEntry(e);
@@ -22195,7 +23837,7 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
22195
23837
  for (const e of liveEvents) caps.add(e.capName);
22196
23838
  return [...caps].sort();
22197
23839
  }, [initialEvents, liveEvents]);
22198
- const toggleRow = (0, react.useCallback)((id) => {
23840
+ const toggleRow = (0, react$1.useCallback)((id) => {
22199
23841
  setExpandedRows((prev) => {
22200
23842
  const next = new Set(prev);
22201
23843
  if (next.has(id)) next.delete(id);
@@ -22203,7 +23845,7 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
22203
23845
  return next;
22204
23846
  });
22205
23847
  }, []);
22206
- const toggleCap = (0, react.useCallback)((cap) => {
23848
+ const toggleCap = (0, react$1.useCallback)((cap) => {
22207
23849
  setActiveCaps((prev) => {
22208
23850
  const next = new Set(prev);
22209
23851
  if (next.has(cap)) next.delete(cap);
@@ -22211,39 +23853,39 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
22211
23853
  return next;
22212
23854
  });
22213
23855
  }, []);
22214
- const handleReset = (0, react.useCallback)(() => {
23856
+ const handleReset = (0, react$1.useCallback)(() => {
22215
23857
  setActiveCaps(new Set(defaultCaps ?? []));
22216
23858
  setSearchText("");
22217
23859
  }, [defaultCaps]);
22218
- const handleClear = (0, react.useCallback)(() => {
23860
+ const handleClear = (0, react$1.useCallback)(() => {
22219
23861
  setClearedAt(Date.now());
22220
23862
  buffer.reset();
22221
23863
  }, [buffer]);
22222
- const [copiedAll, setCopiedAll] = (0, react.useState)(false);
22223
- const [copiedRowId, setCopiedRowId] = (0, react.useState)(null);
22224
- const formatEntryForCopy = (0, react.useCallback)((entry) => {
23864
+ const [copiedAll, setCopiedAll] = (0, react$1.useState)(false);
23865
+ const [copiedRowId, setCopiedRowId] = (0, react$1.useState)(null);
23866
+ const formatEntryForCopy = (0, react$1.useCallback)((entry) => {
22225
23867
  return `${new Date(entry.timestamp).toISOString()} [${entry.capName}] slice=${JSON.stringify(entry.slice)}`;
22226
23868
  }, []);
22227
- const handleCopyAll = (0, react.useCallback)(() => {
23869
+ const handleCopyAll = (0, react$1.useCallback)(() => {
22228
23870
  const lines = allEntries.map(formatEntryForCopy);
22229
23871
  navigator.clipboard.writeText(lines.join("\n")).then(() => {
22230
23872
  setCopiedAll(true);
22231
23873
  setTimeout(() => setCopiedAll(false), 1500);
22232
23874
  });
22233
23875
  }, [allEntries, formatEntryForCopy]);
22234
- const copyOne = (0, react.useCallback)((entry) => {
23876
+ const copyOne = (0, react$1.useCallback)((entry) => {
22235
23877
  navigator.clipboard.writeText(formatEntryForCopy(entry)).then(() => {
22236
23878
  setCopiedRowId(entry.id);
22237
23879
  setTimeout(() => setCopiedRowId((prev) => prev === entry.id ? null : prev), 1200);
22238
23880
  });
22239
23881
  }, [formatEntryForCopy]);
22240
- const handleSelectAllCaps = (0, react.useCallback)(() => {
23882
+ const handleSelectAllCaps = (0, react$1.useCallback)(() => {
22241
23883
  setActiveCaps(new Set(visibleCaps));
22242
23884
  }, [visibleCaps]);
22243
- const handleSelectNoCaps = (0, react.useCallback)(() => {
23885
+ const handleSelectNoCaps = (0, react$1.useCallback)(() => {
22244
23886
  setActiveCaps(/* @__PURE__ */ new Set());
22245
23887
  }, []);
22246
- const filteredPopoverCaps = (0, react.useMemo)(() => {
23888
+ const filteredPopoverCaps = (0, react$1.useMemo)(() => {
22247
23889
  const needle = filterSearch.trim().toLowerCase();
22248
23890
  if (!needle) return visibleCaps;
22249
23891
  return visibleCaps.filter((c) => c.toLowerCase().includes(needle));
@@ -22252,7 +23894,7 @@ function StateValuesStream({ deviceId, defaultCaps, maxHeight = "max-h-96", limi
22252
23894
  const totalActive = activeCaps.size;
22253
23895
  const allSelected = totalActive === 0 || totalActive === totalAvailable;
22254
23896
  const filterLabel = allSelected ? "All" : `${totalActive}/${totalAvailable}`;
22255
- (0, react.useEffect)(() => {
23897
+ (0, react$1.useEffect)(() => {
22256
23898
  if (!filterOpen) return;
22257
23899
  const onDocClick = (e) => {
22258
23900
  const root = filterRootRef.current;
@@ -22612,14 +24254,14 @@ var TABS = [
22612
24254
  }
22613
24255
  ];
22614
24256
  function DeviceActivityPanel({ deviceId, defaultEventCategories, defaultStateCaps, initialTab = "events", className, maxHeight = "max-h-96" }) {
22615
- const [tab, setTab] = (0, react.useState)(initialTab);
24257
+ const [tab, setTab] = (0, react$1.useState)(initialTab);
22616
24258
  const logsBuffer = useLiveBuffer(PANEL_BUFFER_SIZE);
22617
24259
  const eventsBuffer = useLiveBuffer(PANEL_BUFFER_SIZE);
22618
24260
  const stateBuffer = useLiveBuffer(PANEL_BUFFER_SIZE);
22619
24261
  const logsReset = logsBuffer.reset;
22620
24262
  const eventsReset = eventsBuffer.reset;
22621
24263
  const stateReset = stateBuffer.reset;
22622
- (0, react.useEffect)(() => {
24264
+ (0, react$1.useEffect)(() => {
22623
24265
  logsReset();
22624
24266
  eventsReset();
22625
24267
  stateReset();
@@ -22683,9 +24325,9 @@ function DeviceActivityPanel({ deviceId, defaultEventCategories, defaultStateCap
22683
24325
  * for reboot, RefreshCw for restart).
22684
24326
  */
22685
24327
  function ConfirmActionButton({ label, icon: Icon, title = "Confirm action", description, confirmLabel, triggerVariant = "outline", confirmVariant = "danger", size = "sm", disabled, className, action, onSuccess }) {
22686
- const [open, setOpen] = (0, react.useState)(false);
22687
- const [running, setRunning] = (0, react.useState)(false);
22688
- const [error, setError] = (0, react.useState)(null);
24328
+ const [open, setOpen] = (0, react$1.useState)(false);
24329
+ const [running, setRunning] = (0, react$1.useState)(false);
24330
+ const [error, setError] = (0, react$1.useState)(null);
22689
24331
  const handleConfirm = async () => {
22690
24332
  setError(null);
22691
24333
  setRunning(true);
@@ -22764,9 +24406,9 @@ function ConfirmActionButton({ label, icon: Icon, title = "Confirm action", desc
22764
24406
  * release (`startContinuous` + `stopContinuous` on pointer up).
22765
24407
  */
22766
24408
  function DPadButton({ direction, icon: Icon, disabled, className, variant, onMove, onStart, onStop }) {
22767
- const [pressedAt, setPressedAt] = (0, react.useState)(null);
22768
- const [continuous, setContinuous] = (0, react.useState)(false);
22769
- const handlePointerDown = (0, react.useCallback)((e) => {
24409
+ const [pressedAt, setPressedAt] = (0, react$1.useState)(null);
24410
+ const [continuous, setContinuous] = (0, react$1.useState)(false);
24411
+ const handlePointerDown = (0, react$1.useCallback)((e) => {
22770
24412
  if (disabled) return;
22771
24413
  e.currentTarget.setPointerCapture(e.pointerId);
22772
24414
  setPressedAt(Date.now());
@@ -22781,7 +24423,7 @@ function DPadButton({ direction, icon: Icon, disabled, className, variant, onMov
22781
24423
  disabled,
22782
24424
  onStart
22783
24425
  ]);
22784
- const handlePointerUp = (0, react.useCallback)((e) => {
24426
+ const handlePointerUp = (0, react$1.useCallback)((e) => {
22785
24427
  const timerId = Number(e.currentTarget.dataset.timer);
22786
24428
  if (timerId) clearTimeout(timerId);
22787
24429
  e.currentTarget.dataset.timer = "";
@@ -22796,7 +24438,7 @@ function DPadButton({ direction, icon: Icon, disabled, className, variant, onMov
22796
24438
  onStop,
22797
24439
  pressedAt
22798
24440
  ]);
22799
- const handlePointerCancel = (0, react.useCallback)((e) => {
24441
+ const handlePointerCancel = (0, react$1.useCallback)((e) => {
22800
24442
  const timerId = Number(e.currentTarget.dataset.timer);
22801
24443
  if (timerId) clearTimeout(timerId);
22802
24444
  e.currentTarget.dataset.timer = "";
@@ -22819,7 +24461,7 @@ function DPadButton({ direction, icon: Icon, disabled, className, variant, onMov
22819
24461
  }
22820
24462
  function PTZOverlay({ controls, mode = "overlay", showPresets, showZoom = true, showHome = true, className }) {
22821
24463
  const { move, startContinuous, stopContinuous, zoom, goHome, goToPreset, presets, busy, error } = controls;
22822
- const [presetsOpen, setPresetsOpen] = (0, react.useState)(false);
24464
+ const [presetsOpen, setPresetsOpen] = (0, react$1.useState)(false);
22823
24465
  const presetsVisible = (showPresets ?? presets.length > 0) && presets.length > 0;
22824
24466
  const isPanel = mode === "panel";
22825
24467
  const containerClass = isPanel ? "flex flex-col items-stretch gap-2 w-full h-full p-3" : "pointer-events-auto absolute top-3 right-3 z-10 flex flex-col items-end gap-2";
@@ -22972,11 +24614,11 @@ function downloadDataUrl(filename, dataUrl) {
22972
24614
  document.body.removeChild(link);
22973
24615
  }
22974
24616
  function SnapshotButton({ trpc, deviceId, deviceName, size = "sm", className }) {
22975
- const [busy, setBusy] = (0, react.useState)(false);
22976
- const [done, setDone] = (0, react.useState)(false);
22977
- const [error, setError] = (0, react.useState)(null);
24617
+ const [busy, setBusy] = (0, react$1.useState)(false);
24618
+ const [done, setDone] = (0, react$1.useState)(false);
24619
+ const [error, setError] = (0, react$1.useState)(null);
22978
24620
  const safeName = deviceName.replace(/[^a-zA-Z0-9_.-]+/g, "_");
22979
- const fetchSnapshot = (0, react.useCallback)(async (action) => {
24621
+ const fetchSnapshot = (0, react$1.useCallback)(async (action) => {
22980
24622
  setBusy(true);
22981
24623
  setError(null);
22982
24624
  setDone(false);
@@ -23009,8 +24651,8 @@ function SnapshotButton({ trpc, deviceId, deviceName, size = "sm", className })
23009
24651
  safeName
23010
24652
  ]);
23011
24653
  const sizeClasses = size === "md" ? "h-9 px-3 text-sm gap-2" : "h-7 px-2.5 text-[11px] gap-1.5";
23012
- const [pressTimer, setPressTimer] = (0, react.useState)(null);
23013
- const [longPressed, setLongPressed] = (0, react.useState)(false);
24654
+ const [pressTimer, setPressTimer] = (0, react$1.useState)(null);
24655
+ const [longPressed, setLongPressed] = (0, react$1.useState)(false);
23014
24656
  const handlePointerDown = () => {
23015
24657
  setLongPressed(false);
23016
24658
  setPressTimer(setTimeout(() => {
@@ -23117,7 +24759,7 @@ function DoorbellRecentPanel({ history, limit = 5, latestIsFresh, className }) {
23117
24759
  * touch devices, no extra wiring needed.
23118
24760
  */
23119
24761
  function KebabMenu({ items, header, triggerClassName, title = "More actions" }) {
23120
- const [open, setOpen] = (0, react.useState)(false);
24762
+ const [open, setOpen] = (0, react$1.useState)(false);
23121
24763
  const visible = items.filter((i) => !i.hidden);
23122
24764
  if (visible.length === 0) return null;
23123
24765
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Popover, {
@@ -23259,19 +24901,19 @@ function clampedAccessForRow(row, parent) {
23259
24901
  function ScopePicker({ value, onChange, clampToParent, emptyHint }) {
23260
24902
  const { data: addons } = useAddonsList();
23261
24903
  const { data: devices } = useDeviceManagerListAll({});
23262
- const addonChoices = (0, react.useMemo)(() => (addons ?? []).map((a) => ({
24904
+ const addonChoices = (0, react$1.useMemo)(() => (addons ?? []).map((a) => ({
23263
24905
  value: a.manifest.id,
23264
24906
  label: a.manifest.id
23265
24907
  })).sort((a, b) => a.label.localeCompare(b.label)), [addons]);
23266
- const capChoices = (0, react.useMemo)(() => [..._camstack_types.KNOWN_CAP_NAMES].sort().map((c) => ({
24908
+ const capChoices = (0, react$1.useMemo)(() => [..._camstack_types.KNOWN_CAP_NAMES].sort().map((c) => ({
23267
24909
  value: c,
23268
24910
  label: c
23269
24911
  })), []);
23270
- const deviceChoices = (0, react.useMemo)(() => (devices ?? []).map((d) => ({
24912
+ const deviceChoices = (0, react$1.useMemo)(() => (devices ?? []).map((d) => ({
23271
24913
  value: String(d.id),
23272
24914
  label: `${d.name} (#${d.id} · ${d.addonId})`
23273
24915
  })).sort((a, b) => a.label.localeCompare(b.label)), [devices]);
23274
- const parentDeviceClamp = (0, react.useMemo)(() => clampToParent == null ? null : parentDeviceTargets(clampToParent), [clampToParent]);
24916
+ const parentDeviceClamp = (0, react$1.useMemo)(() => clampToParent == null ? null : parentDeviceTargets(clampToParent), [clampToParent]);
23275
24917
  /**
23276
24918
  * Build a fresh scope row when `type` changes. The discriminated union
23277
24919
  * forces us to re-construct the object per variant so the resulting
@@ -23438,8 +25080,8 @@ function ScopePicker({ value, onChange, clampToParent, emptyHint }) {
23438
25080
  });
23439
25081
  }
23440
25082
  function DeviceTargetPicker({ value, choices, clampToParent, onChange }) {
23441
- const [pendingAdd, setPendingAdd] = (0, react.useState)("");
23442
- const visibleChoices = (0, react.useMemo)(() => {
25083
+ const [pendingAdd, setPendingAdd] = (0, react$1.useState)("");
25084
+ const visibleChoices = (0, react$1.useMemo)(() => {
23443
25085
  const filtered = clampToParent == null ? choices : choices.filter((c) => clampToParent.includes(c.value));
23444
25086
  const taken = new Set(value);
23445
25087
  return filtered.filter((c) => !taken.has(c.value));
@@ -23535,11 +25177,11 @@ function validateScopes(scopes) {
23535
25177
  */
23536
25178
  var ZoneEditingContext = createSharedContext("camstack:zone-editing", null);
23537
25179
  function ZoneEditingProvider({ children }) {
23538
- const [editing, setEditingRaw] = (0, react.useState)(false);
23539
- const [drawingKind, setDrawingKindRaw] = (0, react.useState)(null);
23540
- const [selectedZoneId, setSelectedZoneIdRaw] = (0, react.useState)(null);
23541
- const [editingDraft, setEditingDraftRaw] = (0, react.useState)(null);
23542
- const setEditing = (0, react.useCallback)((next) => {
25180
+ const [editing, setEditingRaw] = (0, react$1.useState)(false);
25181
+ const [drawingKind, setDrawingKindRaw] = (0, react$1.useState)(null);
25182
+ const [selectedZoneId, setSelectedZoneIdRaw] = (0, react$1.useState)(null);
25183
+ const [editingDraft, setEditingDraftRaw] = (0, react$1.useState)(null);
25184
+ const setEditing = (0, react$1.useCallback)((next) => {
23543
25185
  setEditingRaw(next);
23544
25186
  if (!next) {
23545
25187
  setDrawingKindRaw(null);
@@ -23547,38 +25189,38 @@ function ZoneEditingProvider({ children }) {
23547
25189
  setEditingDraftRaw(null);
23548
25190
  }
23549
25191
  }, []);
23550
- const setDrawingKind = (0, react.useCallback)((kind) => {
25192
+ const setDrawingKind = (0, react$1.useCallback)((kind) => {
23551
25193
  setDrawingKindRaw(kind);
23552
25194
  }, []);
23553
- const setSelectedZoneId = (0, react.useCallback)((id) => {
25195
+ const setSelectedZoneId = (0, react$1.useCallback)((id) => {
23554
25196
  setSelectedZoneIdRaw(id);
23555
25197
  }, []);
23556
- const startDrawing = (0, react.useCallback)((kind) => {
25198
+ const startDrawing = (0, react$1.useCallback)((kind) => {
23557
25199
  setEditingRaw(true);
23558
25200
  setSelectedZoneIdRaw(null);
23559
25201
  setDrawingKindRaw(kind);
23560
25202
  setEditingDraftRaw(null);
23561
25203
  }, []);
23562
- const exitEditing = (0, react.useCallback)(() => {
25204
+ const exitEditing = (0, react$1.useCallback)(() => {
23563
25205
  setEditingRaw(false);
23564
25206
  setDrawingKindRaw(null);
23565
25207
  setSelectedZoneIdRaw(null);
23566
25208
  setEditingDraftRaw(null);
23567
25209
  }, []);
23568
- const enterDraft = (0, react.useCallback)((draft) => {
25210
+ const enterDraft = (0, react$1.useCallback)((draft) => {
23569
25211
  setSelectedZoneIdRaw(draft.id);
23570
25212
  setEditingDraftRaw(draft);
23571
25213
  }, []);
23572
- const updateDraft = (0, react.useCallback)((patch) => {
25214
+ const updateDraft = (0, react$1.useCallback)((patch) => {
23573
25215
  setEditingDraftRaw((prev) => prev === null ? prev : {
23574
25216
  ...prev,
23575
25217
  ...patch
23576
25218
  });
23577
25219
  }, []);
23578
- const discardDraft = (0, react.useCallback)(() => {
25220
+ const discardDraft = (0, react$1.useCallback)(() => {
23579
25221
  setEditingDraftRaw(null);
23580
25222
  }, []);
23581
- const value = (0, react.useMemo)(() => ({
25223
+ const value = (0, react$1.useMemo)(() => ({
23582
25224
  editing,
23583
25225
  drawingKind,
23584
25226
  selectedZoneId,
@@ -23614,7 +25256,7 @@ function ZoneEditingProvider({ children }) {
23614
25256
  * provider so callers that mount in pages without zones (e.g. a
23615
25257
  * shared hero on a non-camera device) can no-op gracefully. */
23616
25258
  function useZoneEditing() {
23617
- return (0, react.useContext)(ZoneEditingContext);
25259
+ return (0, react$1.useContext)(ZoneEditingContext);
23618
25260
  }
23619
25261
  //#endregion
23620
25262
  //#region src/hooks/use-device-detections.ts
@@ -23642,14 +25284,14 @@ function matchesDevice(source, deviceId) {
23642
25284
  return source?.id === deviceId;
23643
25285
  }
23644
25286
  function useDeviceDetections(trpc, deviceId) {
23645
- const [motion, setMotion] = (0, react.useState)(null);
23646
- const [motionRaw, setMotionRaw] = (0, react.useState)(null);
23647
- const [detection, setDetection] = (0, react.useState)(null);
23648
- const [phase, setPhase] = (0, react.useState)("watching");
23649
- const motionTimer = (0, react.useRef)(void 0);
23650
- const motionRawTimer = (0, react.useRef)(void 0);
23651
- const detectionTimer = (0, react.useRef)(void 0);
23652
- (0, react.useEffect)(() => {
25287
+ const [motion, setMotion] = (0, react$1.useState)(null);
25288
+ const [motionRaw, setMotionRaw] = (0, react$1.useState)(null);
25289
+ const [detection, setDetection] = (0, react$1.useState)(null);
25290
+ const [phase, setPhase] = (0, react$1.useState)("watching");
25291
+ const motionTimer = (0, react$1.useRef)(void 0);
25292
+ const motionRawTimer = (0, react$1.useRef)(void 0);
25293
+ const detectionTimer = (0, react$1.useRef)(void 0);
25294
+ (0, react$1.useEffect)(() => {
23653
25295
  if (deviceId === null) return;
23654
25296
  const sub = safeSubscribe(trpc, "detection.motion-analysis", (event) => {
23655
25297
  const e = event;
@@ -23672,7 +25314,7 @@ function useDeviceDetections(trpc, deviceId) {
23672
25314
  if (motionTimer.current) clearTimeout(motionTimer.current);
23673
25315
  };
23674
25316
  }, [trpc, deviceId]);
23675
- (0, react.useEffect)(() => {
25317
+ (0, react$1.useEffect)(() => {
23676
25318
  if (deviceId === null) return;
23677
25319
  const sub = safeSubscribe(trpc, "detection.motion-zones-raw", (event) => {
23678
25320
  const e = event;
@@ -23696,7 +25338,7 @@ function useDeviceDetections(trpc, deviceId) {
23696
25338
  if (motionRawTimer.current) clearTimeout(motionRawTimer.current);
23697
25339
  };
23698
25340
  }, [trpc, deviceId]);
23699
- (0, react.useEffect)(() => {
25341
+ (0, react$1.useEffect)(() => {
23700
25342
  if (deviceId === null) return;
23701
25343
  const sub = safeSubscribe(trpc, "detection.result", (event) => {
23702
25344
  const e = event;
@@ -23716,7 +25358,7 @@ function useDeviceDetections(trpc, deviceId) {
23716
25358
  if (detectionTimer.current) clearTimeout(detectionTimer.current);
23717
25359
  };
23718
25360
  }, [trpc, deviceId]);
23719
- (0, react.useEffect)(() => {
25361
+ (0, react$1.useEffect)(() => {
23720
25362
  if (deviceId === null) return;
23721
25363
  const sub = safeSubscribe(trpc, "detection.phase-transition", (event) => {
23722
25364
  const e = event;
@@ -23753,8 +25395,8 @@ function useDeviceDetections(trpc, deviceId) {
23753
25395
  * @param pollIntervalMs - how often to refresh profile slots (default: 5000)
23754
25396
  */
23755
25397
  function useDeviceWebrtc(trpc, deviceId, pollIntervalMs = 5e3) {
23756
- const [remoteStreams, setRemoteStreams] = (0, react.useState)([]);
23757
- (0, react.useEffect)(() => {
25398
+ const [remoteStreams, setRemoteStreams] = (0, react$1.useState)([]);
25399
+ (0, react$1.useEffect)(() => {
23758
25400
  if (deviceId === null) return;
23759
25401
  let cancelled = false;
23760
25402
  const fetch = () => {
@@ -23773,8 +25415,8 @@ function useDeviceWebrtc(trpc, deviceId, pollIntervalMs = 5e3) {
23773
25415
  deviceId,
23774
25416
  pollIntervalMs
23775
25417
  ]);
23776
- const [pipelineMetrics, setPipelineMetrics] = (0, react.useState)(null);
23777
- (0, react.useEffect)(() => {
25418
+ const [pipelineMetrics, setPipelineMetrics] = (0, react$1.useState)(null);
25419
+ (0, react$1.useEffect)(() => {
23778
25420
  if (deviceId === null) return;
23779
25421
  let cancelled = false;
23780
25422
  if (trpc.pipelineOrchestrator) trpc.pipelineOrchestrator.getCameraMetrics.query({ deviceId }).then((m) => {
@@ -23801,7 +25443,7 @@ function useDeviceWebrtc(trpc, deviceId, pollIntervalMs = 5e3) {
23801
25443
  droppedFrames: payload.metrics.droppedFrames
23802
25444
  });
23803
25445
  });
23804
- const { streams, hasWebrtc } = (0, react.useMemo)(() => {
25446
+ const { streams, hasWebrtc } = (0, react$1.useMemo)(() => {
23805
25447
  if (deviceId === null || remoteStreams.length === 0) return {
23806
25448
  streams: [],
23807
25449
  hasWebrtc: false
@@ -23823,7 +25465,7 @@ function useDeviceWebrtc(trpc, deviceId, pollIntervalMs = 5e3) {
23823
25465
  streams,
23824
25466
  hasWebrtc,
23825
25467
  pipelineMetrics,
23826
- createSession: (0, react.useCallback)(async (target, hints) => {
25468
+ createSession: (0, react$1.useCallback)(async (target, hints) => {
23827
25469
  if (deviceId === null) throw new Error("No device selected");
23828
25470
  const res = await trpc.webrtcSession.createSession.mutate({
23829
25471
  deviceId,
@@ -23835,7 +25477,7 @@ function useDeviceWebrtc(trpc, deviceId, pollIntervalMs = 5e3) {
23835
25477
  sdpOffer: res.sdpOffer
23836
25478
  };
23837
25479
  }, [trpc, deviceId]),
23838
- sendAnswer: (0, react.useCallback)(async (sessionId, sdpAnswer) => {
25480
+ sendAnswer: (0, react$1.useCallback)(async (sessionId, sdpAnswer) => {
23839
25481
  if (deviceId === null) throw new Error("No device selected");
23840
25482
  await trpc.webrtcSession.handleAnswer.mutate({
23841
25483
  deviceId,
@@ -23843,7 +25485,7 @@ function useDeviceWebrtc(trpc, deviceId, pollIntervalMs = 5e3) {
23843
25485
  sdpAnswer
23844
25486
  });
23845
25487
  }, [trpc, deviceId]),
23846
- closeSession: (0, react.useCallback)(async (sessionId) => {
25488
+ closeSession: (0, react$1.useCallback)(async (sessionId) => {
23847
25489
  if (deviceId === null) return;
23848
25490
  await trpc.webrtcSession.closeSession.mutate({
23849
25491
  deviceId,
@@ -23916,10 +25558,10 @@ function usePTZ(trpc, deviceId, options) {
23916
25558
  const pulseMs = options?.pulseMs ?? 250;
23917
25559
  const enabled = options?.enabled ?? true;
23918
25560
  const ptz = useDeviceProxy(trpc, enabled ? deviceId : null)?.ptz;
23919
- const [presets, setPresets] = (0, react.useState)([]);
23920
- const [busy, setBusy] = (0, react.useState)(false);
23921
- const [error, setError] = (0, react.useState)(null);
23922
- const refreshPresets = (0, react.useCallback)(async () => {
25561
+ const [presets, setPresets] = (0, react$1.useState)([]);
25562
+ const [busy, setBusy] = (0, react$1.useState)(false);
25563
+ const [error, setError] = (0, react$1.useState)(null);
25564
+ const refreshPresets = (0, react$1.useCallback)(async () => {
23923
25565
  if (!enabled || !ptz) return;
23924
25566
  try {
23925
25567
  setPresets(await ptz.getPresets({}));
@@ -23929,10 +25571,10 @@ function usePTZ(trpc, deviceId, options) {
23929
25571
  setError(msg);
23930
25572
  }
23931
25573
  }, [ptz, enabled]);
23932
- (0, react.useEffect)(() => {
25574
+ (0, react$1.useEffect)(() => {
23933
25575
  refreshPresets();
23934
25576
  }, [refreshPresets]);
23935
- const wrap = (0, react.useCallback)(async (fn) => {
25577
+ const wrap = (0, react$1.useCallback)(async (fn) => {
23936
25578
  if (!enabled || !ptz) return void 0;
23937
25579
  setError(null);
23938
25580
  setBusy(true);
@@ -23946,7 +25588,7 @@ function usePTZ(trpc, deviceId, options) {
23946
25588
  }
23947
25589
  }, [enabled, ptz]);
23948
25590
  return {
23949
- move: (0, react.useCallback)(async (direction, speed) => {
25591
+ move: (0, react$1.useCallback)(async (direction, speed) => {
23950
25592
  if (!ptz) return;
23951
25593
  const v = DIRECTION_VECTORS[direction];
23952
25594
  const s = speed ?? defaultSpeed;
@@ -23965,7 +25607,7 @@ function usePTZ(trpc, deviceId, options) {
23965
25607
  pulseMs,
23966
25608
  wrap
23967
25609
  ]),
23968
- startContinuous: (0, react.useCallback)(async (direction, speed) => {
25610
+ startContinuous: (0, react$1.useCallback)(async (direction, speed) => {
23969
25611
  if (!ptz) return;
23970
25612
  const v = DIRECTION_VECTORS[direction];
23971
25613
  const s = speed ?? defaultSpeed;
@@ -23979,11 +25621,11 @@ function usePTZ(trpc, deviceId, options) {
23979
25621
  defaultSpeed,
23980
25622
  wrap
23981
25623
  ]),
23982
- stopContinuous: (0, react.useCallback)(async () => {
25624
+ stopContinuous: (0, react$1.useCallback)(async () => {
23983
25625
  if (!ptz) return;
23984
25626
  await wrap(() => ptz.stop({}));
23985
25627
  }, [ptz, wrap]),
23986
- zoom: (0, react.useCallback)(async (direction, speed) => {
25628
+ zoom: (0, react$1.useCallback)(async (direction, speed) => {
23987
25629
  if (!ptz) return;
23988
25630
  const z = direction === "in" ? 1 : -1;
23989
25631
  const s = speed ?? defaultSpeed;
@@ -24001,11 +25643,11 @@ function usePTZ(trpc, deviceId, options) {
24001
25643
  pulseMs,
24002
25644
  wrap
24003
25645
  ]),
24004
- goHome: (0, react.useCallback)(async () => {
25646
+ goHome: (0, react$1.useCallback)(async () => {
24005
25647
  if (!ptz) return;
24006
25648
  await wrap(() => ptz.goHome({}));
24007
25649
  }, [ptz, wrap]),
24008
- goToPreset: (0, react.useCallback)(async (presetId) => {
25650
+ goToPreset: (0, react$1.useCallback)(async (presetId) => {
24009
25651
  if (!ptz) return;
24010
25652
  await wrap(() => ptz.goToPreset({ presetId }));
24011
25653
  }, [ptz, wrap]),
@@ -24032,8 +25674,8 @@ function useDoorbellEvents(options) {
24032
25674
  const deviceId = options?.deviceId ?? null;
24033
25675
  const historyLimit = options?.historyLimit ?? 20;
24034
25676
  const event = useEventStreamLatest("doorbell.onPressed", deviceId !== null ? (data) => data.deviceId === deviceId : void 0);
24035
- const [history, setHistory] = (0, react.useState)([]);
24036
- (0, react.useEffect)(() => {
25677
+ const [history, setHistory] = (0, react$1.useState)([]);
25678
+ (0, react$1.useEffect)(() => {
24037
25679
  if (!event) return;
24038
25680
  setHistory((prev) => {
24039
25681
  if (prev.length > 0 && prev[0].deviceId === event.deviceId && prev[0].timestamp === event.timestamp) return prev;
@@ -24069,9 +25711,9 @@ function useDoorbellEvents(options) {
24069
25711
  */
24070
25712
  function useDevices(filters) {
24071
25713
  const system = useSystem();
24072
- const filtersKey = (0, react.useMemo)(() => filters ? JSON.stringify(filters) : "", [filters]);
24073
- const [devices, setDevices] = (0, react.useState)(() => system.listDevices(filters));
24074
- (0, react.useEffect)(() => {
25714
+ const filtersKey = (0, react$1.useMemo)(() => filters ? JSON.stringify(filters) : "", [filters]);
25715
+ const [devices, setDevices] = (0, react$1.useState)(() => system.listDevices(filters));
25716
+ (0, react$1.useEffect)(() => {
24075
25717
  const refresh = () => {
24076
25718
  setDevices(system.listDevices(filters));
24077
25719
  };
@@ -24104,8 +25746,8 @@ function useDevices(filters) {
24104
25746
  */
24105
25747
  function useDevice(deviceId) {
24106
25748
  const system = useSystem();
24107
- const [device, setDevice] = (0, react.useState)(() => deviceId === null ? null : system.getDevice(deviceId));
24108
- (0, react.useEffect)(() => {
25749
+ const [device, setDevice] = (0, react$1.useState)(() => deviceId === null ? null : system.getDevice(deviceId));
25750
+ (0, react$1.useEffect)(() => {
24109
25751
  if (deviceId === null) {
24110
25752
  setDevice(null);
24111
25753
  return;
@@ -24203,15 +25845,15 @@ function useSystemMutation(select, opts) {
24203
25845
  function useEventInvalidation(queryKey, categories) {
24204
25846
  const system = useSystem();
24205
25847
  const queryClient = (0, _tanstack_react_query.useQueryClient)();
24206
- const [tick, setTick] = (0, react.useState)(system.connectionVersion);
24207
- (0, react.useEffect)(() => {
25848
+ const [tick, setTick] = (0, react$1.useState)(system.connectionVersion);
25849
+ (0, react$1.useEffect)(() => {
24208
25850
  return system.subscribeConnectionEvents((state, version) => {
24209
25851
  if (state === "connected") setTick(version);
24210
25852
  });
24211
25853
  }, [system]);
24212
25854
  const key = categories.join("|");
24213
25855
  const keyJson = JSON.stringify(queryKey);
24214
- (0, react.useEffect)(() => {
25856
+ (0, react$1.useEffect)(() => {
24215
25857
  const subs = [];
24216
25858
  const refresh = () => {
24217
25859
  const raw = JSON.parse(keyJson);
@@ -24266,6 +25908,7 @@ exports.ConfigFormField = FormField;
24266
25908
  exports.ConfigSchemaField = ConfigSchemaField;
24267
25909
  exports.ConfirmActionButton = ConfirmActionButton;
24268
25910
  exports.ConfirmDialogProvider = ConfirmDialogProvider;
25911
+ exports.CopyButton = CopyButton;
24269
25912
  exports.CustomFieldRenderersProvider = CustomFieldRenderersProvider;
24270
25913
  exports.DEFAULT_COLOR = DEFAULT_COLOR;
24271
25914
  exports.DataTable = DataTable;
@@ -24276,6 +25919,7 @@ exports.DevShell = DevShell;
24276
25919
  exports.DeviceActivityPanel = DeviceActivityPanel;
24277
25920
  exports.DeviceCard = DeviceCard;
24278
25921
  exports.DeviceContextProvider = DeviceContextProvider;
25922
+ exports.DeviceExportPanel = DeviceExportPanel;
24279
25923
  exports.DeviceGrid = DeviceGrid;
24280
25924
  exports.DeviceItem = DeviceItem;
24281
25925
  exports.DeviceList = DeviceList;
@@ -24293,6 +25937,7 @@ exports.DropdownContent = DropdownContent;
24293
25937
  exports.DropdownItem = DropdownItem;
24294
25938
  exports.DropdownTrigger = DropdownTrigger;
24295
25939
  exports.EmptyState = EmptyState;
25940
+ exports.ErrorBox = ErrorBox;
24296
25941
  exports.EventStream = EventStream;
24297
25942
  exports.FilterBar = FilterBar;
24298
25943
  exports.FloatingEventStream = FloatingEventStream;
@@ -24330,6 +25975,7 @@ exports.Popover = Popover;
24330
25975
  exports.PopoverContent = PopoverContent;
24331
25976
  exports.PopoverTrigger = PopoverTrigger;
24332
25977
  exports.ProviderBadge = ProviderBadge;
25978
+ exports.QrCode = QrCode;
24333
25979
  exports.ResponseLog = ResponseLog;
24334
25980
  exports.SECTION_BODY = SECTION_BODY;
24335
25981
  exports.SECTION_CARD = SECTION_CARD;
@@ -24404,12 +26050,15 @@ exports.useAddonsCustom = useAddonsCustom;
24404
26050
  exports.useAddonsForceRefresh = useAddonsForceRefresh;
24405
26051
  exports.useAddonsGetAddonAutoUpdate = useAddonsGetAddonAutoUpdate;
24406
26052
  exports.useAddonsGetAutoUpdateSettings = useAddonsGetAutoUpdateSettings;
26053
+ exports.useAddonsGetLastRestart = useAddonsGetLastRestart;
24407
26054
  exports.useAddonsGetLogs = useAddonsGetLogs;
24408
26055
  exports.useAddonsGetVersions = useAddonsGetVersions;
24409
26056
  exports.useAddonsInstallFromWorkspace = useAddonsInstallFromWorkspace;
24410
26057
  exports.useAddonsInstallPackage = useAddonsInstallPackage;
24411
26058
  exports.useAddonsIsWorkspaceAvailable = useAddonsIsWorkspaceAvailable;
24412
26059
  exports.useAddonsList = useAddonsList;
26060
+ exports.useAddonsListCapabilityProviders = useAddonsListCapabilityProviders;
26061
+ exports.useAddonsListFrameworkPackages = useAddonsListFrameworkPackages;
24413
26062
  exports.useAddonsListPackages = useAddonsListPackages;
24414
26063
  exports.useAddonsListUpdates = useAddonsListUpdates;
24415
26064
  exports.useAddonsListWorkspacePackages = useAddonsListWorkspacePackages;
@@ -24423,6 +26072,7 @@ exports.useAddonsSearchAvailable = useAddonsSearchAvailable;
24423
26072
  exports.useAddonsSetAddonAutoUpdate = useAddonsSetAddonAutoUpdate;
24424
26073
  exports.useAddonsSetAutoUpdateSettings = useAddonsSetAutoUpdateSettings;
24425
26074
  exports.useAddonsUninstallPackage = useAddonsUninstallPackage;
26075
+ exports.useAddonsUpdateFrameworkPackage = useAddonsUpdateFrameworkPackage;
24426
26076
  exports.useAddonsUpdatePackage = useAddonsUpdatePackage;
24427
26077
  exports.useAlertsDismiss = useAlertsDismiss;
24428
26078
  exports.useAlertsEmit = useAlertsEmit;
@@ -24624,11 +26274,15 @@ exports.useMeshNetworkGetStatus = useMeshNetworkGetStatus;
24624
26274
  exports.useMeshNetworkJoin = useMeshNetworkJoin;
24625
26275
  exports.useMeshNetworkLeave = useMeshNetworkLeave;
24626
26276
  exports.useMeshNetworkListPeers = useMeshNetworkListPeers;
26277
+ exports.useMeshNetworkLogout = useMeshNetworkLogout;
24627
26278
  exports.useMeshNetworkStartLogin = useMeshNetworkStartLogin;
24628
26279
  exports.useMeshNetworkTestConnection = useMeshNetworkTestConnection;
24629
26280
  exports.useMeshOrchestratorJoinProvider = useMeshOrchestratorJoinProvider;
24630
26281
  exports.useMeshOrchestratorLeaveProvider = useMeshOrchestratorLeaveProvider;
26282
+ exports.useMeshOrchestratorListProviderPeers = useMeshOrchestratorListProviderPeers;
24631
26283
  exports.useMeshOrchestratorListProviders = useMeshOrchestratorListProviders;
26284
+ exports.useMeshOrchestratorLogoutProvider = useMeshOrchestratorLogoutProvider;
26285
+ exports.useMeshOrchestratorStartLoginProvider = useMeshOrchestratorStartLoginProvider;
24632
26286
  exports.useMetricsProviderCollectSnapshot = useMetricsProviderCollectSnapshot;
24633
26287
  exports.useMetricsProviderGetAddonStats = useMetricsProviderGetAddonStats;
24634
26288
  exports.useMetricsProviderGetCached = useMetricsProviderGetCached;
@@ -24665,6 +26319,7 @@ exports.useNetworkQualityReportClientStats = useNetworkQualityReportClientStats;
24665
26319
  exports.useNodesClusterAddonStatus = useNodesClusterAddonStatus;
24666
26320
  exports.useNodesDeployAddon = useNodesDeployAddon;
24667
26321
  exports.useNodesExecuteQuery = useNodesExecuteQuery;
26322
+ exports.useNodesGetNodeAddons = useNodesGetNodeAddons;
24668
26323
  exports.useNodesRenameNode = useNodesRenameNode;
24669
26324
  exports.useNodesRestartAddon = useNodesRestartAddon;
24670
26325
  exports.useNodesRestartNode = useNodesRestartNode;