@mp70/react-networks 0.1.1-alpha → 0.1.4-alpha

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.css CHANGED
@@ -90,3 +90,39 @@
90
90
  background-color: #e9ecef;
91
91
  }
92
92
 
93
+ /* React Networks Attribution */
94
+ .react-networks-attribution {
95
+ padding: 0;
96
+ margin: 0;
97
+ z-index: 1000;
98
+ }
99
+
100
+ .react-networks-attribution-link {
101
+ font-size: 7px;
102
+ color: #9ca3af;
103
+ text-decoration: none;
104
+ font-family: Inter, system-ui, -apple-system, sans-serif;
105
+ transition: color 0.2s ease;
106
+ padding: 1px 4px;
107
+ border-radius: 2px;
108
+ display: inline-block;
109
+ background: rgba(0, 0, 0, 0.3);
110
+ backdrop-filter: blur(4px);
111
+ }
112
+
113
+ .react-networks-attribution-link:hover {
114
+ color: #e5e7eb;
115
+ background: rgba(0, 0, 0, 0.4);
116
+ }
117
+
118
+ /* Light mode attribution */
119
+ .react-flow-light .react-networks-attribution-link {
120
+ color: #6b7280;
121
+ background: rgba(255, 255, 255, 0.6);
122
+ }
123
+
124
+ .react-flow-light .react-networks-attribution-link:hover {
125
+ color: #1a1a1a;
126
+ background: rgba(255, 255, 255, 0.8);
127
+ }
128
+
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import React$1 from 'react';
2
- import { NodeProps, EdgeProps } from 'reactflow';
2
+ import { NodeProps, EdgeProps, Edge, Connection } from 'reactflow';
3
3
 
4
4
  /**
5
5
  * Rack device width configuration
@@ -285,6 +285,8 @@ interface NetworkDiagramProps {
285
285
  onFlowMethods?: (methods: {
286
286
  toObject: () => any;
287
287
  setViewport: (viewport: any) => void;
288
+ setNodes: (nodes: any[]) => void;
289
+ setEdges: (edges: any[]) => void;
288
290
  toImage: (options?: any) => Promise<string>;
289
291
  }) => void;
290
292
  /** Show download button */
@@ -502,7 +504,7 @@ interface DevicePlacementValidation {
502
504
  /**
503
505
  * Validate device placements within a rack schema
504
506
  */
505
- declare function validateRackDevicePlacements(rack: RackConfig, options?: RackSchemaOptions): DevicePlacementValidation;
507
+ declare function validateRackDevicePlacements(rack: RackConfig, _options?: RackSchemaOptions): DevicePlacementValidation;
506
508
  /**
507
509
  * Build NetworkNode array from RackConfig array with comprehensive validation
508
510
  */
@@ -567,6 +569,74 @@ declare function getPDUPortType(portIndex: number): string;
567
569
  */
568
570
  declare function getDeviceConnectorType(deviceName: string): string;
569
571
 
572
+ /**
573
+ * Get the color code for a device status
574
+ * @param status - The device status
575
+ * @returns Hex color code for the status
576
+ * @public
577
+ */
578
+ declare function getStatusColor(status: DeviceStatus | string): string;
579
+
580
+ /**
581
+ * Calculate the bounding box of a rack node
582
+ * @param rack - The rack node
583
+ * @returns Object with left, right, top, and bottom coordinates
584
+ * @public
585
+ */
586
+ declare function getRackBounds(rack: NetworkNode): {
587
+ left: number;
588
+ right: number;
589
+ top: number;
590
+ bottom: number;
591
+ };
592
+ /**
593
+ * Check if a point is inside a rack's bounds
594
+ * @param point - The point coordinates { x, y }
595
+ * @param rack - The rack node
596
+ * @returns True if the point is inside the rack
597
+ * @public
598
+ */
599
+ declare function isPointInRack(point: {
600
+ x: number;
601
+ y: number;
602
+ }, rack: NetworkNode): boolean;
603
+ /**
604
+ * Find the nearest rack to a point from a list of racks
605
+ * Only considers racks that contain the point
606
+ * @param point - The point coordinates { x, y }
607
+ * @param racks - Array of rack nodes
608
+ * @returns The nearest rack node, or null if no rack contains the point
609
+ * @public
610
+ */
611
+ declare function findNearestRack(point: {
612
+ x: number;
613
+ y: number;
614
+ }, racks: NetworkNode[]): NetworkNode | null;
615
+
616
+ /**
617
+ * Options for replacing an edge in the edges array
618
+ */
619
+ interface ReplaceEdgeOptions {
620
+ /** Existing edges array */
621
+ edges: Edge[];
622
+ /** Connection parameters for the new edge */
623
+ connection: Connection;
624
+ /** Type of edge to create */
625
+ edgeType: 'power' | 'fiber';
626
+ /** Function to calculate zIndex for the edge */
627
+ selectEdgeZIndex: (edge: NetworkEdge) => number;
628
+ /** Whether to find edge by source or target */
629
+ findBy: 'source' | 'target';
630
+ }
631
+ /**
632
+ * Replace an existing edge with a new connection
633
+ * This is used for PDU and switch connections that allow replacing existing edges
634
+ * @param options - Options for edge replacement
635
+ * @returns New edges array with the edge replaced, or null if no existing edge found
636
+ * @public
637
+ */
638
+ declare function replaceEdge(options: ReplaceEdgeOptions): Edge[] | null;
639
+
570
640
  interface NetworkDiagramState {
571
641
  nodes: NetworkNode[];
572
642
  edges: NetworkEdge[];
@@ -600,4 +670,4 @@ declare function useNetworkDiagram(store: NetworkDiagramStore): NetworkDiagramSt
600
670
  declare function useNodes(store: NetworkDiagramStore): NetworkNode[];
601
671
  declare function useEdges(store: NetworkDiagramStore): NetworkEdge[];
602
672
 
603
- export { DeviceNode, DevicePlacementError, type DevicePlacementValidation, type FiberCable, FiberEdge, FiberNode, NetworkDiagram, type NetworkDiagramProps, type NetworkEdge, type NetworkNode, POWER_CONNECTORS, PowerEdge, type RackConfig, type RackDevice, RackNode, type RackSchemaOptions, VerticalPDU, Width, addDeviceToRack, buildNodesFromRackConfig, calculateDevicePositionFromU, createNetworkDiagramStore, createRackConfigFromNodes, findNextAvailableUPosition, generateLayout, getConnectorConfig, getDeviceConnectorType, getPDUPortType, getPowerPortStyle, inventoryCableToNetworkEdge, inventoryDeviceToNetworkNode, inventoryRackToNetworkNode, inventoryToNetworkDiagram, isHighPowerConnector, isUPositionAvailable, removeDeviceFromRack, snapToUPosition, updateDeviceUPosition$1 as updateDeviceUPosition, updateDeviceUPosition as updateDeviceUPositionInSchema, useEdges as useDiagramEdges, useNodes as useDiagramNodes, useNetworkDiagram, validateAndSnapDevice, validateRackDevicePlacements };
673
+ export { DeviceNode, DevicePlacementError, type DevicePlacementValidation, type FiberCable, FiberEdge, FiberNode, NetworkDiagram, type NetworkDiagramProps, type NetworkEdge, type NetworkNode, POWER_CONNECTORS, type Port, type PortBlock, PowerEdge, type RackConfig, type RackDevice, RackNode, type RackSchemaOptions, type ReplaceEdgeOptions, VerticalPDU, Width, addDeviceToRack, buildNodesFromRackConfig, calculateDevicePositionFromU, createNetworkDiagramStore, createRackConfigFromNodes, findNearestRack, findNextAvailableUPosition, generateLayout, getConnectorConfig, getDeviceConnectorType, getPDUPortType, getPowerPortStyle, getRackBounds, getStatusColor, inventoryCableToNetworkEdge, inventoryDeviceToNetworkNode, inventoryRackToNetworkNode, inventoryToNetworkDiagram, isHighPowerConnector, isPointInRack, isUPositionAvailable, removeDeviceFromRack, replaceEdge, snapToUPosition, updateDeviceUPosition$1 as updateDeviceUPosition, updateDeviceUPosition as updateDeviceUPositionInSchema, useEdges as useDiagramEdges, useNodes as useDiagramNodes, useNetworkDiagram, validateAndSnapDevice, validateRackDevicePlacements };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import React$1 from 'react';
2
- import { NodeProps, EdgeProps } from 'reactflow';
2
+ import { NodeProps, EdgeProps, Edge, Connection } from 'reactflow';
3
3
 
4
4
  /**
5
5
  * Rack device width configuration
@@ -285,6 +285,8 @@ interface NetworkDiagramProps {
285
285
  onFlowMethods?: (methods: {
286
286
  toObject: () => any;
287
287
  setViewport: (viewport: any) => void;
288
+ setNodes: (nodes: any[]) => void;
289
+ setEdges: (edges: any[]) => void;
288
290
  toImage: (options?: any) => Promise<string>;
289
291
  }) => void;
290
292
  /** Show download button */
@@ -502,7 +504,7 @@ interface DevicePlacementValidation {
502
504
  /**
503
505
  * Validate device placements within a rack schema
504
506
  */
505
- declare function validateRackDevicePlacements(rack: RackConfig, options?: RackSchemaOptions): DevicePlacementValidation;
507
+ declare function validateRackDevicePlacements(rack: RackConfig, _options?: RackSchemaOptions): DevicePlacementValidation;
506
508
  /**
507
509
  * Build NetworkNode array from RackConfig array with comprehensive validation
508
510
  */
@@ -567,6 +569,74 @@ declare function getPDUPortType(portIndex: number): string;
567
569
  */
568
570
  declare function getDeviceConnectorType(deviceName: string): string;
569
571
 
572
+ /**
573
+ * Get the color code for a device status
574
+ * @param status - The device status
575
+ * @returns Hex color code for the status
576
+ * @public
577
+ */
578
+ declare function getStatusColor(status: DeviceStatus | string): string;
579
+
580
+ /**
581
+ * Calculate the bounding box of a rack node
582
+ * @param rack - The rack node
583
+ * @returns Object with left, right, top, and bottom coordinates
584
+ * @public
585
+ */
586
+ declare function getRackBounds(rack: NetworkNode): {
587
+ left: number;
588
+ right: number;
589
+ top: number;
590
+ bottom: number;
591
+ };
592
+ /**
593
+ * Check if a point is inside a rack's bounds
594
+ * @param point - The point coordinates { x, y }
595
+ * @param rack - The rack node
596
+ * @returns True if the point is inside the rack
597
+ * @public
598
+ */
599
+ declare function isPointInRack(point: {
600
+ x: number;
601
+ y: number;
602
+ }, rack: NetworkNode): boolean;
603
+ /**
604
+ * Find the nearest rack to a point from a list of racks
605
+ * Only considers racks that contain the point
606
+ * @param point - The point coordinates { x, y }
607
+ * @param racks - Array of rack nodes
608
+ * @returns The nearest rack node, or null if no rack contains the point
609
+ * @public
610
+ */
611
+ declare function findNearestRack(point: {
612
+ x: number;
613
+ y: number;
614
+ }, racks: NetworkNode[]): NetworkNode | null;
615
+
616
+ /**
617
+ * Options for replacing an edge in the edges array
618
+ */
619
+ interface ReplaceEdgeOptions {
620
+ /** Existing edges array */
621
+ edges: Edge[];
622
+ /** Connection parameters for the new edge */
623
+ connection: Connection;
624
+ /** Type of edge to create */
625
+ edgeType: 'power' | 'fiber';
626
+ /** Function to calculate zIndex for the edge */
627
+ selectEdgeZIndex: (edge: NetworkEdge) => number;
628
+ /** Whether to find edge by source or target */
629
+ findBy: 'source' | 'target';
630
+ }
631
+ /**
632
+ * Replace an existing edge with a new connection
633
+ * This is used for PDU and switch connections that allow replacing existing edges
634
+ * @param options - Options for edge replacement
635
+ * @returns New edges array with the edge replaced, or null if no existing edge found
636
+ * @public
637
+ */
638
+ declare function replaceEdge(options: ReplaceEdgeOptions): Edge[] | null;
639
+
570
640
  interface NetworkDiagramState {
571
641
  nodes: NetworkNode[];
572
642
  edges: NetworkEdge[];
@@ -600,4 +670,4 @@ declare function useNetworkDiagram(store: NetworkDiagramStore): NetworkDiagramSt
600
670
  declare function useNodes(store: NetworkDiagramStore): NetworkNode[];
601
671
  declare function useEdges(store: NetworkDiagramStore): NetworkEdge[];
602
672
 
603
- export { DeviceNode, DevicePlacementError, type DevicePlacementValidation, type FiberCable, FiberEdge, FiberNode, NetworkDiagram, type NetworkDiagramProps, type NetworkEdge, type NetworkNode, POWER_CONNECTORS, PowerEdge, type RackConfig, type RackDevice, RackNode, type RackSchemaOptions, VerticalPDU, Width, addDeviceToRack, buildNodesFromRackConfig, calculateDevicePositionFromU, createNetworkDiagramStore, createRackConfigFromNodes, findNextAvailableUPosition, generateLayout, getConnectorConfig, getDeviceConnectorType, getPDUPortType, getPowerPortStyle, inventoryCableToNetworkEdge, inventoryDeviceToNetworkNode, inventoryRackToNetworkNode, inventoryToNetworkDiagram, isHighPowerConnector, isUPositionAvailable, removeDeviceFromRack, snapToUPosition, updateDeviceUPosition$1 as updateDeviceUPosition, updateDeviceUPosition as updateDeviceUPositionInSchema, useEdges as useDiagramEdges, useNodes as useDiagramNodes, useNetworkDiagram, validateAndSnapDevice, validateRackDevicePlacements };
673
+ export { DeviceNode, DevicePlacementError, type DevicePlacementValidation, type FiberCable, FiberEdge, FiberNode, NetworkDiagram, type NetworkDiagramProps, type NetworkEdge, type NetworkNode, POWER_CONNECTORS, type Port, type PortBlock, PowerEdge, type RackConfig, type RackDevice, RackNode, type RackSchemaOptions, type ReplaceEdgeOptions, VerticalPDU, Width, addDeviceToRack, buildNodesFromRackConfig, calculateDevicePositionFromU, createNetworkDiagramStore, createRackConfigFromNodes, findNearestRack, findNextAvailableUPosition, generateLayout, getConnectorConfig, getDeviceConnectorType, getPDUPortType, getPowerPortStyle, getRackBounds, getStatusColor, inventoryCableToNetworkEdge, inventoryDeviceToNetworkNode, inventoryRackToNetworkNode, inventoryToNetworkDiagram, isHighPowerConnector, isPointInRack, isUPositionAvailable, removeDeviceFromRack, replaceEdge, snapToUPosition, updateDeviceUPosition$1 as updateDeviceUPosition, updateDeviceUPosition as updateDeviceUPositionInSchema, useEdges as useDiagramEdges, useNodes as useDiagramNodes, useNetworkDiagram, validateAndSnapDevice, validateRackDevicePlacements };
package/dist/index.js CHANGED
@@ -1,2 +1,3 @@
1
- 'use strict';var Be=require('react'),reactflow=require('reactflow'),htmlToImage=require('html-to-image'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var Be__default=/*#__PURE__*/_interopDefault(Be);var ke=()=>"bottom-up",pt=t=>t.data.uNumberingDirection||ke(),vt=(t,e,o)=>o==="bottom-up"?e-t+1:t,Pt=(t,e,o)=>o==="bottom-up"?e-t+1:t;var Et=(t,e,o,i)=>{if(!t.parentId||t.parentId!==e.id)return o;let n=t.data.uHeight||1,a=e.data.uHeight||42,s=pt(e),d=60,l=o.y-d,u=Math.round(l/20)+1,y;s==="bottom-up"?y=vt(u,a,s)-n+1:y=vt(u,a,s);let f=a-n+1,N=Math.max(1,Math.min(f,y));if(s==="top-down"&&y<=1&&(N=1),!Tt(e,t,N,i)){let D=Dt(e,t,i,N);D!==N&&(N=D);}let U;if(s==="bottom-up"){let D=N+n-1,E=Pt(D,a,s);U=d+(E-1)*20-1;}else {let D=Pt(N,a,s);U=d+(D-1)*20-1;}return {x:o.x,y:U,uPosition:N}},Tt=(t,e,o,i)=>{let n=e.data.uHeight||1,a=t.data.uHeight||42;if(o<1||o+n-1>a)return false;let s=i.filter(d=>d.type==="device"&&d.parentId===t.id&&d.id!==e.id);for(let d of s){let l=d.data.uPosition||1,u=d.data.uHeight||1,y=o,f=o+n-1,N=l,U=l+u-1;if(y<=U&&f>=N)return false}return true},Dt=(t,e,o,i=1)=>{let n=e.data.uHeight||1,a=t.data.uHeight||42;for(let s=i;s<=a-n+1;s++)if(Tt(t,e,s,o))return s;return 1},mt=(t,e,o=1)=>{let i=60,n=pt(t),a=t.data.uHeight||42,s=Pt(e,a,n),d;if(n==="bottom-up"){let l=e+o-1,u=Pt(l,a,n);d=i+(u-1)*20-1;}else d=i+(s-1)*20-1;return {x:0,y:d}},Qt=(t,e,o)=>{let i=t.data.uHeight||1,n=mt(e,o,i);return {...t,position:n,data:{...t.data,uPosition:o}}},ve=(t,e)=>{let o=t.data.uPosition||1,i=t.data.uHeight||1,n=e.data.uHeight||42,a=Math.max(1,Math.min(n-i+1,o));return a!==o?Qt(t,e,a):t};var It=({data:t,selected:e,id:o,onViewChange:i,onRackFaceChange:n,isDragOver:a=false})=>{let{label:s,ports:d=0,status:l="active",uHeight:u=42,uPosition:y=1,face:f="front",customHeaderText:N}=t,{getNodes:U,setNodes:D}=reactflow.useReactFlow(),E=U(),[c,F]=Be.useState(true),X=()=>{let _=pt({data:t})==="bottom-up"?"top-down":"bottom-up";D(g=>g.map(T=>T.id===o?{...T,data:{...T.data,uNumberingDirection:_}}:T));},O=()=>{let h=f==="front"?"rear":"front";n?(n(o,h),i&&E.filter(g=>g.parentId===o).forEach(g=>{i(g.id,h);})):i?E.filter(g=>g.parentId===o).forEach(g=>{i(g.id,h);}):D(_=>_.map(g=>g.id===o?{...g,data:{...g.data,face:h}}:g.parentId===o?{...g,data:{...g.data,view:h}}:g));},V=h=>{switch(h){case "active":return "#10b981";case "inactive":return "#6b7280";case "maintenance":return "#f59e0b";default:return "#6b7280"}},et=()=>{let h=[],_=60,g=pt({data:t});for(let T=1;T<=u;T++){let v=_+(T-1)*20-4,R=vt(T,u,g);h.push(jsxRuntime.jsx("div",{style:{position:"absolute",left:"-35px",top:`${v}px`,background:"#374151",color:"#9ca3af",padding:"2px 4px",borderRadius:"2px",fontSize:"8px",fontWeight:"bold",width:"28px",textAlign:"center",border:"1px solid #4b5563",zIndex:10,height:`${20}px`,display:"flex",alignItems:"center",justifyContent:"center",lineHeight:1},children:R},T));}return h};return jsxRuntime.jsxs("div",{className:`rack-node ${e?"selected":""} ${a?"drag-over":""}`,style:{background:"transparent",border:`2px solid ${V(l)}`,borderRadius:"8px",padding:0,width:`${300}px`,height:`${60+u*20}px`,color:"white",fontFamily:"monospace",fontSize:"12px",boxShadow:a?"0 0 20px #3b82f6, 0 0 40px #3b82f6, 0 0 60px #3b82f6":e?"0 0 0 2px #3b82f6":"0 2px 4px rgba(0,0,0,0.1)",position:"relative",display:"flex",flexDirection:"column",transition:"box-shadow 0.2s ease-in-out"},children:[jsxRuntime.jsx(reactflow.Handle,{type:"target",position:reactflow.Position.Top}),jsxRuntime.jsxs("div",{style:{textAlign:"center",marginBottom:0,zIndex:2,background:"#1f2937",padding:"8px",position:"relative",height:`${60}px`,display:"flex",flexDirection:"column",justifyContent:"center"},children:[jsxRuntime.jsx("div",{style:{fontWeight:"bold",marginBottom:"4px"},children:s}),jsxRuntime.jsxs("div",{style:{fontSize:"10px",color:"#9ca3af"},children:[N?jsxRuntime.jsx("span",{style:{color:"#fbbf24",fontWeight:"bold"},children:N}):jsxRuntime.jsxs("span",{children:[typeof d=="number"?d:0," ports"]})," \u2022 ",u,"U \u2022 ",f]}),jsxRuntime.jsxs("div",{style:{display:"flex",gap:"4px",position:"absolute",top:"4px",right:"4px"},children:[jsxRuntime.jsx("button",{onPointerDown:h=>{h.stopPropagation();},onMouseDown:h=>{h.stopPropagation();},onClick:h=>{h.stopPropagation(),h.preventDefault(),F(!c);},style:{background:c?"#10b981":"#374151",color:c?"#ffffff":"#9ca3af",border:"1px solid #4b5563",borderRadius:"2px",padding:"2px 6px",fontSize:"8px",cursor:"pointer",fontFamily:"monospace"},title:`${c?"Hide":"Show"} U markers`,children:"U"}),jsxRuntime.jsx("button",{onPointerDown:h=>{h.stopPropagation();},onMouseDown:h=>{h.stopPropagation();},onClick:h=>{h.stopPropagation(),h.preventDefault(),X();},style:{background:"#374151",color:"#9ca3af",border:"1px solid #4b5563",borderRadius:"2px",padding:"2px 6px",fontSize:"8px",cursor:"pointer",fontFamily:"monospace"},title:`Switch U numbering to ${pt({data:t})==="bottom-up"?"top-down":"bottom-up"}`,children:pt({data:t})==="bottom-up"?"\u2191\u2193":"\u2193\u2191"}),jsxRuntime.jsx("button",{onPointerDown:h=>{h.stopPropagation();},onMouseDown:h=>{h.stopPropagation();},onClick:h=>{h.stopPropagation(),h.preventDefault(),O();},style:{background:"#374151",color:"#9ca3af",border:"1px solid #4b5563",borderRadius:"2px",padding:"2px 6px",fontSize:"8px",cursor:"pointer",fontFamily:"monospace"},title:`Switch to ${f==="front"?"rear":"front"} view`,children:f==="front"?"\u21C4 Rear":"\u21C4 Front"})]})]}),jsxRuntime.jsx("div",{style:{flex:1,background:"transparent",position:"relative",minHeight:`${u*20}px`,overflow:"hidden"}}),c&&jsxRuntime.jsx("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,pointerEvents:"none"},children:et()})]})};var At=({data:t,selected:e})=>{let{label:o,status:i="active"}=t,n=a=>{switch(a){case "active":return "#10b981";case "inactive":return "#6b7280";case "maintenance":return "#f59e0b";default:return "#6b7280"}};return jsxRuntime.jsxs("div",{className:`fiber-node ${e?"selected":""}`,style:{background:"#1f2937",border:`2px solid ${n(i)}`,borderRadius:"50%",width:"60px",height:"60px",display:"flex",alignItems:"center",justifyContent:"center",color:"white",fontFamily:"monospace",fontSize:"10px",fontWeight:"bold",boxShadow:e?"0 0 0 2px #3b82f6":"0 2px 4px rgba(0,0,0,0.1)",position:"relative"},children:[jsxRuntime.jsx(reactflow.Handle,{type:"target",position:reactflow.Position.Top}),jsxRuntime.jsx(reactflow.Handle,{type:"source",position:reactflow.Position.Bottom}),jsxRuntime.jsx(reactflow.Handle,{type:"target",position:reactflow.Position.Left}),jsxRuntime.jsx(reactflow.Handle,{type:"source",position:reactflow.Position.Right}),jsxRuntime.jsx("div",{style:{textAlign:"center"},children:jsxRuntime.jsx("div",{style:{fontSize:"8px",lineHeight:"1.2"},children:o})}),jsxRuntime.jsx("div",{style:{position:"absolute",bottom:"4px",left:"50%",transform:"translateX(-50%)",width:"8px",height:"8px",background:n(i),borderRadius:"50%"}})]})};var Ft=({id:t,sourceX:e,sourceY:o,targetX:i,targetY:n,sourcePosition:a,targetPosition:s,data:d,selected:l,style:u={}})=>{let[y,f,N]=reactflow.getBezierPath({sourceX:e,sourceY:o,sourcePosition:a,targetX:i,targetY:n,targetPosition:s}),{bandwidth:U,length:D,color:E="#00FFFF"}=d||{},c={...u,stroke:E,strokeWidth:l?3:2,strokeDasharray:"none"};return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(reactflow.BaseEdge,{id:t,path:y,style:c}),jsxRuntime.jsx(reactflow.EdgeLabelRenderer,{children:l&&d&&(U||D)&&jsxRuntime.jsxs("div",{style:{position:"absolute",transform:`translate(-50%, -50%) translate(${f}px,${N}px)`,background:"#1f2937",padding:"4px 8px",borderRadius:"4px",fontSize:"10px",color:"white",fontFamily:"monospace",border:`1px solid ${E}`,pointerEvents:"none",zIndex:9999},children:[U&&jsxRuntime.jsx("div",{children:U}),D&&jsxRuntime.jsxs("div",{children:[D,"m"]})]})})]})};var Mt=({id:t,sourceX:e,sourceY:o,targetX:i,targetY:n,sourcePosition:a,targetPosition:s,style:d={},data:l,markerEnd:u})=>{let [y,f,N]=reactflow.getBezierPath({sourceX:e,sourceY:o,sourcePosition:a,targetX:i,targetY:n,targetPosition:s}),U=l?.connectorType||"C13";l?.voltage||"AC";l?.amperage||(U==="C19"?"16A":"10A");return jsxRuntime.jsx(reactflow.BaseEdge,{id:t,path:y,markerEnd:u,style:(()=>{let F={stroke:l?.color||"#f59e0b",strokeWidth:U==="C19"?5:3,strokeLinecap:"round",strokeLinejoin:"round",...d};return U==="C19"?{...F,strokeDasharray:"none"}:{...F,strokeDasharray:"6,3"}})()})};var te=(o=>(o.FULL="full",o.HALF="half",o))(te||{});var zt={C13:{type:"C13",color:"#f59e0b",borderColor:"#d97706",amperage:10,voltage:230,phases:1},C14:{type:"C14",color:"#f59e0b",borderColor:"#d97706",amperage:10,voltage:230,phases:1},C19:{type:"C19",color:"#fbbf24",borderColor:"#d97706",amperage:16,voltage:230,phases:1},C20:{type:"C20",color:"#fbbf24",borderColor:"#d97706",amperage:16,voltage:230,phases:1}};function ht(t){let e=zt[t];if(!e)throw new Error(`Unknown connector type: ${t}`);let o=e.amperage===16;e.amperage===10;let n=o?12:8,a=o?10:5,s=o?{borderRadius:"3px"}:{clipPath:"polygon(2px 0, calc(100% - 2px) 0, 100% 2px, 100% 100%, 0 100%, 0 2px)",borderRadius:"0px"};return {width:n,height:a,color:e.color,borderColor:e.borderColor,fontSize:o?"3px":"4px",...s}}function Rt(t){let e=zt[t];if(!e)throw new Error(`Unknown connector type: ${t}`);return e}function _e(t){return Rt(t).amperage===16}function Lt(t){return t%10<8?"C13":"C19"}function St(t){let e=t.toLowerCase();return e.includes("mx304")||e.includes("mx480")||e.includes("mx960")?"C20":"C14"}var Bt=({data:t,selected:e})=>{let{label:o,status:i="active",deviceType:n="server",manufacturer:a,role:s,uHeight:d=1,uPosition:l=1,width:u="full",ports:y=[],rearPorts:f=[],view:N,powerSide:U="left"}=t,D=N||(f.length>0&&y.length===0?"rear":"front"),E={};E["net-top"]="front",E["net-bottom"]="front",y.length>0&&y.forEach(g=>{g.ports.forEach(T=>{let v=T.type?.includes("power")?T.label:`${g.name}-${T.label}`;E[v]="front";});}),E["pwr-left-1"]="rear",E["pwr-left-2"]="rear",E["net-right-1"]="rear",E["net-right-2"]="rear",f.length>0&&f.forEach(g=>{g.ports.forEach(T=>{let v=T.type?.includes("power")?T.label:`${g.name}-${T.label}`;E[v]="rear";});});let c=d*20,F=u==="half"?"150px":"304px",X=u==="half"?"150px":void 0,O=g=>{switch(g){case "active":return "#10b981";case "inactive":return "#6b7280";case "maintenance":return "#f59e0b";default:return "#6b7280"}},et=(g,T)=>{let v=[];if(g.length===0)return v;let R=Math.max(4,Math.floor(c*.4)),rt=Math.max(2,Math.floor(c*.2));return g.forEach((b,I)=>{b.ports.forEach(($,A)=>{let H=!!$.type&&$.type.includes("power");if(T==="front"&&H)return;let j=H?`${$.label}`:`${b.name}-${$.label}`,J=$.connected,B="#6b7280";if(J)if($.type?.includes("power"))B=$.type==="power_c19"?"#fbbf24":"#f59e0b";else if($.type==="console"||$.type==="mgmt")B="#8b5cf6";else if($.type==="usb")B="#10b981";else switch($.cableType){case "smf":B="#fbbf24";break;case "cat6":B="#8b5cf6";break;case "om3":B="#06b6d4";break;case "om4":B="#8b5cf6";break;case "om5":B="#84cc16";break;case "cat5e":B="#3b82f6";break;case "cat6a":B="#ef4444";break;case "cat7":B="#f97316";break;case "fiber":B="#3b82f6";break;case "ethernet":B="#10b981";break;default:B="#10b981";}let nt=reactflow.Position.Top,M={width:`${R}px`,height:`${rt}px`,background:J?B:"#6b7280",border:`1px solid ${J?B:"#374151"}`,borderRadius:"1px",cursor:"pointer"};if(T==="front")A%2===0?(nt=reactflow.Position.Top,M.transform="translateY(50%)",M.left=`${A/2*(R+2)}px`):(nt=reactflow.Position.Bottom,M.transform="translateY(-50%)",M.left=`${(A-1)/2*(R+2)}px`);else if((n?.toLowerCase().replace(/_/g,"-")||"")==="patch-panel")A%2===0?(nt=reactflow.Position.Top,M.transform="translateY(50%)",M.left=`${A/2*(R+2)}px`):(nt=reactflow.Position.Bottom,M.transform="translateY(-50%)",M.left=`${(A-1)/2*(R+2)}px`);else if($.type?.includes("power")){nt=reactflow.Position.Left,M.transform="translateX(50%)";let st=c<=20?10:20,ot=c<=20?30:50;M.top=`${st+A*ot}%`;let Q=St(o),lt=ht(Q);M={...M,width:`${lt.width}px`,height:`${lt.height}px`,zIndex:10,display:"flex",alignItems:"center",justifyContent:"center",fontSize:lt.fontSize,color:"#1a1a1a",fontFamily:"monospace",fontWeight:"bold",borderRadius:lt.borderRadius,clipPath:lt.clipPath};}else nt=reactflow.Position.Right,M.transform="translateX(-50%)",M.top=`${25+A*50}%`;let gt;H?gt="target":n==="switch"||n==="router"?gt="source":gt=J?"source":"target",v.push(jsxRuntime.jsx(reactflow.Handle,{id:j,type:gt,position:nt,style:M,title:`${b.name} - ${$.label} ${J?"(connected)":"(disconnected)"}`,children:H?A+1:void 0},j));});}),v},h=()=>{let g=[],v=Math.max(4,Math.floor(c*.4)),R=Math.max(2,Math.floor(c*.2));if(D==="front"){if(y.length>0)return et(y,"front");if(n==="switch"&&(o.toLowerCase().includes("agg")||o.toLowerCase().includes("core")||s==="agg"||s==="core"))return _();g.push(jsxRuntime.jsx(reactflow.Handle,{id:"net-top",type:"target",position:reactflow.Position.Top,style:{width:`${v}px`,height:`${R}px`,background:"#10b981",border:"0.5px solid #059669",borderRadius:"1px",cursor:"pointer",transform:"translateY(50%)"},title:"Network Port (Top)"},"net-top")),g.push(jsxRuntime.jsx(reactflow.Handle,{id:"net-bottom",type:"target",position:reactflow.Position.Bottom,style:{width:`${v}px`,height:`${R}px`,background:"#10b981",border:"0.5px solid #059669",borderRadius:"1px",cursor:"pointer",transform:"translateY(-50%)"},title:"Network Port (Bottom)"},"net-bottom"));}else if(D==="rear"){if(f.length>0)return et(f,"rear");let rt=n==="switch",I=(n?.toLowerCase().replace(/_/g,"-")||"")==="patch-panel";if(!I){let $=St(o),A=Rt($),H=ht($),j=c<=20?"10%":"25%";g.push(jsxRuntime.jsx(reactflow.Handle,{id:"pwr-left-1",type:"target",position:reactflow.Position.Left,style:{width:`${H.width}px`,height:`${H.height}px`,background:H.color,border:`1px solid ${H.borderColor}`,cursor:"pointer",transform:"translateX(50%)",top:j,zIndex:10,display:"flex",alignItems:"center",justifyContent:"center",fontSize:H.fontSize,color:"#1a1a1a",fontFamily:"monospace",fontWeight:"bold",borderRadius:H.borderRadius,clipPath:H.clipPath},title:`Power Port 1 (${A.type}) - ${A.voltage}V, ${A.amperage}A`,children:"1"},"pwr-1"));let J=c<=20?"50%":"75%";g.push(jsxRuntime.jsx(reactflow.Handle,{id:"pwr-left-2",type:"target",position:reactflow.Position.Left,style:{width:`${H.width}px`,height:`${H.height}px`,background:H.color,border:`1px solid ${H.borderColor}`,cursor:"pointer",transform:"translateX(50%)",top:J,zIndex:10,display:"flex",alignItems:"center",justifyContent:"center",fontSize:H.fontSize,color:"#1a1a1a",fontFamily:"monospace",fontWeight:"bold",borderRadius:H.borderRadius,clipPath:H.clipPath},title:`Power Port 2 (${A.type}) - ${A.voltage}V, ${A.amperage}A`,children:"2"},"pwr-2"));}!rt&&!I&&(g.push(jsxRuntime.jsx(reactflow.Handle,{id:"net-right-1",type:"target",position:reactflow.Position.Right,style:{width:`${v}px`,height:`${R}px`,background:"#10b981",border:"0.5px solid #059669",borderRadius:"1px",cursor:"pointer",transform:"translateX(-50%)",top:"25%"},title:"Network Port 1 (Right)"},"net-right-1")),g.push(jsxRuntime.jsx(reactflow.Handle,{id:"net-right-2",type:"target",position:reactflow.Position.Right,style:{width:`${v}px`,height:`${R}px`,background:"#10b981",border:"0.5px solid #059669",borderRadius:"1px",cursor:"pointer",transform:"translateX(-50%)",top:"75%"},title:"Network Port 2 (Right)"},"net-right-2")));}return g},_=()=>{let g=[],v=Math.max(10,Math.floor(c*.45)),R=Math.max(5,Math.floor(c*.25));for(let b=1;b<=16;b++){let I=jsxRuntime.jsx(reactflow.Handle,{id:`port-${b}`,type:"source",position:reactflow.Position.Top,style:{width:`${v}px`,height:`${R}px`,background:"#10b981",border:"1px solid #059669",borderRadius:"2px",cursor:"pointer",transform:"translateY(50%)",zIndex:1e3,left:`${(b-1)*(v+2)}px`},title:`Port ${b}`},`port-${b}`);g.push(I);}for(let b=17;b<=32;b++){let I=b-16,$=jsxRuntime.jsx(reactflow.Handle,{id:`port-${b}`,type:"source",position:reactflow.Position.Bottom,style:{width:`${v}px`,height:`${R}px`,background:"#10b981",border:"1px solid #059669",borderRadius:"2px",cursor:"pointer",transform:"translateY(-50%)",zIndex:1e3,left:`${(I-1)*(v+2)}px`},title:`Port ${b}`},`port-${b}`);g.push($);}for(let b=1;b<=4;b++){let I=Math.max(4,Math.floor(c*.3)),$=Math.max(3,Math.floor(c*.15));g.push(jsxRuntime.jsx(reactflow.Handle,{id:`uplink-${b}`,type:"source",position:reactflow.Position.Right,style:{width:`${I}px`,height:`${$}px`,background:"#8b5cf6",border:"0.5px solid #7c3aed",borderRadius:"0.5px",cursor:"pointer",transform:"translateX(-50%)"},title:`Uplink ${b}`},`uplink-${b}`));}return g};return jsxRuntime.jsxs("div",{className:`device-node ${e?"selected":""}`,style:{background:"#1f2937",border:`1px solid ${O(i)}`,borderRadius:"2px",padding:"0px",width:F,...X&&{left:X},height:`${c}px`,color:"white",fontFamily:"monospace",fontSize:"8px",boxShadow:e?"0 0 0 1px #3b82f6":"0 1px 2px rgba(0,0,0,0.1)",position:"relative",display:"flex",flexDirection:"column",justifyContent:"center",cursor:"grab",marginBottom:"0px",boxSizing:"border-box",marginTop:"0px",marginLeft:"0px",marginRight:"0px"},children:[jsxRuntime.jsxs("div",{style:{textAlign:"center",flex:1,display:"flex",flexDirection:"column",justifyContent:"center",overflow:"hidden",padding:"2px"},children:[jsxRuntime.jsx("div",{style:{fontWeight:"bold",fontSize:"7px",lineHeight:"1.1",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},children:o}),d>1&&jsxRuntime.jsx("div",{style:{fontSize:"6px",color:"#9ca3af",lineHeight:"1"},children:a})]}),d>1&&jsxRuntime.jsxs("div",{style:{position:"absolute",bottom:"1px",right:"1px",background:"#374151",color:"#9ca3af",padding:"1px 2px",borderRadius:"1px",fontSize:"6px",lineHeight:"1"},children:[d,"U"]}),jsxRuntime.jsx("div",{style:{position:"absolute",bottom:"1px",left:"1px",width:"4px",height:"4px",background:O(i),borderRadius:"50%"}}),h()]})};var Ot=({data:t,selected:e,id:o})=>{let{label:i,status:n="active",heightCm:a=100,powerPorts:s=36,portTypes:d=[],widthPx:l=15,mgmt_unit:u}=t,y=D=>{switch(D){case "active":return "#10b981";case "inactive":return "#6b7280";case "maintenance":return "#f59e0b";default:return "#6b7280"}},f=a*4.2,N=()=>{let E=Math.ceil(s/10),c=Array(10).fill(0).map((b,I)=>I<8?"10A":"16A");for(let b=0,I=0;b<E;++b)for(let $=0;$<10&&I<s;++$,++I){c[$];}let g=[],T=15,rt=(f-T-3)/(s-9)*.5;for(let b=0;b<s;b++){let I=T-2+rt*b,$=`${b+1}`;if(u&&(u==="top"&&b===0||u==="middle"&&b===Math.floor(s/2)||u==="bottom"&&b===s-1)){g.push(U(I));continue}let H=Lt(b),j=ht(H),J=Math.round((l-j.width)/2-1);g.push(jsxRuntime.jsx(reactflow.Handle,{type:"source",position:reactflow.Position.Right,id:$,style:{position:"absolute",left:`${J}px`,top:`${I-j.height/2}px`,width:`${j.width}px`,height:`${j.height}px`,background:j.color,border:`1px solid ${j.borderColor}`,cursor:"pointer",zIndex:10,display:"flex",alignItems:"center",justifyContent:"center",fontSize:j.fontSize,color:"#1a1a1a",fontFamily:"monospace",fontWeight:"bold",borderRadius:j.borderRadius,clipPath:j.clipPath},title:`Power Port ${b+1} (${H})`,children:b+1},`handle-${$}`));}return g},U=D=>jsxRuntime.jsxs("div",{style:{position:"absolute",left:`${(l-16)/2}px`,top:`${D-12/2}px`,width:"16px",height:"12px",background:"#1a1a1a",border:"1px solid #374151",borderRadius:"1px",display:"flex",flexDirection:"column",padding:"1px",zIndex:10},children:[jsxRuntime.jsx("div",{style:{position:"absolute",left:"-10px",top:"1px",background:"#ffffff",border:"0.5px solid #6b7280",borderRadius:"0.5px",width:"8px",height:"10px",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"3px",color:"#10b981",fontFamily:"monospace",fontWeight:"bold",transform:"rotate(90deg)",transformOrigin:"center"},children:"APC"}),jsxRuntime.jsx(reactflow.Handle,{type:"source",position:reactflow.Position.Right,id:"mgmt-net-1",style:{width:"70%",height:"6px",background:"#10b981",border:"1px solid #059669",borderRadius:"1px",cursor:"pointer",zIndex:11,margin:"0 auto"},title:"Management Network Port"},"mgmt-net-1")]},"mgmt-unit");return jsxRuntime.jsxs("div",{className:`vertical-pdu-node ${e?"selected":""}`,style:{background:"linear-gradient(90deg, #2d3748 0%, #1a202c 50%, #2d3748 100%)",border:`1px solid ${y(n)}`,borderRadius:"2px",padding:0,width:`${l}px`,height:`${f}px`,color:"white",fontFamily:"monospace",fontSize:"12px",boxShadow:e?"0 0 0 2px #3b82f6":"0 1px 3px rgba(0,0,0,0.3)",position:"relative",display:"flex",flexDirection:"column"},children:[jsxRuntime.jsx("div",{style:{textAlign:"center",marginBottom:0,zIndex:2,background:"linear-gradient(90deg, #4a5568 0%, #2d3748 50%, #4a5568 100%)",padding:"2px",position:"relative",height:"20px",display:"flex",flexDirection:"column",justifyContent:"center",borderBottom:"1px solid #4a5568"},children:jsxRuntime.jsx("div",{style:{fontWeight:"bold",fontSize:"6px",color:"#e2e8f0"},children:i})}),jsxRuntime.jsx("div",{style:{flex:1,background:"linear-gradient(180deg, #2d3748 0%, #1a202c 50%, #2d3748 100%)",position:"relative",minHeight:`${f-20}px`,overflow:"hidden"},children:N()})]})};function ze(t,e){if(!t.source||!t.target||!t.sourceHandle||!t.targetHandle)return {valid:true};let o=e.edges.some(c=>c.source===t.source&&c.sourceHandle===t.sourceHandle),i=e.edges.some(c=>c.target===t.target&&c.targetHandle===t.targetHandle);if(o)return {valid:false,reason:"Source port is already connected"};if(i)return {valid:false,reason:"Target port is already connected"};let n=t.sourceHandle,a=t.targetHandle,s=e.nodes.find(c=>c.id===t.source),d=e.nodes.find(c=>c.id===t.target),l=(c,F)=>{if(!c)return false;let X=c.startsWith("pwr")||c.startsWith("power"),O=F?.type==="vertical-pdu"&&c!=="mgmt-net-1";return X||O},u=(c,F)=>{if(!c)return false;if(F?.type==="vertical-pdu"&&c==="mgmt-net-1")return true;let X=c.startsWith("net-")||c.startsWith("port-")||c.startsWith("uplink-")||c.includes("Fiber")||c.includes("Ports"),O=/^[A-Z0-9]+-\d+$/.test(c)&&!c.startsWith("pwr")&&!c.startsWith("power");return X||O},y=l(n,s),f=l(a,d),N=u(n,s),U=u(a,d);if(y&&U||f&&N)return {valid:false,reason:"Cannot connect network cable to power port"};if(y&&!f||f&&!y)return {valid:false,reason:"Power ports must connect to power-compatible ports"};let D=s?.type==="vertical-pdu",E=d?.type==="vertical-pdu";if(y||f){let c=D?d:E?s:null,F=D?s:E?d:null;if(c&&F&&e.edges.filter(V=>{let et=l(V.sourceHandle||""),h=l(V.targetHandle||""),_=V.source===c.id||V.target===c.id;V.source===F.id||V.target===F.id;return (et||h)&&_}).some(V=>V.source===F.id||V.target===F.id))return {valid:false,reason:"Dual-feed required: connect second power to a different PDU"}}return {valid:true}}function Le(t,e){if(!e)return;let o=e.data??{},i=o.handleSideMap;if(i&&i[t])return i[t];if(t==="net-top"||t==="net-bottom")return "front";if(t==="pwr-left-1"||t==="pwr-left-2"||t==="net-right-1"||t==="net-right-2")return "rear";let n=Array.isArray(o.ports)?o.ports:[],a=Array.isArray(o.rearPorts)?o.rearPorts:[];if(t.startsWith("pwr")||t.includes("power"))return "rear";for(let d of n)for(let l of d.ports||[])if((!!l.type&&String(l.type).includes("power")?l.label:`${d.name}-${l.label}`)===t)return "front";for(let d of a)for(let l of d.ports||[])if((!!l.type&&String(l.type).includes("power")?l.label:`${d.name}-${l.label}`)===t)return "rear"}function Vt(t={},e={}){let o={nodes:t.nodes??[],edges:t.edges??[],debug:t.debug??false},i=new Set;return {getState:()=>o,setState:f=>{o={...o,...f},i.forEach(N=>N(o));},subscribe:f=>(i.add(f),()=>i.delete(f)),selectEdgeZIndex:f=>{let N=o.nodes.find(et=>et.id===f.target);if(!N||N.type!=="device")return 1e3;let U=N.data?.view||"front",D=Le(f.targetHandle||"",N);if(D)return U===D?1e3:500;let E=(f.targetHandle||"").toString(),c=E.toLowerCase(),F=c.startsWith("pwr")||c.startsWith("power"),X=c.startsWith("net-")||c.startsWith("port-")||c.startsWith("uplink-")||c.includes("fiber")||c.includes("ports"),O=/^[A-Z0-9]+-\d+$/i.test(E)&&!c.startsWith("pwr")&&!c.startsWith("power"),V=X||O;return F?U==="rear"?1e3:500:V?U==="front"?1e3:500:1e3},validateConnection:f=>(e.validateConnection||ze)(f,o),selectNodeById:f=>o.nodes.find(N=>N.id===f),selectConnectedEdges:f=>o.edges.filter(N=>N.source===f||N.target===f)}}function We(t){let e=n=>t.subscribe(n),o=()=>t.getState();return Be.useSyncExternalStore(e,o,o)}function Gt(t){let e=i=>t.subscribe(i),o=()=>t.getState().nodes;return Be.useSyncExternalStore(e,o,o)}function Yt(t){let e=i=>t.subscribe(i),o=()=>t.getState().edges;return Be.useSyncExternalStore(e,o,o)}function ne(t){return t.selectEdgeZIndex}var Je=(t,e,o)=>({rack:i=>jsxRuntime.jsx(It,{...i,onViewChange:t,onRackFaceChange:e,isDragOver:o===i.id}),fiber:At,device:Bt,"vertical-pdu":Ot}),Qe={fiber:Ft,power:Mt},to=({nodes:t,edges:e,initialNodes:o,initialEdges:i,onNodesChange:n,onEdgesChange:a,store:s,debug:d,onNodeClick:l,onEdgeClick:u,onViewChange:y,onRackFaceChange:f,className:N,style:U,alignRacksToBottom:D,colorMode:E="dark",onInit:c,onFlowMethods:F,showDownloadButton:X=false,downloadButtonPosition:O="top-right",downloadButtonText:V="Download Image",downloadButtonStyle:et})=>{let h=Array.isArray(t)&&Array.isArray(e),_=Be__default.default.useMemo(()=>s||Vt({nodes:h?t||[]:o||t||[],edges:h?e||[]:i||e||[],debug:d}),[s,h,d]),g=Gt(_),T=Yt(_),[v,R,rt]=reactflow.useNodesState(g),[b,I,$]=reactflow.useEdgesState(T),A=ne(_),H=Be.useRef(null),{toObject:j,setViewport:J}=reactflow.useReactFlow();Be.useEffect(()=>{F&&F({toObject:j,setViewport:J,toImage:r=>H.current?htmlToImage.toPng(H.current,r):Promise.reject(new Error("ReactFlow wrapper not available"))});},[F,j,J]);let B=Be.useCallback(()=>{if(!H.current){d&&console.error("ReactFlow wrapper ref is not available");return}htmlToImage.toPng(H.current,{filter:r=>!(r?.classList?.contains("react-flow__minimap")||r?.classList?.contains("react-flow__controls")||r?.classList?.contains("react-flow__attribution")||r?.classList?.contains("download-button")||r?.tagName==="BUTTON"),backgroundColor:E==="light"?"#ffffff":"#1a1a1a",pixelRatio:2}).then(r=>{let p=document.createElement("a");p.download=`network-diagram-${new Date().toISOString().split("T")[0]}.png`,p.href=r,p.click();}).catch(r=>{d&&console.error("Error downloading image:",r);});},[E]),[nt,M]=Be.useState(null),gt=Be.useMemo(()=>Je(y,f,nt),[y,f,nt]),Kt=Be.useMemo(()=>Qe,[]),st=Be.useRef(v);Be.useEffect(()=>{st.current=v;},[v]);let ot=Be.useRef(b);Be.useEffect(()=>{ot.current=b;},[b]),Be.useEffect(()=>{R(g);},[g,R]),Be.useEffect(()=>{I(T);},[T,I]),Be.useEffect(()=>{h&&_.setState({nodes:t||[]});},[h,t,_]),Be.useEffect(()=>{h&&_.setState({edges:e||[]});},[h,e,_]),Be.useEffect(()=>{if(!D||!v||v.length===0)return;let r=v.filter(w=>w.type==="rack");if(r.length===0)return;let p=r.map(w=>{let C=w.data&&w.data.uHeight||42,W=60+C*20;return (w.position?.y||0)+W}),m=Math.min(...p),x=Math.max(...p);if(x-m<20)return;let P=x,z=v.map(w=>{if(w.type!=="rack")return w;let C=w.data&&w.data.uHeight||42,W=60+C*20,Z=(w.position?.y||0)+W,G=P-Z;return Math.abs(G)<5?w:{...w,position:{x:w.position?.x||0,y:(w.position?.y||0)+G}}});z.some((w,C)=>w.position!==v[C].position)&&R(z);},[D,v,R]);let Q=Be.useCallback(r=>st.current.find(p=>p.id===r),[]);Be.useEffect(()=>{I(r=>r.map(p=>{let m=A(p);return {...p,zIndex:m,style:{...p.style,zIndex:m}}}));},[v,I,A]),Be.useEffect(()=>{let r=v.map(m=>{if(m.type==="device"&&m.parentId&&m.data.uPosition&&(!m.position||m.position.x===0&&m.position.y===0)){let x=Q(m.parentId);if(x){let k=mt(x,m.data.uPosition);return {...m,position:k}}}return m});r.some((m,x)=>m.position!==v[x].position)&&R(r);},[v,R,Q]);let lt=Be.useCallback(r=>{let p=r.map(m=>{if(m.type==="position"&&m.position){let x=Q(m.id);if(x&&x.type==="device"&&x.parentId){let k=Q(x.parentId);if(k){let P=Et(x,k,m.position,st.current);if(P.uPosition!==void 0){let z={...x,data:{...x.data,uPosition:P.uPosition}};R(S=>S.map(w=>w.id===x.id?z:w));}return {...m,position:{x:P.x,y:P.y}}}}if(x&&x.type==="device"&&x.parentId){let k=Q(x.parentId);if(k){let P=k,z=300,S=(P.data.uHeight||42)*20,w=P.position.x,C=P.position.x+z,W=P.position.y,Z=P.position.y+S;if(m.position.x<w||m.position.x>C||m.position.y<W||m.position.y>Z){let G=m.position.x+P.position.x,wt=m.position.y+P.position.y,xt={...x,parentId:void 0,extent:void 0,data:{...x.data,uPosition:void 0}};return R(Ne=>Ne.map(Jt=>Jt.id===x.id?xt:Jt)),{...m,position:{x:G,y:wt}}}}}}return m});rt(p);},[rt,R,Q]),ge=Be.useCallback((r,p)=>{M(null);},[]),fe=Be.useCallback((r,p,m)=>{if(p.type==="device"&&!p.parentId){let x=st.current.filter(z=>z.type==="rack"),k=null,P=1/0;for(let z of x){let S=z,w=Math.sqrt(Math.pow(p.position.x-S.position.x,2)+Math.pow(p.position.y-S.position.y,2)),C=300,W=(S.data.uHeight||42)*20,Z=S.position.x,G=S.position.x+C,wt=S.position.y,xt=S.position.y+W;p.position.x>=Z&&p.position.x<=G&&p.position.y>=wt&&p.position.y<=xt&&w<P&&(P=w,k=S);}M(k?k.id:null);}else M(null);},[]),me=Be.useCallback((r,p,m)=>{if(p.type==="device"&&!p.parentId){let x=st.current.filter(z=>z.type==="rack"),k=null,P=1/0;for(let z of x){let S=z,w=Math.sqrt(Math.pow(p.position.x-S.position.x,2)+Math.pow(p.position.y-S.position.y,2)),C=300,W=(S.data.uHeight||42)*20,Z=S.position.x,G=S.position.x+C,wt=S.position.y,xt=S.position.y+W;p.position.x>=Z&&p.position.x<=G&&p.position.y>=wt&&p.position.y<=xt&&w<P&&(P=w,k=S);}if(k){let z=p.position.x-k.position.x,S=p.position.y-k.position.y,w={...p,parentId:k.id,extent:"parent",position:{x:z,y:S},data:{...p.data,uPosition:1}};R(C=>C.map(W=>W.id===p.id?w:W));}}M(null);},[R]);Be.useCallback(r=>{if(!r.source||!r.target||!r.sourceHandle||!r.targetHandle)return {valid:true};let p=r.sourceHandle,m=r.targetHandle,x=ot.current.some(P=>P.source===r.source&&P.sourceHandle===p),k=ot.current.some(P=>P.target===r.target&&P.targetHandle===m);return x?{valid:false,reason:"Source port is already connected"}:k?{valid:false,reason:"Target port is already connected"}:{valid:true}},[]);let he=Be.useCallback(r=>{let p=Q(r.source),m=p?.type==="vertical-pdu",x=p?.type==="device"&&p.data?.deviceType==="switch",k=!!r.targetHandle&&(r.targetHandle.startsWith("pwr")||r.targetHandle.startsWith("power")),P=!!r.targetHandle&&(r.targetHandle.startsWith("net-")||r.targetHandle.startsWith("port-")||/^[A-Z0-9]+-\d+$/i.test(r.targetHandle));if(m&&k&&r.target&&r.targetHandle){let w=ot.current.find(C=>C.target===r.target&&C.targetHandle===r.targetHandle);if(w){let C={...r,type:"power",zIndex:A({...r,id:"temp-id"})};I(W=>{let Z=W.filter(G=>G.id!==w.id);return reactflow.addEdge(C,Z)});return}}if(x&&P&&r.target&&r.targetHandle){let w=ot.current.find(C=>C.target===r.target&&C.targetHandle===r.targetHandle);if(w){let C={...r,type:"fiber",zIndex:A({...r,id:"temp-id"})};I(W=>{let Z=W.filter(G=>G.id!==w.id);return reactflow.addEdge(C,Z)});return}}let z=_.validateConnection({source:r.source??null,target:r.target??null,sourceHandle:r.sourceHandle??null,targetHandle:r.targetHandle??null});if(!z.valid){if(m&&r.source&&r.sourceHandle){let w=ot.current.find(C=>C.source===r.source&&C.sourceHandle===r.sourceHandle);if(w){let C={...r,type:k?"power":"fiber",zIndex:A({...r,id:"temp-id"})};I(W=>{let Z=W.filter(G=>G.id!==w.id);return reactflow.addEdge(C,Z)});return}}if(x&&r.source&&r.sourceHandle){let w=ot.current.find(C=>C.source===r.source&&C.sourceHandle===r.sourceHandle);if(w){let C={...r,type:"fiber",zIndex:A({...r,id:"temp-id"})};I(W=>{let Z=W.filter(G=>G.id!==w.id);return reactflow.addEdge(C,Z)});return}}d&&console.warn(`Connection rejected: ${z.reason}`);return}let S={...r,type:m&&k?"power":"fiber",zIndex:A({...r,id:"temp-id"})};I(w=>reactflow.addEdge(S,w));},[I,_,A,Q]),ye=Be.useCallback((r,p)=>{if((r.metaKey||r.ctrlKey)&&p.type==="device"){let x=p.data||{},k=x.view||(Array.isArray(x.rearPorts)&&x.rearPorts.length>0?"rear":"front"),P=k==="front"?"rear":"front";d&&console.log(`Command+click: Toggling device ${p.id} from ${k} to ${P}`),y&&y(p.id,P),l&&l(p);}else l&&l(p);},[y,l,d]),be=Be.useCallback(()=>{},[]),we=Be.useCallback((r,p)=>{u&&u(p);},[u]),[L,qt]=Be.useState(null);reactflow.useOnSelectionChange({onChange:({nodes:r})=>{if(r&&r.length===1){let p=r[0];qt(p),l&&l(p);}else qt(null),l&&l(null);}});let xe=Be.useCallback(()=>{if(!L)return;let r=Q(L.id);if(r){if(r.type==="rack"){let m=(r.data&&r.data.face||"front")==="front"?"rear":"front";f?f(r.id,m):R(x=>x.map(k=>k.id===r.id?{...k,data:{...k.data,face:m}}:k.parentId===r.id?{...k,data:{...k.data,view:m}}:k));return}if(r.type==="device"){let p=r.data||{},m=Array.isArray(p.rearPorts)&&p.rearPorts.length>0,x=Array.isArray(p.ports)&&p.ports.length>0,P=(p.view||(m&&!x?"rear":"front"))==="front"?"rear":"front";y?y(r.id,P):R(z=>z.map(S=>S.id===r.id?{...S,data:{...S.data,view:P}}:S));}}},[L,Q,f,y,R]);return jsxRuntime.jsxs("div",{ref:H,className:`${N||""} ${E==="light"?"react-flow-light":"react-flow-dark"}`,style:{width:"100%",height:"100%",...U},children:[jsxRuntime.jsxs(reactflow.ReactFlow,{nodes:v,edges:b,onNodesChange:r=>{lt(r);r.reduce((m,x)=>(x.type==="add"||x.type==="remove",m),null);h?n&&n(st.current):_.setState({nodes:st.current});},onEdgesChange:r=>{$(r),h?a&&a(ot.current):_.setState({edges:ot.current});},onConnect:he,onNodeClick:ye,onNodeDoubleClick:be,onNodeDragStart:ge,onNodeDrag:fe,onNodeDragStop:me,onEdgeClick:we,onInit:c,nodeTypes:gt,edgeTypes:Kt,defaultEdgeOptions:{zIndex:1e3,reconnectable:true},nodesDraggable:true,nodesConnectable:true,elementsSelectable:true,selectNodesOnDrag:false,fitView:true,attributionPosition:"bottom-left",children:[jsxRuntime.jsx(reactflow.Background,{}),jsxRuntime.jsx(reactflow.Controls,{}),jsxRuntime.jsx(reactflow.MiniMap,{})]}),X&&jsxRuntime.jsx("button",{className:"download-button",onClick:B,style:{position:"absolute",top:O.includes("top")?"10px":"auto",bottom:O.includes("bottom")?"10px":"auto",right:O.includes("right")?"10px":"auto",left:O.includes("left")?"10px":"auto",zIndex:1e3,background:"#374151",color:"#e5e7eb",border:"1px solid #4b5563",borderRadius:"4px",padding:"0.5rem 0.75rem",fontSize:"0.875rem",cursor:"pointer",transition:"all 0.2s ease",...et},children:V}),L&&(L.type==="rack"||L.type==="device")&&jsxRuntime.jsx("div",{style:{position:"absolute",top:12,right:12,display:"flex",gap:8,zIndex:2e3},children:jsxRuntime.jsx("button",{onClick:r=>{r.preventDefault(),xe();},style:{background:"#374151",color:"#e5e7eb",border:"1px solid #4b5563",borderRadius:4,padding:"6px 10px",fontSize:11,fontFamily:"monospace",cursor:"pointer"},title:L.type==="rack"?(L.data?.face||"front")==="front"?"Switch to rear":"Switch to front":(L.data?.view||(Array.isArray(L.data?.rearPorts)&&L.data.rearPorts.length>0&&!(Array.isArray(L.data?.ports)&&L.data.ports.length>0)?"rear":"front"))==="front"?"Switch to rear":"Switch to front",children:L.type==="rack"?(L.data?.face||"front")==="front"?"\u21C4 Rear":"\u21C4 Front":(L.data?.view||(Array.isArray(L.data?.rearPorts)&&L.data.rearPorts.length>0&&!(Array.isArray(L.data?.ports)&&L.data.ports.length>0)?"rear":"front"))==="front"?"\u21C4 Rear":"\u21C4 Front"})})]})},eo=t=>jsxRuntime.jsx(reactflow.ReactFlowProvider,{children:jsxRuntime.jsx(to,{...t})});var de=t=>({id:`rack-${t.id}`,type:"rack",position:{x:0,y:0},data:{label:t.name,status:typeof t.status=="object"&&t.status?t.status.value:t.status,uHeight:t.u_height??t.units??42,inventoryId:t.id,inventoryType:"rack",facilityId:t.facility_id,serial:t.serial,assetTag:t.asset_tag,site:typeof t.site=="object"&&t.site?t.site.name:t.site,role:typeof t.role=="object"&&t.role?t.role.name:t.role,tenant:typeof t.tenant=="object"&&t.tenant?t.tenant.name:t.tenant}}),le=t=>({id:`device-${t.id}`,type:"device",position:{x:0,y:0},parentId:t.rack?`rack-${typeof t.rack=="object"&&t.rack?t.rack.id:t.rack}`:void 0,extent:t.rack?"parent":void 0,data:{label:t.name,status:typeof t.status=="object"&&t.status?t.status.value:t.status,deviceType:t.device_type?.model??t.model,manufacturer:t.device_type?.manufacturer?.name??t.manufacturer,role:typeof t.device_role=="object"&&t.device_role?t.device_role.name:t.role,uHeight:t.device_type?.u_height??t.u_height??1,uPosition:t.position||1,view:t.face||"front",inventoryId:t.id,inventoryType:"device",primaryIp4:typeof t.primary_ip4=="object"&&t.primary_ip4?t.primary_ip4.address:t.primary_ip4,primaryIp6:typeof t.primary_ip6=="object"&&t.primary_ip6?t.primary_ip6.address:t.primary_ip6,site:typeof t.site=="object"&&t.site?t.site.name:t.site,rack:typeof t.rack=="object"&&t.rack?t.rack.name:t.rack}}),pe=t=>{let e=n=>{if(!n)return;if(typeof n=="string")return n;let a=n.device;return typeof a=="object"&&a?a.id:a},o=e(t.termination_a),i=e(t.termination_b);return {id:`cable-${t.id}`,source:`device-${o}`,target:`device-${i}`,type:"fiber",data:{bandwidth:t.type?.label??t.bandwidth,length:t.length||0,color:t.color,inventoryId:t.id,inventoryType:"cable",status:typeof t.status=="object"&&t.status?t.status.value:t.status,terminationA:typeof t.termination_a=="object"&&t.termination_a?t.termination_a.name:t.termination_a,terminationB:typeof t.termination_b=="object"&&t.termination_b?t.termination_b.name:t.termination_b}}},oo=t=>{let e=[],o=[];return t.racks.forEach(i=>e.push(de(i))),t.devices.forEach(i=>e.push(le(i))),t.cables.forEach(i=>o.push(pe(i))),{nodes:e,edges:o}},ro=t=>{let e=t.filter(n=>n.type==="rack"),o=t.filter(n=>n.type==="device"),i=t.filter(n=>!["rack","device"].includes(n.type));return e.forEach((n,a)=>{n.position={x:a*300,y:100};}),o.forEach(n=>{if(n.parentId){let a=e.find(s=>s.id===n.parentId);if(a){let s=n.data.uPosition||1,d=n.data.uHeight||1;n.position={x:a.position.x+50,y:a.position.y+s*20-d*10};}}else n.position={x:Math.random()*400+100,y:Math.random()*200+50};}),i.forEach((n,a)=>{n.position={x:a*150+100,y:300};}),t};var bt=class extends Error{constructor(o,i,n,a,s){super(`Device placement conflict: ${i} at U${n}-${n+a-1} in rack ${o}${s?` conflicts with ${s}`:""}`);this.rackId=o;this.deviceId=i;this.uPosition=n;this.uHeight=a;this.conflictWith=s;this.name="DevicePlacementError";}};function Zt(t,e={}){let{conflictPolicy:o="strict"}=e,i=[],n=[];for(let a of t.devices)a.unit+a.height-1>t.units&&n.push({deviceId:a.id,uPosition:a.unit,uHeight:a.height,rackUHeight:t.units});for(let a=0;a<t.devices.length;a++){let s=t.devices[a],d=s.unit,l=s.unit+s.height-1;for(let u=a+1;u<t.devices.length;u++){let y=t.devices[u],f=y.unit,N=y.unit+y.height-1;d<=N&&l>=f&&i.push({deviceId:s.id,uPosition:s.unit,uHeight:s.height,conflictWith:y.id});}}return {isValid:i.length===0&&n.length===0,conflicts:i,outOfBounds:n}}function ue(t,e,o={}){let{deviceTypeMapping:i={}}=o,n=i[t.type]||"device",a=mt(e,t.unit,t.height);return {id:t.id,type:n,position:a,parentId:e.id,extent:"parent",data:{label:t.name,status:"active",deviceType:t.type,uHeight:t.height,uPosition:t.unit,width:t.width||"full",role:t.role,ports:t.ports,rearPorts:t.rearPorts,connections:t.connections}}}function no(t){return {id:t.id,type:"rack",position:t.position,data:{label:t.name,status:"active",uHeight:t.units,uNumberingDirection:t.uNumberingDirection||"bottom-up",customHeaderText:t.customHeaderText,ports:[]}}}function io(t,e={}){let{conflictPolicy:o="strict",validatePlacements:i=true}=e,n=[],a=[];if(i)for(let s of t){let d=Zt(s,e);if(!d.isValid&&o==="strict"){let l=[];throw d.conflicts.forEach(u=>{l.push(`Device ${u.deviceId} at U${u.uPosition}-${u.uPosition+u.uHeight-1} conflicts with ${u.conflictWith}`);}),d.outOfBounds.forEach(u=>{l.push(`Device ${u.deviceId} at U${u.uPosition}-${u.uPosition+u.uHeight-1} exceeds rack height (${u.rackUHeight}U)`);}),new bt(s.id,d.conflicts[0]?.deviceId||d.outOfBounds[0]?.deviceId||"unknown",d.conflicts[0]?.uPosition||d.outOfBounds[0]?.uPosition||1,d.conflicts[0]?.uHeight||d.outOfBounds[0]?.uHeight||1)}}for(let s of t){let d=no(s);n.push(d);for(let l of s.devices)try{let u=ue(l,d,e);a.push(u);}catch(u){if(o==="strict")throw u;if(o==="nearest"){let y=Dt(d,{id:l.id,data:{label:l.name,uHeight:l.height}},a,l.unit);if(y!==l.unit){console.warn(`Device ${l.id} moved from U${l.unit} to U${y} due to conflict`);let f={...l,unit:y},N=ue(f,d,e);a.push(N);}else throw new bt(s.id,l.id,l.unit,l.height)}}}return n.push(...a),n}function ao(t){let e=[],o=t.filter(i=>i.type==="rack");for(let i of o){let a=t.filter(s=>s.type==="device"&&s.parentId===i.id).map(s=>({id:s.id,name:s.data.label,unit:s.data.uPosition||1,height:s.data.uHeight||1,type:s.data.deviceType||"server",width:s.data.width,ports:s.data.ports,connections:s.data.connections}));e.push({id:i.id,name:i.data.label,position:i.position,units:i.data.uHeight||42,uNumberingDirection:i.data.uNumberingDirection||"bottom-up",customHeaderText:i.data.customHeaderText,devices:a});}return e}function so(t,e,o,i){return t.map(n=>n.id!==e?n:{...n,devices:n.devices.map(a=>a.id!==o?a:{...a,unit:i})})}function co(t,e,o,i={}){let{conflictPolicy:n="strict"}=i;return t.map(a=>{if(a.id!==e)return a;if(n==="strict"&&!Zt({...a,devices:[...a.devices,o]},i).isValid)throw new bt(e,o.id,o.unit,o.height);return {...a,devices:[...a.devices,o]}})}function lo(t,e,o){return t.map(i=>i.id!==e?i:{...i,devices:i.devices.filter(n=>n.id!==o)})}exports.DeviceNode=Bt;exports.DevicePlacementError=bt;exports.FiberEdge=Ft;exports.FiberNode=At;exports.NetworkDiagram=eo;exports.POWER_CONNECTORS=zt;exports.PowerEdge=Mt;exports.RackNode=It;exports.VerticalPDU=Ot;exports.Width=te;exports.addDeviceToRack=co;exports.buildNodesFromRackConfig=io;exports.calculateDevicePositionFromU=mt;exports.createNetworkDiagramStore=Vt;exports.createRackConfigFromNodes=ao;exports.findNextAvailableUPosition=Dt;exports.generateLayout=ro;exports.getConnectorConfig=Rt;exports.getDeviceConnectorType=St;exports.getPDUPortType=Lt;exports.getPowerPortStyle=ht;exports.inventoryCableToNetworkEdge=pe;exports.inventoryDeviceToNetworkNode=le;exports.inventoryRackToNetworkNode=de;exports.inventoryToNetworkDiagram=oo;exports.isHighPowerConnector=_e;exports.isUPositionAvailable=Tt;exports.removeDeviceFromRack=lo;exports.snapToUPosition=Et;exports.updateDeviceUPosition=Qt;exports.updateDeviceUPositionInSchema=so;exports.useDiagramEdges=Yt;exports.useDiagramNodes=Gt;exports.useNetworkDiagram=We;exports.validateAndSnapDevice=ve;exports.validateRackDevicePlacements=Zt;//# sourceMappingURL=index.js.map
1
+ 'use strict';var Lt=require('react'),reactflow=require('reactflow'),htmlToImage=require('html-to-image'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var Lt__default=/*#__PURE__*/_interopDefault(Lt);var Pt=()=>"bottom-up",se=e=>e.data.uNumberingDirection||Pt(),xe=(e,o,t)=>t==="bottom-up"?o-e+1:e,Ne=(e,o,t)=>t==="bottom-up"?o-e+1:e;var Te=(e,o,t,i)=>{if(!e.parentId||e.parentId!==o.id)return t;let r=e.data.uHeight||1,a=o.data.uHeight||42,c=se(o),s=60,d=t.y-s,f=Math.round(d/20)+1,h;c==="bottom-up"?h=xe(f,a,c)-r+1:h=xe(f,a,c);let m=a-r+1,k=Math.max(1,Math.min(m,h));if(c==="top-down"&&h<=1&&(k=1),!Ie(o,e,k,i)){let P=ke(o,e,i,k);P!==k&&(k=P);}let v;if(c==="bottom-up"){let P=k+r-1,$=Ne(P,a,c);v=s+($-1)*20-1;}else {let P=Ne(k,a,c);v=s+(P-1)*20-1;}return {x:t.x,y:v,uPosition:k}},Ie=(e,o,t,i)=>{let r=o.data.uHeight||1,a=e.data.uHeight||42;if(t<1||t+r-1>a)return false;let c=i.filter(s=>s.type==="device"&&s.parentId===e.id&&s.id!==o.id);for(let s of c){let d=s.data.uPosition||1,f=s.data.uHeight||1,h=t,m=t+r-1,k=d,v=d+f-1;if(h<=v&&m>=k)return false}return true},ke=(e,o,t,i=1)=>{let r=o.data.uHeight||1,a=e.data.uHeight||42;for(let c=i;c<=a-r+1;c++)if(Ie(e,o,c,t))return c;return 1},ue=(e,o,t=1)=>{let i=60,r=se(e),a=e.data.uHeight||42,c=Ne(o,a,r),s;if(r==="bottom-up"){let d=o+t-1,f=Ne(d,a,r);s=i+(f-1)*20-1;}else s=i+(c-1)*20-1;return {x:0,y:s}},Qe=(e,o,t)=>{let i=e.data.uHeight||1,r=ue(o,t,i);return {...e,position:r,data:{...e.data,uPosition:t}}},Dt=(e,o)=>{let t=e.data.uPosition||1,i=e.data.uHeight||1,r=o.data.uHeight||42,a=Math.max(1,Math.min(r-i+1,t));return a!==t?Qe(e,o,a):e};function Z(e){switch(e){case "active":return "#10b981";case "inactive":return "#6b7280";case "maintenance":return "#f59e0b";default:return "#6b7280"}}var Ue=({data:e,selected:o,id:t,onViewChange:i,onRackFaceChange:r,isDragOver:a=false})=>{let{label:c,ports:s=0,status:d="active",uHeight:f=42,face:h="front",customHeaderText:m}=e,{getNodes:k,setNodes:v}=reactflow.useReactFlow(),P=k(),[$,b]=Lt.useState(true),T=()=>{let D=se({data:e})==="bottom-up"?"top-down":"bottom-up";v(p=>p.map(l=>l.id===t?{...l,data:{...l.data,uNumberingDirection:D}}:l));},B=()=>{let u=h==="front"?"rear":"front";r?(r(t,u),i&&P.filter(p=>p.parentId===t).forEach(p=>{i(p.id,u);})):i?P.filter(p=>p.parentId===t).forEach(p=>{i(p.id,u);}):v(D=>D.map(p=>p.id===t?{...p,data:{...p.data,face:u}}:p.parentId===t?{...p,data:{...p.data,view:u}}:p));},M=()=>{let u=[],D=60,p=se({data:e});for(let l=1;l<=f;l++){let I=D+(l-1)*20-4,U=xe(l,f,p);u.push(jsxRuntime.jsx("div",{style:{position:"absolute",left:"-35px",top:`${I}px`,background:"#374151",color:"#9ca3af",padding:"2px 4px",borderRadius:"2px",fontSize:"8px",fontWeight:"bold",width:"28px",textAlign:"center",border:"1px solid #4b5563",zIndex:10,height:`${20}px`,display:"flex",alignItems:"center",justifyContent:"center",lineHeight:1},children:U},l));}return u};return jsxRuntime.jsxs("div",{className:`rack-node ${o?"selected":""} ${a?"drag-over":""}`,style:{background:"transparent",border:`2px solid ${Z(d)}`,borderRadius:"8px",padding:0,width:`${300}px`,height:`${60+f*20}px`,color:"white",fontFamily:"monospace",fontSize:"12px",boxShadow:a?"0 0 20px #3b82f6, 0 0 40px #3b82f6, 0 0 60px #3b82f6":o?"0 0 0 2px #3b82f6":"0 2px 4px rgba(0,0,0,0.1)",position:"relative",display:"flex",flexDirection:"column",transition:"box-shadow 0.2s ease-in-out"},children:[jsxRuntime.jsxs("div",{style:{textAlign:"center",marginBottom:0,zIndex:2,background:"#1f2937",padding:"8px",position:"relative",height:`${60}px`,display:"flex",flexDirection:"column",justifyContent:"center"},children:[jsxRuntime.jsx("div",{style:{fontWeight:"bold",marginBottom:"4px"},children:c}),jsxRuntime.jsxs("div",{style:{fontSize:"10px",color:"#9ca3af"},children:[m?jsxRuntime.jsx("span",{style:{color:"#fbbf24",fontWeight:"bold"},children:m}):jsxRuntime.jsxs("span",{children:[typeof s=="number"?s:0," ports"]})," \u2022 ",f,"U \u2022 ",h]}),jsxRuntime.jsxs("div",{style:{display:"flex",gap:"4px",position:"absolute",top:"4px",right:"4px"},children:[jsxRuntime.jsx("button",{onPointerDown:u=>{u.stopPropagation();},onMouseDown:u=>{u.stopPropagation();},onClick:u=>{u.stopPropagation(),u.preventDefault(),b(!$);},style:{background:$?"#10b981":"#374151",color:$?"#ffffff":"#9ca3af",border:"1px solid #4b5563",borderRadius:"2px",padding:"2px 6px",fontSize:"8px",cursor:"pointer",fontFamily:"monospace"},title:`${$?"Hide":"Show"} U markers`,children:"U"}),jsxRuntime.jsx("button",{onPointerDown:u=>{u.stopPropagation();},onMouseDown:u=>{u.stopPropagation();},onClick:u=>{u.stopPropagation(),u.preventDefault(),T();},style:{background:"#374151",color:"#9ca3af",border:"1px solid #4b5563",borderRadius:"2px",padding:"2px 6px",fontSize:"8px",cursor:"pointer",fontFamily:"monospace"},title:`Switch U numbering to ${se({data:e})==="bottom-up"?"top-down":"bottom-up"}`,children:se({data:e})==="bottom-up"?"\u2191\u2193":"\u2193\u2191"}),jsxRuntime.jsx("button",{onPointerDown:u=>{u.stopPropagation();},onMouseDown:u=>{u.stopPropagation();},onClick:u=>{u.stopPropagation(),u.preventDefault(),B();},style:{background:"#374151",color:"#9ca3af",border:"1px solid #4b5563",borderRadius:"2px",padding:"2px 6px",fontSize:"8px",cursor:"pointer",fontFamily:"monospace"},title:`Switch to ${h==="front"?"rear":"front"} view`,children:h==="front"?"\u21C4 Rear":"\u21C4 Front"})]})]}),jsxRuntime.jsx("div",{style:{flex:1,background:"transparent",position:"relative",minHeight:`${f*20}px`,overflow:"hidden"}}),$&&jsxRuntime.jsx("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,pointerEvents:"none"},children:M()})]})};var _e=({data:e,selected:o})=>{let{label:t,status:i="active"}=e;return jsxRuntime.jsxs("div",{className:`fiber-node ${o?"selected":""}`,style:{background:"#1f2937",border:`2px solid ${Z(i)}`,borderRadius:"50%",width:"60px",height:"60px",display:"flex",alignItems:"center",justifyContent:"center",color:"white",fontFamily:"monospace",fontSize:"10px",fontWeight:"bold",boxShadow:o?"0 0 0 2px #3b82f6":"0 2px 4px rgba(0,0,0,0.1)",position:"relative"},children:[jsxRuntime.jsx(reactflow.Handle,{type:"target",position:reactflow.Position.Top}),jsxRuntime.jsx(reactflow.Handle,{type:"source",position:reactflow.Position.Bottom}),jsxRuntime.jsx(reactflow.Handle,{type:"target",position:reactflow.Position.Left}),jsxRuntime.jsx(reactflow.Handle,{type:"source",position:reactflow.Position.Right}),jsxRuntime.jsx("div",{style:{textAlign:"center"},children:jsxRuntime.jsx("div",{style:{fontSize:"8px",lineHeight:"1.2"},children:t})}),jsxRuntime.jsx("div",{style:{position:"absolute",bottom:"4px",left:"50%",transform:"translateX(-50%)",width:"8px",height:"8px",background:Z(i),borderRadius:"50%"}})]})};var Me=({id:e,sourceX:o,sourceY:t,targetX:i,targetY:r,sourcePosition:a,targetPosition:c,data:s,selected:d,style:f={}})=>{let[h,m,k]=reactflow.getBezierPath({sourceX:o,sourceY:t,sourcePosition:a,targetX:i,targetY:r,targetPosition:c}),{bandwidth:v,length:P,color:$="#00FFFF"}=s||{},b={...f,stroke:$,strokeWidth:d?3:2,strokeDasharray:"none"};return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(reactflow.BaseEdge,{id:e,path:h,style:b}),jsxRuntime.jsx(reactflow.EdgeLabelRenderer,{children:d&&s&&(v||P)&&jsxRuntime.jsxs("div",{style:{position:"absolute",transform:`translate(-50%, -50%) translate(${m}px,${k}px)`,background:"#1f2937",padding:"4px 8px",borderRadius:"4px",fontSize:"10px",color:"white",fontFamily:"monospace",border:`1px solid ${$}`,pointerEvents:"none",zIndex:9999},children:[v&&jsxRuntime.jsx("div",{children:v}),P&&jsxRuntime.jsxs("div",{children:[P,"m"]})]})})]})};var ze=({id:e,sourceX:o,sourceY:t,targetX:i,targetY:r,sourcePosition:a,targetPosition:c,style:s={},data:d,markerEnd:f})=>{let[h]=reactflow.getBezierPath({sourceX:o,sourceY:t,sourcePosition:a,targetX:i,targetY:r,targetPosition:c}),m=d?.connectorType||"C13";return jsxRuntime.jsx(reactflow.BaseEdge,{id:e,path:h,markerEnd:f,style:(()=>{let v={stroke:d?.color||"#f59e0b",strokeWidth:m==="C19"?5:3,strokeLinecap:"round",strokeLinejoin:"round",...s};return m==="C19"?{...v,strokeDasharray:"none"}:{...v,strokeDasharray:"6,3"}})()})};var et=(t=>(t.FULL="full",t.HALF="half",t))(et||{});var Be={C13:{type:"C13",color:"#f59e0b",borderColor:"#d97706",amperage:10,voltage:230,phases:1},C14:{type:"C14",color:"#f59e0b",borderColor:"#d97706",amperage:10,voltage:230,phases:1},C19:{type:"C19",color:"#fbbf24",borderColor:"#d97706",amperage:16,voltage:230,phases:1},C20:{type:"C20",color:"#fbbf24",borderColor:"#d97706",amperage:16,voltage:230,phases:1}};function ge(e){let o=Be[e];if(!o)throw new Error(`Unknown connector type: ${e}`);let t=o.amperage===16,i=t?12:8,r=t?10:5,a=t?{borderRadius:"3px"}:{clipPath:"polygon(2px 0, calc(100% - 2px) 0, 100% 2px, 100% 100%, 0 100%, 0 2px)",borderRadius:"0px"};return {width:i,height:r,color:o.color,borderColor:o.borderColor,fontSize:t?"3px":"4px",...a}}function De(e){let o=Be[e];if(!o)throw new Error(`Unknown connector type: ${e}`);return o}function At(e){return De(e).amperage===16}function We(e){return e%10<8?"C13":"C19"}function Re(e){let o=e.toLowerCase();return o.includes("mx304")||o.includes("mx480")||o.includes("mx960")?"C20":"C14"}var Oe=({data:e,selected:o})=>{let{label:t,status:i="active",deviceType:r="server",manufacturer:a,role:c,uHeight:s=1,width:d="full",ports:f=[],rearPorts:h=[],view:m}=e,k=m||(h.length>0&&f.length===0?"rear":"front"),v={};v["net-top"]="front",v["net-bottom"]="front",f.length>0&&f.forEach(u=>{u.ports.forEach(D=>{let p=D.type?.includes("power")?D.label:`${u.name}-${D.label}`;v[p]="front";});}),v["pwr-left-1"]="rear",v["pwr-left-2"]="rear",v["net-right-1"]="rear",v["net-right-2"]="rear",h.length>0&&h.forEach(u=>{u.ports.forEach(D=>{let p=D.type?.includes("power")?D.label:`${u.name}-${D.label}`;v[p]="rear";});});let P=s*20,$=d==="half"?"150px":"304px",b=d==="half"?"150px":void 0,T=(u,D)=>{let p=[];if(u.length===0)return p;let l=Math.max(4,Math.floor(P*.4)),I=Math.max(2,Math.floor(P*.2));return u.forEach((U,C)=>{U.ports.forEach((y,R)=>{let G=!!y.type&&y.type.includes("power");if(D==="front"&&G)return;let A=G?`${y.label}`:`${U.name}-${y.label}`,ee=y.connected,E="#6b7280";if(ee)if(y.type?.includes("power"))E=y.type==="power_c19"?"#fbbf24":"#f59e0b";else if(y.type==="console"||y.type==="mgmt")E="#8b5cf6";else if(y.type==="usb")E="#10b981";else switch(y.cableType){case "smf":E="#fbbf24";break;case "cat6":E="#8b5cf6";break;case "om3":E="#06b6d4";break;case "om4":E="#8b5cf6";break;case "om5":E="#84cc16";break;case "cat5e":E="#3b82f6";break;case "cat6a":E="#ef4444";break;case "cat7":E="#f97316";break;case "fiber":E="#3b82f6";break;case "ethernet":E="#10b981";break;default:E="#10b981";}let W=reactflow.Position.Top,F={width:`${l}px`,height:`${I}px`,background:ee?E:"#6b7280",border:`1px solid ${ee?E:"#374151"}`,borderRadius:"1px",cursor:"pointer"};if(D==="front")R%2===0?(W=reactflow.Position.Top,F.transform="translateY(50%)",F.left=`${R/2*(l+2)}px`):(W=reactflow.Position.Bottom,F.transform="translateY(-50%)",F.left=`${(R-1)/2*(l+2)}px`);else if((r?.toLowerCase().replace(/_/g,"-")||"")==="patch-panel")R%2===0?(W=reactflow.Position.Top,F.transform="translateY(50%)",F.left=`${R/2*(l+2)}px`):(W=reactflow.Position.Bottom,F.transform="translateY(-50%)",F.left=`${(R-1)/2*(l+2)}px`);else if(y.type?.includes("power")){W=reactflow.Position.Left,F.transform="translateX(50%)";let we=P<=20?10:20,de=P<=20?30:50;F.top=`${we+R*de}%`;let He=Re(t),ae=ge(He);F={...F,width:`${ae.width}px`,height:`${ae.height}px`,zIndex:10,display:"flex",alignItems:"center",justifyContent:"center",fontSize:ae.fontSize,color:"#1a1a1a",fontFamily:"monospace",fontWeight:"bold",borderRadius:ae.borderRadius,clipPath:ae.clipPath};}else W=reactflow.Position.Right,F.transform="translateX(-50%)",F.top=`${25+R*50}%`;let ye=(r?.toLowerCase().replace(/_/g,"-")||"")==="patch-panel",oe;if(G)oe="target";else if(r==="switch"||r==="router")oe="source",p.push(jsxRuntime.jsx(reactflow.Handle,{id:`${A}-target`,type:"target",position:W,style:F,title:`${U.name} - ${y.label} (input) ${ee?"(connected)":"(disconnected)"}`},`${A}-target`));else if(ye){oe=D==="rear"?"source":"target";let ie=D==="rear"?"target":"source";p.push(jsxRuntime.jsx(reactflow.Handle,{id:`${A}-${ie}`,type:ie,position:W,style:F,title:`${U.name} - ${y.label} (${ie}) ${ee?"(connected)":"(disconnected)"}`},`${A}-${ie}`));}else oe=ee?"source":"target";p.push(jsxRuntime.jsx(reactflow.Handle,{id:A,type:oe,position:W,style:F,title:`${U.name} - ${y.label} ${ee?"(connected)":"(disconnected)"}`,children:G?R+1:void 0},A));});}),p},B=()=>{let u=[],D=Math.max(4,Math.floor(P*.4)),p=Math.max(2,Math.floor(P*.2));if(k==="front"){if(f.length>0)return T(f,"front");if(r==="switch"&&(t.toLowerCase().includes("agg")||t.toLowerCase().includes("core")||c==="agg"||c==="core"))return M();u.push(jsxRuntime.jsx(reactflow.Handle,{id:"net-top",type:"target",position:reactflow.Position.Top,style:{width:`${D}px`,height:`${p}px`,background:"#10b981",border:"0.5px solid #059669",borderRadius:"1px",cursor:"pointer",transform:"translateY(50%)"},title:"Network Port (Top)"},"net-top")),u.push(jsxRuntime.jsx(reactflow.Handle,{id:"net-bottom",type:"target",position:reactflow.Position.Bottom,style:{width:`${D}px`,height:`${p}px`,background:"#10b981",border:"0.5px solid #059669",borderRadius:"1px",cursor:"pointer",transform:"translateY(-50%)"},title:"Network Port (Bottom)"},"net-bottom"));}else if(k==="rear"){if(h.length>0)return T(h,"rear");let l=r==="switch",U=(r?.toLowerCase().replace(/_/g,"-")||"")==="patch-panel";if(!U){let C=Re(t),y=De(C),R=ge(C),G=P<=20?"10%":"25%";u.push(jsxRuntime.jsx(reactflow.Handle,{id:"pwr-left-1",type:"target",position:reactflow.Position.Left,style:{width:`${R.width}px`,height:`${R.height}px`,background:R.color,border:`1px solid ${R.borderColor}`,cursor:"pointer",transform:"translateX(50%)",top:G,zIndex:10,display:"flex",alignItems:"center",justifyContent:"center",fontSize:R.fontSize,color:"#1a1a1a",fontFamily:"monospace",fontWeight:"bold",borderRadius:R.borderRadius,clipPath:R.clipPath},title:`Power Port 1 (${y.type}) - ${y.voltage}V, ${y.amperage}A`,children:"1"},"pwr-1"));let A=P<=20?"50%":"75%";u.push(jsxRuntime.jsx(reactflow.Handle,{id:"pwr-left-2",type:"target",position:reactflow.Position.Left,style:{width:`${R.width}px`,height:`${R.height}px`,background:R.color,border:`1px solid ${R.borderColor}`,cursor:"pointer",transform:"translateX(50%)",top:A,zIndex:10,display:"flex",alignItems:"center",justifyContent:"center",fontSize:R.fontSize,color:"#1a1a1a",fontFamily:"monospace",fontWeight:"bold",borderRadius:R.borderRadius,clipPath:R.clipPath},title:`Power Port 2 (${y.type}) - ${y.voltage}V, ${y.amperage}A`,children:"2"},"pwr-2"));}!l&&!U&&(u.push(jsxRuntime.jsx(reactflow.Handle,{id:"net-right-1",type:"target",position:reactflow.Position.Right,style:{width:`${D}px`,height:`${p}px`,background:"#10b981",border:"0.5px solid #059669",borderRadius:"1px",cursor:"pointer",transform:"translateX(-50%)",top:"25%"},title:"Network Port 1 (Right)"},"net-right-1")),u.push(jsxRuntime.jsx(reactflow.Handle,{id:"net-right-2",type:"target",position:reactflow.Position.Right,style:{width:`${D}px`,height:`${p}px`,background:"#10b981",border:"0.5px solid #059669",borderRadius:"1px",cursor:"pointer",transform:"translateX(-50%)",top:"75%"},title:"Network Port 2 (Right)"},"net-right-2")));}return u},M=()=>{let u=[],D=Math.max(10,Math.floor(P*.45)),p=Math.max(5,Math.floor(P*.25));for(let l=1;l<=16;l++){let I=jsxRuntime.jsx(reactflow.Handle,{id:`port-${l}`,type:"source",position:reactflow.Position.Top,style:{width:`${D}px`,height:`${p}px`,background:"#10b981",border:"1px solid #059669",borderRadius:"2px",cursor:"pointer",transform:"translateY(50%)",zIndex:1e3,left:`${(l-1)*(D+2)}px`},title:`Port ${l}`},`port-${l}`);u.push(I);}for(let l=17;l<=32;l++){let I=l-16,U=jsxRuntime.jsx(reactflow.Handle,{id:`port-${l}`,type:"source",position:reactflow.Position.Bottom,style:{width:`${D}px`,height:`${p}px`,background:"#10b981",border:"1px solid #059669",borderRadius:"2px",cursor:"pointer",transform:"translateY(-50%)",zIndex:1e3,left:`${(I-1)*(D+2)}px`},title:`Port ${l}`},`port-${l}`);u.push(U);}for(let l=1;l<=4;l++){let I=Math.max(4,Math.floor(P*.3)),U=Math.max(3,Math.floor(P*.15));u.push(jsxRuntime.jsx(reactflow.Handle,{id:`uplink-${l}`,type:"source",position:reactflow.Position.Right,style:{width:`${I}px`,height:`${U}px`,background:"#8b5cf6",border:"0.5px solid #7c3aed",borderRadius:"0.5px",cursor:"pointer",transform:"translateX(-50%)"},title:`Uplink ${l}`},`uplink-${l}`));}return u};return jsxRuntime.jsxs("div",{className:`device-node ${o?"selected":""}`,style:{background:"#1f2937",border:`1px solid ${Z(i)}`,borderRadius:"2px",padding:"0px",width:$,...b&&{left:b},height:`${P}px`,color:"white",fontFamily:"monospace",fontSize:"8px",boxShadow:o?"0 0 0 1px #3b82f6":"0 1px 2px rgba(0,0,0,0.1)",position:"relative",display:"flex",flexDirection:"column",justifyContent:"center",cursor:"grab",marginBottom:"0px",boxSizing:"border-box",marginTop:"0px",marginLeft:"0px",marginRight:"0px"},children:[jsxRuntime.jsxs("div",{style:{textAlign:"center",flex:1,display:"flex",flexDirection:"column",justifyContent:"center",overflow:"hidden",padding:"2px"},children:[jsxRuntime.jsx("div",{style:{fontWeight:"bold",fontSize:"7px",lineHeight:"1.1",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},children:t}),s>1&&jsxRuntime.jsx("div",{style:{fontSize:"6px",color:"#9ca3af",lineHeight:"1"},children:a})]}),s>1&&jsxRuntime.jsxs("div",{style:{position:"absolute",bottom:"1px",right:"1px",background:"#374151",color:"#9ca3af",padding:"1px 2px",borderRadius:"1px",fontSize:"6px",lineHeight:"1"},children:[s,"U"]}),jsxRuntime.jsx("div",{style:{position:"absolute",bottom:"1px",left:"1px",width:"4px",height:"4px",background:Z(i),borderRadius:"50%"}}),B()]})};var Ve=({data:e,selected:o})=>{let{label:t,status:i="active",heightCm:r=100,powerPorts:a=36,widthPx:c=15,mgmt_unit:s}=e,d=r*4.2,f=()=>{let k=Math.ceil(a/10),v=Array(10).fill(0).map((p,l)=>l<8?"10A":"16A");for(let p=0,l=0;p<k;++p)for(let I=0;I<10&&l<a;++I,++l){v[I];}let T=[],B=15,D=(d-B-3)/(a-9)*.5;for(let p=0;p<a;p++){let l=B-2+D*p,I=`${p+1}`;if(s&&(s==="top"&&p===0||s==="middle"&&p===Math.floor(a/2)||s==="bottom"&&p===a-1)){T.push(h(l));continue}let C=We(p),y=ge(C),R=Math.round((c-y.width)/2-1);T.push(jsxRuntime.jsx(reactflow.Handle,{type:"source",position:reactflow.Position.Right,id:I,style:{position:"absolute",left:`${R}px`,top:`${l-y.height/2}px`,width:`${y.width}px`,height:`${y.height}px`,background:y.color,border:`1px solid ${y.borderColor}`,cursor:"pointer",zIndex:10,display:"flex",alignItems:"center",justifyContent:"center",fontSize:y.fontSize,color:"#1a1a1a",fontFamily:"monospace",fontWeight:"bold",borderRadius:y.borderRadius,clipPath:y.clipPath},title:`Power Port ${p+1} (${C})`,children:p+1},`handle-${I}`));}return T},h=m=>jsxRuntime.jsxs("div",{style:{position:"absolute",left:`${(c-16)/2}px`,top:`${m-12/2}px`,width:"16px",height:"12px",background:"#1a1a1a",border:"1px solid #374151",borderRadius:"1px",display:"flex",flexDirection:"column",padding:"1px",zIndex:10},children:[jsxRuntime.jsx("div",{style:{position:"absolute",left:"-10px",top:"1px",background:"#ffffff",border:"0.5px solid #6b7280",borderRadius:"0.5px",width:"8px",height:"10px",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"3px",color:"#10b981",fontFamily:"monospace",fontWeight:"bold",transform:"rotate(90deg)",transformOrigin:"center"},children:"APC"}),jsxRuntime.jsx(reactflow.Handle,{type:"source",position:reactflow.Position.Right,id:"mgmt-net-1",style:{width:"70%",height:"6px",background:"#10b981",border:"1px solid #059669",borderRadius:"1px",cursor:"pointer",zIndex:11,margin:"0 auto"},title:"Management Network Port"},"mgmt-net-1")]},"mgmt-unit");return jsxRuntime.jsxs("div",{className:`vertical-pdu-node ${o?"selected":""}`,style:{background:"linear-gradient(90deg, #2d3748 0%, #1a202c 50%, #2d3748 100%)",border:`1px solid ${Z(i)}`,borderRadius:"2px",padding:0,width:`${c}px`,height:`${d}px`,color:"white",fontFamily:"monospace",fontSize:"12px",boxShadow:o?"0 0 0 2px #3b82f6":"0 1px 3px rgba(0,0,0,0.3)",position:"relative",display:"flex",flexDirection:"column"},children:[jsxRuntime.jsx("div",{style:{textAlign:"center",marginBottom:0,zIndex:2,background:"linear-gradient(90deg, #4a5568 0%, #2d3748 50%, #4a5568 100%)",padding:"2px",position:"relative",height:"20px",display:"flex",flexDirection:"column",justifyContent:"center",borderBottom:"1px solid #4a5568"},children:jsxRuntime.jsx("div",{style:{fontWeight:"bold",fontSize:"6px",color:"#e2e8f0"},children:t})}),jsxRuntime.jsx("div",{style:{flex:1,background:"linear-gradient(180deg, #2d3748 0%, #1a202c 50%, #2d3748 100%)",position:"relative",minHeight:`${d-20}px`,overflow:"hidden"},children:f()})]})};function Mt(e,o){if(!e.source||!e.target||!e.sourceHandle||!e.targetHandle)return {valid:true};let t=o.edges.some(b=>b.source===e.source&&b.sourceHandle===e.sourceHandle),i=o.edges.some(b=>b.target===e.target&&b.targetHandle===e.targetHandle);if(t)return {valid:false,reason:"Source port is already connected"};if(i)return {valid:false,reason:"Target port is already connected"};let r=e.sourceHandle,a=e.targetHandle,c=o.nodes.find(b=>b.id===e.source),s=o.nodes.find(b=>b.id===e.target),d=(b,T)=>{if(!b)return false;let B=b.startsWith("pwr")||b.startsWith("power"),M=T?.type==="vertical-pdu"&&b!=="mgmt-net-1";return B||M},f=(b,T)=>{if(!b)return false;if(T?.type==="vertical-pdu"&&b==="mgmt-net-1")return true;let B=b.startsWith("net-")||b.startsWith("port-")||b.startsWith("uplink-")||b.includes("Fiber")||b.includes("Ports"),M=/^[A-Z0-9]+-\d+$/.test(b)&&!b.startsWith("pwr")&&!b.startsWith("power");return B||M},h=d(r,c),m=d(a,s),k=f(r,c),v=f(a,s);if(h&&v||m&&k)return {valid:false,reason:"Cannot connect network cable to power port"};if(h&&!m||m&&!h)return {valid:false,reason:"Power ports must connect to power-compatible ports"};let P=c?.type==="vertical-pdu",$=s?.type==="vertical-pdu";if(h||m){let b=P?s:$?c:null,T=P?c:$?s:null;if(b&&T&&o.edges.filter(u=>{let D=d(u.sourceHandle||""),p=d(u.targetHandle||""),l=u.source===b.id||u.target===b.id;return (D||p)&&l}).some(u=>u.source===T.id||u.target===T.id))return {valid:false,reason:"Dual-feed required: connect second power to a different PDU"}}return {valid:true}}function zt(e,o){if(!o)return;let t=o.data??{},i=t.handleSideMap;if(i&&i[e])return i[e];if(e==="net-top"||e==="net-bottom")return "front";if(e==="pwr-left-1"||e==="pwr-left-2"||e==="net-right-1"||e==="net-right-2")return "rear";let r=Array.isArray(t.ports)?t.ports:[],a=Array.isArray(t.rearPorts)?t.rearPorts:[];if(e.startsWith("pwr")||e.includes("power"))return "rear";for(let s of r)for(let d of s.ports||[])if((!!d.type&&String(d.type).includes("power")?d.label:`${s.name}-${d.label}`)===e)return "front";for(let s of a)for(let d of s.ports||[])if((!!d.type&&String(d.type).includes("power")?d.label:`${s.name}-${d.label}`)===e)return "rear"}function je(e={},o={}){let t={nodes:e.nodes??[],edges:e.edges??[],debug:e.debug??false},i=new Set;return {getState:()=>t,setState:m=>{t={...t,...m},i.forEach(k=>k(t));},subscribe:m=>(i.add(m),()=>i.delete(m)),selectEdgeZIndex:m=>{let k=t.nodes.find(D=>D.id===m.target);if(!k||k.type!=="device")return 1e3;let v=k.data?.view||"front",P=zt(m.targetHandle||"",k);if(P)return v===P?1e3:500;let $=(m.targetHandle||"").toString(),b=$.toLowerCase(),T=b.startsWith("pwr")||b.startsWith("power"),B=b.startsWith("net-")||b.startsWith("port-")||b.startsWith("uplink-")||b.includes("fiber")||b.includes("ports"),M=/^[A-Z0-9]+-\d+$/i.test($)&&!b.startsWith("pwr")&&!b.startsWith("power"),u=B||M;return T?v==="rear"?1e3:500:u?v==="front"?1e3:500:1e3},validateConnection:m=>(o.validateConnection||Mt)(m,t),selectNodeById:m=>t.nodes.find(k=>k.id===m),selectConnectedEdges:m=>t.edges.filter(k=>k.source===m||k.target===m)}}function Bt(e){let o=r=>e.subscribe(r),t=()=>e.getState();return Lt.useSyncExternalStore(o,t,t)}function Xe(e){let o=i=>e.subscribe(i),t=()=>e.getState().nodes;return Lt.useSyncExternalStore(o,t,t)}function Ge(e){let o=i=>e.subscribe(i),t=()=>e.getState().edges;return Lt.useSyncExternalStore(o,t,t)}function nt(e){return e.selectEdgeZIndex}function it(e){let o=300,t=(e.data.uHeight||42)*20,i=e.position.x,r=e.position.x+o,a=e.position.y,c=e.position.y+t;return {left:i,right:r,top:a,bottom:c}}function Se(e,o){let t=it(o);return e.x>=t.left&&e.x<=t.right&&e.y>=t.top&&e.y<=t.bottom}function Ce(e,o){let t=null,i=1/0;for(let r of o){if(!Se(e,r))continue;let a=Math.sqrt(Math.pow(e.x-r.position.x,2)+Math.pow(e.y-r.position.y,2));a<i&&(i=a,t=r);}return t}function me(e){let{edges:o,connection:t,edgeType:i,selectEdgeZIndex:r,findBy:a}=e,c=a==="source"?t.sourceHandle:t.targetHandle,s=a==="source"?t.source:t.target;if(!c||!s)return null;let d=o.find(v=>a==="source"?v.source===s&&v.sourceHandle===c:v.target===s&&v.targetHandle===c);if(!d)return null;let f=o.filter(v=>v.id!==d.id),h=reactflow.addEdge(t,f),m=h[h.length-1],k={...m,type:i,zIndex:r({...t,id:m.id,type:i}),style:{...m.style,zIndex:r({...t,id:m.id,type:i})}};return [...h.slice(0,-1),k]}var eo=(e,o,t)=>({rack:i=>jsxRuntime.jsx(Ue,{...i,onViewChange:e,onRackFaceChange:o,isDragOver:t===i.id}),fiber:_e,device:Oe,"vertical-pdu":Ve}),to={fiber:Me,power:ze},oo=({nodes:e,edges:o,initialNodes:t,initialEdges:i,onNodesChange:r,onEdgesChange:a,store:c,debug:s,onNodeClick:d,onEdgeClick:f,onViewChange:h,onRackFaceChange:m,className:k,style:v,alignRacksToBottom:P,colorMode:$="dark",onInit:b,onFlowMethods:T,showDownloadButton:B=false,downloadButtonPosition:M="top-right",downloadButtonText:u="Download Image",downloadButtonStyle:D})=>{let p=Array.isArray(e)&&Array.isArray(o),l=Lt__default.default.useMemo(()=>c||je({nodes:p?e||[]:t||e||[],edges:p?o||[]:i||o||[],debug:s}),[c,p,s]),I=Xe(l),U=Ge(l),[C,y,R]=reactflow.useNodesState(I),[G,A,ee]=reactflow.useEdgesState(U),E=nt(l),W=Lt.useRef(null),{toObject:F,setViewport:Ee,setNodes:ye,setEdges:oe}=reactflow.useReactFlow();Lt.useEffect(()=>{T&&T({toObject:F,setViewport:Ee,setNodes:n=>{ye(n),l.setState({nodes:n});},setEdges:n=>{oe(n),l.setState({edges:n});},toImage:n=>W.current?htmlToImage.toPng(W.current,n):Promise.reject(new Error("ReactFlow wrapper not available"))});},[T,F,Ee,ye,oe,l]);let ie=Lt.useCallback(()=>{if(!W.current){s&&console.error("ReactFlow wrapper ref is not available");return}htmlToImage.toPng(W.current,{filter:n=>!(n?.classList?.contains("react-flow__minimap")||n?.classList?.contains("react-flow__controls")||n?.classList?.contains("react-flow__attribution")||n?.classList?.contains("download-button")||n?.tagName==="BUTTON"),backgroundColor:$==="light"?"#ffffff":"#1a1a1a",pixelRatio:2}).then(n=>{let g=document.createElement("a");g.download=`network-diagram-${new Date().toISOString().split("T")[0]}.png`,g.href=n,g.click();}).catch(n=>{s&&console.error("Error downloading image:",n);});},[$,s]),[we,de]=Lt.useState(null),He=Lt.useMemo(()=>eo(h,m,we),[h,m,we]),ae=Lt.useMemo(()=>to,[]),re=Lt.useRef(C);Lt.useEffect(()=>{re.current=C;},[C]);let te=Lt.useRef(G);Lt.useEffect(()=>{te.current=G;},[G]),Lt.useEffect(()=>{y(I);},[I,y]),Lt.useEffect(()=>{A(U);},[U,A]),Lt.useEffect(()=>{p&&l.setState({nodes:e||[]});},[p,e,l]),Lt.useEffect(()=>{p&&l.setState({edges:o||[]});},[p,o,l]),Lt.useEffect(()=>{if(!P||!C||C.length===0)return;let n=C.filter(H=>H.type==="rack");if(n.length===0)return;let g=n.map(H=>{let le=H.data?.uHeight||42,$e=60+le*20;return (H.position?.y||0)+$e}),w=Math.min(...g),N=Math.max(...g);if(N-w<20)return;let x=N,V=C.map(H=>{if(H.type!=="rack")return H;let le=H.data?.uHeight||42,$e=60+le*20,vt=(H.position?.y||0)+$e,Je=x-vt;return Math.abs(Je)<5?H:{...H,position:{x:H.position?.x||0,y:(H.position?.y||0)+Je}}});V.some((H,_)=>H.position!==C[_].position)&&y(V);},[P,C,y]);let q=Lt.useCallback(n=>re.current.find(g=>g.id===n),[]);Lt.useEffect(()=>{A(n=>n.map(g=>{let w=E(g);return {...g,zIndex:w,style:{...g.style,zIndex:w}}}));},[C,A,E]),Lt.useEffect(()=>{let n=C.map(w=>{if(w.type==="device"&&w.parentId&&w.data.uPosition&&(!w.position||w.position.x===0&&w.position.y===0)){let N=q(w.parentId);if(N){let S=ue(N,w.data.uPosition);return {...w,position:S}}}return w});n.some((w,N)=>w.position!==C[N].position)&&y(n);},[C,y,q]);let ft=Lt.useCallback(n=>{let g=n.map(w=>{if(w.type==="position"&&w.position){let N=q(w.id);if(N&&N.type==="device"&&N.parentId){let S=q(N.parentId);if(S){let x=Te(N,S,w.position,re.current);if(x.uPosition!==void 0){let V={...N,data:{...N.data,uPosition:x.uPosition}};y(O=>O.map(H=>H.id===N.id?V:H));}return {...w,position:{x:x.x,y:x.y}}}}if(N&&N.type==="device"&&N.parentId){let S=q(N.parentId);if(S){let x=S;if(!Se(w.position,x)){let V=w.position.x+x.position.x,O=w.position.y+x.position.y,H={...N,parentId:void 0,extent:void 0,data:{...N.data,uPosition:void 0}};return y(_=>_.map(le=>le.id===N.id?H:le)),{...w,position:{x:V,y:O}}}}}}return w});R(g);},[R,y,q]),mt=Lt.useCallback((n,g)=>{de(null);},[]),ht=Lt.useCallback((n,g,w)=>{if(g.type==="device"&&!g.parentId){let N=re.current.filter(x=>x.type==="rack").map(x=>x),S=Ce(g.position,N);de(S?.id??null);}else de(null);},[]),bt=Lt.useCallback((n,g,w)=>{if(g.type==="device"&&!g.parentId){let N=re.current.filter(x=>x.type==="rack").map(x=>x),S=Ce(g.position,N);if(S){let x=g.position.x-S.position.x,V=g.position.y-S.position.y,O={...g,parentId:S.id,extent:"parent",position:{x,y:V},data:{...g.data,uPosition:1}},H=re.current.map(_=>_.id===g.id?O:_);y(H),p||l.setState({nodes:H});}}de(null);},[y,p,l]);Lt.useCallback(n=>{if(!n.source||!n.target||!n.sourceHandle||!n.targetHandle)return {valid:true};let g=n.sourceHandle,w=n.targetHandle,N=te.current.some(x=>x.source===n.source&&x.sourceHandle===g),S=te.current.some(x=>x.target===n.target&&x.targetHandle===w);return N?{valid:false,reason:"Source port is already connected"}:S?{valid:false,reason:"Target port is already connected"}:{valid:true}},[]);let yt=Lt.useCallback(n=>{let g=q(n.source),w=g?.type==="vertical-pdu",N=g?.data,S=g?.type==="device"&&N?.deviceType==="switch",x=!!n.targetHandle&&(n.targetHandle.startsWith("pwr")||n.targetHandle.startsWith("power")),V=!!n.targetHandle&&(n.targetHandle.startsWith("net-")||n.targetHandle.startsWith("port-")||/^[A-Z0-9]+-\d+$/i.test(n.targetHandle));if(w&&x&&n.target&&n.targetHandle){let _=me({edges:te.current,connection:n,edgeType:"power",selectEdgeZIndex:E,findBy:"target"});if(_){A(_);return}}if(S&&V&&n.target&&n.targetHandle){let _=me({edges:te.current,connection:n,edgeType:"fiber",selectEdgeZIndex:E,findBy:"target"});if(_){A(_);return}}let O=l.validateConnection({source:n.source??null,target:n.target??null,sourceHandle:n.sourceHandle??null,targetHandle:n.targetHandle??null});if(!O.valid){if(w&&n.source&&n.sourceHandle){let _=me({edges:te.current,connection:n,edgeType:x?"power":"fiber",selectEdgeZIndex:E,findBy:"source"});if(_){A(_);return}}if(S&&n.source&&n.sourceHandle){let _=me({edges:te.current,connection:n,edgeType:"fiber",selectEdgeZIndex:E,findBy:"source"});if(_){A(_);return}}s&&console.warn(`Connection rejected: ${O.reason}`);return}let H={...n,type:w&&x?"power":"fiber",zIndex:E({...n,id:"temp-id"})};A(_=>reactflow.addEdge(H,_));},[A,l,E,q,s]),wt=Lt.useCallback((n,g)=>{if((n.metaKey||n.ctrlKey)&&g.type==="device"){let N=g.data||{},S=N.view||(Array.isArray(N.rearPorts)&&N.rearPorts.length>0?"rear":"front"),x=S==="front"?"rear":"front";s&&console.log(`Command+click: Toggling device ${g.id} from ${S} to ${x}`),h&&h(g.id,x),d&&d(g);}else d&&d(g);},[h,d,s]),xt=Lt.useCallback(()=>{},[]),Nt=Lt.useCallback((n,g)=>{f&&f(g);},[f]),[J,qe]=Lt.useState(null);reactflow.useOnSelectionChange({onChange:({nodes:n})=>{if(n&&n.length===1){let g=n[0];qe(g),d&&d(g);}else qe(null),d&&d(null);}});let kt=Lt.useCallback(()=>{if(!J)return;let n=q(J.id);if(n){if(n.type==="rack"){let N=((n.data||{}).face||"front")==="front"?"rear":"front";m?m(n.id,N):y(S=>S.map(x=>x.id===n.id?{...x,data:{...x.data,face:N}}:x.parentId===n.id?{...x,data:{...x.data,view:N}}:x));return}if(n.type==="device"){let g=n.data||{},w=Array.isArray(g.rearPorts)&&g.rearPorts.length>0,N=Array.isArray(g.ports)&&g.ports.length>0,x=(g.view||(w&&!N?"rear":"front"))==="front"?"rear":"front";h?h(n.id,x):y(V=>V.map(O=>O.id===n.id?{...O,data:{...O.data,view:x}}:O));}}},[J,q,m,h,y]);return jsxRuntime.jsxs("div",{ref:W,className:`${k||""} ${$==="light"?"react-flow-light":"react-flow-dark"}`,style:{width:"100%",height:"100%",...v},children:[jsxRuntime.jsxs(reactflow.ReactFlow,{nodes:C,edges:G,onNodesChange:n=>{ft(n),p?r&&r(re.current):l.setState({nodes:re.current});},onEdgesChange:n=>{ee(n),p?a&&a(te.current):l.setState({edges:te.current});},onConnect:yt,onNodeClick:wt,onNodeDoubleClick:xt,onNodeDragStart:mt,onNodeDrag:ht,onNodeDragStop:bt,onEdgeClick:Nt,onInit:b,nodeTypes:He,edgeTypes:ae,defaultEdgeOptions:{zIndex:1e3,reconnectable:true},nodesDraggable:true,nodesConnectable:true,elementsSelectable:true,selectNodesOnDrag:false,fitView:true,proOptions:{hideAttribution:true},children:[jsxRuntime.jsx(reactflow.Background,{}),jsxRuntime.jsx(reactflow.Controls,{}),jsxRuntime.jsx(reactflow.MiniMap,{}),jsxRuntime.jsx(reactflow.Panel,{position:"bottom-right",className:"react-networks-attribution",children:jsxRuntime.jsx("a",{href:"https://github.com/MP70/react-networks",target:"_blank",rel:"noopener noreferrer",className:"react-networks-attribution-link",children:"react-networks"})})]}),B&&jsxRuntime.jsx("button",{className:"download-button",onClick:ie,style:{position:"absolute",top:M.includes("top")?"10px":"auto",bottom:M.includes("bottom")?"10px":"auto",right:M.includes("right")?"10px":"auto",left:M.includes("left")?"10px":"auto",zIndex:1e3,background:"#374151",color:"#e5e7eb",border:"1px solid #4b5563",borderRadius:"4px",padding:"0.5rem 0.75rem",fontSize:"0.875rem",cursor:"pointer",transition:"all 0.2s ease",...D},children:u}),J&&(J.type==="rack"||J.type==="device")&&jsxRuntime.jsx("div",{style:{position:"absolute",top:12,right:12,display:"flex",gap:8,zIndex:2e3},children:jsxRuntime.jsx("button",{onClick:n=>{n.preventDefault(),kt();},style:{background:"#374151",color:"#e5e7eb",border:"1px solid #4b5563",borderRadius:4,padding:"6px 10px",fontSize:11,fontFamily:"monospace",cursor:"pointer"},title:(()=>{let n=J.data;if(J.type==="rack")return (n?.face||"front")==="front"?"Switch to rear":"Switch to front";{let g=Array.isArray(n?.rearPorts)&&n.rearPorts.length>0,w=Array.isArray(n?.ports)&&n.ports.length>0;return (n?.view||(g&&!w?"rear":"front"))==="front"?"Switch to rear":"Switch to front"}})(),children:(()=>{let n=J.data;if(J.type==="rack")return (n?.face||"front")==="front"?"\u21C4 Rear":"\u21C4 Front";{let g=Array.isArray(n?.rearPorts)&&n.rearPorts.length>0,w=Array.isArray(n?.ports)&&n.ports.length>0;return (n?.view||(g&&!w?"rear":"front"))==="front"?"\u21C4 Rear":"\u21C4 Front"}})()})})]})},ro=e=>jsxRuntime.jsx(reactflow.ReactFlowProvider,{children:jsxRuntime.jsx(oo,{...e})});var lt=e=>({id:`rack-${e.id}`,type:"rack",position:{x:0,y:0},data:{label:e.name,status:typeof e.status=="object"&&e.status?e.status.value:e.status,uHeight:e.u_height??e.units??42,inventoryId:e.id,inventoryType:"rack",facilityId:e.facility_id,serial:e.serial,assetTag:e.asset_tag,site:typeof e.site=="object"&&e.site?e.site.name:e.site,role:typeof e.role=="object"&&e.role?e.role.name:e.role,tenant:typeof e.tenant=="object"&&e.tenant?e.tenant.name:e.tenant}}),pt=e=>({id:`device-${e.id}`,type:"device",position:{x:0,y:0},parentId:e.rack?`rack-${typeof e.rack=="object"&&e.rack?e.rack.id:e.rack}`:void 0,extent:e.rack?"parent":void 0,data:{label:e.name,status:typeof e.status=="object"&&e.status?e.status.value:e.status,deviceType:e.device_type?.model??e.model,manufacturer:e.device_type?.manufacturer?.name??e.manufacturer,role:typeof e.device_role=="object"&&e.device_role?e.device_role.name:e.role,uHeight:e.device_type?.u_height??e.u_height??1,uPosition:e.position||1,view:e.face||"front",inventoryId:e.id,inventoryType:"device",primaryIp4:typeof e.primary_ip4=="object"&&e.primary_ip4?e.primary_ip4.address:e.primary_ip4,primaryIp6:typeof e.primary_ip6=="object"&&e.primary_ip6?e.primary_ip6.address:e.primary_ip6,site:typeof e.site=="object"&&e.site?e.site.name:e.site,rack:typeof e.rack=="object"&&e.rack?e.rack.name:e.rack}}),ut=e=>{let o=r=>{if(!r)return;if(typeof r=="string")return r;let a=r.device;return typeof a=="object"&&a?a.id:a},t=o(e.termination_a),i=o(e.termination_b);return {id:`cable-${e.id}`,source:`device-${t}`,target:`device-${i}`,type:"fiber",data:{bandwidth:e.type?.label??e.bandwidth,length:e.length||0,color:e.color,inventoryId:e.id,inventoryType:"cable",status:typeof e.status=="object"&&e.status?e.status.value:e.status,terminationA:typeof e.termination_a=="object"&&e.termination_a?e.termination_a.name:e.termination_a,terminationB:typeof e.termination_b=="object"&&e.termination_b?e.termination_b.name:e.termination_b}}},no=e=>{let o=[],t=[];return e.racks.forEach(i=>o.push(lt(i))),e.devices.forEach(i=>o.push(pt(i))),e.cables.forEach(i=>t.push(ut(i))),{nodes:o,edges:t}},io=e=>{let o=e.filter(r=>r.type==="rack"),t=e.filter(r=>r.type==="device"),i=e.filter(r=>!["rack","device"].includes(r.type));return o.forEach((r,a)=>{r.position={x:a*300,y:100};}),t.forEach(r=>{if(r.parentId){let a=o.find(c=>c.id===r.parentId);if(a){let c=r.data.uPosition||1,s=r.data.uHeight||1;r.position={x:a.position.x+50,y:a.position.y+c*20-s*10};}}else r.position={x:Math.random()*400+100,y:Math.random()*200+50};}),i.forEach((r,a)=>{r.position={x:a*150+100,y:300};}),e};var he=class extends Error{constructor(t,i,r,a,c){super(`Device placement conflict: ${i} at U${r}-${r+a-1} in rack ${t}${c?` conflicts with ${c}`:""}`);this.rackId=t;this.deviceId=i;this.uPosition=r;this.uHeight=a;this.conflictWith=c;this.name="DevicePlacementError";}};function Ke(e,o={}){let t=[],i=[];for(let r of e.devices)r.unit+r.height-1>e.units&&i.push({deviceId:r.id,uPosition:r.unit,uHeight:r.height,rackUHeight:e.units});for(let r=0;r<e.devices.length;r++){let a=e.devices[r],c=a.unit,s=a.unit+a.height-1;for(let d=r+1;d<e.devices.length;d++){let f=e.devices[d],h=f.unit,m=f.unit+f.height-1;c<=m&&s>=h&&t.push({deviceId:a.id,uPosition:a.unit,uHeight:a.height,conflictWith:f.id});}}return {isValid:t.length===0&&i.length===0,conflicts:t,outOfBounds:i}}function gt(e,o,t={}){let{deviceTypeMapping:i={}}=t,r=i[e.type]||"device",a=ue(o,e.unit,e.height);return {id:e.id,type:r,position:a,parentId:o.id,extent:"parent",data:{label:e.name,status:"active",deviceType:e.type,uHeight:e.height,uPosition:e.unit,width:e.width||"full",role:e.role,ports:e.ports,rearPorts:e.rearPorts,connections:e.connections}}}function ao(e){return {id:e.id,type:"rack",position:e.position,data:{label:e.name,status:"active",uHeight:e.units,uNumberingDirection:e.uNumberingDirection||"bottom-up",customHeaderText:e.customHeaderText,ports:[]}}}function so(e,o={}){let{conflictPolicy:t="strict",validatePlacements:i=true}=o,r=[],a=[];if(i)for(let c of e){let s=Ke(c,o);if(!s.isValid&&t==="strict"){let d=[];throw s.conflicts.forEach(f=>{d.push(`Device ${f.deviceId} at U${f.uPosition}-${f.uPosition+f.uHeight-1} conflicts with ${f.conflictWith}`);}),s.outOfBounds.forEach(f=>{d.push(`Device ${f.deviceId} at U${f.uPosition}-${f.uPosition+f.uHeight-1} exceeds rack height (${f.rackUHeight}U)`);}),new he(c.id,s.conflicts[0]?.deviceId||s.outOfBounds[0]?.deviceId||"unknown",s.conflicts[0]?.uPosition||s.outOfBounds[0]?.uPosition||1,s.conflicts[0]?.uHeight||s.outOfBounds[0]?.uHeight||1)}}for(let c of e){let s=ao(c);r.push(s);for(let d of c.devices)try{let f=gt(d,s,o);a.push(f);}catch(f){if(t==="strict")throw f;if(t==="nearest"){let h=ke(s,{id:d.id,data:{label:d.name,uHeight:d.height}},a,d.unit);if(h!==d.unit){console.warn(`Device ${d.id} moved from U${d.unit} to U${h} due to conflict`);let m={...d,unit:h},k=gt(m,s,o);a.push(k);}else throw new he(c.id,d.id,d.unit,d.height)}}}return r.push(...a),r}function co(e){let o=[],t=e.filter(i=>i.type==="rack");for(let i of t){let a=e.filter(c=>c.type==="device"&&c.parentId===i.id).map(c=>({id:c.id,name:c.data.label,unit:c.data.uPosition||1,height:c.data.uHeight||1,type:c.data.deviceType||"server",width:c.data.width,ports:c.data.ports,connections:c.data.connections}));o.push({id:i.id,name:i.data.label,position:i.position,units:i.data.uHeight||42,uNumberingDirection:i.data.uNumberingDirection||"bottom-up",customHeaderText:i.data.customHeaderText,devices:a});}return o}function lo(e,o,t,i){return e.map(r=>r.id!==o?r:{...r,devices:r.devices.map(a=>a.id!==t?a:{...a,unit:i})})}function po(e,o,t,i={}){let{conflictPolicy:r="strict"}=i;return e.map(a=>{if(a.id!==o)return a;if(r==="strict"&&!Ke({...a,devices:[...a.devices,t]},i).isValid)throw new he(o,t.id,t.unit,t.height);return {...a,devices:[...a.devices,t]}})}function uo(e,o,t){return e.map(i=>i.id!==o?i:{...i,devices:i.devices.filter(r=>r.id!==t)})}
2
+ exports.DeviceNode=Oe;exports.DevicePlacementError=he;exports.FiberEdge=Me;exports.FiberNode=_e;exports.NetworkDiagram=ro;exports.POWER_CONNECTORS=Be;exports.PowerEdge=ze;exports.RackNode=Ue;exports.VerticalPDU=Ve;exports.Width=et;exports.addDeviceToRack=po;exports.buildNodesFromRackConfig=so;exports.calculateDevicePositionFromU=ue;exports.createNetworkDiagramStore=je;exports.createRackConfigFromNodes=co;exports.findNearestRack=Ce;exports.findNextAvailableUPosition=ke;exports.generateLayout=io;exports.getConnectorConfig=De;exports.getDeviceConnectorType=Re;exports.getPDUPortType=We;exports.getPowerPortStyle=ge;exports.getRackBounds=it;exports.getStatusColor=Z;exports.inventoryCableToNetworkEdge=ut;exports.inventoryDeviceToNetworkNode=pt;exports.inventoryRackToNetworkNode=lt;exports.inventoryToNetworkDiagram=no;exports.isHighPowerConnector=At;exports.isPointInRack=Se;exports.isUPositionAvailable=Ie;exports.removeDeviceFromRack=uo;exports.replaceEdge=me;exports.snapToUPosition=Te;exports.updateDeviceUPosition=Qe;exports.updateDeviceUPositionInSchema=lo;exports.useDiagramEdges=Ge;exports.useDiagramNodes=Xe;exports.useNetworkDiagram=Bt;exports.validateAndSnapDevice=Dt;exports.validateRackDevicePlacements=Ke;//# sourceMappingURL=index.js.map
2
3
  //# sourceMappingURL=index.js.map