@viasoftbr/shared-ui 0.0.4 → 0.0.6

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.js CHANGED
@@ -2953,6 +2953,35 @@ function buildWsUrl(path = "/") {
2953
2953
  return `${proto}://${host}${path.startsWith("/") ? path : "/" + path}`;
2954
2954
  }
2955
2955
  }
2956
+ function extractBearerToken(headers, explicitToken) {
2957
+ if (explicitToken)
2958
+ return explicitToken;
2959
+ if (!headers)
2960
+ return null;
2961
+ const authHeader = headers.Authorization || headers.authorization;
2962
+ if (!authHeader)
2963
+ return null;
2964
+ const match = authHeader.match(/^Bearer\s+(.+)$/i);
2965
+ return match ? match[1] : null;
2966
+ }
2967
+ function appendWsQueryParam(url, key, value) {
2968
+ try {
2969
+ const parsed = new URL(
2970
+ url,
2971
+ typeof window !== "undefined" ? window.location.href : void 0
2972
+ );
2973
+ parsed.searchParams.set(key, value);
2974
+ return parsed.toString();
2975
+ } catch {
2976
+ const separator = url.includes("?") ? "&" : "?";
2977
+ return `${url}${separator}${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
2978
+ }
2979
+ }
2980
+ function normalizeProtocols(protocols) {
2981
+ if (!protocols)
2982
+ return void 0;
2983
+ return Array.isArray(protocols) ? protocols.filter(Boolean) : [protocols];
2984
+ }
2956
2985
  async function encodeFfurl(settings) {
2957
2986
  const { ffurl } = await fetchApi.postJson("/auth/protocols/ffurl/encode", settings);
2958
2987
  return ffurl;
@@ -2961,8 +2990,28 @@ async function decodeFfurl(ffurl) {
2961
2990
  const { settings } = await fetchApi.postJson("/auth/protocols/ffurl/decode", { ffurl });
2962
2991
  return settings;
2963
2992
  }
2964
- function subscribeToWebsocket(url, onMessage) {
2965
- const socket = new WebSocket(url);
2993
+ function subscribeToWebsocket(url, onMessage, options = {}) {
2994
+ const bearerToken = extractBearerToken(options.headers, options.bearerToken);
2995
+ const bearerStrategy = options.bearerStrategy ?? "query";
2996
+ let resolvedUrl = url;
2997
+ const protocols = normalizeProtocols(options.protocols) ?? [];
2998
+ if (options.headers && Object.keys(options.headers).length > 0) {
2999
+ console.warn(
3000
+ "WebSocket connections in browsers do not support custom HTTP headers. shared-ui will derive bearer auth from Authorization and forward it using query string or subprotocol."
3001
+ );
3002
+ }
3003
+ if (bearerToken) {
3004
+ if (bearerStrategy === "protocol") {
3005
+ protocols.push("bearer", bearerToken);
3006
+ } else {
3007
+ resolvedUrl = appendWsQueryParam(
3008
+ url,
3009
+ options.bearerQueryParam ?? "access_token",
3010
+ bearerToken
3011
+ );
3012
+ }
3013
+ }
3014
+ const socket = protocols.length > 0 ? new WebSocket(resolvedUrl, protocols) : new WebSocket(resolvedUrl);
2966
3015
  socket.onmessage = (event) => {
2967
3016
  try {
2968
3017
  const data = JSON.parse(event.data);
@@ -3013,140 +3062,6 @@ var authService = {
3013
3062
  }
3014
3063
  };
3015
3064
 
3016
- // src/services/loadRemoteModule.ts
3017
- import * as React from "react";
3018
- import * as ReactDOM from "react-dom";
3019
- var sharedScopeInitialized = false;
3020
- function getSharedScope() {
3021
- if (!globalThis.__federation_shared__) {
3022
- globalThis.__federation_shared__ = {};
3023
- }
3024
- if (!sharedScopeInitialized) {
3025
- globalThis.__federation_shared__["react"] = {
3026
- "18.3.1": {
3027
- get: () => Promise.resolve(() => React),
3028
- loaded: true,
3029
- from: "core",
3030
- scope: "default"
3031
- }
3032
- };
3033
- globalThis.__federation_shared__["react-dom"] = {
3034
- "18.3.1": {
3035
- get: () => Promise.resolve(() => ReactDOM),
3036
- loaded: true,
3037
- from: "core",
3038
- scope: "default"
3039
- }
3040
- };
3041
- sharedScopeInitialized = true;
3042
- }
3043
- return globalThis.__federation_shared__;
3044
- }
3045
- var loadedContainers = /* @__PURE__ */ new Map();
3046
- var initializedContainers = /* @__PURE__ */ new Set();
3047
- async function loadContainer(url) {
3048
- if (loadedContainers.has(url)) {
3049
- return loadedContainers.get(url);
3050
- }
3051
- const loadPromise = (async () => {
3052
- try {
3053
- const container = await import(
3054
- /* @vite-ignore */
3055
- url
3056
- );
3057
- if (container.init && !initializedContainers.has(url)) {
3058
- await container.init(getSharedScope());
3059
- initializedContainers.add(url);
3060
- }
3061
- return container;
3062
- } catch (error2) {
3063
- loadedContainers.delete(url);
3064
- initializedContainers.delete(url);
3065
- throw error2;
3066
- }
3067
- })();
3068
- loadedContainers.set(url, loadPromise);
3069
- return loadPromise;
3070
- }
3071
- async function loadRemoteModule(config) {
3072
- const container = await loadContainer(config.url);
3073
- if (!container || typeof container.get !== "function") {
3074
- throw new Error(`Container inv\xE1lido ou sem m\xE9todo get: ${config.scope}`);
3075
- }
3076
- if (typeof container.dynamicLoadingCss === "function") {
3077
- try {
3078
- await container.dynamicLoadingCss([]);
3079
- } catch (err) {
3080
- console.warn(`Aviso: Falha ao carregar CSS global do remote ${config.scope}`, err);
3081
- }
3082
- }
3083
- const factory2 = await container.get(config.module);
3084
- const moduleExports = await factory2();
3085
- if (moduleExports && typeof moduleExports === "object" && "default" in moduleExports) {
3086
- return moduleExports.default;
3087
- }
3088
- return moduleExports;
3089
- }
3090
-
3091
- // src/services/metadataLoader.ts
3092
- var MetadataLoader = class {
3093
- constructor() {
3094
- __publicField(this, "metadataCache", /* @__PURE__ */ new Map());
3095
- }
3096
- async loadMetadata(metadataUrl) {
3097
- if (this.metadataCache.has(metadataUrl)) {
3098
- return this.metadataCache.get(metadataUrl) || [];
3099
- }
3100
- try {
3101
- const response = await fetch(metadataUrl);
3102
- console.log(response);
3103
- if (!response.ok) {
3104
- throw new Error(`Failed to fetch metadata: ${response.statusText}`);
3105
- }
3106
- const data = await response.json();
3107
- let metadata;
3108
- if (Array.isArray(data)) {
3109
- metadata = data;
3110
- } else if (data.pages && Array.isArray(data.pages)) {
3111
- metadata = data.pages;
3112
- } else {
3113
- throw new Error(
3114
- "Invalid metadata format: expected array or object with pages property"
3115
- );
3116
- }
3117
- metadata.forEach((page, index3) => {
3118
- if (!page.id || !page.name || !page.path || !page.url) {
3119
- throw new Error(
3120
- `Invalid page metadata at index ${index3}: missing required fields`
3121
- );
3122
- }
3123
- });
3124
- this.metadataCache.set(metadataUrl, metadata);
3125
- return metadata;
3126
- } catch (error2) {
3127
- console.warn(`Failed to load metadata from ${metadataUrl}:`, error2);
3128
- return [];
3129
- }
3130
- }
3131
- async loadFromDirectory(directoryUrl) {
3132
- try {
3133
- const manifestUrl = `${directoryUrl}/manifest.json`;
3134
- return await this.loadMetadata(manifestUrl);
3135
- } catch (error2) {
3136
- throw new Error(
3137
- `Directory manifest not found at ${directoryUrl}/manifest.json: ${error2}`
3138
- );
3139
- }
3140
- }
3141
- clearCache() {
3142
- this.metadataCache.clear();
3143
- }
3144
- getCachedMetadata(metadataUrl) {
3145
- return this.metadataCache.get(metadataUrl);
3146
- }
3147
- };
3148
- var metadataLoader = new MetadataLoader();
3149
-
3150
3065
  // src/services/registry.ts
3151
3066
  var PluginRegistryImpl = class {
3152
3067
  constructor() {
@@ -25936,26 +25851,33 @@ var Accordion = ({ title, children, defaultOpen = false }) => {
25936
25851
  var Accordion_default = Accordion;
25937
25852
 
25938
25853
  // src/components/display/Section.tsx
25939
- import { useEffect as useEffect2, useRef, createContext as createContext2, useContext as useContext2 } from "react";
25854
+ import { useEffect as useEffect2, useRef, createContext as createContext2, use as use2 } from "react";
25940
25855
 
25941
25856
  // src/context/AuthContext.tsx
25942
- import { createContext, useContext, useEffect, useState as useState2 } from "react";
25857
+ import { createContext, use, useEffect, useState as useState2 } from "react";
25943
25858
  import { jsx as jsx2 } from "react/jsx-runtime";
25944
25859
  var AuthContext = createContext(void 0);
25945
- var AuthProvider = ({ children, onNavigate }) => {
25946
- const [user, setUser] = useState2(null);
25947
- const [accessToken, setToken] = useState2(null);
25860
+ var AuthProvider = ({
25861
+ children,
25862
+ onNavigate,
25863
+ storage = typeof window !== "undefined" ? window.localStorage : null,
25864
+ authService: authService2 = authService,
25865
+ initialUser = null,
25866
+ initialAccessToken = null
25867
+ }) => {
25868
+ const [user, setUser] = useState2(initialUser);
25869
+ const [accessToken, setToken] = useState2(initialAccessToken ?? null);
25948
25870
  const [loading, setLoading] = useState2(true);
25949
25871
  useEffect(() => {
25950
25872
  try {
25951
- const storedUser = localStorage.getItem("user");
25873
+ const storedUser = storage?.getItem("user");
25952
25874
  if (storedUser)
25953
25875
  setUser(JSON.parse(storedUser));
25954
25876
  } catch {
25955
25877
  }
25956
25878
  try {
25957
- const savedAccess = localStorage.getItem("accessToken");
25958
- const savedRefresh = localStorage.getItem("refreshToken");
25879
+ const savedAccess = storage?.getItem("accessToken");
25880
+ const savedRefresh = storage?.getItem("refreshToken");
25959
25881
  if (savedAccess) {
25960
25882
  setToken(savedAccess);
25961
25883
  setAccessToken(savedAccess);
@@ -25966,15 +25888,17 @@ var AuthProvider = ({ children, onNavigate }) => {
25966
25888
  } catch {
25967
25889
  }
25968
25890
  setLoading(false);
25969
- }, []);
25891
+ }, [storage]);
25970
25892
  const login = async (username, password, options) => {
25971
- const resp = await authService.login(username, password);
25893
+ const resp = await authService2.login(username, password);
25972
25894
  setToken(resp.accessToken);
25973
25895
  setAccessToken(resp.accessToken);
25974
25896
  setRefreshToken(resp.refreshToken);
25975
25897
  setUser(resp.user);
25976
25898
  try {
25977
- localStorage.setItem("user", JSON.stringify(resp.user));
25899
+ storage?.setItem("user", JSON.stringify(resp.user));
25900
+ storage?.setItem("accessToken", resp.accessToken);
25901
+ storage?.setItem("refreshToken", resp.refreshToken);
25978
25902
  } catch {
25979
25903
  }
25980
25904
  if (options?.redirect !== false)
@@ -25982,13 +25906,15 @@ var AuthProvider = ({ children, onNavigate }) => {
25982
25906
  };
25983
25907
  const logout = async () => {
25984
25908
  try {
25985
- await authService.logout();
25909
+ await authService2.logout();
25986
25910
  } finally {
25987
25911
  setToken(null);
25988
25912
  clearTokens();
25989
25913
  setUser(null);
25990
25914
  try {
25991
- localStorage.removeItem("user");
25915
+ storage?.removeItem("user");
25916
+ storage?.removeItem("accessToken");
25917
+ storage?.removeItem("refreshToken");
25992
25918
  } catch {
25993
25919
  }
25994
25920
  onNavigate?.("/login");
@@ -26000,10 +25926,10 @@ var AuthProvider = ({ children, onNavigate }) => {
26000
25926
  const want = Array.isArray(roles) ? roles : [roles];
26001
25927
  return want.some((r17) => user.role === r17);
26002
25928
  };
26003
- return /* @__PURE__ */ jsx2(AuthContext.Provider, { value: { user, accessToken, loading, login, logout, hasRole }, children });
25929
+ return /* @__PURE__ */ jsx2(AuthContext, { value: { user, accessToken, loading, login, logout, hasRole }, children });
26004
25930
  };
26005
25931
  function useAuth() {
26006
- const ctx = useContext(AuthContext);
25932
+ const ctx = use(AuthContext);
26007
25933
  if (!ctx)
26008
25934
  throw new Error("useAuth must be used within AuthProvider");
26009
25935
  return ctx;
@@ -26052,7 +25978,7 @@ var SkeletonBlock = ({ lines = 3, className = "" }) => {
26052
25978
  import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
26053
25979
  var SectionContext = createContext2(void 0);
26054
25980
  function useSection() {
26055
- const ctx = useContext2(SectionContext);
25981
+ const ctx = use2(SectionContext);
26056
25982
  return ctx ?? { readonly: false };
26057
25983
  }
26058
25984
  var Section2 = ({ id, title, icon, expanded, onToggle, children, readonly, loading = false }) => {
@@ -26097,7 +26023,7 @@ var Section2 = ({ id, title, icon, expanded, onToggle, children, readonly, loadi
26097
26023
  overflow-hidden
26098
26024
  ${expanded ? "max-h-fit opacity-100" : "max-h-0 opacity-0"}
26099
26025
  `,
26100
- children: /* @__PURE__ */ jsx4("div", { className: "px-6 py-4 border-t transition-all transition-discrete border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/50", children: /* @__PURE__ */ jsx4(SectionContext.Provider, { value: { readonly: !!effectiveReadonly }, children: loading ? /* @__PURE__ */ jsx4(SkeletonBlock, { lines: 5 }) : children }) })
26026
+ children: /* @__PURE__ */ jsx4("div", { className: "px-6 py-4 border-t transition-all transition-discrete border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/50", children: /* @__PURE__ */ jsx4(SectionContext, { value: { readonly: !!effectiveReadonly }, children: loading ? /* @__PURE__ */ jsx4(SkeletonBlock, { lines: 5 }) : children }) })
26101
26027
  }
26102
26028
  )
26103
26029
  ] });
@@ -28256,7 +28182,7 @@ function m6(u16, t15) {
28256
28182
  }
28257
28183
 
28258
28184
  // node_modules/.pnpm/@floating-ui+react@0.26.28_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/@floating-ui/react/dist/floating-ui.react.mjs
28259
- import * as React6 from "react";
28185
+ import * as React5 from "react";
28260
28186
  import { useLayoutEffect as useLayoutEffect2, useEffect as useEffect5, useRef as useRef4 } from "react";
28261
28187
 
28262
28188
  // node_modules/.pnpm/@floating-ui+utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs
@@ -28561,7 +28487,7 @@ function rectToClientRect(rect) {
28561
28487
  }
28562
28488
 
28563
28489
  // node_modules/.pnpm/@floating-ui+react@0.26.28_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/@floating-ui/react/dist/floating-ui.react.mjs
28564
- import * as ReactDOM3 from "react-dom";
28490
+ import * as ReactDOM2 from "react-dom";
28565
28491
 
28566
28492
  // node_modules/.pnpm/@floating-ui+core@1.7.4/node_modules/@floating-ui/core/dist/floating-ui.core.mjs
28567
28493
  function computeCoordsFromPlacement(_ref, placement, rtl) {
@@ -29764,9 +29690,9 @@ var computePosition2 = (reference, floating, options) => {
29764
29690
  };
29765
29691
 
29766
29692
  // node_modules/.pnpm/@floating-ui+react-dom@2.1.7_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.mjs
29767
- import * as React5 from "react";
29693
+ import * as React4 from "react";
29768
29694
  import { useLayoutEffect } from "react";
29769
- import * as ReactDOM2 from "react-dom";
29695
+ import * as ReactDOM from "react-dom";
29770
29696
  var isClient = typeof document !== "undefined";
29771
29697
  var noop2 = function noop3() {
29772
29698
  };
@@ -29831,7 +29757,7 @@ function roundByDPR(element, value) {
29831
29757
  return Math.round(value * dpr) / dpr;
29832
29758
  }
29833
29759
  function useLatestRef(value) {
29834
- const ref = React5.useRef(value);
29760
+ const ref = React4.useRef(value);
29835
29761
  index(() => {
29836
29762
  ref.current = value;
29837
29763
  });
@@ -29854,7 +29780,7 @@ function useFloating(options) {
29854
29780
  whileElementsMounted,
29855
29781
  open
29856
29782
  } = options;
29857
- const [data, setData] = React5.useState({
29783
+ const [data, setData] = React4.useState({
29858
29784
  x: 0,
29859
29785
  y: 0,
29860
29786
  strategy,
@@ -29862,19 +29788,19 @@ function useFloating(options) {
29862
29788
  middlewareData: {},
29863
29789
  isPositioned: false
29864
29790
  });
29865
- const [latestMiddleware, setLatestMiddleware] = React5.useState(middleware);
29791
+ const [latestMiddleware, setLatestMiddleware] = React4.useState(middleware);
29866
29792
  if (!deepEqual(latestMiddleware, middleware)) {
29867
29793
  setLatestMiddleware(middleware);
29868
29794
  }
29869
- const [_reference, _setReference] = React5.useState(null);
29870
- const [_floating, _setFloating] = React5.useState(null);
29871
- const setReference = React5.useCallback((node) => {
29795
+ const [_reference, _setReference] = React4.useState(null);
29796
+ const [_floating, _setFloating] = React4.useState(null);
29797
+ const setReference = React4.useCallback((node) => {
29872
29798
  if (node !== referenceRef.current) {
29873
29799
  referenceRef.current = node;
29874
29800
  _setReference(node);
29875
29801
  }
29876
29802
  }, []);
29877
- const setFloating = React5.useCallback((node) => {
29803
+ const setFloating = React4.useCallback((node) => {
29878
29804
  if (node !== floatingRef.current) {
29879
29805
  floatingRef.current = node;
29880
29806
  _setFloating(node);
@@ -29882,14 +29808,14 @@ function useFloating(options) {
29882
29808
  }, []);
29883
29809
  const referenceEl = externalReference || _reference;
29884
29810
  const floatingEl = externalFloating || _floating;
29885
- const referenceRef = React5.useRef(null);
29886
- const floatingRef = React5.useRef(null);
29887
- const dataRef = React5.useRef(data);
29811
+ const referenceRef = React4.useRef(null);
29812
+ const floatingRef = React4.useRef(null);
29813
+ const dataRef = React4.useRef(data);
29888
29814
  const hasWhileElementsMounted = whileElementsMounted != null;
29889
29815
  const whileElementsMountedRef = useLatestRef(whileElementsMounted);
29890
29816
  const platformRef = useLatestRef(platform2);
29891
29817
  const openRef = useLatestRef(open);
29892
- const update = React5.useCallback(() => {
29818
+ const update = React4.useCallback(() => {
29893
29819
  if (!referenceRef.current || !floatingRef.current) {
29894
29820
  return;
29895
29821
  }
@@ -29912,7 +29838,7 @@ function useFloating(options) {
29912
29838
  };
29913
29839
  if (isMountedRef.current && !deepEqual(dataRef.current, fullData)) {
29914
29840
  dataRef.current = fullData;
29915
- ReactDOM2.flushSync(() => {
29841
+ ReactDOM.flushSync(() => {
29916
29842
  setData(fullData);
29917
29843
  });
29918
29844
  }
@@ -29927,7 +29853,7 @@ function useFloating(options) {
29927
29853
  }));
29928
29854
  }
29929
29855
  }, [open]);
29930
- const isMountedRef = React5.useRef(false);
29856
+ const isMountedRef = React4.useRef(false);
29931
29857
  index(() => {
29932
29858
  isMountedRef.current = true;
29933
29859
  return () => {
@@ -29946,17 +29872,17 @@ function useFloating(options) {
29946
29872
  update();
29947
29873
  }
29948
29874
  }, [referenceEl, floatingEl, update, whileElementsMountedRef, hasWhileElementsMounted]);
29949
- const refs = React5.useMemo(() => ({
29875
+ const refs = React4.useMemo(() => ({
29950
29876
  reference: referenceRef,
29951
29877
  floating: floatingRef,
29952
29878
  setReference,
29953
29879
  setFloating
29954
29880
  }), [setReference, setFloating]);
29955
- const elements = React5.useMemo(() => ({
29881
+ const elements = React4.useMemo(() => ({
29956
29882
  reference: referenceEl,
29957
29883
  floating: floatingEl
29958
29884
  }), [referenceEl, floatingEl]);
29959
- const floatingStyles = React5.useMemo(() => {
29885
+ const floatingStyles = React4.useMemo(() => {
29960
29886
  const initialStyles = {
29961
29887
  position: strategy,
29962
29888
  left: 0,
@@ -29982,7 +29908,7 @@ function useFloating(options) {
29982
29908
  top: y8
29983
29909
  };
29984
29910
  }, [strategy, transform, elements.floating, data.x, data.y]);
29985
- return React5.useMemo(() => ({
29911
+ return React4.useMemo(() => ({
29986
29912
  ...data,
29987
29913
  update,
29988
29914
  refs,
@@ -30009,12 +29935,12 @@ var size3 = (options, deps) => ({
30009
29935
 
30010
29936
  // node_modules/.pnpm/@floating-ui+react@0.26.28_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/@floating-ui/react/dist/floating-ui.react.mjs
30011
29937
  var SafeReact = {
30012
- ...React6
29938
+ ...React5
30013
29939
  };
30014
29940
  var useInsertionEffect = SafeReact.useInsertionEffect;
30015
29941
  var useSafeInsertionEffect = useInsertionEffect || ((fn) => fn());
30016
29942
  function useEffectEvent(callback) {
30017
- const ref = React6.useRef(() => {
29943
+ const ref = React5.useRef(() => {
30018
29944
  if (true) {
30019
29945
  throw new Error("Cannot call an event handler while rendering.");
30020
29946
  }
@@ -30022,7 +29948,7 @@ function useEffectEvent(callback) {
30022
29948
  useSafeInsertionEffect(() => {
30023
29949
  ref.current = callback;
30024
29950
  });
30025
- return React6.useCallback(function() {
29951
+ return React5.useCallback(function() {
30026
29952
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
30027
29953
  args[_key] = arguments[_key];
30028
29954
  }
@@ -30045,13 +29971,13 @@ var genId = () => (
30045
29971
  "floating-ui-" + Math.random().toString(36).slice(2, 6) + count++
30046
29972
  );
30047
29973
  function useFloatingId() {
30048
- const [id, setId] = React6.useState(() => serverHandoffComplete ? genId() : void 0);
29974
+ const [id, setId] = React5.useState(() => serverHandoffComplete ? genId() : void 0);
30049
29975
  index2(() => {
30050
29976
  if (id == null) {
30051
29977
  setId(genId());
30052
29978
  }
30053
29979
  }, []);
30054
- React6.useEffect(() => {
29980
+ React5.useEffect(() => {
30055
29981
  serverHandoffComplete = true;
30056
29982
  }, []);
30057
29983
  return id;
@@ -30102,13 +30028,13 @@ function createPubSub() {
30102
30028
  }
30103
30029
  };
30104
30030
  }
30105
- var FloatingNodeContext = /* @__PURE__ */ React6.createContext(null);
30106
- var FloatingTreeContext = /* @__PURE__ */ React6.createContext(null);
30031
+ var FloatingNodeContext = /* @__PURE__ */ React5.createContext(null);
30032
+ var FloatingTreeContext = /* @__PURE__ */ React5.createContext(null);
30107
30033
  var useFloatingParentNodeId = () => {
30108
30034
  var _React$useContext;
30109
- return ((_React$useContext = React6.useContext(FloatingNodeContext)) == null ? void 0 : _React$useContext.id) || null;
30035
+ return ((_React$useContext = React5.useContext(FloatingNodeContext)) == null ? void 0 : _React$useContext.id) || null;
30110
30036
  };
30111
- var useFloatingTree = () => React6.useContext(FloatingTreeContext);
30037
+ var useFloatingTree = () => React5.useContext(FloatingTreeContext);
30112
30038
  var FOCUSABLE_ATTRIBUTE = "data-floating-ui-focusable";
30113
30039
  function useFloatingRootContext(options) {
30114
30040
  const {
@@ -30117,8 +30043,8 @@ function useFloatingRootContext(options) {
30117
30043
  elements: elementsProp
30118
30044
  } = options;
30119
30045
  const floatingId = useId();
30120
- const dataRef = React6.useRef({});
30121
- const [events] = React6.useState(() => createPubSub());
30046
+ const dataRef = React5.useRef({});
30047
+ const [events] = React5.useState(() => createPubSub());
30122
30048
  const nested = useFloatingParentNodeId() != null;
30123
30049
  if (true) {
30124
30050
  const optionDomReference = elementsProp.reference;
@@ -30126,7 +30052,7 @@ function useFloatingRootContext(options) {
30126
30052
  error("Cannot pass a virtual element to the `elements.reference` option,", "as it must be a real DOM element. Use `refs.setPositionReference()`", "instead.");
30127
30053
  }
30128
30054
  }
30129
- const [positionReference, setPositionReference] = React6.useState(elementsProp.reference);
30055
+ const [positionReference, setPositionReference] = React5.useState(elementsProp.reference);
30130
30056
  const onOpenChange = useEffectEvent((open2, event, reason) => {
30131
30057
  dataRef.current.openEvent = open2 ? event : void 0;
30132
30058
  events.emit("openchange", {
@@ -30137,15 +30063,15 @@ function useFloatingRootContext(options) {
30137
30063
  });
30138
30064
  onOpenChangeProp == null || onOpenChangeProp(open2, event, reason);
30139
30065
  });
30140
- const refs = React6.useMemo(() => ({
30066
+ const refs = React5.useMemo(() => ({
30141
30067
  setPositionReference
30142
30068
  }), []);
30143
- const elements = React6.useMemo(() => ({
30069
+ const elements = React5.useMemo(() => ({
30144
30070
  reference: positionReference || elementsProp.reference || null,
30145
30071
  floating: elementsProp.floating || null,
30146
30072
  domReference: elementsProp.reference
30147
30073
  }), [positionReference, elementsProp.reference, elementsProp.floating]);
30148
- return React6.useMemo(() => ({
30074
+ return React5.useMemo(() => ({
30149
30075
  dataRef,
30150
30076
  open,
30151
30077
  onOpenChange,
@@ -30172,11 +30098,11 @@ function useFloating2(options) {
30172
30098
  });
30173
30099
  const rootContext = options.rootContext || internalRootContext;
30174
30100
  const computedElements = rootContext.elements;
30175
- const [_domReference, setDomReference] = React6.useState(null);
30176
- const [positionReference, _setPositionReference] = React6.useState(null);
30101
+ const [_domReference, setDomReference] = React5.useState(null);
30102
+ const [positionReference, _setPositionReference] = React5.useState(null);
30177
30103
  const optionDomReference = computedElements == null ? void 0 : computedElements.domReference;
30178
30104
  const domReference = optionDomReference || _domReference;
30179
- const domReferenceRef = React6.useRef(null);
30105
+ const domReferenceRef = React5.useRef(null);
30180
30106
  const tree = useFloatingTree();
30181
30107
  index2(() => {
30182
30108
  if (domReference) {
@@ -30192,7 +30118,7 @@ function useFloating2(options) {
30192
30118
  }
30193
30119
  }
30194
30120
  });
30195
- const setPositionReference = React6.useCallback((node) => {
30121
+ const setPositionReference = React5.useCallback((node) => {
30196
30122
  const computedPositionReference = isElement(node) ? {
30197
30123
  getBoundingClientRect: () => node.getBoundingClientRect(),
30198
30124
  contextElement: node
@@ -30200,7 +30126,7 @@ function useFloating2(options) {
30200
30126
  _setPositionReference(computedPositionReference);
30201
30127
  position.refs.setReference(computedPositionReference);
30202
30128
  }, [position.refs]);
30203
- const setReference = React6.useCallback((node) => {
30129
+ const setReference = React5.useCallback((node) => {
30204
30130
  if (isElement(node) || node === null) {
30205
30131
  domReferenceRef.current = node;
30206
30132
  setDomReference(node);
@@ -30212,17 +30138,17 @@ function useFloating2(options) {
30212
30138
  position.refs.setReference(node);
30213
30139
  }
30214
30140
  }, [position.refs]);
30215
- const refs = React6.useMemo(() => ({
30141
+ const refs = React5.useMemo(() => ({
30216
30142
  ...position.refs,
30217
30143
  setReference,
30218
30144
  setPositionReference,
30219
30145
  domReference: domReferenceRef
30220
30146
  }), [position.refs, setReference, setPositionReference]);
30221
- const elements = React6.useMemo(() => ({
30147
+ const elements = React5.useMemo(() => ({
30222
30148
  ...position.elements,
30223
30149
  domReference
30224
30150
  }), [position.elements, domReference]);
30225
- const context = React6.useMemo(() => ({
30151
+ const context = React5.useMemo(() => ({
30226
30152
  ...position,
30227
30153
  ...rootContext,
30228
30154
  refs,
@@ -30236,7 +30162,7 @@ function useFloating2(options) {
30236
30162
  node.context = context;
30237
30163
  }
30238
30164
  });
30239
- return React6.useMemo(() => ({
30165
+ return React5.useMemo(() => ({
30240
30166
  ...position,
30241
30167
  context,
30242
30168
  refs,
@@ -30308,22 +30234,22 @@ function useInteractions(propsList) {
30308
30234
  const referenceDeps = propsList.map((key) => key == null ? void 0 : key.reference);
30309
30235
  const floatingDeps = propsList.map((key) => key == null ? void 0 : key.floating);
30310
30236
  const itemDeps = propsList.map((key) => key == null ? void 0 : key.item);
30311
- const getReferenceProps = React6.useCallback(
30237
+ const getReferenceProps = React5.useCallback(
30312
30238
  (userProps) => mergeProps(userProps, propsList, "reference"),
30313
30239
  // eslint-disable-next-line react-hooks/exhaustive-deps
30314
30240
  referenceDeps
30315
30241
  );
30316
- const getFloatingProps = React6.useCallback(
30242
+ const getFloatingProps = React5.useCallback(
30317
30243
  (userProps) => mergeProps(userProps, propsList, "floating"),
30318
30244
  // eslint-disable-next-line react-hooks/exhaustive-deps
30319
30245
  floatingDeps
30320
30246
  );
30321
- const getItemProps = React6.useCallback(
30247
+ const getItemProps = React5.useCallback(
30322
30248
  (userProps) => mergeProps(userProps, propsList, "item"),
30323
30249
  // eslint-disable-next-line react-hooks/exhaustive-deps
30324
30250
  itemDeps
30325
30251
  );
30326
- return React6.useMemo(() => ({
30252
+ return React5.useMemo(() => ({
30327
30253
  getReferenceProps,
30328
30254
  getFloatingProps,
30329
30255
  getItemProps
@@ -30394,7 +30320,7 @@ var inner = (props) => ({
30394
30320
  scrollEl.scrollTop = diffY;
30395
30321
  if (onFallbackChange) {
30396
30322
  const shouldFallback = scrollEl.offsetHeight < item.offsetHeight * min(minItemsVisible, listRef.current.length) - 1 || refOverflow.top >= -referenceOverflowThreshold || refOverflow.bottom >= -referenceOverflowThreshold;
30397
- ReactDOM3.flushSync(() => onFallbackChange(shouldFallback));
30323
+ ReactDOM2.flushSync(() => onFallbackChange(shouldFallback));
30398
30324
  }
30399
30325
  if (overflowRef) {
30400
30326
  overflowRef.current = await detectOverflow2(getArgsWithCustomFloatingHeight({
@@ -30419,10 +30345,10 @@ function useInnerOffset(context, props) {
30419
30345
  onChange: unstable_onChange
30420
30346
  } = props;
30421
30347
  const onChange = useEffectEvent(unstable_onChange);
30422
- const controlledScrollingRef = React6.useRef(false);
30423
- const prevScrollTopRef = React6.useRef(null);
30424
- const initialOverflowRef = React6.useRef(null);
30425
- React6.useEffect(() => {
30348
+ const controlledScrollingRef = React5.useRef(false);
30349
+ const prevScrollTopRef = React5.useRef(null);
30350
+ const initialOverflowRef = React5.useRef(null);
30351
+ React5.useEffect(() => {
30426
30352
  if (!enabled)
30427
30353
  return;
30428
30354
  function onWheel(e10) {
@@ -30440,7 +30366,7 @@ function useInnerOffset(context, props) {
30440
30366
  }
30441
30367
  if (!isAtTop && dY > 0 || !isAtBottom && dY < 0) {
30442
30368
  e10.preventDefault();
30443
- ReactDOM3.flushSync(() => {
30369
+ ReactDOM2.flushSync(() => {
30444
30370
  onChange((d9) => d9 + Math[method](dY, remainingScroll * sign));
30445
30371
  });
30446
30372
  } else if (/firefox/i.test(getUserAgent())) {
@@ -30465,7 +30391,7 @@ function useInnerOffset(context, props) {
30465
30391
  };
30466
30392
  }
30467
30393
  }, [enabled, open, elements.floating, overflowRef, scrollRef, onChange]);
30468
- const floating = React6.useMemo(() => ({
30394
+ const floating = React5.useMemo(() => ({
30469
30395
  onKeyDown() {
30470
30396
  controlledScrollingRef.current = true;
30471
30397
  },
@@ -30483,7 +30409,7 @@ function useInnerOffset(context, props) {
30483
30409
  if (prevScrollTopRef.current !== null) {
30484
30410
  const scrollDiff = el.scrollTop - prevScrollTopRef.current;
30485
30411
  if (overflowRef.current.bottom < -0.5 && scrollDiff < -1 || overflowRef.current.top < -0.5 && scrollDiff > 1) {
30486
- ReactDOM3.flushSync(() => onChange((d9) => d9 + scrollDiff));
30412
+ ReactDOM2.flushSync(() => onChange((d9) => d9 + scrollDiff));
30487
30413
  }
30488
30414
  }
30489
30415
  requestAnimationFrame(() => {
@@ -30491,7 +30417,7 @@ function useInnerOffset(context, props) {
30491
30417
  });
30492
30418
  }
30493
30419
  }), [elements.floating, onChange, overflowRef, scrollRef]);
30494
- return React6.useMemo(() => enabled ? {
30420
+ return React5.useMemo(() => enabled ? {
30495
30421
  floating
30496
30422
  } : {}, [enabled, floating]);
30497
30423
  }
@@ -32849,7 +32775,7 @@ var MiddlewareServiceGroup = ({ expanded, onToggle, loading, settings, onChange
32849
32775
  var Service_default = MiddlewareServiceGroup;
32850
32776
 
32851
32777
  // src/components/encoder/DvB.tsx
32852
- import { useState as useState12, useEffect as useEffect9, useImperativeHandle, forwardRef as forwardRef4 } from "react";
32778
+ import { useState as useState12, useEffect as useEffect9 } from "react";
32853
32779
  import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
32854
32780
  var defaultDvBSettings = {
32855
32781
  engine: "cpu",
@@ -32994,7 +32920,8 @@ var normalizeDvBData = (data) => {
32994
32920
  protocol: parseProtocolUrl(data.output_url || defaultProtocolSettings.ffurl)
32995
32921
  };
32996
32922
  };
32997
- var DvB = forwardRef4(function DvB2({ settings, setSettings, encoderId, isLoading, setIsLoading }, ref) {
32923
+ var DvB = function DvB2(props) {
32924
+ const { settings, setSettings, encoderId, isLoading, setIsLoading, ref } = props;
32998
32925
  const [internalSettings, setInternalSettings] = useState12(defaultDvBSettings);
32999
32926
  const [expandedSections, setExpandedSections] = useState12({
33000
32927
  video: true,
@@ -33055,13 +32982,33 @@ var DvB = forwardRef4(function DvB2({ settings, setSettings, encoderId, isLoadin
33055
32982
  newTracks[idx] = { label: newTracks[idx].label, value: !newTracks[idx].value };
33056
32983
  setTracks(newTracks);
33057
32984
  };
33058
- useImperativeHandle(ref, () => ({
33059
- getSettings: () => ({ ...effectiveSettings, output_url: buildProtocolUrl(effectiveSettings.protocol) }),
33060
- reset: () => {
33061
- effectiveSetSettings(savedSettings);
33062
- },
33063
- isDirty: () => JSON.stringify(effectiveSettings) !== JSON.stringify(savedSettings)
33064
- }));
32985
+ useEffect9(() => {
32986
+ if (!ref)
32987
+ return;
32988
+ const impl = {
32989
+ getSettings: () => ({ ...effectiveSettings, output_url: buildProtocolUrl(effectiveSettings.protocol) }),
32990
+ reset: () => {
32991
+ effectiveSetSettings(savedSettings);
32992
+ },
32993
+ isDirty: () => JSON.stringify(effectiveSettings) !== JSON.stringify(savedSettings)
32994
+ };
32995
+ try {
32996
+ if (typeof ref === "function")
32997
+ ref(impl);
32998
+ else if ("current" in ref)
32999
+ ref.current = impl;
33000
+ } catch {
33001
+ }
33002
+ return () => {
33003
+ try {
33004
+ if (typeof ref === "function")
33005
+ ref(null);
33006
+ else if ("current" in ref)
33007
+ ref.current = null;
33008
+ } catch {
33009
+ }
33010
+ };
33011
+ }, [ref, effectiveSettings, savedSettings, effectiveSetSettings]);
33065
33012
  return /* @__PURE__ */ jsxs15("div", { className: "space-y-4 pl-4 border-l-[1px] border-gray-600 custom-scroll overflow-y-auto max-h-[670px]", children: [
33066
33013
  /* @__PURE__ */ jsxs15(VideoGroup_default, { expanded: expandedSections.video, onToggle: toggleSection, loading: isLoading ?? false, children: [
33067
33014
  /* @__PURE__ */ jsxs15("div", { children: [
@@ -33408,11 +33355,11 @@ var DvB = forwardRef4(function DvB2({ settings, setSettings, encoderId, isLoadin
33408
33355
  }
33409
33356
  )
33410
33357
  ] });
33411
- });
33358
+ };
33412
33359
  var DvB_default = DvB;
33413
33360
 
33414
33361
  // src/components/encoder/Livecast.tsx
33415
- import { useState as useState13, useEffect as useEffect10, useImperativeHandle as useImperativeHandle2, forwardRef as forwardRef5 } from "react";
33362
+ import { useState as useState13, useEffect as useEffect10 } from "react";
33416
33363
  import { jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
33417
33364
  var defaultLivecastSettings = {
33418
33365
  service_label: "Encoder 2",
@@ -33536,7 +33483,8 @@ var normalizeLivecastData = (data) => {
33536
33483
  protocol: parsed
33537
33484
  };
33538
33485
  };
33539
- var Livecast = forwardRef5(function Livecast2({ settings, setSettings, encoderId, isLoading, setIsLoading }, ref) {
33486
+ var Livecast = function Livecast2(props) {
33487
+ const { settings, setSettings, encoderId, isLoading, setIsLoading, ref } = props;
33540
33488
  const [expandedSections, setExpandedSections] = useState13({
33541
33489
  video: true,
33542
33490
  audio: false,
@@ -33592,16 +33540,33 @@ var Livecast = forwardRef5(function Livecast2({ settings, setSettings, encoderId
33592
33540
  const next = { ...effectiveSettings, [key]: !effectiveSettings[key] };
33593
33541
  effectiveSetSettings(next);
33594
33542
  };
33595
- useImperativeHandle2(ref, () => ({
33596
- getSettings: () => ({
33597
- ...effectiveSettings,
33598
- send_url: buildProtocolUrl2(effectiveSettings.protocol)
33599
- }),
33600
- reset: () => {
33601
- effectiveSetSettings(savedSettings);
33602
- },
33603
- isDirty: () => JSON.stringify(effectiveSettings) !== JSON.stringify(savedSettings)
33604
- }));
33543
+ useEffect10(() => {
33544
+ if (!ref)
33545
+ return;
33546
+ const impl = {
33547
+ getSettings: () => ({ ...effectiveSettings, send_url: buildProtocolUrl2(effectiveSettings.protocol) }),
33548
+ reset: () => {
33549
+ effectiveSetSettings(savedSettings);
33550
+ },
33551
+ isDirty: () => JSON.stringify(effectiveSettings) !== JSON.stringify(savedSettings)
33552
+ };
33553
+ try {
33554
+ if (typeof ref === "function")
33555
+ ref(impl);
33556
+ else if ("current" in ref)
33557
+ ref.current = impl;
33558
+ } catch {
33559
+ }
33560
+ return () => {
33561
+ try {
33562
+ if (typeof ref === "function")
33563
+ ref(null);
33564
+ else if ("current" in ref)
33565
+ ref.current = null;
33566
+ } catch {
33567
+ }
33568
+ };
33569
+ }, [ref, effectiveSettings, savedSettings, effectiveSetSettings]);
33605
33570
  return /* @__PURE__ */ jsxs16("div", { className: "space-y-4 px-4 border-x-[1px] border-gray-500 custom-scroll overflow-y-auto max-h-[670px]", children: [
33606
33571
  /* @__PURE__ */ jsx19(VideoGroup_default, { expanded: expandedSections.video, onToggle: toggleSection, loading: isLoading ?? false, children: /* @__PURE__ */ jsxs16("div", { className: "grid grid-cols-1 md:grid-cols-4 gap-4", children: [
33607
33572
  /* @__PURE__ */ jsx19(
@@ -33752,7 +33717,7 @@ var Livecast = forwardRef5(function Livecast2({ settings, setSettings, encoderId
33752
33717
  }
33753
33718
  )
33754
33719
  ] });
33755
- });
33720
+ };
33756
33721
  var Livecast_default = Livecast;
33757
33722
 
33758
33723
  // src/components/encoder/ViewLog.tsx
@@ -34535,31 +34500,39 @@ var EditInPlaceField = ({ initialValue, onSave }) => {
34535
34500
  var EditInPlaceField_default = EditInPlaceField;
34536
34501
 
34537
34502
  // src/context/ThemeContext.tsx
34538
- import { createContext as createContext4, useContext as useContext4, useEffect as useEffect14, useState as useState18 } from "react";
34503
+ import { createContext as createContext4, use as use3, useEffect as useEffect14, useState as useState18 } from "react";
34539
34504
  import { jsx as jsx25 } from "react/jsx-runtime";
34540
34505
  var ThemeContext = createContext4(void 0);
34541
- function ThemeProvider({ children }) {
34506
+ function ThemeProvider({ children, storage }) {
34507
+ const resolvedStorage = storage ?? (typeof window !== "undefined" ? window.localStorage : null);
34542
34508
  const [theme, setTheme] = useState18(() => {
34543
- const savedTheme = localStorage.getItem("theme");
34544
- const systemPreference = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
34545
- return savedTheme || systemPreference;
34509
+ try {
34510
+ if (!resolvedStorage)
34511
+ return "light";
34512
+ const savedTheme = resolvedStorage.getItem("theme");
34513
+ const systemPreference = typeof window !== "undefined" && window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
34514
+ return savedTheme ?? systemPreference;
34515
+ } catch {
34516
+ return "light";
34517
+ }
34546
34518
  });
34547
34519
  useEffect14(() => {
34548
- const root = document.documentElement;
34549
- if (theme === "dark") {
34550
- root.classList.add("dark");
34551
- } else {
34552
- root.classList.remove("dark");
34520
+ if (typeof document !== "undefined") {
34521
+ const root = document.documentElement;
34522
+ root.classList.toggle("dark", theme === "dark");
34553
34523
  }
34554
- localStorage.setItem("theme", theme);
34555
- }, [theme]);
34524
+ try {
34525
+ resolvedStorage?.setItem("theme", theme);
34526
+ } catch {
34527
+ }
34528
+ }, [theme, resolvedStorage]);
34556
34529
  const toggleTheme = () => {
34557
- setTheme((prevTheme) => prevTheme === "light" ? "dark" : "light");
34530
+ setTheme((prev) => prev === "light" ? "dark" : "light");
34558
34531
  };
34559
- return /* @__PURE__ */ jsx25(ThemeContext.Provider, { value: { theme, toggleTheme }, children });
34532
+ return /* @__PURE__ */ jsx25(ThemeContext, { value: { theme, toggleTheme }, children });
34560
34533
  }
34561
34534
  function useTheme() {
34562
- const context = useContext4(ThemeContext);
34535
+ const context = use3(ThemeContext);
34563
34536
  if (context === void 0) {
34564
34537
  throw new Error("useTheme must be used within a ThemeProvider");
34565
34538
  }
@@ -35536,18 +35509,18 @@ var Footer = () => {
35536
35509
  var Footer_default = Footer;
35537
35510
 
35538
35511
  // src/components/main/Header.tsx
35539
- import React19, { useEffect as useEffect15, useState as useState21 } from "react";
35512
+ import React18, { useEffect as useEffect15, useState as useState21 } from "react";
35540
35513
  import { Link as Link3 } from "react-router-dom";
35541
35514
  import { Fragment as Fragment3, jsx as jsx33, jsxs as jsxs29 } from "react/jsx-runtime";
35542
35515
  function classNames(...classes) {
35543
35516
  return classes.filter(Boolean).join(" ");
35544
35517
  }
35545
35518
  var Header = ({ isSidebarOpen, setSidebarOpen, onNavigate }) => {
35546
- const [status, setStatus] = React19.useState(null);
35547
- const [loading, setLoading] = React19.useState(true);
35548
- const [error2, setError] = React19.useState(null);
35519
+ const [status, setStatus] = React18.useState(null);
35520
+ const [loading, setLoading] = React18.useState(true);
35521
+ const [error2, setError] = React18.useState(null);
35549
35522
  const { theme, toggleTheme } = useTheme();
35550
- React19.useEffect(() => {
35523
+ React18.useEffect(() => {
35551
35524
  let active = true;
35552
35525
  (async () => {
35553
35526
  try {
@@ -35906,7 +35879,7 @@ var Header = ({ isSidebarOpen, setSidebarOpen, onNavigate }) => {
35906
35879
  var Header_default = Header;
35907
35880
 
35908
35881
  // src/components/main/PageHeader.tsx
35909
- import React20 from "react";
35882
+ import React19 from "react";
35910
35883
  import { Fragment as Fragment4, jsx as jsx34, jsxs as jsxs30 } from "react/jsx-runtime";
35911
35884
  var PageHeader = ({
35912
35885
  icon,
@@ -35916,7 +35889,7 @@ var PageHeader = ({
35916
35889
  hasStates = false,
35917
35890
  children
35918
35891
  }) => {
35919
- const [currentState, setState] = React20.useState(state);
35892
+ const [currentState, setState] = React19.useState(state);
35920
35893
  const startStop = () => {
35921
35894
  setState(currentState == "start" ? "stop" : "start");
35922
35895
  console.log("here", currentState);
@@ -36796,6 +36769,20 @@ var InterfacesTimeseries = ({
36796
36769
  };
36797
36770
  var InterfacesTimeseries_default = InterfacesTimeseries;
36798
36771
 
36772
+ // src/components/network/validators.ts
36773
+ var isValidIPv4 = (ip) => {
36774
+ if (!ip)
36775
+ return false;
36776
+ const ipv4Regex = /^(25[0-5]|2[0-4]\d|1?\d?\d)(\.(25[0-5]|2[0-4]\d|1?\d?\d)){3}$/;
36777
+ return ipv4Regex.test(ip.trim());
36778
+ };
36779
+ var isValidIPv6 = (ip) => {
36780
+ if (!ip)
36781
+ return false;
36782
+ const ipv6Regex = /^(?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4}$|^((?:[A-F0-9]{1,4}(?::|$)){1,8})$/i;
36783
+ return ipv6Regex.test(ip.trim());
36784
+ };
36785
+
36799
36786
  // src/components/system/RequireAuth.tsx
36800
36787
  import { Navigate } from "react-router-dom";
36801
36788
  import { jsx as jsx40, jsxs as jsxs36 } from "react/jsx-runtime";
@@ -36835,7 +36822,7 @@ var RequireAuth_default = RequireAuth;
36835
36822
  import { useEffect as useEffect19, useState as useState26 } from "react";
36836
36823
 
36837
36824
  // node_modules/.pnpm/react-i18next@16.5.4_i18next@25.8.2_typescript@5.9.3__react-dom@19.2.4_react@19.2.4__react@19.2.4_typescript@5.9.3/node_modules/react-i18next/dist/es/Trans.js
36838
- import { useContext as useContext5 } from "react";
36825
+ import { useContext as useContext2 } from "react";
36839
36826
 
36840
36827
  // node_modules/.pnpm/react-i18next@16.5.4_i18next@25.8.2_typescript@5.9.3__react-dom@19.2.4_react@19.2.4__react@19.2.4_typescript@5.9.3/node_modules/react-i18next/dist/es/TransWithoutContext.js
36841
36828
  import { Fragment as Fragment7, isValidElement, cloneElement as cloneElement2, createElement as createElement5, Children } from "react";
@@ -39228,7 +39215,7 @@ var dir = instance.dir;
39228
39215
  var init = instance.init;
39229
39216
  var loadResources = instance.loadResources;
39230
39217
  var reloadResources = instance.reloadResources;
39231
- var use = instance.use;
39218
+ var use4 = instance.use;
39232
39219
  var changeLanguage = instance.changeLanguage;
39233
39220
  var getFixedT = instance.getFixedT;
39234
39221
  var t14 = instance.t;
@@ -39395,10 +39382,10 @@ var ReportNamespaces = class {
39395
39382
  };
39396
39383
 
39397
39384
  // node_modules/.pnpm/react-i18next@16.5.4_i18next@25.8.2_typescript@5.9.3__react-dom@19.2.4_react@19.2.4__react@19.2.4_typescript@5.9.3/node_modules/react-i18next/dist/es/IcuTrans.js
39398
- import { useContext as useContext6 } from "react";
39385
+ import { useContext as useContext3 } from "react";
39399
39386
 
39400
39387
  // node_modules/.pnpm/react-i18next@16.5.4_i18next@25.8.2_typescript@5.9.3__react-dom@19.2.4_react@19.2.4__react@19.2.4_typescript@5.9.3/node_modules/react-i18next/dist/es/IcuTransWithoutContext.js
39401
- import React25 from "react";
39388
+ import React24 from "react";
39402
39389
 
39403
39390
  // node_modules/.pnpm/react-i18next@16.5.4_i18next@25.8.2_typescript@5.9.3__react-dom@19.2.4_react@19.2.4__react@19.2.4_typescript@5.9.3/node_modules/react-i18next/dist/es/IcuTransUtils/TranslationParserError.js
39404
39391
  var TranslationParserError = class _TranslationParserError extends Error {
@@ -39680,7 +39667,7 @@ var tokenize = (translation) => {
39680
39667
  };
39681
39668
 
39682
39669
  // node_modules/.pnpm/react-i18next@16.5.4_i18next@25.8.2_typescript@5.9.3__react-dom@19.2.4_react@19.2.4__react@19.2.4_typescript@5.9.3/node_modules/react-i18next/dist/es/IcuTransUtils/renderTranslation.js
39683
- import React24 from "react";
39670
+ import React23 from "react";
39684
39671
  var renderDeclarationNode = (declaration, children, childDeclarations) => {
39685
39672
  const {
39686
39673
  type,
@@ -39691,15 +39678,15 @@ var renderDeclarationNode = (declaration, children, childDeclarations) => {
39691
39678
  children: _childrenToRemove,
39692
39679
  ...propsWithoutChildren
39693
39680
  } = props;
39694
- return React24.createElement(type, propsWithoutChildren, ...children);
39681
+ return React23.createElement(type, propsWithoutChildren, ...children);
39695
39682
  }
39696
39683
  if (children.length === 0) {
39697
- return React24.createElement(type, props);
39684
+ return React23.createElement(type, props);
39698
39685
  }
39699
39686
  if (children.length === 1) {
39700
- return React24.createElement(type, props, children[0]);
39687
+ return React23.createElement(type, props, children[0]);
39701
39688
  }
39702
- return React24.createElement(type, props, ...children);
39689
+ return React23.createElement(type, props, ...children);
39703
39690
  };
39704
39691
  var renderTranslation = (translation, declarations = []) => {
39705
39692
  if (!translation) {
@@ -39799,7 +39786,7 @@ function IcuTransWithoutContext({
39799
39786
  warnOnce(i18n, "NO_I18NEXT_INSTANCE", `IcuTrans: You need to pass in an i18next instance using i18nextReactModule`, {
39800
39787
  i18nKey
39801
39788
  });
39802
- return React25.createElement(React25.Fragment, {}, defaultTranslation);
39789
+ return React24.createElement(React24.Fragment, {}, defaultTranslation);
39803
39790
  }
39804
39791
  const t15 = tFromProps || i18n.t?.bind(i18n) || ((k11) => k11);
39805
39792
  let namespaces = ns || t15.ns || i18n.options?.defaultNS;
@@ -39820,13 +39807,13 @@ function IcuTransWithoutContext({
39820
39807
  });
39821
39808
  try {
39822
39809
  const rendered = renderTranslation(translation, content);
39823
- return React25.createElement(React25.Fragment, {}, ...rendered);
39810
+ return React24.createElement(React24.Fragment, {}, ...rendered);
39824
39811
  } catch (error2) {
39825
39812
  warn2(i18n, "ICU_TRANS_RENDER_ERROR", `IcuTrans component error for key "${i18nKey}": ${error2.message}`, {
39826
39813
  i18nKey,
39827
39814
  error: error2
39828
39815
  });
39829
- return React25.createElement(React25.Fragment, {}, translation);
39816
+ return React24.createElement(React24.Fragment, {}, translation);
39830
39817
  }
39831
39818
  }
39832
39819
  IcuTransWithoutContext.displayName = "IcuTransWithoutContext";
@@ -39844,7 +39831,7 @@ function IcuTrans({
39844
39831
  const {
39845
39832
  i18n: i18nFromContext,
39846
39833
  defaultNS: defaultNSFromContext
39847
- } = useContext6(I18nContext) || {};
39834
+ } = useContext3(I18nContext) || {};
39848
39835
  const i18n = i18nFromProps || i18nFromContext || getI18n();
39849
39836
  const t15 = tFromProps || i18n?.t.bind(i18n);
39850
39837
  return IcuTransWithoutContext({
@@ -39860,7 +39847,7 @@ function IcuTrans({
39860
39847
  IcuTrans.displayName = "IcuTrans";
39861
39848
 
39862
39849
  // node_modules/.pnpm/react-i18next@16.5.4_i18next@25.8.2_typescript@5.9.3__react-dom@19.2.4_react@19.2.4__react@19.2.4_typescript@5.9.3/node_modules/react-i18next/dist/es/useTranslation.js
39863
- import { useContext as useContext7, useCallback as useCallback3, useMemo as useMemo6, useEffect as useEffect18, useRef as useRef9, useState as useState25 } from "react";
39850
+ import { useContext as useContext4, useCallback as useCallback3, useMemo as useMemo6, useEffect as useEffect18, useRef as useRef9, useState as useState25 } from "react";
39864
39851
  import { useSyncExternalStore } from "use-sync-external-store/shim";
39865
39852
  var notReadyT = (k11, optsOrDefaultValue) => {
39866
39853
  if (isString3(optsOrDefaultValue))
@@ -39882,7 +39869,7 @@ var useTranslation = (ns, props = {}) => {
39882
39869
  const {
39883
39870
  i18n: i18nFromContext,
39884
39871
  defaultNS: defaultNSFromContext
39885
- } = useContext7(I18nContext) || {};
39872
+ } = useContext4(I18nContext) || {};
39886
39873
  const i18n = i18nFromProps || i18nFromContext || getI18n();
39887
39874
  if (i18n && !i18n.reportNamespaces)
39888
39875
  i18n.reportNamespaces = new ReportNamespaces();
@@ -40032,7 +40019,7 @@ import { createElement as createElement7, useMemo as useMemo7 } from "react";
40032
40019
  import { createElement as createElement8 } from "react";
40033
40020
 
40034
40021
  // node_modules/.pnpm/react-i18next@16.5.4_i18next@25.8.2_typescript@5.9.3__react-dom@19.2.4_react@19.2.4__react@19.2.4_typescript@5.9.3/node_modules/react-i18next/dist/es/useSSR.js
40035
- import { useContext as useContext8 } from "react";
40022
+ import { useContext as useContext5 } from "react";
40036
40023
 
40037
40024
  // src/locales/pt/translation.json
40038
40025
  var translation_default = {
@@ -40269,11 +40256,14 @@ instance.use(initReactI18next).init({
40269
40256
  var i18n_default = instance;
40270
40257
 
40271
40258
  // src/context/SharedUiProvider.tsx
40272
- import React26 from "react";
40259
+ import React25 from "react";
40273
40260
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
40274
40261
  import { jsx as jsx41 } from "react/jsx-runtime";
40275
40262
  function SharedUiProvider({ children, client }) {
40276
- const internal = React26.useMemo(() => client ?? new QueryClient(), [client]);
40263
+ const ref = React25.useRef(null);
40264
+ if (!ref.current)
40265
+ ref.current = client ?? new QueryClient();
40266
+ const internal = ref.current;
40277
40267
  return /* @__PURE__ */ jsx41(QueryClientProvider, { client: internal, children });
40278
40268
  }
40279
40269
 
@@ -40516,48 +40506,13 @@ var ConfigWizard = ({ basePath = "./config-xcoder-wizard/php", onComplete }) =>
40516
40506
  };
40517
40507
  var Wizard_default = ConfigWizard;
40518
40508
 
40519
- // src/components/RemoteModule.tsx
40520
- import { useEffect as useEffect20, useState as useState27 } from "react";
40521
- import { Fragment as Fragment8, jsx as jsx43, jsxs as jsxs38 } from "react/jsx-runtime";
40522
- function RemoteModule({ scope, url, module, fallback }) {
40523
- const [Component2, setComponent] = useState27(null);
40524
- const [error2, setError] = useState27(null);
40525
- const [loading, setLoading] = useState27(true);
40526
- useEffect20(() => {
40527
- setLoading(true);
40528
- setError(null);
40529
- loadRemoteModule({ scope, url, module }).then((mod) => {
40530
- setComponent(() => mod);
40531
- }).catch((err) => {
40532
- console.error("Erro ao carregar m\xF3dulo:", err);
40533
- setError(err.message);
40534
- }).finally(() => {
40535
- setLoading(false);
40536
- });
40537
- }, [scope, url, module]);
40538
- if (loading) {
40539
- return /* @__PURE__ */ jsx43("div", { className: "flex items-center justify-center h-64", children: /* @__PURE__ */ jsx43("div", { className: "animate-spin rounded-full h-12 w-12 border-b-2 border-primary dark:border-primary-purple" }) });
40540
- }
40541
- if (error2) {
40542
- return /* @__PURE__ */ jsxs38("div", { className: "p-6 bg-red-50 dark:bg-red-950/30 border border-red-200 dark:border-red-800 rounded-lg", children: [
40543
- /* @__PURE__ */ jsx43("h3", { className: "text-lg font-semibold text-red-800 dark:text-red-300 mb-2", children: "Erro ao carregar m\xF3dulo" }),
40544
- /* @__PURE__ */ jsx43("p", { className: "text-red-600 dark:text-red-400", children: error2 }),
40545
- /* @__PURE__ */ jsx43("p", { className: "text-sm text-red-500 dark:text-red-500 mt-2", children: "Verifique se o m\xF3dulo est\xE1 instalado e o servidor est\xE1 rodando." })
40546
- ] });
40547
- }
40548
- if (!Component2) {
40549
- return /* @__PURE__ */ jsx43(Fragment8, { children: fallback || /* @__PURE__ */ jsx43("div", { className: "p-4 text-neutral-500 dark:text-neutral-400", children: "M\xF3dulo n\xE3o encontrado" }) });
40550
- }
40551
- return /* @__PURE__ */ jsx43(Component2, {});
40552
- }
40553
-
40554
40509
  // src/components/xcoder/Fflog.tsx
40555
- import { useEffect as useEffect21, useState as useState28 } from "react";
40556
- import { jsx as jsx44, jsxs as jsxs39 } from "react/jsx-runtime";
40510
+ import { useEffect as useEffect20, useState as useState27 } from "react";
40511
+ import { jsx as jsx43, jsxs as jsxs38 } from "react/jsx-runtime";
40557
40512
  var Fflog = ({ index: index3 }) => {
40558
- const [message, setMessage] = useState28("");
40559
- const [tooltip, setTooltip] = useState28("Copy to Clipboard");
40560
- useEffect21(() => {
40513
+ const [message, setMessage] = useState27("");
40514
+ const [tooltip, setTooltip] = useState27("Copy to Clipboard");
40515
+ useEffect20(() => {
40561
40516
  const cleanupSocket = subscribeToWebsocket(buildWsUrl("/ws"), (data) => {
40562
40517
  const aux = data?.logs[index3 - 1];
40563
40518
  setMessage(aux.log);
@@ -40570,7 +40525,7 @@ var Fflog = ({ index: index3 }) => {
40570
40525
  cleanupSocket();
40571
40526
  };
40572
40527
  }, []);
40573
- return /* @__PURE__ */ jsxs39(
40528
+ return /* @__PURE__ */ jsxs38(
40574
40529
  "div",
40575
40530
  {
40576
40531
  "data-tooltip-id": "tooltip",
@@ -40585,8 +40540,8 @@ var Fflog = ({ index: index3 }) => {
40585
40540
  },
40586
40541
  onMouseLeave: () => message == "" ? setTooltip("Copy to Clipboard") : "",
40587
40542
  children: [
40588
- /* @__PURE__ */ jsx44(M10, { id: "tooltip" }),
40589
- /* @__PURE__ */ jsx44("p", { className: "relative mt-[-10px] text-justify text-gray-900 dark:text-slate-200 font-mono", style: { overflow: "hidden", whiteSpace: "nowrap", textOverflow: "ellipsis" }, children: message })
40543
+ /* @__PURE__ */ jsx43(M10, { id: "tooltip" }),
40544
+ /* @__PURE__ */ jsx43("p", { className: "relative mt-[-10px] text-justify text-gray-900 dark:text-slate-200 font-mono", style: { overflow: "hidden", whiteSpace: "nowrap", textOverflow: "ellipsis" }, children: message })
40590
40545
  ]
40591
40546
  }
40592
40547
  );
@@ -40594,7 +40549,7 @@ var Fflog = ({ index: index3 }) => {
40594
40549
  var Fflog_default = Fflog;
40595
40550
 
40596
40551
  // src/components/xcoder/Metrics.tsx
40597
- import { jsx as jsx45, jsxs as jsxs40 } from "react/jsx-runtime";
40552
+ import { jsx as jsx44, jsxs as jsxs39 } from "react/jsx-runtime";
40598
40553
  var MetricBar = ({ label, value, suffix, color }) => {
40599
40554
  const colorClasses = {
40600
40555
  blue: "bg-blue-500",
@@ -40603,15 +40558,15 @@ var MetricBar = ({ label, value, suffix, color }) => {
40603
40558
  cyan: "bg-cyan-500",
40604
40559
  pink: "bg-pink-500"
40605
40560
  };
40606
- return /* @__PURE__ */ jsxs40("div", { className: "space-y-1", children: [
40607
- /* @__PURE__ */ jsxs40("div", { className: "flex items-center justify-between text-sm", children: [
40608
- /* @__PURE__ */ jsx45("span", { className: "text-gray-900 dark:text-slate-400", children: label }),
40609
- /* @__PURE__ */ jsxs40("span", { className: "text-gray-900 dark:text-white font-mono", children: [
40561
+ return /* @__PURE__ */ jsxs39("div", { className: "space-y-1", children: [
40562
+ /* @__PURE__ */ jsxs39("div", { className: "flex items-center justify-between text-sm", children: [
40563
+ /* @__PURE__ */ jsx44("span", { className: "text-gray-900 dark:text-slate-400", children: label }),
40564
+ /* @__PURE__ */ jsxs39("span", { className: "text-gray-900 dark:text-white font-mono", children: [
40610
40565
  Math.round(value),
40611
40566
  suffix
40612
40567
  ] })
40613
40568
  ] }),
40614
- /* @__PURE__ */ jsx45("div", { className: "h-2 bg-slate-300 dark:bg-slate-800 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx45(
40569
+ /* @__PURE__ */ jsx44("div", { className: "h-2 bg-slate-300 dark:bg-slate-800 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx44(
40615
40570
  "div",
40616
40571
  {
40617
40572
  className: `h-full transition-all duration-300 ${colorClasses[color]}`,
@@ -40623,8 +40578,8 @@ var MetricBar = ({ label, value, suffix, color }) => {
40623
40578
  var Metrics_default = MetricBar;
40624
40579
 
40625
40580
  // src/components/xcoder/Panel.tsx
40626
- import { useState as useState29, useEffect as useEffect22 } from "react";
40627
- import { Fragment as Fragment9, jsx as jsx46, jsxs as jsxs41 } from "react/jsx-runtime";
40581
+ import { useState as useState28, useEffect as useEffect21 } from "react";
40582
+ import { Fragment as Fragment8, jsx as jsx45, jsxs as jsxs40 } from "react/jsx-runtime";
40628
40583
  var convertServiceToOption = (serviceString) => {
40629
40584
  const match = serviceString.match(/^([^@]+)@/);
40630
40585
  if (!match) {
@@ -40638,12 +40593,12 @@ var convertServiceToOption = (serviceString) => {
40638
40593
  return { label, value: rawValue };
40639
40594
  };
40640
40595
  var EncoderDecoderPanel = ({ index: index3 }) => {
40641
- const [status, setStatus] = useState29("idle");
40642
- const [modes, setModes] = useState29([]);
40643
- const [oldModes, setOldModes] = useState29(modes);
40644
- const [open, setOpen] = useState29(false);
40645
- const [optionsList, setOptionsList] = useState29([]);
40646
- useEffect22(() => {
40596
+ const [status, setStatus] = useState28("idle");
40597
+ const [modes, setModes] = useState28([]);
40598
+ const [oldModes, setOldModes] = useState28(modes);
40599
+ const [open, setOpen] = useState28(false);
40600
+ const [optionsList, setOptionsList] = useState28([]);
40601
+ useEffect21(() => {
40647
40602
  const cleanupSocket = subscribeToWebsocket(buildWsUrl("/"), (data) => {
40648
40603
  setStatus(data?.services[`xcoder_${index3}`].status);
40649
40604
  });
@@ -40677,52 +40632,52 @@ var EncoderDecoderPanel = ({ index: index3 }) => {
40677
40632
  m: state ? "stop" : "start"
40678
40633
  });
40679
40634
  };
40680
- return /* @__PURE__ */ jsxs41("div", { className: "bg-gray-200 dark:bg-slate-900/50 border bg-gray-200 border-gray-400 dark:border-slate-800 rounded-lg", children: [
40681
- /* @__PURE__ */ jsxs41("div", { className: "px-6 py-3 border-b border-slate-800 flex items-center justify-between", children: [
40682
- /* @__PURE__ */ jsxs41("div", { className: "flex items-center gap-3", children: [
40683
- /* @__PURE__ */ jsx46(Radio, { className: "w-5 h-5 text-blue-500" }),
40684
- /* @__PURE__ */ jsx46("h1", { className: "text-base font-medium text-gray-800 dark:text-white hover:underline", children: /* @__PURE__ */ jsxs41("a", { href: `/page/${modes[index3 - 1]?.split("@")[0] ?? "encoder-dvb"}?channel=${index3}`, children: [
40635
+ return /* @__PURE__ */ jsxs40("div", { className: "bg-gray-200 dark:bg-slate-900/50 border bg-gray-200 border-gray-400 dark:border-slate-800 rounded-lg", children: [
40636
+ /* @__PURE__ */ jsxs40("div", { className: "px-6 py-3 border-b border-slate-800 flex items-center justify-between", children: [
40637
+ /* @__PURE__ */ jsxs40("div", { className: "flex items-center gap-3", children: [
40638
+ /* @__PURE__ */ jsx45(Radio, { className: "w-5 h-5 text-blue-500" }),
40639
+ /* @__PURE__ */ jsx45("h1", { className: "text-base font-medium text-gray-800 dark:text-white hover:underline", children: /* @__PURE__ */ jsxs40("a", { href: `/page/${modes[index3 - 1]?.split("@")[0] ?? "encoder-dvb"}?channel=${index3}`, children: [
40685
40640
  "Xcoder BMD Video Interface (",
40686
40641
  index3,
40687
40642
  ")"
40688
40643
  ] }) })
40689
40644
  ] }),
40690
- /* @__PURE__ */ jsxs41("div", { className: "flex items-center gap-4", children: [
40691
- /* @__PURE__ */ jsx46(
40645
+ /* @__PURE__ */ jsxs40("div", { className: "flex items-center gap-4", children: [
40646
+ /* @__PURE__ */ jsx45(
40692
40647
  "button",
40693
40648
  {
40694
40649
  onClick: () => startStop(status == "running"),
40695
40650
  className: `flex items-center gap-2 px-4 py-2 rounded-md text-sm font-medium transition-all ${status == "running" ? "bg-red-600 hover:bg-red-700 text-white" : "bg-blue-600 hover:bg-blue-700 text-white"}`,
40696
- children: status == "running" ? /* @__PURE__ */ jsxs41(Fragment9, { children: [
40697
- /* @__PURE__ */ jsx46(Pause, { className: "w-4 h-4" }),
40651
+ children: status == "running" ? /* @__PURE__ */ jsxs40(Fragment8, { children: [
40652
+ /* @__PURE__ */ jsx45(Pause, { className: "w-4 h-4" }),
40698
40653
  "Stop"
40699
- ] }) : /* @__PURE__ */ jsxs41(Fragment9, { children: [
40700
- /* @__PURE__ */ jsx46(Play, { className: "w-4 h-4" }),
40654
+ ] }) : /* @__PURE__ */ jsxs40(Fragment8, { children: [
40655
+ /* @__PURE__ */ jsx45(Play, { className: "w-4 h-4" }),
40701
40656
  "Start"
40702
40657
  ] })
40703
40658
  }
40704
40659
  ),
40705
- /* @__PURE__ */ jsxs41("div", { className: `flex w-[100px] justify-center items-center gap-2 px-4 py-2 rounded-md ${status == "running" ? "bg-yellow-600" : "bg-slate-700"}`, children: [
40706
- /* @__PURE__ */ jsx46("div", { className: `w-2 h-2 rounded-full bg-white ${status == "running" ? "block" : "hidden"}` }),
40707
- /* @__PURE__ */ jsx46("span", { className: "text-sm text-slate-100 font-mono font-bold", children: status == "running" ? "READY" : "STANDBY" })
40660
+ /* @__PURE__ */ jsxs40("div", { className: `flex w-[100px] justify-center items-center gap-2 px-4 py-2 rounded-md ${status == "running" ? "bg-yellow-600" : "bg-slate-700"}`, children: [
40661
+ /* @__PURE__ */ jsx45("div", { className: `w-2 h-2 rounded-full bg-white ${status == "running" ? "block" : "hidden"}` }),
40662
+ /* @__PURE__ */ jsx45("span", { className: "text-sm text-slate-100 font-mono font-bold", children: status == "running" ? "READY" : "STANDBY" })
40708
40663
  ] }),
40709
- /* @__PURE__ */ jsx46(
40664
+ /* @__PURE__ */ jsx45(
40710
40665
  "button",
40711
40666
  {
40712
40667
  onClick: () => setOpen(true),
40713
40668
  className: "p-2 rounded-md transition-colors",
40714
- children: /* @__PURE__ */ jsx46(Settings, { className: "w-5 h-5 text-slate-400 hover:text-blue-400" })
40669
+ children: /* @__PURE__ */ jsx45(Settings, { className: "w-5 h-5 text-slate-400 hover:text-blue-400" })
40715
40670
  }
40716
40671
  )
40717
40672
  ] })
40718
40673
  ] }),
40719
- /* @__PURE__ */ jsx46(
40674
+ /* @__PURE__ */ jsx45(
40720
40675
  Modal_default,
40721
40676
  {
40722
40677
  open,
40723
40678
  setOpen,
40724
40679
  title: "Switching Operation Mode",
40725
- element: /* @__PURE__ */ jsx46("div", { children: optionsList[index3 - 1] && /* @__PURE__ */ jsx46("div", { className: "relative p-6", children: /* @__PURE__ */ jsx46(
40680
+ element: /* @__PURE__ */ jsx45("div", { children: optionsList[index3 - 1] && /* @__PURE__ */ jsx45("div", { className: "relative p-6", children: /* @__PURE__ */ jsx45(
40726
40681
  SelectField_default,
40727
40682
  {
40728
40683
  label: "New Mode",
@@ -40743,15 +40698,15 @@ var EncoderDecoderPanel = ({ index: index3 }) => {
40743
40698
  }
40744
40699
  }
40745
40700
  ),
40746
- /* @__PURE__ */ jsx46("div", { className: "p-6", children: /* @__PURE__ */ jsx46(Preview_default, { index: index3, setVuPts: () => {
40701
+ /* @__PURE__ */ jsx45("div", { className: "p-6", children: /* @__PURE__ */ jsx45(Preview_default, { index: index3, setVuPts: () => {
40747
40702
  } }) })
40748
40703
  ] });
40749
40704
  };
40750
40705
  var Panel_default = EncoderDecoderPanel;
40751
40706
 
40752
40707
  // src/components/xcoder/Preview.tsx
40753
- import { useEffect as useEffect23, useLayoutEffect as useLayoutEffect3, useMemo as useMemo8, useRef as useRef10, useState as useState30 } from "react";
40754
- import { jsx as jsx47, jsxs as jsxs42 } from "react/jsx-runtime";
40708
+ import { useEffect as useEffect22, useLayoutEffect as useLayoutEffect3, useMemo as useMemo8, useRef as useRef10, useState as useState29 } from "react";
40709
+ import { jsx as jsx46, jsxs as jsxs41 } from "react/jsx-runtime";
40755
40710
  var Preview = ({
40756
40711
  index: index3,
40757
40712
  setVuPts,
@@ -40761,8 +40716,8 @@ var Preview = ({
40761
40716
  orientation = "horizontal"
40762
40717
  }) => {
40763
40718
  const logEndRef = useRef10(null);
40764
- const [message, setMessage] = useState30([]);
40765
- useEffect23(() => {
40719
+ const [message, setMessage] = useState29([]);
40720
+ useEffect22(() => {
40766
40721
  const cleanupSocket = subscribeToWebsocket(buildWsUrl("/"), (data) => {
40767
40722
  const aux = data?.services[`xcoder_${index3}`];
40768
40723
  setMessage(aux.decklinkEvents.split("\n"));
@@ -40771,21 +40726,21 @@ var Preview = ({
40771
40726
  cleanupSocket();
40772
40727
  };
40773
40728
  }, []);
40774
- useEffect23(() => {
40729
+ useEffect22(() => {
40775
40730
  if (logEndRef.current) {
40776
40731
  logEndRef.current.scrollTop = logEndRef.current.scrollHeight;
40777
40732
  }
40778
40733
  }, [message]);
40779
- const [vuChannels, setVuChannels] = useState30(
40734
+ const [vuChannels, setVuChannels] = useState29(
40780
40735
  Array(8).fill({ left: 0, right: 0 })
40781
40736
  );
40782
40737
  const channelCount = 8;
40783
40738
  const vuBars = useMemo8(() => {
40784
- return Array.from({ length: channelCount }, (_7, i14) => /* @__PURE__ */ jsx47(VUMeter_default, { index: i14, volume: vuChannels }, `vu-bar-${i14}`));
40739
+ return Array.from({ length: channelCount }, (_7, i14) => /* @__PURE__ */ jsx46(VUMeter_default, { index: i14, volume: vuChannels }, `vu-bar-${i14}`));
40785
40740
  }, [channelCount, vuChannels]);
40786
40741
  const playerRef = useRef10(null);
40787
40742
  const vuRef = useRef10(null);
40788
- const [height, setHeight] = useState30("auto");
40743
+ const [height, setHeight] = useState29("auto");
40789
40744
  useLayoutEffect3(() => {
40790
40745
  const p8 = playerRef.current;
40791
40746
  const v6 = vuRef.current;
@@ -40800,15 +40755,15 @@ var Preview = ({
40800
40755
  }
40801
40756
  ;
40802
40757
  }, []);
40803
- const [isOpen, setIsOpen] = useState30(false);
40804
- const logData = message.map((log, i14) => /* @__PURE__ */ jsx47("div", { className: "flex gap-2", children: /* @__PURE__ */ jsx47("span", { className: "text-slate-900 dark:text-slate-300 break-words", children: log }) }, i14));
40805
- return /* @__PURE__ */ jsxs42("div", { className: `"w-full h-full" ${orientation === "horizontal" ? "" : "py-6"}`, children: [
40806
- /* @__PURE__ */ jsxs42(
40758
+ const [isOpen, setIsOpen] = useState29(false);
40759
+ const logData = message.map((log, i14) => /* @__PURE__ */ jsx46("div", { className: "flex gap-2", children: /* @__PURE__ */ jsx46("span", { className: "text-slate-900 dark:text-slate-300 break-words", children: log }) }, i14));
40760
+ return /* @__PURE__ */ jsxs41("div", { className: `"w-full h-full" ${orientation === "horizontal" ? "" : "py-6"}`, children: [
40761
+ /* @__PURE__ */ jsxs41(
40807
40762
  "div",
40808
40763
  {
40809
40764
  className: `grid gap-6 mb-5 ${orientation === "horizontal" ? "grid-cols-[1fr_300px] items-start" : "grid-cols-1"}`,
40810
40765
  children: [
40811
- /* @__PURE__ */ jsx47("div", { ref: playerRef, className: "bg-black rounded-lg overflow-hidden aspect-video", children: /* @__PURE__ */ jsx47("div", { className: "w-full h-full relative flex items-center justify-center", children: /* @__PURE__ */ jsx47(
40766
+ /* @__PURE__ */ jsx46("div", { ref: playerRef, className: "bg-black rounded-lg overflow-hidden aspect-video", children: /* @__PURE__ */ jsx46("div", { className: "w-full h-full relative flex items-center justify-center", children: /* @__PURE__ */ jsx46(
40812
40767
  VideoPlayer_default,
40813
40768
  {
40814
40769
  pgmIndex: index3,
@@ -40817,10 +40772,10 @@ var Preview = ({
40817
40772
  setVuChannels
40818
40773
  }
40819
40774
  ) }) }),
40820
- /* @__PURE__ */ jsxs42("div", { className: `flex flex-col ${orientation === "horizontal" ? "h-full" : "h-[200px]"}`, children: [
40821
- /* @__PURE__ */ jsx47("div", { ref: vuRef, className: `bg-gray-100 dark:bg-slate-800/50 border border-slate-200 dark:border-slate-700 rounded-lg p-4 ${showDlog || showStreamControl ? "mb-5" : "flex-1"}`, children: /* @__PURE__ */ jsx47("div", { className: `flex justify-between items-end ${showDlog || showStreamControl ? "h-32" : "h-full"}`, children: vuBars }) }),
40822
- showStreamControl && /* @__PURE__ */ jsx47(StreamControl_default, { index: index3 }),
40823
- showDlog && /* @__PURE__ */ jsx47("div", { className: "bg-gray-100 dark:bg-slate-800/50 border border-slate-200 dark:border-slate-700 rounded-lg overflow-hidden flex-1", children: /* @__PURE__ */ jsxs42(
40775
+ /* @__PURE__ */ jsxs41("div", { className: `flex flex-col ${orientation === "horizontal" ? "h-full" : "h-[200px]"}`, children: [
40776
+ /* @__PURE__ */ jsx46("div", { ref: vuRef, className: `bg-gray-100 dark:bg-slate-800/50 border border-slate-200 dark:border-slate-700 rounded-lg p-4 ${showDlog || showStreamControl ? "mb-5" : "flex-1"}`, children: /* @__PURE__ */ jsx46("div", { className: `flex justify-between items-end ${showDlog || showStreamControl ? "h-32" : "h-full"}`, children: vuBars }) }),
40777
+ showStreamControl && /* @__PURE__ */ jsx46(StreamControl_default, { index: index3 }),
40778
+ showDlog && /* @__PURE__ */ jsx46("div", { className: "bg-gray-100 dark:bg-slate-800/50 border border-slate-200 dark:border-slate-700 rounded-lg overflow-hidden flex-1", children: /* @__PURE__ */ jsxs41(
40824
40779
  "div",
40825
40780
  {
40826
40781
  ref: logEndRef,
@@ -40831,7 +40786,7 @@ var Preview = ({
40831
40786
  style: { height },
40832
40787
  onClick: () => setIsOpen(true),
40833
40788
  children: [
40834
- /* @__PURE__ */ jsx47(M10, { id: "tooltip" }),
40789
+ /* @__PURE__ */ jsx46(M10, { id: "tooltip" }),
40835
40790
  logData
40836
40791
  ]
40837
40792
  }
@@ -40840,15 +40795,15 @@ var Preview = ({
40840
40795
  ]
40841
40796
  }
40842
40797
  ),
40843
- showFflog && /* @__PURE__ */ jsx47(Fflog_default, { index: index3 }),
40844
- /* @__PURE__ */ jsx47(
40798
+ showFflog && /* @__PURE__ */ jsx46(Fflog_default, { index: index3 }),
40799
+ /* @__PURE__ */ jsx46(
40845
40800
  Modal_default,
40846
40801
  {
40847
40802
  open: isOpen,
40848
40803
  setOpen: () => setIsOpen(!isOpen),
40849
40804
  title: "Log Message",
40850
- element: /* @__PURE__ */ jsx47("div", { className: "custom-scroll overflow-y-auto p-3 h-[300px]", children: logData }),
40851
- icon: /* @__PURE__ */ jsx47(FileClock, { "aria-hidden": "true", className: "size-6 text-yellow-600" }),
40805
+ element: /* @__PURE__ */ jsx46("div", { className: "custom-scroll overflow-y-auto p-3 h-[300px]", children: logData }),
40806
+ icon: /* @__PURE__ */ jsx46(FileClock, { "aria-hidden": "true", className: "size-6 text-yellow-600" }),
40852
40807
  positiveLabel: "Copy",
40853
40808
  positiveCommand: () => {
40854
40809
  navigator.clipboard.writeText(message.join("\n"));
@@ -40860,11 +40815,11 @@ var Preview = ({
40860
40815
  var Preview_default = Preview;
40861
40816
 
40862
40817
  // src/components/xcoder/StreamControl.tsx
40863
- import { useState as useState31 } from "react";
40864
- import { jsx as jsx48, jsxs as jsxs43 } from "react/jsx-runtime";
40818
+ import { useState as useState30 } from "react";
40819
+ import { jsx as jsx47, jsxs as jsxs42 } from "react/jsx-runtime";
40865
40820
  var StreamControl = ({ index: index3 }) => {
40866
- const [bufferValue, setBufferValue] = useState31(0);
40867
- const [syncValue, setSyncValue] = useState31(0);
40821
+ const [bufferValue, setBufferValue] = useState30(0);
40822
+ const [syncValue, setSyncValue] = useState30(0);
40868
40823
  const minBuffer = 0;
40869
40824
  const maxBuffer = 100;
40870
40825
  const minSync = -30;
@@ -40877,45 +40832,45 @@ var StreamControl = ({ index: index3 }) => {
40877
40832
  true,
40878
40833
  1e3
40879
40834
  );
40880
- return /* @__PURE__ */ jsxs43("div", { className: "w-80 space-y-3", children: [
40881
- /* @__PURE__ */ jsx48("div", { className: "bg-gray-100 dark:bg-slate-800/50 border border-slate-200 dark:border-slate-700 rounded-lg p-3 max-h-[300px] min-h-[100px] overflow-auto", children: /* @__PURE__ */ jsxs43("div", { className: "text-xs space-y-2 text-gray-800 dark:text-slate-200", children: [
40882
- /* @__PURE__ */ jsxs43("div", { className: "space-y-1", children: [
40883
- /* @__PURE__ */ jsxs43("div", { className: "flex gap-2", children: [
40884
- /* @__PURE__ */ jsx48("span", { className: "font-medium", children: "Service Name:" }),
40885
- /* @__PURE__ */ jsx48("span", { className: "truncate", children: data?.service_name ?? "\u2014" })
40835
+ return /* @__PURE__ */ jsxs42("div", { className: "w-80 space-y-3", children: [
40836
+ /* @__PURE__ */ jsx47("div", { className: "bg-gray-100 dark:bg-slate-800/50 border border-slate-200 dark:border-slate-700 rounded-lg p-3 max-h-[300px] min-h-[100px] overflow-auto", children: /* @__PURE__ */ jsxs42("div", { className: "text-xs space-y-2 text-gray-800 dark:text-slate-200", children: [
40837
+ /* @__PURE__ */ jsxs42("div", { className: "space-y-1", children: [
40838
+ /* @__PURE__ */ jsxs42("div", { className: "flex gap-2", children: [
40839
+ /* @__PURE__ */ jsx47("span", { className: "font-medium", children: "Service Name:" }),
40840
+ /* @__PURE__ */ jsx47("span", { className: "truncate", children: data?.service_name ?? "\u2014" })
40886
40841
  ] }),
40887
- /* @__PURE__ */ jsxs43("div", { className: "flex gap-2", children: [
40888
- /* @__PURE__ */ jsx48("span", { className: "font-medium", children: "Service Provider:" }),
40889
- /* @__PURE__ */ jsx48("span", { className: "truncate", children: data?.service_provider ?? "\u2014" })
40842
+ /* @__PURE__ */ jsxs42("div", { className: "flex gap-2", children: [
40843
+ /* @__PURE__ */ jsx47("span", { className: "font-medium", children: "Service Provider:" }),
40844
+ /* @__PURE__ */ jsx47("span", { className: "truncate", children: data?.service_provider ?? "\u2014" })
40890
40845
  ] })
40891
40846
  ] }),
40892
- /* @__PURE__ */ jsxs43("div", { className: "space-y-1.5 pt-2", children: [
40893
- /* @__PURE__ */ jsxs43("div", { className: "flex items-center gap-2", children: [
40894
- /* @__PURE__ */ jsx48(Video, { className: "w-4 h-4 text-sky-400" }),
40895
- /* @__PURE__ */ jsxs43("span", { className: "truncate", children: [
40847
+ /* @__PURE__ */ jsxs42("div", { className: "space-y-1.5 pt-2", children: [
40848
+ /* @__PURE__ */ jsxs42("div", { className: "flex items-center gap-2", children: [
40849
+ /* @__PURE__ */ jsx47(Video, { className: "w-4 h-4 text-sky-400" }),
40850
+ /* @__PURE__ */ jsxs42("span", { className: "truncate", children: [
40896
40851
  "Video 0: ",
40897
40852
  data?.input_streans[1].input_stream.type
40898
40853
  ] })
40899
40854
  ] }),
40900
- /* @__PURE__ */ jsxs43("div", { className: "flex items-center gap-2", children: [
40901
- /* @__PURE__ */ jsx48(Volume2, { className: "w-4 h-4 text-emerald-400" }),
40902
- /* @__PURE__ */ jsxs43("span", { className: "truncate", children: [
40855
+ /* @__PURE__ */ jsxs42("div", { className: "flex items-center gap-2", children: [
40856
+ /* @__PURE__ */ jsx47(Volume2, { className: "w-4 h-4 text-emerald-400" }),
40857
+ /* @__PURE__ */ jsxs42("span", { className: "truncate", children: [
40903
40858
  "Audio 1: ",
40904
40859
  data?.input_streans[0].input_stream.type
40905
40860
  ] })
40906
40861
  ] })
40907
40862
  ] })
40908
40863
  ] }) }),
40909
- /* @__PURE__ */ jsx48("div", { className: "bg-gray-100 dark:bg-slate-800/50 border border-slate-200 dark:border-slate-700 rounded-lg p-3", children: /* @__PURE__ */ jsxs43("div", { className: "space-y-3 text-slate-200 text-xs", children: [
40910
- /* @__PURE__ */ jsx48(SliderField_default, { value: bufferValue, setValue: setBufferValue, label: "Fifo Size:", min: minBuffer, max: maxBuffer }),
40911
- /* @__PURE__ */ jsx48(SliderField_default, { value: syncValue, setValue: setSyncValue, label: "A/V Sync:", min: minSync, max: maxSync, content: ["<", ">"], step: 10 }),
40912
- /* @__PURE__ */ jsxs43("div", { className: "pt-2 border-t border-slate-700 text-xs text-gray-700 dark:text-slate-300 flex justify-between", children: [
40913
- /* @__PURE__ */ jsxs43("span", { children: [
40864
+ /* @__PURE__ */ jsx47("div", { className: "bg-gray-100 dark:bg-slate-800/50 border border-slate-200 dark:border-slate-700 rounded-lg p-3", children: /* @__PURE__ */ jsxs42("div", { className: "space-y-3 text-slate-200 text-xs", children: [
40865
+ /* @__PURE__ */ jsx47(SliderField_default, { value: bufferValue, setValue: setBufferValue, label: "Fifo Size:", min: minBuffer, max: maxBuffer }),
40866
+ /* @__PURE__ */ jsx47(SliderField_default, { value: syncValue, setValue: setSyncValue, label: "A/V Sync:", min: minSync, max: maxSync, content: ["<", ">"], step: 10 }),
40867
+ /* @__PURE__ */ jsxs42("div", { className: "pt-2 border-t border-slate-700 text-xs text-gray-700 dark:text-slate-300 flex justify-between", children: [
40868
+ /* @__PURE__ */ jsxs42("span", { children: [
40914
40869
  "Buffer: ",
40915
40870
  bufferValue,
40916
40871
  " frames"
40917
40872
  ] }),
40918
- /* @__PURE__ */ jsxs43("span", { children: [
40873
+ /* @__PURE__ */ jsxs42("span", { children: [
40919
40874
  "Sync: ",
40920
40875
  syncValue > 0 ? "+" : "",
40921
40876
  syncValue,
@@ -40928,8 +40883,8 @@ var StreamControl = ({ index: index3 }) => {
40928
40883
  var StreamControl_default = StreamControl;
40929
40884
 
40930
40885
  // src/components/xcoder/VideoPlayer.tsx
40931
- import { useEffect as useEffect24, useMemo as useMemo9, useRef as useRef11 } from "react";
40932
- import { jsx as jsx49 } from "react/jsx-runtime";
40886
+ import { useEffect as useEffect23, useMemo as useMemo9, useRef as useRef11 } from "react";
40887
+ import { jsx as jsx48 } from "react/jsx-runtime";
40933
40888
  var VideoPlayer = ({
40934
40889
  pgmIndex,
40935
40890
  vuChannels,
@@ -40940,7 +40895,7 @@ var VideoPlayer = ({
40940
40895
  const videoRef = useRef11(dummyCanvas);
40941
40896
  const prevRawChannelsRef = useRef11(null);
40942
40897
  const playerRef = useRef11(null);
40943
- useEffect24(() => {
40898
+ useEffect23(() => {
40944
40899
  let cancelled = false;
40945
40900
  if (!videoRef.current) {
40946
40901
  console.warn("Video canvas not ready yet");
@@ -41061,7 +41016,7 @@ var VideoPlayer = ({
41061
41016
  initPlayer();
41062
41017
  }
41063
41018
  }, [pgmIndex]);
41064
- return /* @__PURE__ */ jsx49(
41019
+ return /* @__PURE__ */ jsx48(
41065
41020
  "canvas",
41066
41021
  {
41067
41022
  ref: videoRef,
@@ -41072,15 +41027,15 @@ var VideoPlayer = ({
41072
41027
  var VideoPlayer_default = VideoPlayer;
41073
41028
 
41074
41029
  // src/components/xcoder/VUMeter.tsx
41075
- import { useRef as useRef12, useEffect as useEffect25, useCallback as useCallback4, useState as useState32 } from "react";
41076
- import { jsx as jsx50, jsxs as jsxs44 } from "react/jsx-runtime";
41030
+ import { useRef as useRef12, useEffect as useEffect24, useCallback as useCallback4, useState as useState31 } from "react";
41031
+ import { jsx as jsx49, jsxs as jsxs43 } from "react/jsx-runtime";
41077
41032
  var VUBar = ({ index: index3, volume, width = "15px", displayMarks = false }) => {
41078
- const [tickerTarget, setTickerTarget] = useState32({ left: 0, right: 0 });
41079
- const [tickerTransition, setTickerTransition] = useState32({
41033
+ const [tickerTarget, setTickerTarget] = useState31({ left: 0, right: 0 });
41034
+ const [tickerTransition, setTickerTransition] = useState31({
41080
41035
  left: 0,
41081
41036
  right: 0
41082
41037
  });
41083
- const [resetVUTimeout, setResetVUTimeout] = useState32(0);
41038
+ const [resetVUTimeout, setResetVUTimeout] = useState31(0);
41084
41039
  const tickerLeftRef = useRef12(null);
41085
41040
  const tickerRightRef = useRef12(null);
41086
41041
  const blockerLeftRef = useRef12(null);
@@ -41135,7 +41090,7 @@ var VUBar = ({ index: index3, volume, width = "15px", displayMarks = false }) =>
41135
41090
  } catch (e10) {
41136
41091
  }
41137
41092
  }, []);
41138
- useEffect25(() => {
41093
+ useEffect24(() => {
41139
41094
  calcVolume();
41140
41095
  if (resetVUTimeout) {
41141
41096
  clearTimeout(resetVUTimeout);
@@ -41150,9 +41105,9 @@ var VUBar = ({ index: index3, volume, width = "15px", displayMarks = false }) =>
41150
41105
  const MIN_DB = -70;
41151
41106
  const MAX_DB = 0;
41152
41107
  const measures = [0, -10, -20, -30, -40, -50, -60, -70];
41153
- return /* @__PURE__ */ jsxs44("div", { className: "flex w-full h-full justify-center", children: [
41154
- /* @__PURE__ */ jsx50("div", { className: displayMarks ? "mt-[60px]" : "hidden", children: measures.map((db) => {
41155
- return /* @__PURE__ */ jsxs44(
41108
+ return /* @__PURE__ */ jsxs43("div", { className: "flex w-full h-full justify-center", children: [
41109
+ /* @__PURE__ */ jsx49("div", { className: displayMarks ? "mt-[60px]" : "hidden", children: measures.map((db) => {
41110
+ return /* @__PURE__ */ jsxs43(
41156
41111
  "div",
41157
41112
  {
41158
41113
  style: { marginBottom: `${(db - MIN_DB) / (MAX_DB - MIN_DB) * 100}px`, marginRight: "25px", textAlignLast: "center" },
@@ -41173,15 +41128,15 @@ var VUBar = ({ index: index3, volume, width = "15px", displayMarks = false }) =>
41173
41128
  db
41174
41129
  );
41175
41130
  }) }),
41176
- /* @__PURE__ */ jsxs44("div", { className: `h-full w-full text-xs text-center text-white`, style: { maxWidth: `${width}` }, children: [
41177
- /* @__PURE__ */ jsxs44("div", { className: "flex border border-gray-400 w-full h-[96%] rotate-180 scale-x-[-1]", children: [
41178
- /* @__PURE__ */ jsxs44("div", { ref: fillerRef, className: "w-1/2 h-full", style: { background: "linear-gradient(180deg, rgba(0, 187, 0, 1) 0%, rgba(255, 162, 0, 1) 50%, rgba(255, 0, 0, 1) 100%)", borderRadius: "inherit" }, children: [
41179
- /* @__PURE__ */ jsx50("div", { ref: blockerLeftRef, className: "absolute bg-gray-200 dark:bg-[#18191d] bottom-0 w-1/2", style: { height: `${100 - volume[index3].left}%`, transition: "height 0.1s ease-out" } }),
41180
- /* @__PURE__ */ jsx50("div", { ref: tickerLeftRef, className: "absolute h-[5px] w-1/2 bg-white border border-black", style: { top: `${tickerTarget.left}%`, transition: `top ${tickerTransition.left}s ease-out` } })
41131
+ /* @__PURE__ */ jsxs43("div", { className: `h-full w-full text-xs text-center text-white`, style: { maxWidth: `${width}` }, children: [
41132
+ /* @__PURE__ */ jsxs43("div", { className: "flex border border-gray-400 w-full h-[96%] rotate-180 scale-x-[-1]", children: [
41133
+ /* @__PURE__ */ jsxs43("div", { ref: fillerRef, className: "w-1/2 h-full", style: { background: "linear-gradient(180deg, rgba(0, 187, 0, 1) 0%, rgba(255, 162, 0, 1) 50%, rgba(255, 0, 0, 1) 100%)", borderRadius: "inherit" }, children: [
41134
+ /* @__PURE__ */ jsx49("div", { ref: blockerLeftRef, className: "absolute bg-gray-200 dark:bg-[#18191d] bottom-0 w-1/2", style: { height: `${100 - volume[index3].left}%`, transition: "height 0.1s ease-out" } }),
41135
+ /* @__PURE__ */ jsx49("div", { ref: tickerLeftRef, className: "absolute h-[5px] w-1/2 bg-white border border-black", style: { top: `${tickerTarget.left}%`, transition: `top ${tickerTransition.left}s ease-out` } })
41181
41136
  ] }),
41182
- /* @__PURE__ */ jsxs44("div", { className: "w-1/2 h-full", style: { background: "linear-gradient(180deg, rgba(0, 187, 0, 1) 0%, rgba(255, 162, 0, 1) 50%, rgba(255, 0, 0, 1) 100%)", borderRadius: "inherit" }, children: [
41183
- /* @__PURE__ */ jsx50("div", { ref: blockerRightRef, className: "absolute bg-gray-200 dark:bg-[#18191d] bottom-0 w-1/2", style: { height: `${100 - volume[index3].right}%`, transition: "height 0.1s ease-out" } }),
41184
- /* @__PURE__ */ jsx50("div", { ref: tickerRightRef, className: "absolute h-[5px] w-1/2 bg-white border border-black", style: { top: `${tickerTarget.right}%`, transition: `top ${tickerTransition.right}s ease-out` } })
41137
+ /* @__PURE__ */ jsxs43("div", { className: "w-1/2 h-full", style: { background: "linear-gradient(180deg, rgba(0, 187, 0, 1) 0%, rgba(255, 162, 0, 1) 50%, rgba(255, 0, 0, 1) 100%)", borderRadius: "inherit" }, children: [
41138
+ /* @__PURE__ */ jsx49("div", { ref: blockerRightRef, className: "absolute bg-gray-200 dark:bg-[#18191d] bottom-0 w-1/2", style: { height: `${100 - volume[index3].right}%`, transition: "height 0.1s ease-out" } }),
41139
+ /* @__PURE__ */ jsx49("div", { ref: tickerRightRef, className: "absolute h-[5px] w-1/2 bg-white border border-black", style: { top: `${tickerTarget.right}%`, transition: `top ${tickerTransition.right}s ease-out` } })
41185
41140
  ] })
41186
41141
  ] }),
41187
41142
  index3 + 1
@@ -41191,7 +41146,7 @@ var VUBar = ({ index: index3, volume, width = "15px", displayMarks = false }) =>
41191
41146
  var VUMeter_default = VUBar;
41192
41147
 
41193
41148
  // src/hooks/useSettings.ts
41194
- import { useState as useState33, useEffect as useEffect26, useCallback as useCallback5, useMemo as useMemo10 } from "react";
41149
+ import { useState as useState32, useEffect as useEffect25, useCallback as useCallback5, useMemo as useMemo10 } from "react";
41195
41150
  import { useQuery as useQuery2, useMutation, useQueryClient } from "@tanstack/react-query";
41196
41151
  function useSettings(defaultSettings4, options) {
41197
41152
  const {
@@ -41206,8 +41161,8 @@ function useSettings(defaultSettings4, options) {
41206
41161
  refetchInterval
41207
41162
  } = options;
41208
41163
  const queryClient = useQueryClient();
41209
- const [settings, setSettings] = useState33(defaultSettings4);
41210
- const [savedSettings, setSavedSettings] = useState33(defaultSettings4);
41164
+ const [settings, setSettings] = useState32(defaultSettings4);
41165
+ const [savedSettings, setSavedSettings] = useState32(defaultSettings4);
41211
41166
  const {
41212
41167
  data,
41213
41168
  isLoading,
@@ -41222,7 +41177,7 @@ function useSettings(defaultSettings4, options) {
41222
41177
  enabled,
41223
41178
  refetchInterval
41224
41179
  });
41225
- useEffect26(() => {
41180
+ useEffect25(() => {
41226
41181
  if (data) {
41227
41182
  setSettings(data);
41228
41183
  setSavedSettings(data);
@@ -41277,13 +41232,13 @@ function useSettings(defaultSettings4, options) {
41277
41232
  }
41278
41233
 
41279
41234
  // src/hooks/useAvailableSubservices.ts
41280
- import { useEffect as useEffect27, useState as useState34 } from "react";
41235
+ import { useEffect as useEffect26, useState as useState33 } from "react";
41281
41236
  function useAvailableSubservices(serviceKey, fallbackCount = 4) {
41282
- const [options, setOptions] = useState34(
41237
+ const [options, setOptions] = useState33(
41283
41238
  Array.from({ length: fallbackCount }).map((_7, i14) => ({ label: `Channel ${i14 + 1}`, value: `${i14}` }))
41284
41239
  );
41285
- const [loading, setLoading] = useState34(false);
41286
- useEffect27(() => {
41240
+ const [loading, setLoading] = useState33(false);
41241
+ useEffect26(() => {
41287
41242
  let mounted = true;
41288
41243
  (async () => {
41289
41244
  setLoading(true);
@@ -41324,6 +41279,7 @@ export {
41324
41279
  Accordion_default as Accordion,
41325
41280
  AddNetwork_default as AddNetwork,
41326
41281
  AudioGroup_default as AudioGroup,
41282
+ AuthContext,
41327
41283
  AuthProvider,
41328
41284
  CheckboxField_default as CheckboxField,
41329
41285
  ColorField_default as ColorField,
@@ -41341,7 +41297,6 @@ export {
41341
41297
  InterfacesTable_default as InterfacesTable,
41342
41298
  InterfacesTimeseries_default as InterfacesTimeseries,
41343
41299
  Livecast_default as Livecast,
41344
- MetadataLoader,
41345
41300
  Metrics_default as MetricBar,
41346
41301
  Auth_default as MiddlewareAuthGroup,
41347
41302
  Channels_default as MiddlewareChannelsGroup,
@@ -41355,7 +41310,6 @@ export {
41355
41310
  Protocol_default as Protocol,
41356
41311
  ProtocolGroup_default as ProtocolGroup,
41357
41312
  RangeField_default as RangeField,
41358
- RemoteModule,
41359
41313
  RequireAuth_default as RequireAuth,
41360
41314
  Role,
41361
41315
  SaveDiscard_default as SaveDiscard,
@@ -41366,6 +41320,7 @@ export {
41366
41320
  SliderField_default as SliderField,
41367
41321
  StreamControl_default as StreamControl,
41368
41322
  SwitchField_default as SwitchField,
41323
+ ThemeContext,
41369
41324
  ThemeProvider,
41370
41325
  VUMeter_default as VUBar,
41371
41326
  Validation_default as ValidationItem,
@@ -41387,8 +41342,8 @@ export {
41387
41342
  getRefreshToken,
41388
41343
  hostConfigLoader,
41389
41344
  isFirstRun,
41390
- loadRemoteModule,
41391
- metadataLoader,
41345
+ isValidIPv4,
41346
+ isValidIPv6,
41392
41347
  registry,
41393
41348
  saveConfig,
41394
41349
  setAccessToken,