@procaaso/alphinity-ui-components 1.8.1 → 1.8.3

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
@@ -999,7 +999,7 @@ var NodeControlsPanel = ({
999
999
  };
1000
1000
 
1001
1001
  // src/components/DeviceControlPanel/DeviceControlPanel.tsx
1002
- var import_react5 = require("react");
1002
+ var import_react5 = __toESM(require("react"), 1);
1003
1003
 
1004
1004
  // src/theme/statusColors.ts
1005
1005
  var DEFAULT_STATUS_COLORS = {
@@ -1026,7 +1026,7 @@ function resolveStatusColor(status, customMap) {
1026
1026
 
1027
1027
  // src/components/DeviceControlPanel/DeviceControlPanel.tsx
1028
1028
  var import_jsx_runtime8 = require("react/jsx-runtime");
1029
- function DeviceControlPanel({
1029
+ function DeviceControlPanelImpl({
1030
1030
  binding,
1031
1031
  onClose,
1032
1032
  position = "bottom",
@@ -1951,6 +1951,7 @@ function DeviceControlPanel({
1951
1951
  ` })
1952
1952
  ] });
1953
1953
  }
1954
+ var DeviceControlPanel = import_react5.default.memo(DeviceControlPanelImpl);
1954
1955
 
1955
1956
  // src/components/NumpadDialog/NumpadDialog.tsx
1956
1957
  var import_react6 = require("react");
@@ -3382,7 +3383,10 @@ var ThemeToggle = ({
3382
3383
  };
3383
3384
 
3384
3385
  // src/components/PIDCanvas/PIDCanvas.tsx
3385
- var import_react17 = require("react");
3386
+ var import_react20 = __toESM(require("react"), 1);
3387
+
3388
+ // src/components/PIDCanvas/NodeRenderer.tsx
3389
+ var import_react10 = __toESM(require("react"), 1);
3386
3390
 
3387
3391
  // src/diagram/symbols/mockSymbolLibrary.ts
3388
3392
  var mockSymbolLibrary = {
@@ -4604,7 +4608,7 @@ function getAvailableSymbols() {
4604
4608
 
4605
4609
  // src/components/PIDCanvas/NodeRenderer.tsx
4606
4610
  var import_jsx_runtime16 = require("react/jsx-runtime");
4607
- function NodeRenderer({
4611
+ function NodeRendererImpl({
4608
4612
  nodes: nodes2,
4609
4613
  selectedNodeIds,
4610
4614
  onNodeClick,
@@ -4750,10 +4754,12 @@ function NodeRenderer({
4750
4754
  );
4751
4755
  }) });
4752
4756
  }
4757
+ var NodeRenderer = import_react10.default.memo(NodeRendererImpl);
4753
4758
 
4754
4759
  // src/components/PIDCanvas/PipeRenderer.tsx
4760
+ var import_react11 = __toESM(require("react"), 1);
4755
4761
  var import_jsx_runtime17 = require("react/jsx-runtime");
4756
- function PipeRenderer({
4762
+ function PipeRendererImpl({
4757
4763
  pipes,
4758
4764
  selectedPipeIds,
4759
4765
  onPipeClick,
@@ -4930,8 +4936,10 @@ function PipeRenderer({
4930
4936
  );
4931
4937
  }) });
4932
4938
  }
4939
+ var PipeRenderer = import_react11.default.memo(PipeRendererImpl);
4933
4940
 
4934
4941
  // src/components/PIDCanvas/DataOverlay.tsx
4942
+ var import_react12 = __toESM(require("react"), 1);
4935
4943
  var import_jsx_runtime18 = require("react/jsx-runtime");
4936
4944
  var PULSE_KEYFRAME_ID = "pid-data-overlay-pulse-keyframes";
4937
4945
  var PULSE_ANIMATION = "pid-data-overlay-pulse 1.5s ease-in-out infinite";
@@ -4957,7 +4965,7 @@ function renderStatusDot(cx, cy, scale, fill) {
4957
4965
  }
4958
4966
  );
4959
4967
  }
4960
- function DataOverlay({
4968
+ function DataOverlayImpl({
4961
4969
  nodeId,
4962
4970
  x,
4963
4971
  y,
@@ -4977,6 +4985,24 @@ function DataOverlay({
4977
4985
  const backgroundColor = display?.backgroundColor;
4978
4986
  const offsetX = display?.offsetX ?? 0;
4979
4987
  const offsetY = display?.offsetY ?? 0;
4988
+ const sparklinePath = import_react12.default.useMemo(() => {
4989
+ if (!showSparkline || !history || history.length < 2) return "";
4990
+ const width = 70 * scale;
4991
+ const height = 20 * scale;
4992
+ const padding = 5 * scale;
4993
+ const effectiveWidth = width - padding * 2;
4994
+ const effectiveHeight = height - padding * 2;
4995
+ const hasEuRange = scaling?.euLow !== void 0 && scaling?.euHigh !== void 0 && scaling.euHigh !== scaling.euLow;
4996
+ const min = hasEuRange ? scaling.euLow : Math.min(...history);
4997
+ const max = hasEuRange ? scaling.euHigh : Math.max(...history);
4998
+ const range = max - min || 1;
4999
+ const points = history.map((val, i) => {
5000
+ const xPos = i / (history.length - 1) * effectiveWidth + padding;
5001
+ const yPos = height - padding - (val - min) / range * effectiveHeight;
5002
+ return `${xPos.toFixed(2)},${yPos.toFixed(2)}`;
5003
+ });
5004
+ return `M ${points.join(" L ")}`;
5005
+ }, [showSparkline, history, scaling, scale]);
4980
5006
  if (!showValue) {
4981
5007
  return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_jsx_runtime18.Fragment, {});
4982
5008
  }
@@ -4996,24 +5022,6 @@ function DataOverlay({
4996
5022
  const finalTextColor = textColor || colors.text;
4997
5023
  const formattedValue = formatValue(value.value);
4998
5024
  const displayText = unit ? `${formattedValue} ${unit}` : formattedValue;
4999
- const sparklinePath = (() => {
5000
- if (!showSparkline || !history || history.length < 2) return "";
5001
- const width = 70 * scale;
5002
- const height = 20 * scale;
5003
- const padding = 5 * scale;
5004
- const effectiveWidth = width - padding * 2;
5005
- const effectiveHeight = height - padding * 2;
5006
- const hasEuRange = scaling?.euLow !== void 0 && scaling?.euHigh !== void 0 && scaling.euHigh !== scaling.euLow;
5007
- const min = hasEuRange ? scaling.euLow : Math.min(...history);
5008
- const max = hasEuRange ? scaling.euHigh : Math.max(...history);
5009
- const range = max - min || 1;
5010
- const points = history.map((val, i) => {
5011
- const xPos = i / (history.length - 1) * effectiveWidth + padding;
5012
- const yPos = height - padding - (val - min) / range * effectiveHeight;
5013
- return `${xPos.toFixed(2)},${yPos.toFixed(2)}`;
5014
- });
5015
- return `M ${points.join(" L ")}`;
5016
- })();
5017
5025
  const hasSparkline = showSparkline && sparklinePath;
5018
5026
  const overlayHeight = (label ? hasSparkline ? 55 : 30 : hasSparkline ? 47 : 22) * scale;
5019
5027
  const overlayWidth = 80 * scale;
@@ -5093,9 +5101,10 @@ function DataOverlay({
5093
5101
  ) })
5094
5102
  ] });
5095
5103
  }
5104
+ var DataOverlay = import_react12.default.memo(DataOverlayImpl);
5096
5105
 
5097
5106
  // src/components/PIDCanvas/PositionPanel.tsx
5098
- var import_react10 = require("react");
5107
+ var import_react13 = require("react");
5099
5108
  var import_jsx_runtime19 = require("react/jsx-runtime");
5100
5109
  function PositionPanel({
5101
5110
  selectedNode,
@@ -5104,9 +5113,9 @@ function PositionPanel({
5104
5113
  onWaypointPositionChange,
5105
5114
  position = "top-right"
5106
5115
  }) {
5107
- const [x, setX] = (0, import_react10.useState)("");
5108
- const [y, setY] = (0, import_react10.useState)("");
5109
- (0, import_react10.useEffect)(() => {
5116
+ const [x, setX] = (0, import_react13.useState)("");
5117
+ const [y, setY] = (0, import_react13.useState)("");
5118
+ (0, import_react13.useEffect)(() => {
5110
5119
  if (selectedNode) {
5111
5120
  setX(selectedNode.transform.x.toFixed(2));
5112
5121
  setY(selectedNode.transform.y.toFixed(2));
@@ -5232,7 +5241,7 @@ function PositionPanel({
5232
5241
  }
5233
5242
 
5234
5243
  // src/diagram/hooks/useViewBox.ts
5235
- var import_react11 = require("react");
5244
+ var import_react14 = require("react");
5236
5245
  function useViewBox(options) {
5237
5246
  const {
5238
5247
  initialViewBox,
@@ -5243,16 +5252,16 @@ function useViewBox(options) {
5243
5252
  zoomSensitivity = 1e-3,
5244
5253
  allowLeftClickPan = true
5245
5254
  } = options;
5246
- const [viewBox, setViewBox] = (0, import_react11.useState)(initialViewBox);
5247
- const svgRef = (0, import_react11.useRef)(null);
5248
- const isPanningRef = (0, import_react11.useRef)(false);
5249
- const lastMousePosRef = (0, import_react11.useRef)({ x: 0, y: 0 });
5250
- const spaceKeyDownRef = (0, import_react11.useRef)(false);
5251
- const lastTouchDistanceRef = (0, import_react11.useRef)(null);
5252
- const resetViewBox = (0, import_react11.useCallback)(() => {
5255
+ const [viewBox, setViewBox] = (0, import_react14.useState)(initialViewBox);
5256
+ const svgRef = (0, import_react14.useRef)(null);
5257
+ const isPanningRef = (0, import_react14.useRef)(false);
5258
+ const lastMousePosRef = (0, import_react14.useRef)({ x: 0, y: 0 });
5259
+ const spaceKeyDownRef = (0, import_react14.useRef)(false);
5260
+ const lastTouchDistanceRef = (0, import_react14.useRef)(null);
5261
+ const resetViewBox = (0, import_react14.useCallback)(() => {
5253
5262
  setViewBox(initialViewBox);
5254
5263
  }, [initialViewBox]);
5255
- const zoomIn = (0, import_react11.useCallback)(() => {
5264
+ const zoomIn = (0, import_react14.useCallback)(() => {
5256
5265
  setViewBox((prev) => {
5257
5266
  const currentZoom = initialViewBox.width / prev.width;
5258
5267
  const newZoom = Math.min(1 / minZoom, currentZoom * 1.25);
@@ -5269,7 +5278,7 @@ function useViewBox(options) {
5269
5278
  };
5270
5279
  });
5271
5280
  }, [initialViewBox, minZoom]);
5272
- const zoomOut = (0, import_react11.useCallback)(() => {
5281
+ const zoomOut = (0, import_react14.useCallback)(() => {
5273
5282
  setViewBox((prev) => {
5274
5283
  const currentZoom = initialViewBox.width / prev.width;
5275
5284
  const newZoom = Math.max(1 / maxZoom, currentZoom * 0.8);
@@ -5286,7 +5295,7 @@ function useViewBox(options) {
5286
5295
  };
5287
5296
  });
5288
5297
  }, [initialViewBox, maxZoom]);
5289
- const fitToContent = (0, import_react11.useCallback)((bounds, padding = 50) => {
5298
+ const fitToContent = (0, import_react14.useCallback)((bounds, padding = 50) => {
5290
5299
  const contentWidth = bounds.maxX - bounds.minX;
5291
5300
  const contentHeight = bounds.maxY - bounds.minY;
5292
5301
  if (contentWidth === 0 || contentHeight === 0) {
@@ -5314,7 +5323,7 @@ function useViewBox(options) {
5314
5323
  height: newHeight
5315
5324
  });
5316
5325
  }, [initialViewBox]);
5317
- (0, import_react11.useEffect)(() => {
5326
+ (0, import_react14.useEffect)(() => {
5318
5327
  if (!enableZoom || !svgRef.current) return;
5319
5328
  const svg = svgRef.current;
5320
5329
  const handleWheel = (e) => {
@@ -5347,7 +5356,7 @@ function useViewBox(options) {
5347
5356
  svg.addEventListener("wheel", handleWheel, { passive: false });
5348
5357
  return () => svg.removeEventListener("wheel", handleWheel);
5349
5358
  }, [enableZoom, zoomSensitivity, minZoom, initialViewBox]);
5350
- (0, import_react11.useEffect)(() => {
5359
+ (0, import_react14.useEffect)(() => {
5351
5360
  if (!enablePan || !svgRef.current) return;
5352
5361
  const svg = svgRef.current;
5353
5362
  const handleMouseDown = (e) => {
@@ -5423,7 +5432,7 @@ function useViewBox(options) {
5423
5432
  window.removeEventListener("keyup", handleKeyUp);
5424
5433
  };
5425
5434
  }, [enablePan, allowLeftClickPan]);
5426
- (0, import_react11.useEffect)(() => {
5435
+ (0, import_react14.useEffect)(() => {
5427
5436
  if (!svgRef.current) return;
5428
5437
  if (!enablePan && !enableZoom) return;
5429
5438
  const svg = svgRef.current;
@@ -5514,7 +5523,7 @@ function useViewBox(options) {
5514
5523
  svg.removeEventListener("touchend", handleTouchEnd);
5515
5524
  };
5516
5525
  }, [enablePan, enableZoom, minZoom, initialViewBox]);
5517
- const screenToWorld = (0, import_react11.useCallback)(
5526
+ const screenToWorld = (0, import_react14.useCallback)(
5518
5527
  (screenX, screenY) => {
5519
5528
  const svg = svgRef.current;
5520
5529
  if (!svg) return { x: screenX, y: screenY };
@@ -5553,15 +5562,15 @@ function useViewBox(options) {
5553
5562
  }
5554
5563
 
5555
5564
  // src/diagram/hooks/useSelection.ts
5556
- var import_react12 = require("react");
5565
+ var import_react15 = require("react");
5557
5566
  function useSelection(options = {}) {
5558
5567
  const {
5559
5568
  multiSelect = true,
5560
5569
  initialSelection = { selectedNodeIds: /* @__PURE__ */ new Set(), selectedPipeIds: /* @__PURE__ */ new Set() },
5561
5570
  onSelectionChange
5562
5571
  } = options;
5563
- const [selection, setSelection] = (0, import_react12.useState)(initialSelection);
5564
- const notifyChange = (0, import_react12.useCallback)(
5572
+ const [selection, setSelection] = (0, import_react15.useState)(initialSelection);
5573
+ const notifyChange = (0, import_react15.useCallback)(
5565
5574
  (newSelection) => {
5566
5575
  if (onSelectionChange) {
5567
5576
  onSelectionChange(newSelection);
@@ -5569,15 +5578,15 @@ function useSelection(options = {}) {
5569
5578
  },
5570
5579
  [onSelectionChange]
5571
5580
  );
5572
- const isNodeSelected = (0, import_react12.useCallback)(
5581
+ const isNodeSelected = (0, import_react15.useCallback)(
5573
5582
  (nodeId) => selection.selectedNodeIds.has(nodeId),
5574
5583
  [selection.selectedNodeIds]
5575
5584
  );
5576
- const isPipeSelected = (0, import_react12.useCallback)(
5585
+ const isPipeSelected = (0, import_react15.useCallback)(
5577
5586
  (pipeId) => selection.selectedPipeIds.has(pipeId),
5578
5587
  [selection.selectedPipeIds]
5579
5588
  );
5580
- const selectNode = (0, import_react12.useCallback)(
5589
+ const selectNode = (0, import_react15.useCallback)(
5581
5590
  (nodeId, isMultiSelect = false) => {
5582
5591
  setSelection((prev) => {
5583
5592
  const newNodeIds = new Set(isMultiSelect && multiSelect ? prev.selectedNodeIds : []);
@@ -5596,7 +5605,7 @@ function useSelection(options = {}) {
5596
5605
  },
5597
5606
  [multiSelect, notifyChange]
5598
5607
  );
5599
- const selectPipe = (0, import_react12.useCallback)(
5608
+ const selectPipe = (0, import_react15.useCallback)(
5600
5609
  (pipeId, isMultiSelect = false) => {
5601
5610
  setSelection((prev) => {
5602
5611
  const newPipeIds = new Set(isMultiSelect && multiSelect ? prev.selectedPipeIds : []);
@@ -5615,7 +5624,7 @@ function useSelection(options = {}) {
5615
5624
  },
5616
5625
  [multiSelect, notifyChange]
5617
5626
  );
5618
- const clearSelection = (0, import_react12.useCallback)(() => {
5627
+ const clearSelection = (0, import_react15.useCallback)(() => {
5619
5628
  const newSelection = {
5620
5629
  selectedNodeIds: /* @__PURE__ */ new Set(),
5621
5630
  selectedPipeIds: /* @__PURE__ */ new Set()
@@ -5623,7 +5632,7 @@ function useSelection(options = {}) {
5623
5632
  setSelection(newSelection);
5624
5633
  notifyChange(newSelection);
5625
5634
  }, [notifyChange]);
5626
- const selectNodes = (0, import_react12.useCallback)(
5635
+ const selectNodes = (0, import_react15.useCallback)(
5627
5636
  (nodeIds) => {
5628
5637
  const newSelection = {
5629
5638
  selectedNodeIds: new Set(nodeIds),
@@ -5634,7 +5643,7 @@ function useSelection(options = {}) {
5634
5643
  },
5635
5644
  [notifyChange]
5636
5645
  );
5637
- const selectPipes = (0, import_react12.useCallback)(
5646
+ const selectPipes = (0, import_react15.useCallback)(
5638
5647
  (pipeIds) => {
5639
5648
  const newSelection = {
5640
5649
  selectedNodeIds: /* @__PURE__ */ new Set(),
@@ -5658,23 +5667,23 @@ function useSelection(options = {}) {
5658
5667
  }
5659
5668
 
5660
5669
  // src/diagram/hooks/useTelemetry.ts
5661
- var import_react13 = require("react");
5670
+ var import_react16 = require("react");
5662
5671
  function useTelemetry(options = {}) {
5663
5672
  const {
5664
5673
  initialBindings = [],
5665
5674
  onTelemetryChange,
5666
5675
  refreshInterval = 0
5667
5676
  } = options;
5668
- const [telemetry, setTelemetry] = (0, import_react13.useState)(() => {
5677
+ const [telemetry, setTelemetry] = (0, import_react16.useState)(() => {
5669
5678
  const map = /* @__PURE__ */ new Map();
5670
5679
  initialBindings.forEach((binding) => {
5671
5680
  map.set(binding.nodeId, binding);
5672
5681
  });
5673
5682
  return map;
5674
5683
  });
5675
- const telemetryRef = (0, import_react13.useRef)(telemetry);
5684
+ const telemetryRef = (0, import_react16.useRef)(telemetry);
5676
5685
  telemetryRef.current = telemetry;
5677
- const notifyChange = (0, import_react13.useCallback)(
5686
+ const notifyChange = (0, import_react16.useCallback)(
5678
5687
  (newTelemetry) => {
5679
5688
  if (onTelemetryChange) {
5680
5689
  onTelemetryChange(newTelemetry);
@@ -5682,7 +5691,7 @@ function useTelemetry(options = {}) {
5682
5691
  },
5683
5692
  [onTelemetryChange]
5684
5693
  );
5685
- const updateTelemetry = (0, import_react13.useCallback)(
5694
+ const updateTelemetry = (0, import_react16.useCallback)(
5686
5695
  (nodeId, value) => {
5687
5696
  setTelemetry((prev) => {
5688
5697
  const newMap = new Map(prev);
@@ -5712,7 +5721,7 @@ function useTelemetry(options = {}) {
5712
5721
  },
5713
5722
  [notifyChange]
5714
5723
  );
5715
- const updateTelemetryBatch = (0, import_react13.useCallback)(
5724
+ const updateTelemetryBatch = (0, import_react16.useCallback)(
5716
5725
  (updates) => {
5717
5726
  setTelemetry((prev) => {
5718
5727
  const newMap = new Map(prev);
@@ -5766,16 +5775,16 @@ function useTelemetry(options = {}) {
5766
5775
  },
5767
5776
  [notifyChange]
5768
5777
  );
5769
- const getTelemetry = (0, import_react13.useCallback)(
5778
+ const getTelemetry = (0, import_react16.useCallback)(
5770
5779
  (nodeId) => telemetryRef.current.get(nodeId),
5771
5780
  []
5772
5781
  );
5773
- const clearTelemetry = (0, import_react13.useCallback)(() => {
5782
+ const clearTelemetry = (0, import_react16.useCallback)(() => {
5774
5783
  const newMap = /* @__PURE__ */ new Map();
5775
5784
  setTelemetry(newMap);
5776
5785
  notifyChange(newMap);
5777
5786
  }, [notifyChange]);
5778
- const setBindings = (0, import_react13.useCallback)(
5787
+ const setBindings = (0, import_react16.useCallback)(
5779
5788
  (bindings) => {
5780
5789
  const newMap = /* @__PURE__ */ new Map();
5781
5790
  bindings.forEach((binding) => {
@@ -5786,7 +5795,7 @@ function useTelemetry(options = {}) {
5786
5795
  },
5787
5796
  [notifyChange]
5788
5797
  );
5789
- (0, import_react13.useEffect)(() => {
5798
+ (0, import_react16.useEffect)(() => {
5790
5799
  if (refreshInterval <= 0) return;
5791
5800
  const intervalId = setInterval(() => {
5792
5801
  notifyChange(telemetryRef.current);
@@ -5804,10 +5813,10 @@ function useTelemetry(options = {}) {
5804
5813
  }
5805
5814
 
5806
5815
  // src/diagram/hooks/useTelemetryStatus.ts
5807
- var import_react14 = require("react");
5816
+ var import_react17 = require("react");
5808
5817
  function useTelemetryStatus(telemetry, diagram, setDiagram, options = {}) {
5809
5818
  const { enabled = true, mapStatus } = options;
5810
- (0, import_react14.useEffect)(() => {
5819
+ (0, import_react17.useEffect)(() => {
5811
5820
  if (!enabled) return;
5812
5821
  const defaultMapStatus = (telemetryStatus) => {
5813
5822
  switch (telemetryStatus) {
@@ -5846,7 +5855,7 @@ function useTelemetryStatus(telemetry, diagram, setDiagram, options = {}) {
5846
5855
  }
5847
5856
 
5848
5857
  // src/diagram/hooks/useDrag.ts
5849
- var import_react15 = require("react");
5858
+ var import_react18 = require("react");
5850
5859
  function useDrag(options = {}) {
5851
5860
  const {
5852
5861
  onDragStart,
@@ -5856,23 +5865,23 @@ function useDrag(options = {}) {
5856
5865
  dragThreshold = 3,
5857
5866
  screenToWorld = (x, y) => ({ x, y })
5858
5867
  } = options;
5859
- const [dragState, setDragState] = (0, import_react15.useState)({
5868
+ const [dragState, setDragState] = (0, import_react18.useState)({
5860
5869
  isDragging: false,
5861
5870
  startPosition: null,
5862
5871
  offset: { x: 0, y: 0 },
5863
5872
  draggedId: null
5864
5873
  });
5865
- const [isListening, setIsListening] = (0, import_react15.useState)(false);
5866
- const dragStartRef = (0, import_react15.useRef)(null);
5867
- const hasMovedRef = (0, import_react15.useRef)(false);
5868
- const applySnap = (0, import_react15.useCallback)(
5874
+ const [isListening, setIsListening] = (0, import_react18.useState)(false);
5875
+ const dragStartRef = (0, import_react18.useRef)(null);
5876
+ const hasMovedRef = (0, import_react18.useRef)(false);
5877
+ const applySnap = (0, import_react18.useCallback)(
5869
5878
  (value) => {
5870
5879
  if (snapToGrid <= 0) return value;
5871
5880
  return Math.round(value / snapToGrid) * snapToGrid;
5872
5881
  },
5873
5882
  [snapToGrid]
5874
5883
  );
5875
- const handleMouseMove = (0, import_react15.useCallback)(
5884
+ const handleMouseMove = (0, import_react18.useCallback)(
5876
5885
  (event) => {
5877
5886
  if (!dragStartRef.current) return;
5878
5887
  const { id, screenStart: _screenStart, itemPosition, clickOffset } = dragStartRef.current;
@@ -5913,7 +5922,7 @@ function useDrag(options = {}) {
5913
5922
  },
5914
5923
  [screenToWorld, dragThreshold, applySnap, onDragStart, onDragMove]
5915
5924
  );
5916
- const handleMouseUp = (0, import_react15.useCallback)(
5925
+ const handleMouseUp = (0, import_react18.useCallback)(
5917
5926
  (event) => {
5918
5927
  if (!dragStartRef.current || !hasMovedRef.current) {
5919
5928
  dragStartRef.current = null;
@@ -5950,7 +5959,7 @@ function useDrag(options = {}) {
5950
5959
  },
5951
5960
  [screenToWorld, applySnap, onDragEnd]
5952
5961
  );
5953
- const handleTouchMove = (0, import_react15.useCallback)(
5962
+ const handleTouchMove = (0, import_react18.useCallback)(
5954
5963
  (event) => {
5955
5964
  if (!dragStartRef.current || event.touches.length !== 1) return;
5956
5965
  const touch = event.touches[0];
@@ -5993,7 +6002,7 @@ function useDrag(options = {}) {
5993
6002
  },
5994
6003
  [screenToWorld, dragThreshold, applySnap, onDragStart, onDragMove]
5995
6004
  );
5996
- const handleTouchEnd = (0, import_react15.useCallback)(
6005
+ const handleTouchEnd = (0, import_react18.useCallback)(
5997
6006
  (event) => {
5998
6007
  if (!dragStartRef.current || !hasMovedRef.current) {
5999
6008
  dragStartRef.current = null;
@@ -6031,7 +6040,7 @@ function useDrag(options = {}) {
6031
6040
  },
6032
6041
  [screenToWorld, applySnap, onDragEnd]
6033
6042
  );
6034
- (0, import_react15.useEffect)(() => {
6043
+ (0, import_react18.useEffect)(() => {
6035
6044
  if (!isListening) return;
6036
6045
  document.addEventListener("mousemove", handleMouseMove);
6037
6046
  document.addEventListener("mouseup", handleMouseUp);
@@ -6046,7 +6055,7 @@ function useDrag(options = {}) {
6046
6055
  document.removeEventListener("touchcancel", handleTouchEnd);
6047
6056
  };
6048
6057
  }, [isListening, handleMouseMove, handleMouseUp, handleTouchMove, handleTouchEnd]);
6049
- const startDrag = (0, import_react15.useCallback)(
6058
+ const startDrag = (0, import_react18.useCallback)(
6050
6059
  (id, event, itemPosition) => {
6051
6060
  event.stopPropagation();
6052
6061
  let clientX;
@@ -6076,7 +6085,7 @@ function useDrag(options = {}) {
6076
6085
  },
6077
6086
  [screenToWorld]
6078
6087
  );
6079
- const cancelDrag = (0, import_react15.useCallback)(() => {
6088
+ const cancelDrag = (0, import_react18.useCallback)(() => {
6080
6089
  dragStartRef.current = null;
6081
6090
  hasMovedRef.current = false;
6082
6091
  setIsListening(false);
@@ -6087,7 +6096,7 @@ function useDrag(options = {}) {
6087
6096
  draggedId: null
6088
6097
  });
6089
6098
  }, []);
6090
- const isDraggingItem = (0, import_react15.useCallback)(
6099
+ const isDraggingItem = (0, import_react18.useCallback)(
6091
6100
  (id) => dragState.isDragging && dragState.draggedId === id,
6092
6101
  [dragState.isDragging, dragState.draggedId]
6093
6102
  );
@@ -6100,7 +6109,7 @@ function useDrag(options = {}) {
6100
6109
  }
6101
6110
 
6102
6111
  // src/diagram/hooks/useKeyboardShortcuts.ts
6103
- var import_react16 = require("react");
6112
+ var import_react19 = require("react");
6104
6113
  function useKeyboardShortcuts(options) {
6105
6114
  const {
6106
6115
  onDelete,
@@ -6111,7 +6120,7 @@ function useKeyboardShortcuts(options) {
6111
6120
  onSelectAll,
6112
6121
  enabled = true
6113
6122
  } = options;
6114
- (0, import_react16.useEffect)(() => {
6123
+ (0, import_react19.useEffect)(() => {
6115
6124
  if (!enabled) return;
6116
6125
  const handleKeyDown = (event) => {
6117
6126
  const target = event.target;
@@ -6221,18 +6230,19 @@ function nodeHasPort(node, portId) {
6221
6230
 
6222
6231
  // src/components/PIDCanvas/PIDCanvas.tsx
6223
6232
  var import_jsx_runtime20 = require("react/jsx-runtime");
6224
- function PIDCanvas({
6233
+ var DEFAULT_FEATURES = {
6234
+ pan: true,
6235
+ zoom: true,
6236
+ selection: false,
6237
+ multiSelect: true,
6238
+ telemetry: false,
6239
+ dragNodes: false
6240
+ };
6241
+ function PIDCanvasImpl({
6225
6242
  diagram,
6226
6243
  className = "",
6227
6244
  style,
6228
- features = {
6229
- pan: true,
6230
- zoom: true,
6231
- selection: false,
6232
- multiSelect: true,
6233
- telemetry: false,
6234
- dragNodes: false
6235
- },
6245
+ features = DEFAULT_FEATURES,
6236
6246
  onSelectionChange,
6237
6247
  onNodeClick,
6238
6248
  onPipeClick,
@@ -6248,21 +6258,21 @@ function PIDCanvas({
6248
6258
  statusColorMap,
6249
6259
  ...props
6250
6260
  }) {
6251
- const [localDiagram, setLocalDiagram] = (0, import_react17.useState)(diagram);
6252
- const [dragOverPosition, setDragOverPosition] = (0, import_react17.useState)(null);
6253
- const [isConnecting, setIsConnecting] = (0, import_react17.useState)(false);
6254
- const [connectionSource, setConnectionSource] = (0, import_react17.useState)(null);
6255
- const [connectionSourcePort, setConnectionSourcePort] = (0, import_react17.useState)(null);
6256
- const [connectionCursor, setConnectionCursor] = (0, import_react17.useState)(null);
6257
- const [hoveredNode, setHoveredNode] = (0, import_react17.useState)(null);
6258
- const [hoveredPort, setHoveredPort] = (0, import_react17.useState)(null);
6259
- const [selectedWaypoint, setSelectedWaypoint] = (0, import_react17.useState)(null);
6260
- const historyStack = (0, import_react17.useRef)([]);
6261
- const redoStack = (0, import_react17.useRef)([]);
6262
- const isUndoRedoAction = (0, import_react17.useRef)(false);
6263
- const isInternalChange = (0, import_react17.useRef)(false);
6264
- const lastInternalDiagram = (0, import_react17.useRef)(null);
6265
- (0, import_react17.useEffect)(() => {
6261
+ const [localDiagram, setLocalDiagram] = (0, import_react20.useState)(diagram);
6262
+ const [dragOverPosition, setDragOverPosition] = (0, import_react20.useState)(null);
6263
+ const [isConnecting, setIsConnecting] = (0, import_react20.useState)(false);
6264
+ const [connectionSource, setConnectionSource] = (0, import_react20.useState)(null);
6265
+ const [connectionSourcePort, setConnectionSourcePort] = (0, import_react20.useState)(null);
6266
+ const [connectionCursor, setConnectionCursor] = (0, import_react20.useState)(null);
6267
+ const [hoveredNode, setHoveredNode] = (0, import_react20.useState)(null);
6268
+ const [hoveredPort, setHoveredPort] = (0, import_react20.useState)(null);
6269
+ const [selectedWaypoint, setSelectedWaypoint] = (0, import_react20.useState)(null);
6270
+ const historyStack = (0, import_react20.useRef)([]);
6271
+ const redoStack = (0, import_react20.useRef)([]);
6272
+ const isUndoRedoAction = (0, import_react20.useRef)(false);
6273
+ const isInternalChange = (0, import_react20.useRef)(false);
6274
+ const lastInternalDiagram = (0, import_react20.useRef)(null);
6275
+ (0, import_react20.useEffect)(() => {
6266
6276
  const isExternal = !isInternalChange.current && diagram !== lastInternalDiagram.current;
6267
6277
  if (isExternal) {
6268
6278
  setLocalDiagram(diagram);
@@ -6284,7 +6294,7 @@ function PIDCanvas({
6284
6294
  enablePan: features.pan ?? true,
6285
6295
  enableZoom: features.zoom ?? true
6286
6296
  });
6287
- const calculateContentBounds = (0, import_react17.useCallback)(() => {
6297
+ const calculateContentBounds = (0, import_react20.useCallback)(() => {
6288
6298
  const nodes2 = localDiagram.nodes.filter((n) => n.visible !== false);
6289
6299
  if (nodes2.length === 0) {
6290
6300
  return null;
@@ -6307,7 +6317,7 @@ function PIDCanvas({
6307
6317
  });
6308
6318
  return { minX, minY, maxX, maxY };
6309
6319
  }, [localDiagram.nodes]);
6310
- (0, import_react17.useEffect)(() => {
6320
+ (0, import_react20.useEffect)(() => {
6311
6321
  if (onMounted) {
6312
6322
  const controls = {
6313
6323
  fitToContent: (padding = 50) => {
@@ -6348,8 +6358,8 @@ function PIDCanvas({
6348
6358
  });
6349
6359
  const dragEnabled = features.dragNodes ?? false;
6350
6360
  const selectionEnabled = features.selection ?? false;
6351
- const containerRef = (0, import_react17.useRef)(null);
6352
- const pushToHistory = (0, import_react17.useCallback)((currentDiagram) => {
6361
+ const containerRef = (0, import_react20.useRef)(null);
6362
+ const pushToHistory = (0, import_react20.useCallback)((currentDiagram) => {
6353
6363
  if (isUndoRedoAction.current) return;
6354
6364
  const snapshot = JSON.parse(JSON.stringify(currentDiagram));
6355
6365
  historyStack.current.push(snapshot);
@@ -6358,7 +6368,7 @@ function PIDCanvas({
6358
6368
  }
6359
6369
  redoStack.current = [];
6360
6370
  }, []);
6361
- const undo = (0, import_react17.useCallback)(() => {
6371
+ const undo = (0, import_react20.useCallback)(() => {
6362
6372
  if (historyStack.current.length === 0) return;
6363
6373
  isUndoRedoAction.current = true;
6364
6374
  const currentSnapshot = JSON.parse(JSON.stringify(localDiagram));
@@ -6372,7 +6382,7 @@ function PIDCanvas({
6372
6382
  isUndoRedoAction.current = false;
6373
6383
  }, 0);
6374
6384
  }, [localDiagram, onDiagramChange]);
6375
- const redo = (0, import_react17.useCallback)(() => {
6385
+ const redo = (0, import_react20.useCallback)(() => {
6376
6386
  if (redoStack.current.length === 0) return;
6377
6387
  isUndoRedoAction.current = true;
6378
6388
  const currentSnapshot = JSON.parse(JSON.stringify(localDiagram));
@@ -6386,7 +6396,7 @@ function PIDCanvas({
6386
6396
  isUndoRedoAction.current = false;
6387
6397
  }, 0);
6388
6398
  }, [localDiagram, onDiagramChange]);
6389
- (0, import_react17.useEffect)(() => {
6399
+ (0, import_react20.useEffect)(() => {
6390
6400
  const handleKeyDown = (e) => {
6391
6401
  const isCtrlOrCmd = e.ctrlKey || e.metaKey;
6392
6402
  if (isCtrlOrCmd && e.key === "z" && !e.shiftKey) {
@@ -6403,7 +6413,7 @@ function PIDCanvas({
6403
6413
  window.addEventListener("keydown", handleKeyDown);
6404
6414
  return () => window.removeEventListener("keydown", handleKeyDown);
6405
6415
  }, [undo, redo]);
6406
- (0, import_react17.useEffect)(() => {
6416
+ (0, import_react20.useEffect)(() => {
6407
6417
  if (!features.dragNodes) return;
6408
6418
  const handleKeyDown = (e) => {
6409
6419
  if (selection.selectedNodeIds.size === 0 && !selectedWaypoint) return;
@@ -6488,7 +6498,7 @@ function PIDCanvas({
6488
6498
  onNodeMove,
6489
6499
  pushToHistory
6490
6500
  ]);
6491
- const handlePositionChange = (0, import_react17.useCallback)(
6501
+ const handlePositionChange = (0, import_react20.useCallback)(
6492
6502
  (nodeId, x, y) => {
6493
6503
  pushToHistory(localDiagram);
6494
6504
  const updatedNodes = localDiagram.nodes.map(
@@ -6510,7 +6520,7 @@ function PIDCanvas({
6510
6520
  },
6511
6521
  [localDiagram, onDiagramChange, onNodeMove, pushToHistory]
6512
6522
  );
6513
- const handleWaypointPositionChange = (0, import_react17.useCallback)(
6523
+ const handleWaypointPositionChange = (0, import_react20.useCallback)(
6514
6524
  (pipeId, pointIndex, x, y) => {
6515
6525
  pushToHistory(localDiagram);
6516
6526
  const updatedPipes = localDiagram.pipes.map((pipe) => {
@@ -6528,7 +6538,7 @@ function PIDCanvas({
6528
6538
  },
6529
6539
  [localDiagram, onDiagramChange, pushToHistory]
6530
6540
  );
6531
- const handleDragEnd = (0, import_react17.useCallback)(
6541
+ const handleDragEnd = (0, import_react20.useCallback)(
6532
6542
  (nodeId, offset, finalPosition) => {
6533
6543
  const dragDistance = Math.sqrt(offset.x ** 2 + offset.y ** 2);
6534
6544
  if (dragDistance < 2) {
@@ -6609,7 +6619,7 @@ function PIDCanvas({
6609
6619
  onDiagramChange?.(updatedDiagram);
6610
6620
  }
6611
6621
  });
6612
- const handleNodeDragStart = (0, import_react17.useCallback)(
6622
+ const handleNodeDragStart = (0, import_react20.useCallback)(
6613
6623
  (nodeId, event) => {
6614
6624
  const node = localDiagram.nodes.find((n) => n.id === nodeId);
6615
6625
  if (!node) return;
@@ -6617,7 +6627,7 @@ function PIDCanvas({
6617
6627
  },
6618
6628
  [localDiagram.nodes, startDrag]
6619
6629
  );
6620
- const handleWaypointClick = (0, import_react17.useCallback)(
6630
+ const handleWaypointClick = (0, import_react20.useCallback)(
6621
6631
  (pipeId, pointIndex) => {
6622
6632
  setSelectedWaypoint({ pipeId, pointIndex });
6623
6633
  if (selectionEnabled) {
@@ -6626,7 +6636,7 @@ function PIDCanvas({
6626
6636
  },
6627
6637
  [selectionEnabled, clearSelection]
6628
6638
  );
6629
- const handleWaypointDragStart = (0, import_react17.useCallback)(
6639
+ const handleWaypointDragStart = (0, import_react20.useCallback)(
6630
6640
  (pipeId, pointIndex, event) => {
6631
6641
  const pipe = localDiagram.pipes.find((p) => p.id === pipeId);
6632
6642
  if (!pipe || pointIndex >= pipe.routePoints.length) return;
@@ -6635,7 +6645,7 @@ function PIDCanvas({
6635
6645
  },
6636
6646
  [localDiagram.pipes, startWaypointDrag]
6637
6647
  );
6638
- const handlePipeSegmentClick = (0, import_react17.useCallback)(
6648
+ const handlePipeSegmentClick = (0, import_react20.useCallback)(
6639
6649
  (pipeId, position, segmentIndex) => {
6640
6650
  pushToHistory(localDiagram);
6641
6651
  const updatedPipes = localDiagram.pipes.map((pipe) => {
@@ -6654,7 +6664,7 @@ function PIDCanvas({
6654
6664
  [localDiagram, onDiagramChange, pushToHistory]
6655
6665
  );
6656
6666
  const telemetryEnabled = features.telemetry ?? false;
6657
- const handleDelete = (0, import_react17.useCallback)(() => {
6667
+ const handleDelete = (0, import_react20.useCallback)(() => {
6658
6668
  if (!selectionEnabled) return;
6659
6669
  const { selectedNodeIds, selectedPipeIds } = selection;
6660
6670
  if (selectedNodeIds.size === 0 && selectedPipeIds.size === 0) return;
@@ -6683,62 +6693,81 @@ function PIDCanvas({
6683
6693
  onDelete,
6684
6694
  pushToHistory
6685
6695
  ]);
6686
- const handleCopy = (0, import_react17.useCallback)(() => {
6696
+ const handleCopy = (0, import_react20.useCallback)(() => {
6687
6697
  if (!selectionEnabled) return;
6688
6698
  const { selectedNodeIds, selectedPipeIds } = selection;
6689
6699
  if (selectedNodeIds.size === 0 && selectedPipeIds.size === 0) return;
6690
6700
  onItemsCopied?.(Array.from(selectedNodeIds), Array.from(selectedPipeIds));
6691
6701
  }, [selection, selectionEnabled, onItemsCopied]);
6692
- const handlePaste = (0, import_react17.useCallback)(() => {
6702
+ const handlePaste = (0, import_react20.useCallback)(() => {
6693
6703
  if (!selectionEnabled) return;
6694
6704
  onPaste?.();
6695
6705
  }, [selectionEnabled, onPaste]);
6696
- const handleNodeDoubleClick = (nodeId, event) => {
6697
- if (!selectionEnabled) return;
6698
- console.log("Node double-clicked:", nodeId);
6699
- selectNode(nodeId, event.ctrlKey || event.metaKey);
6700
- };
6706
+ const handleNodeDoubleClick = (0, import_react20.useCallback)(
6707
+ (nodeId, event) => {
6708
+ if (!selectionEnabled) return;
6709
+ console.log("Node double-clicked:", nodeId);
6710
+ selectNode(nodeId, event.ctrlKey || event.metaKey);
6711
+ },
6712
+ [selectionEnabled, selectNode]
6713
+ );
6701
6714
  useKeyboardShortcuts({
6702
6715
  enabled: features.keyboardShortcuts ?? false,
6703
6716
  onDelete: handleDelete,
6704
6717
  onCopy: handleCopy,
6705
6718
  onPaste: handlePaste
6706
6719
  });
6707
- const handleNodeClick = (nodeId, event) => {
6708
- const connectionModeEnabled = features.connectionMode ?? false;
6709
- if (connectionModeEnabled && isConnecting) {
6710
- if (connectionSource && connectionSource !== nodeId) {
6711
- onPipeCreated?.(
6712
- connectionSource,
6713
- nodeId,
6714
- connectionSourcePort || void 0,
6715
- hoveredPort || void 0
6716
- );
6717
- setIsConnecting(false);
6718
- setConnectionSource(null);
6719
- setConnectionSourcePort(null);
6720
- setConnectionCursor(null);
6721
- setHoveredPort(null);
6720
+ const handleNodeClick = (0, import_react20.useCallback)(
6721
+ (nodeId, event) => {
6722
+ const connectionModeEnabled = features.connectionMode ?? false;
6723
+ if (connectionModeEnabled && isConnecting) {
6724
+ if (connectionSource && connectionSource !== nodeId) {
6725
+ onPipeCreated?.(
6726
+ connectionSource,
6727
+ nodeId,
6728
+ connectionSourcePort || void 0,
6729
+ hoveredPort || void 0
6730
+ );
6731
+ setIsConnecting(false);
6732
+ setConnectionSource(null);
6733
+ setConnectionSourcePort(null);
6734
+ setConnectionCursor(null);
6735
+ setHoveredPort(null);
6736
+ }
6737
+ return;
6722
6738
  }
6723
- return;
6724
- }
6725
- if (connectionModeEnabled && !isConnecting) {
6726
- setIsConnecting(true);
6727
- setConnectionSource(nodeId);
6728
- setConnectionSourcePort(hoveredPort);
6729
- return;
6730
- }
6731
- if (selectionEnabled) {
6732
- selectNode(nodeId, event.ctrlKey || event.metaKey);
6733
- }
6734
- onNodeClick?.(nodeId);
6735
- };
6736
- const handlePipeClick = (pipeId, event) => {
6737
- if (selectionEnabled) {
6738
- selectPipe(pipeId, event.ctrlKey || event.metaKey);
6739
- }
6740
- onPipeClick?.(pipeId);
6741
- };
6739
+ if (connectionModeEnabled && !isConnecting) {
6740
+ setIsConnecting(true);
6741
+ setConnectionSource(nodeId);
6742
+ setConnectionSourcePort(hoveredPort);
6743
+ return;
6744
+ }
6745
+ if (selectionEnabled) {
6746
+ selectNode(nodeId, event.ctrlKey || event.metaKey);
6747
+ }
6748
+ onNodeClick?.(nodeId);
6749
+ },
6750
+ [
6751
+ features.connectionMode,
6752
+ isConnecting,
6753
+ connectionSource,
6754
+ connectionSourcePort,
6755
+ hoveredPort,
6756
+ onPipeCreated,
6757
+ selectionEnabled,
6758
+ selectNode,
6759
+ onNodeClick
6760
+ ]
6761
+ );
6762
+ const handlePipeClick = (0, import_react20.useCallback)(
6763
+ (pipeId, event) => {
6764
+ if (selectionEnabled) {
6765
+ selectPipe(pipeId, event.ctrlKey || event.metaKey);
6766
+ }
6767
+ onPipeClick?.(pipeId);
6768
+ },
6769
+ [selectionEnabled, selectPipe, onPipeClick]
6770
+ );
6742
6771
  const handleCanvasClick = (e) => {
6743
6772
  const target = e.target;
6744
6773
  if (target.closest(".pipe-route-point")) {
@@ -6749,7 +6778,7 @@ function PIDCanvas({
6749
6778
  }
6750
6779
  setSelectedWaypoint(null);
6751
6780
  };
6752
- const handleDragOver = (0, import_react17.useCallback)(
6781
+ const handleDragOver = (0, import_react20.useCallback)(
6753
6782
  (event) => {
6754
6783
  if (!features.allowSymbolDrop) return;
6755
6784
  event.preventDefault();
@@ -6760,7 +6789,7 @@ function PIDCanvas({
6760
6789
  },
6761
6790
  [features.allowSymbolDrop, screenToWorld, svgRef]
6762
6791
  );
6763
- const handleDrop = (0, import_react17.useCallback)(
6792
+ const handleDrop = (0, import_react20.useCallback)(
6764
6793
  (event) => {
6765
6794
  if (!features.allowSymbolDrop) return;
6766
6795
  event.preventDefault();
@@ -6773,10 +6802,10 @@ function PIDCanvas({
6773
6802
  },
6774
6803
  [features.allowSymbolDrop, screenToWorld, onSymbolDrop, svgRef]
6775
6804
  );
6776
- const handleDragLeave = (0, import_react17.useCallback)(() => {
6805
+ const handleDragLeave = (0, import_react20.useCallback)(() => {
6777
6806
  setDragOverPosition(null);
6778
6807
  }, []);
6779
- const handleMouseMove = (0, import_react17.useCallback)(
6808
+ const handleMouseMove = (0, import_react20.useCallback)(
6780
6809
  (event) => {
6781
6810
  const connectionModeEnabled = features.connectionMode ?? false;
6782
6811
  if (connectionModeEnabled) {
@@ -7086,9 +7115,10 @@ function PIDCanvas({
7086
7115
  }
7087
7116
  );
7088
7117
  }
7118
+ var PIDCanvas = import_react20.default.memo(PIDCanvasImpl);
7089
7119
 
7090
7120
  // src/components/SymbolLibrary/SymbolLibrary.tsx
7091
- var import_react18 = require("react");
7121
+ var import_react21 = require("react");
7092
7122
  var import_jsx_runtime21 = require("react/jsx-runtime");
7093
7123
  function SymbolLibrary({
7094
7124
  className = "",
@@ -7096,8 +7126,8 @@ function SymbolLibrary({
7096
7126
  showCategories = true,
7097
7127
  categories = ["Valves", "Pumps", "Tanks", "Instruments", "Displays"]
7098
7128
  }) {
7099
- const [selectedCategory, setSelectedCategory] = (0, import_react18.useState)("all");
7100
- const [searchQuery, setSearchQuery] = (0, import_react18.useState)("");
7129
+ const [selectedCategory, setSelectedCategory] = (0, import_react21.useState)("all");
7130
+ const [searchQuery, setSearchQuery] = (0, import_react21.useState)("");
7101
7131
  const symbolIds = getAvailableSymbols();
7102
7132
  const allSymbols = symbolIds.map((id) => getSymbolDefinition(id)).filter((symbol) => symbol !== void 0);
7103
7133
  const categoryMap = {
@@ -8148,13 +8178,13 @@ function createControlBinding(nodeId, deviceConfig, actions) {
8148
8178
  }
8149
8179
 
8150
8180
  // src/hooks/useDeviceControls.ts
8151
- var import_react19 = require("react");
8181
+ var import_react22 = require("react");
8152
8182
  function commandKey(nodeId, kind, suffix) {
8153
8183
  return suffix ? `${nodeId}:${kind}:${suffix}` : `${nodeId}:${kind}`;
8154
8184
  }
8155
8185
  function useDeviceControls(initialBindings, options) {
8156
8186
  const { commandTimeoutMs } = options ?? {};
8157
- const [controls, setControls] = (0, import_react19.useState)(() => {
8187
+ const [controls, setControls] = (0, import_react22.useState)(() => {
8158
8188
  const map = /* @__PURE__ */ new Map();
8159
8189
  if (initialBindings) {
8160
8190
  initialBindings.forEach((binding) => {
@@ -8163,12 +8193,12 @@ function useDeviceControls(initialBindings, options) {
8163
8193
  }
8164
8194
  return map;
8165
8195
  });
8166
- const pendingRef = (0, import_react19.useRef)(/* @__PURE__ */ new Map());
8167
- const [pendingCommands, setPendingCommands] = (0, import_react19.useState)(() => /* @__PURE__ */ new Set());
8168
- const syncPending = (0, import_react19.useCallback)(() => {
8196
+ const pendingRef = (0, import_react22.useRef)(/* @__PURE__ */ new Map());
8197
+ const [pendingCommands, setPendingCommands] = (0, import_react22.useState)(() => /* @__PURE__ */ new Set());
8198
+ const syncPending = (0, import_react22.useCallback)(() => {
8169
8199
  setPendingCommands(new Set(pendingRef.current.keys()));
8170
8200
  }, []);
8171
- const updateControl = (0, import_react19.useCallback)((nodeId, updates) => {
8201
+ const updateControl = (0, import_react22.useCallback)((nodeId, updates) => {
8172
8202
  setControls((prev) => {
8173
8203
  const newMap = new Map(prev);
8174
8204
  const existing = newMap.get(nodeId);
@@ -8182,7 +8212,7 @@ function useDeviceControls(initialBindings, options) {
8182
8212
  return newMap;
8183
8213
  });
8184
8214
  }, []);
8185
- const updateControlBatch = (0, import_react19.useCallback)((updates) => {
8215
+ const updateControlBatch = (0, import_react22.useCallback)((updates) => {
8186
8216
  setControls((prev) => {
8187
8217
  const newMap = new Map(prev);
8188
8218
  Object.entries(updates).forEach(([nodeId, update]) => {
@@ -8194,7 +8224,7 @@ function useDeviceControls(initialBindings, options) {
8194
8224
  return newMap;
8195
8225
  });
8196
8226
  }, []);
8197
- const updateDeviceState = (0, import_react19.useCallback)(
8227
+ const updateDeviceState = (0, import_react22.useCallback)(
8198
8228
  (nodeId, stateUpdates) => {
8199
8229
  setControls((prev) => {
8200
8230
  const newMap = new Map(prev);
@@ -8210,7 +8240,7 @@ function useDeviceControls(initialBindings, options) {
8210
8240
  },
8211
8241
  []
8212
8242
  );
8213
- const updateParameter = (0, import_react19.useCallback)(
8243
+ const updateParameter = (0, import_react22.useCallback)(
8214
8244
  (nodeId, parameterId, value) => {
8215
8245
  setControls((prev) => {
8216
8246
  const newMap = new Map(prev);
@@ -8237,27 +8267,27 @@ function useDeviceControls(initialBindings, options) {
8237
8267
  },
8238
8268
  []
8239
8269
  );
8240
- const setControlBinding = (0, import_react19.useCallback)((binding) => {
8270
+ const setControlBinding = (0, import_react22.useCallback)((binding) => {
8241
8271
  setControls((prev) => {
8242
8272
  const newMap = new Map(prev);
8243
8273
  newMap.set(binding.nodeId, binding);
8244
8274
  return newMap;
8245
8275
  });
8246
8276
  }, []);
8247
- const removeControlBinding = (0, import_react19.useCallback)((nodeId) => {
8277
+ const removeControlBinding = (0, import_react22.useCallback)((nodeId) => {
8248
8278
  setControls((prev) => {
8249
8279
  const newMap = new Map(prev);
8250
8280
  newMap.delete(nodeId);
8251
8281
  return newMap;
8252
8282
  });
8253
8283
  }, []);
8254
- const getControlBinding = (0, import_react19.useCallback)(
8284
+ const getControlBinding = (0, import_react22.useCallback)(
8255
8285
  (nodeId) => {
8256
8286
  return controls.get(nodeId);
8257
8287
  },
8258
8288
  [controls]
8259
8289
  );
8260
- const isCommandPending = (0, import_react19.useCallback)(
8290
+ const isCommandPending = (0, import_react22.useCallback)(
8261
8291
  (nodeId, kind) => {
8262
8292
  if (kind) {
8263
8293
  const prefix2 = `${nodeId}:${kind}`;
@@ -8274,7 +8304,7 @@ function useDeviceControls(initialBindings, options) {
8274
8304
  },
8275
8305
  [pendingCommands]
8276
8306
  );
8277
- const markPending = (0, import_react19.useCallback)(
8307
+ const markPending = (0, import_react22.useCallback)(
8278
8308
  (key, delta) => {
8279
8309
  const next = (pendingRef.current.get(key) ?? 0) + delta;
8280
8310
  if (next > 0) pendingRef.current.set(key, next);
@@ -8283,7 +8313,7 @@ function useDeviceControls(initialBindings, options) {
8283
8313
  },
8284
8314
  [syncPending]
8285
8315
  );
8286
- const runCommand = (0, import_react19.useCallback)(
8316
+ const runCommand = (0, import_react22.useCallback)(
8287
8317
  async (nodeId, key, invoke, messages) => {
8288
8318
  const binding = controls.get(nodeId);
8289
8319
  if (!binding) return;
@@ -8323,7 +8353,7 @@ function useDeviceControls(initialBindings, options) {
8323
8353
  },
8324
8354
  [controls, updateDeviceState, markPending, commandTimeoutMs]
8325
8355
  );
8326
- const sendModeChange = (0, import_react19.useCallback)(
8356
+ const sendModeChange = (0, import_react22.useCallback)(
8327
8357
  (nodeId, mode) => runCommand(
8328
8358
  nodeId,
8329
8359
  commandKey(nodeId, "mode"),
@@ -8332,7 +8362,7 @@ function useDeviceControls(initialBindings, options) {
8332
8362
  ),
8333
8363
  [runCommand]
8334
8364
  );
8335
- const sendParameterChange = (0, import_react19.useCallback)(
8365
+ const sendParameterChange = (0, import_react22.useCallback)(
8336
8366
  (nodeId, parameterId, value) => runCommand(
8337
8367
  nodeId,
8338
8368
  commandKey(nodeId, "parameter", parameterId),
@@ -8341,21 +8371,21 @@ function useDeviceControls(initialBindings, options) {
8341
8371
  ),
8342
8372
  [runCommand]
8343
8373
  );
8344
- const sendStartCommand = (0, import_react19.useCallback)(
8374
+ const sendStartCommand = (0, import_react22.useCallback)(
8345
8375
  (nodeId) => runCommand(nodeId, commandKey(nodeId, "start"), (binding) => binding.actions.onStart?.(), {
8346
8376
  success: "Start command sent",
8347
8377
  failure: "Start command failed"
8348
8378
  }),
8349
8379
  [runCommand]
8350
8380
  );
8351
- const sendStopCommand = (0, import_react19.useCallback)(
8381
+ const sendStopCommand = (0, import_react22.useCallback)(
8352
8382
  (nodeId) => runCommand(nodeId, commandKey(nodeId, "stop"), (binding) => binding.actions.onStop?.(), {
8353
8383
  success: "Stop command sent",
8354
8384
  failure: "Stop command failed"
8355
8385
  }),
8356
8386
  [runCommand]
8357
8387
  );
8358
- const sendCustomAction = (0, import_react19.useCallback)(
8388
+ const sendCustomAction = (0, import_react22.useCallback)(
8359
8389
  (nodeId, actionId) => runCommand(
8360
8390
  nodeId,
8361
8391
  commandKey(nodeId, "action", actionId),
@@ -8408,9 +8438,9 @@ function createConfigBinding(nodeId, tag, parameters, actions, options) {
8408
8438
  }
8409
8439
 
8410
8440
  // src/hooks/useDeviceConfigs.ts
8411
- var import_react20 = require("react");
8441
+ var import_react23 = require("react");
8412
8442
  function useDeviceConfigs(initialConfigs) {
8413
- const [configs, setConfigs] = (0, import_react20.useState)(() => {
8443
+ const [configs, setConfigs] = (0, import_react23.useState)(() => {
8414
8444
  const map = /* @__PURE__ */ new Map();
8415
8445
  if (initialConfigs) {
8416
8446
  initialConfigs.forEach((config) => {
@@ -8419,13 +8449,13 @@ function useDeviceConfigs(initialConfigs) {
8419
8449
  }
8420
8450
  return map;
8421
8451
  });
8422
- const getConfig = (0, import_react20.useCallback)(
8452
+ const getConfig = (0, import_react23.useCallback)(
8423
8453
  (nodeId) => {
8424
8454
  return configs.get(nodeId);
8425
8455
  },
8426
8456
  [configs]
8427
8457
  );
8428
- const updateConfig = (0, import_react20.useCallback)((nodeId, updates) => {
8458
+ const updateConfig = (0, import_react23.useCallback)((nodeId, updates) => {
8429
8459
  setConfigs((prev) => {
8430
8460
  const newMap = new Map(prev);
8431
8461
  const existing = newMap.get(nodeId);
@@ -8439,7 +8469,7 @@ function useDeviceConfigs(initialConfigs) {
8439
8469
  return newMap;
8440
8470
  });
8441
8471
  }, []);
8442
- const updateConfigState = (0, import_react20.useCallback)((nodeId, stateUpdates) => {
8472
+ const updateConfigState = (0, import_react23.useCallback)((nodeId, stateUpdates) => {
8443
8473
  setConfigs((prev) => {
8444
8474
  const newMap = new Map(prev);
8445
8475
  const existing = newMap.get(nodeId);
@@ -8452,7 +8482,7 @@ function useDeviceConfigs(initialConfigs) {
8452
8482
  return newMap;
8453
8483
  });
8454
8484
  }, []);
8455
- const updateConfigBatch = (0, import_react20.useCallback)((updates) => {
8485
+ const updateConfigBatch = (0, import_react23.useCallback)((updates) => {
8456
8486
  setConfigs((prev) => {
8457
8487
  const newMap = new Map(prev);
8458
8488
  Object.entries(updates).forEach(([nodeId, update]) => {
@@ -8464,7 +8494,7 @@ function useDeviceConfigs(initialConfigs) {
8464
8494
  return newMap;
8465
8495
  });
8466
8496
  }, []);
8467
- const updateParameterValue = (0, import_react20.useCallback)((nodeId, parameterId, value) => {
8497
+ const updateParameterValue = (0, import_react23.useCallback)((nodeId, parameterId, value) => {
8468
8498
  setConfigs((prev) => {
8469
8499
  const newMap = new Map(prev);
8470
8500
  const existing = newMap.get(nodeId);
@@ -8481,7 +8511,7 @@ function useDeviceConfigs(initialConfigs) {
8481
8511
  return newMap;
8482
8512
  });
8483
8513
  }, []);
8484
- const applyConfig = (0, import_react20.useCallback)(
8514
+ const applyConfig = (0, import_react23.useCallback)(
8485
8515
  async (nodeId) => {
8486
8516
  const config = configs.get(nodeId);
8487
8517
  if (!config || !config.actions.onApply) {
@@ -8514,7 +8544,7 @@ function useDeviceConfigs(initialConfigs) {
8514
8544
  },
8515
8545
  [configs, updateConfigState]
8516
8546
  );
8517
- const saveConfig = (0, import_react20.useCallback)(
8547
+ const saveConfig = (0, import_react23.useCallback)(
8518
8548
  async (nodeId) => {
8519
8549
  const config = configs.get(nodeId);
8520
8550
  if (!config || !config.actions.onSave) {
@@ -8548,7 +8578,7 @@ function useDeviceConfigs(initialConfigs) {
8548
8578
  },
8549
8579
  [configs, updateConfigState]
8550
8580
  );
8551
- const resetConfig = (0, import_react20.useCallback)(
8581
+ const resetConfig = (0, import_react23.useCallback)(
8552
8582
  async (nodeId) => {
8553
8583
  const config = configs.get(nodeId);
8554
8584
  if (!config) {
@@ -8578,7 +8608,7 @@ function useDeviceConfigs(initialConfigs) {
8578
8608
  },
8579
8609
  [configs, updateConfig, updateConfigState]
8580
8610
  );
8581
- const cancelConfig = (0, import_react20.useCallback)(
8611
+ const cancelConfig = (0, import_react23.useCallback)(
8582
8612
  (nodeId) => {
8583
8613
  const config = configs.get(nodeId);
8584
8614
  if (config?.actions.onCancel) {
@@ -8587,7 +8617,7 @@ function useDeviceConfigs(initialConfigs) {
8587
8617
  },
8588
8618
  [configs]
8589
8619
  );
8590
- const validateConfig = (0, import_react20.useCallback)(
8620
+ const validateConfig = (0, import_react23.useCallback)(
8591
8621
  (nodeId) => {
8592
8622
  const config = configs.get(nodeId);
8593
8623
  if (!config) {
@@ -8629,21 +8659,21 @@ function useDeviceConfigs(initialConfigs) {
8629
8659
  },
8630
8660
  [configs, updateConfigState]
8631
8661
  );
8632
- const setConfig = (0, import_react20.useCallback)((config) => {
8662
+ const setConfig = (0, import_react23.useCallback)((config) => {
8633
8663
  setConfigs((prev) => {
8634
8664
  const newMap = new Map(prev);
8635
8665
  newMap.set(config.nodeId, config);
8636
8666
  return newMap;
8637
8667
  });
8638
8668
  }, []);
8639
- const removeConfig = (0, import_react20.useCallback)((nodeId) => {
8669
+ const removeConfig = (0, import_react23.useCallback)((nodeId) => {
8640
8670
  setConfigs((prev) => {
8641
8671
  const newMap = new Map(prev);
8642
8672
  newMap.delete(nodeId);
8643
8673
  return newMap;
8644
8674
  });
8645
8675
  }, []);
8646
- const clearConfigs = (0, import_react20.useCallback)(() => {
8676
+ const clearConfigs = (0, import_react23.useCallback)(() => {
8647
8677
  setConfigs(/* @__PURE__ */ new Map());
8648
8678
  }, []);
8649
8679
  return {
@@ -8665,9 +8695,9 @@ function useDeviceConfigs(initialConfigs) {
8665
8695
  }
8666
8696
 
8667
8697
  // src/components/DeviceConfigPanel/DeviceConfigPanel.tsx
8668
- var import_react21 = require("react");
8698
+ var import_react24 = __toESM(require("react"), 1);
8669
8699
  var import_jsx_runtime23 = require("react/jsx-runtime");
8670
- function DeviceConfigPanel({
8700
+ function DeviceConfigPanelImpl({
8671
8701
  binding,
8672
8702
  onClose,
8673
8703
  onUndock,
@@ -8684,7 +8714,7 @@ function DeviceConfigPanel({
8684
8714
  showControlsButton = true,
8685
8715
  embedded = false
8686
8716
  }) {
8687
- const [localValues, setLocalValues] = (0, import_react21.useState)(() => {
8717
+ const [localValues, setLocalValues] = (0, import_react24.useState)(() => {
8688
8718
  if (binding) {
8689
8719
  const values = {};
8690
8720
  binding.parameters.forEach((param) => {
@@ -8694,7 +8724,7 @@ function DeviceConfigPanel({
8694
8724
  }
8695
8725
  return {};
8696
8726
  });
8697
- const [collapsedSections, setCollapsedSections] = (0, import_react21.useState)(() => {
8727
+ const [collapsedSections, setCollapsedSections] = (0, import_react24.useState)(() => {
8698
8728
  const collapsed = /* @__PURE__ */ new Set();
8699
8729
  if (binding?.sections) {
8700
8730
  binding.sections.forEach((section) => {
@@ -8705,9 +8735,9 @@ function DeviceConfigPanel({
8705
8735
  }
8706
8736
  return collapsed;
8707
8737
  });
8708
- const [showToast, setShowToast] = (0, import_react21.useState)(true);
8709
- const [bindingId, setBindingId] = (0, import_react21.useState)(binding?.nodeId || null);
8710
- const lastResultTimestampRef = (0, import_react21.useRef)(0);
8738
+ const [showToast, setShowToast] = (0, import_react24.useState)(true);
8739
+ const [bindingId, setBindingId] = (0, import_react24.useState)(binding?.nodeId || null);
8740
+ const lastResultTimestampRef = (0, import_react24.useRef)(0);
8711
8741
  if (binding && binding.nodeId !== bindingId) {
8712
8742
  const values = {};
8713
8743
  binding.parameters.forEach((param) => {
@@ -8723,7 +8753,7 @@ function DeviceConfigPanel({
8723
8753
  setCollapsedSections(collapsed);
8724
8754
  setBindingId(binding.nodeId);
8725
8755
  }
8726
- (0, import_react21.useEffect)(() => {
8756
+ (0, import_react24.useEffect)(() => {
8727
8757
  const currentTimestamp = binding?.state.lastSaved || 0;
8728
8758
  if (binding?.state.lastSaveResult && currentTimestamp !== lastResultTimestampRef.current) {
8729
8759
  lastResultTimestampRef.current = currentTimestamp;
@@ -8740,7 +8770,7 @@ function DeviceConfigPanel({
8740
8770
  };
8741
8771
  }
8742
8772
  }, [binding?.state.lastSaveResult, binding?.state.lastSaved, toastDuration]);
8743
- const parametersBySection = (0, import_react21.useMemo)(() => {
8773
+ const parametersBySection = (0, import_react24.useMemo)(() => {
8744
8774
  if (!binding) return { _unsectioned: [] };
8745
8775
  const groups = { _unsectioned: [] };
8746
8776
  binding.parameters.forEach((param) => {
@@ -8755,7 +8785,7 @@ function DeviceConfigPanel({
8755
8785
  });
8756
8786
  return groups;
8757
8787
  }, [binding]);
8758
- const sortedSections = (0, import_react21.useMemo)(() => {
8788
+ const sortedSections = (0, import_react24.useMemo)(() => {
8759
8789
  if (!binding?.sections) return [];
8760
8790
  return [...binding.sections].sort((a, b) => (a.order || 0) - (b.order || 0));
8761
8791
  }, [binding]);
@@ -9369,9 +9399,10 @@ function DeviceConfigPanel({
9369
9399
  )
9370
9400
  ] });
9371
9401
  }
9402
+ var DeviceConfigPanel = import_react24.default.memo(DeviceConfigPanelImpl);
9372
9403
 
9373
9404
  // src/diagram/hooks/useSimulation.ts
9374
- var import_react22 = require("react");
9405
+ var import_react25 = require("react");
9375
9406
  function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
9376
9407
  const {
9377
9408
  interval = 2e3,
@@ -9382,7 +9413,7 @@ function useSimulation(telemetry, updateTelemetryBatch, options = {}) {
9382
9413
  historyLength = 10,
9383
9414
  generateValue
9384
9415
  } = options;
9385
- (0, import_react22.useEffect)(() => {
9416
+ (0, import_react25.useEffect)(() => {
9386
9417
  if (!enabled) return;
9387
9418
  const intervalId = setInterval(() => {
9388
9419
  const updates = [];