tscircuit 0.0.3174 → 0.0.3175-libonly

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.
@@ -1045,10 +1045,10 @@ orientation: ${label.orientation}`});for(let inlineLabel of inlineNetLabelPlacem
1045
1045
  `)});let textX=inlineLabel.center.x,textY=inlineLabel.center.y,anchorSide="center",rotation6;if(inlineLabel.stubTracePath){let stubStart=inlineLabel.stubTracePath[0],stubEnd=inlineLabel.stubTracePath[1],labelOffset=inlineLabel.width/2;stubEnd[inlineLabel.axis]>stubStart[inlineLabel.axis]?(labelOffset=-inlineLabel.width/2,anchorSide="center_left"):anchorSide="center_right",inlineLabel.axis==="x"?textX+=labelOffset:textY+=labelOffset}inlineLabel.axis==="y"&&(rotation6=90),graphics.texts.push({x:textX,y:textY,text:inlineLabel.netLabelText??inlineLabel.netId??"",color:"green",fontSize:inlineLabel.height,anchorSide,rotation:rotation6}),graphics.points.push({x:inlineLabel.anchorPoint.x,y:inlineLabel.anchorPoint.y,color:"green",label:`inline anchor
1046
1046
  ${inlineLabel.netLabelText??inlineLabel.netId}`})}return graphics},estimateInlineNetLabelWidth=(text4,fontSize=DEFAULT_INLINE_NET_LABEL_HEIGHT)=>{let fontScale=fontSize/.18;return text4.length*.12*fontScale+.12*fontScale},getAnchorCandidates=(segment5,labelWidth,step=.1)=>{let along2=segment5.axis==="x"?"x":"y",start=segment5.start[along2],end=segment5.end[along2],mid=(start+end)/2,direction4=Math.sign(end-start)||1,pointAt2=value=>segment5.axis==="x"?{x:value,y:segment5.start.y}:{x:segment5.start.x,y:segment5.start.y+(value-start)},slack=segment5.length-labelWidth;if(slack<=0)return[pointAt2(mid)];let offsets=[0];for(let offset3=step;offset3<=slack/2+1e-9;offset3+=step)offsets.push(offset3,-offset3);return offsets.push(slack/2,-slack/2),offsets.map(offset3=>pointAt2(mid+offset3*direction4))},doesPathIntersectBounds3=(path,bounds)=>{for(let i23=0;i23<path.length-1;i23++){let a23=path[i23],b23=path[i23+1],segmentBounds={minX:Math.min(a23.x,b23.x),maxX:Math.max(a23.x,b23.x),minY:Math.min(a23.y,b23.y),maxY:Math.max(a23.y,b23.y)};if(boundsOverlap3(segmentBounds,bounds))return!0}return!1},GEOMETRY_EPSILON3=1e-6,getCollisionLimitedTerminalStubEnd=({start,intendedEnd,minimumLength,traces,ownGlobalConnNetId,ignoredTraceIds})=>{let isHorizontal5=Math.abs(intendedEnd.x-start.x)>=Math.abs(intendedEnd.y-start.y),alongAxis=isHorizontal5?"x":"y",acrossAxis=isHorizontal5?"y":"x",direction4=Math.sign(intendedEnd[alongAxis]-start[alongAxis])||1,intendedLength=Math.abs(intendedEnd[alongAxis]-start[alongAxis]),availableLength=intendedLength;for(let trace of traces)if(!ignoredTraceIds.has(trace.mspPairId)&&trace.globalConnNetId!==ownGlobalConnNetId)for(let segmentIndex=0;segmentIndex<trace.tracePath.length-1;segmentIndex++){let segmentStart=trace.tracePath[segmentIndex],segmentEnd=trace.tracePath[segmentIndex+1],startAlong=(segmentStart[alongAxis]-start[alongAxis])*direction4,endAlong=(segmentEnd[alongAxis]-start[alongAxis])*direction4,startAcross=segmentStart[acrossAxis]-start[acrossAxis],endAcross=segmentEnd[acrossAxis]-start[acrossAxis],minAlong=Math.min(startAlong,endAlong),maxAlong=Math.max(startAlong,endAlong),minAcross=Math.min(startAcross,endAcross),maxAcross=Math.max(startAcross,endAcross),collisionDistance;if(Math.abs(startAcross)<=GEOMETRY_EPSILON3&&Math.abs(endAcross)<=GEOMETRY_EPSILON3&&maxAlong>=-GEOMETRY_EPSILON3&&minAlong<=intendedLength+INLINE_NET_LABEL_STUB_TRACE_CLEARANCE+GEOMETRY_EPSILON3)collisionDistance=Math.max(0,minAlong);else{let crossesStubAxis=minAcross<=GEOMETRY_EPSILON3&&maxAcross>=-GEOMETRY_EPSILON3,perpendicularAlong=(startAlong+endAlong)/2;crossesStubAxis&&Math.abs(startAlong-endAlong)<=GEOMETRY_EPSILON3&&perpendicularAlong>=-GEOMETRY_EPSILON3&&perpendicularAlong<=intendedLength+INLINE_NET_LABEL_STUB_TRACE_CLEARANCE+GEOMETRY_EPSILON3&&(collisionDistance=Math.max(0,perpendicularAlong))}collisionDistance!==void 0&&(availableLength=Math.min(availableLength,collisionDistance-INLINE_NET_LABEL_STUB_TRACE_CLEARANCE))}return availableLength+GEOMETRY_EPSILON3<minimumLength?null:isHorizontal5?{x:start.x+direction4*availableLength,y:start.y}:{x:start.x,y:start.y+direction4*availableLength}},EPSILON210=1e-6,isStrictlyBetween2=({coordinate:coordinate3,segmentStartCoordinate,segmentEndCoordinate})=>coordinate3>Math.min(segmentStartCoordinate,segmentEndCoordinate)+EPSILON210&&coordinate3<Math.max(segmentStartCoordinate,segmentEndCoordinate)-EPSILON210,isStrictInteriorPerpendicularCrossing=({firstSegmentStart,firstSegmentEnd,secondSegmentStart,secondSegmentEnd})=>{let firstIsHorizontal=Math.abs(firstSegmentStart.y-firstSegmentEnd.y)<=EPSILON210,firstIsVertical=Math.abs(firstSegmentStart.x-firstSegmentEnd.x)<=EPSILON210,secondIsHorizontal=Math.abs(secondSegmentStart.y-secondSegmentEnd.y)<=EPSILON210,secondIsVertical=Math.abs(secondSegmentStart.x-secondSegmentEnd.x)<=EPSILON210,horizontalStart,horizontalEnd;if(firstIsHorizontal)horizontalStart=firstSegmentStart,horizontalEnd=firstSegmentEnd;else if(secondIsHorizontal)horizontalStart=secondSegmentStart,horizontalEnd=secondSegmentEnd;else return!1;let verticalStart,verticalEnd;if(firstIsVertical)verticalStart=firstSegmentStart,verticalEnd=firstSegmentEnd;else if(secondIsVertical)verticalStart=secondSegmentStart,verticalEnd=secondSegmentEnd;else return!1;return isStrictlyBetween2({coordinate:verticalStart.x,segmentStartCoordinate:horizontalStart.x,segmentEndCoordinate:horizontalEnd.x})&&isStrictlyBetween2({coordinate:horizontalStart.y,segmentStartCoordinate:verticalStart.y,segmentEndCoordinate:verticalEnd.y})},doesTraceRecoveryPathConflict=(tracePath,collisionTraces)=>{for(let pathIndex=0;pathIndex<tracePath.length-1;pathIndex++){let pathStart=tracePath[pathIndex],pathEnd=tracePath[pathIndex+1];for(let trace of collisionTraces)for(let traceIndex=0;traceIndex<trace.tracePath.length-1;traceIndex++){let traceStart=trace.tracePath[traceIndex],traceEnd=trace.tracePath[traceIndex+1];if(doSegmentsIntersect32(pathStart,pathEnd,traceStart,traceEnd)&&!isStrictInteriorPerpendicularCrossing({firstSegmentStart:pathStart,firstSegmentEnd:pathEnd,secondSegmentStart:traceStart,secondSegmentEnd:traceEnd}))return!0}}return!1},getTraceRecoveryConnectivityMaps=inputProblem=>{let chipMap={},pinMap=new Map;for(let chip of inputProblem.chips){chipMap[chip.chipId]=chip;for(let pin of chip.pins)pinMap.set(pin.pinId,{...pin,chipId:chip.chipId,_facingDirection:pin._facingDirection??getPinDirection2(pin,chip)})}return{chipMap,pinMap}},getSimpleConnectionPath=(first,second)=>{let firstDirection=dir(first._facingDirection),secondDirection=dir(second._facingDirection),dx22=second.x-first.x,dy22=second.y-first.y;if((firstDirection.x?Math.abs(dy22)<=1e-6:Math.abs(dx22)<=1e-6)&&firstDirection.x===-secondDirection.x&&firstDirection.y===-secondDirection.y&&dx22*firstDirection.x+dy22*firstDirection.y>1e-6)return[{x:first.x,y:first.y},{x:second.x,y:second.y}];if(firstDirection.x*secondDirection.x||firstDirection.y*secondDirection.y)return;let elbow=firstDirection.x?{x:second.x,y:first.y}:{x:first.x,y:second.y};for(let[pin,direction4]of[[first,firstDirection],[second,secondDirection]])if((elbow.x-pin.x)*direction4.x+(elbow.y-pin.y)*direction4.y<=1e-6)return;return[{x:first.x,y:first.y},elbow,{x:second.x,y:second.y}]},EPS18=1e-9,isHorizontal4=(start,end)=>Math.abs(start.y-end.y)<EPS18,isVertical5=(start,end)=>Math.abs(start.x-end.x)<EPS18,compactConsecutivePoints=path=>path.filter((point12,index2)=>{let previousPoint=path[index2-1];return!previousPoint||Math.abs(point12.x-previousPoint.x)>=EPS18||Math.abs(point12.y-previousPoint.y)>=EPS18}),isValidOrthogonalPath=path=>{if(path.length<2||!path.every((point12,index2)=>{let nextPoint=path[index2+1];return nextPoint?isHorizontal4(point12,nextPoint)||isVertical5(point12,nextPoint):!0}))return!1;for(let firstSegmentIndex=0;firstSegmentIndex<path.length-1;firstSegmentIndex++)for(let secondSegmentIndex=firstSegmentIndex+2;secondSegmentIndex<path.length-1;secondSegmentIndex++)if(segmentsIntersect22(path[firstSegmentIndex],path[firstSegmentIndex+1],path[secondSegmentIndex],path[secondSegmentIndex+1]))return!1;return!0},getEndpointAlignedSegmentCandidates=tracePath=>{let candidates=[];for(let segmentIndex=2;segmentIndex<=tracePath.length-4;segmentIndex++){let previousPoint=tracePath[segmentIndex-1],start=tracePath[segmentIndex],end=tracePath[segmentIndex+1],nextPoint=tracePath[segmentIndex+2],segmentIsVertical=isVertical5(start,end),segmentIsHorizontal=isHorizontal4(start,end);if(!segmentIsVertical&&!segmentIsHorizontal||segmentIsVertical&&(!isHorizontal4(previousPoint,start)||!isHorizontal4(end,nextPoint))||segmentIsHorizontal&&(!isVertical5(previousPoint,start)||!isVertical5(end,nextPoint)))continue;let alignedCoordinates=segmentIsVertical?[previousPoint.x,nextPoint.x]:[previousPoint.y,nextPoint.y];for(let alignedCoordinate of alignedCoordinates){if(Math.abs(alignedCoordinate-(segmentIsVertical?start.x:start.y))<EPS18)continue;let candidate=tracePath.map(point12=>({...point12}));segmentIsVertical?(candidate[segmentIndex].x=alignedCoordinate,candidate[segmentIndex+1].x=alignedCoordinate):(candidate[segmentIndex].y=alignedCoordinate,candidate[segmentIndex+1].y=alignedCoordinate);let compactedCandidate=compactConsecutivePoints(candidate);isValidOrthogonalPath(compactedCandidate)&&candidates.push(compactedCandidate)}}return candidates},countOtherNetCrossings2=({tracePath,globalConnNetId,otherTraces})=>otherTraces.reduce((crossingCount,otherTrace)=>crossingCount+(otherTrace.globalConnNetId===globalConnNetId?0:countPathIntersections(tracePath,otherTrace.tracePath)),0),reduceTraceCrossings=({tracePath,globalConnNetId,otherTraces,isCandidateValid})=>{let bestPath=tracePath,bestCrossingCount=countOtherNetCrossings2({tracePath,globalConnNetId,otherTraces}),bestPathLength=getPathLength4(tracePath);for(let candidate of getEndpointAlignedSegmentCandidates(tracePath)){if(!isCandidateValid(candidate))continue;let crossingCount=countOtherNetCrossings2({tracePath:candidate,globalConnNetId,otherTraces}),pathLength4=getPathLength4(candidate);(crossingCount<bestCrossingCount||crossingCount===bestCrossingCount&&pathLength4<bestPathLength)&&(bestPath=candidate,bestCrossingCount=crossingCount,bestPathLength=pathLength4)}return bestPath},RECOVERED_TRACE_PREFIX="net-label-to-trace-",MAX_NAMED_NET_RECOVERY_PERPENDICULAR_OFFSET=.05,MAX_ROUTED_COMPONENT_RECOVERY_PERPENDICULAR_OFFSET=.25,getCanonicalPairKey=(firstPinId,secondPinId)=>[firstPinId,secondPinId].sort().join("--"),getPerpendicularOffset=(firstPoint,secondPoint)=>{let xDistance=Math.abs(firstPoint.x-secondPoint.x),yDistance=Math.abs(firstPoint.y-secondPoint.y);return xDistance>=yDistance?yDistance:xDistance},arePinsCoFacingAlongSeparationAxis=(firstPin,secondPin)=>{if(firstPin._facingDirection!==secondPin._facingDirection)return!1;let xDistance=Math.abs(firstPin.x-secondPin.x),yDistance=Math.abs(firstPin.y-secondPin.y);return xDistance>=yDistance?firstPin._facingDirection==="x+"||firstPin._facingDirection==="x-":firstPin._facingDirection==="y+"||firstPin._facingDirection==="y-"},NetLabelToTraceSolver=class extends BaseSolver11{constructor(input2,options={}){super();__publicField(this,"input");__publicField(this,"options");__publicField(this,"inputProblem");__publicField(this,"outputTraces");__publicField(this,"outputNetLabelPlacements");__publicField(this,"recoveredTraceIds",new Set);__publicField(this,"chipMap");__publicField(this,"pinMap");__publicField(this,"canRecoverParallelPair");__publicField(this,"queuedCandidates");__publicField(this,"currentCandidate",null);this.input=input2,this.options=options,this.inputProblem=input2.inputProblem,this.outputTraces=[...input2.traces],this.outputNetLabelPlacements=[...input2.netLabelPlacements];let{chipMap,pinMap}=getTraceRecoveryConnectivityMaps(this.inputProblem);this.chipMap=chipMap,this.pinMap=pinMap,this.canRecoverParallelPair=getParallelNetLabelPolicy(this.inputProblem,getConnectivityMapsFromInputProblem(this.inputProblem).netConnMap,new Set(input2.traces.filter(trace=>trace.pinIds.length>1).flatMap(trace=>trace.pinIds))),this.queuedCandidates=this.buildCandidatePairs(),this.stats.candidateCount=this.queuedCandidates.length,this.stats.recoveredTraceCount=0}getConstructorParams(){return[this.input,this.options]}isPortOnlyFallbackLabel(label,groundGlobalConnNetIds){return!(label.pinIds.length!==1||label.mspConnectionPairIds.length!==0||!label.netId||groundGlobalConnNetIds.has(label.globalConnNetId))}isDirectConnectionLabel(label){if(!label.netId||label.pinIds.length!==1)return!1;let pinId=label.pinIds[0];return this.inputProblem.directConnections.some(connection=>connection.netId===label.netId&&connection.pinIds.includes(pinId))}getMultiPinNetConnection(label){if(!label.netId||label.pinIds.length!==1)return;let pinId=label.pinIds[0];return this.inputProblem.netConnections.find(connection=>connection.isGround===!1&&connection.pinIds.length>2&&connection.netId===label.netId&&connection.pinIds.includes(pinId))}getTwoPinNetConnection(label){return this.inputProblem.netConnections.find(connection=>!connection.isGround&&connection.pinIds.length===2&&connection.netId===label.netId&&connection.pinIds.includes(label.pinIds[0]))}buildCandidatePairs(){let{netConnMap}=getConnectivityMapsFromInputProblem(this.inputProblem),groundGlobalConnNetIds=new Set;for(let connection of this.inputProblem.netConnections){if(!connection.isGround)continue;let globalConnNetId=netConnMap.getNetConnectedToId(connection.netId);globalConnNetId&&groundGlobalConnNetIds.add(globalConnNetId)}let labelsByGlobalNet=new Map;for(let label of this.input.netLabelPlacements){if(!this.isPortOnlyFallbackLabel(label,groundGlobalConnNetIds)||!this.isDirectConnectionLabel(label)&&!this.getMultiPinNetConnection(label)&&!this.getTwoPinNetConnection(label))continue;let labels=labelsByGlobalNet.get(label.globalConnNetId)??[];labels.push(label),labelsByGlobalNet.set(label.globalConnNetId,labels)}let candidates=[];for(let labels of labelsByGlobalNet.values())for(let firstIndex=0;firstIndex<labels.length;firstIndex++)for(let secondIndex=firstIndex+1;secondIndex<labels.length;secondIndex++){let firstLabel=labels[firstIndex],secondLabel=labels[secondIndex],firstPin=this.pinMap.get(firstLabel.pinIds[0]),secondPin=this.pinMap.get(secondLabel.pinIds[0]);if(!firstPin||!secondPin||!this.canRecoverParallelPair(firstPin,secondPin))continue;let perpendicularOffset=getPerpendicularOffset(firstPin,secondPin),bothLabelsBelongToDirectConnections=this.isDirectConnectionLabel(firstLabel)&&this.isDirectConnectionLabel(secondLabel),firstMultiPinNetConnection=this.getMultiPinNetConnection(firstLabel),secondMultiPinNetConnection=this.getMultiPinNetConnection(secondLabel),twoPinNetConnection=this.getTwoPinNetConnection(firstLabel),simpleConnectionPath=!bothLabelsBelongToDirectConnections&&twoPinNetConnection&&firstPin.chipId!==secondPin.chipId&&twoPinNetConnection===this.getTwoPinNetConnection(secondLabel)?getSimpleConnectionPath(firstPin,secondPin):void 0;!simpleConnectionPath&&!bothLabelsBelongToDirectConnections&&(!firstMultiPinNetConnection||firstMultiPinNetConnection!==secondMultiPinNetConnection||perpendicularOffset>MAX_NAMED_NET_RECOVERY_PERPENDICULAR_OFFSET)||arePinsInDifferentSchematicSections(this.inputProblem,firstPin,secondPin)||doesPairCrossRestrictedCenterLines({inputProblem:this.inputProblem,chipMap:this.chipMap,pinIdMap:this.pinMap,p1:firstPin,p2:secondPin})||candidates.push({firstLabel,secondLabel,pins:[firstPin,secondPin],perpendicularOffset,routeDistance:Math.abs(firstPin.x-secondPin.x)+Math.abs(firstPin.y-secondPin.y),key:getCanonicalPairKey(firstPin.pinId,secondPin.pinId),recoveryMode:"fallback_labels",simpleConnectionPath})}candidates.push(...this.buildRoutedComponentCandidates(groundGlobalConnNetIds));let selectedCandidates=this.options.onlyInlineDirectConnections||this.options.onlyInlineConnections?candidates.filter(candidate=>this.options.onlyInlineConnections&&candidate.simpleConnectionPath?.length===2&&this.inputProblem.netConnections.some(net=>net.allowInlineNetLabel&&!net.isGround&&net.pinIds.length===2&&candidate.pins.every(pin=>net.pinIds.includes(pin.pinId)))||this.inputProblem.directConnections.some(connection=>candidate.pins.every(pin=>connection.pinIds.includes(pin.pinId))&&(connection.allowInlineNetLabel||this.inputProblem.netConnections.some(net=>net.allowInlineNetLabel&&candidate.pins.every(pin=>net.pinIds.includes(pin.pinId)))))):candidates;return selectedCandidates.sort((first,second)=>first.perpendicularOffset-second.perpendicularOffset||first.routeDistance-second.routeDistance||first.key.localeCompare(second.key)),selectedCandidates}buildRoutedComponentCandidates(groundGlobalConnNetIds){let{netConnMap}=getConnectivityMapsFromInputProblem(this.inputProblem),candidates=[],directConnections=new Set(this.inputProblem.directConnections);for(let connection of[...this.inputProblem.netConnections.filter(connection2=>connection2.pinIds.length>2&&connection2.isGround===!1),...this.inputProblem.directConnections]){let isDirectConnection=directConnections.has(connection),canRecoverElbow=isDirectConnection&&(this.options.onlyInlineDirectConnections||this.options.onlyInlineConnections),globalConnNetId=netConnMap.getNetConnectedToId(connection.pinIds[0]);if(!globalConnNetId||isDirectConnection&&groundGlobalConnNetIds.has(globalConnNetId))continue;let connectionPinIds=connection.pinIds;isDirectConnection&&(connectionPinIds=[...this.pinMap.keys()].filter(pinId=>netConnMap.getNetConnectedToId(pinId)===globalConnNetId));let traceConnectedPinComponents=getTraceConnectedPinComponents({pinIds:connectionPinIds,traces:this.outputTraces.filter(trace=>trace.globalConnNetId===globalConnNetId)}).filter(component=>component.traces.length>0);for(let firstIndex=0;firstIndex<traceConnectedPinComponents.length;firstIndex++)for(let secondIndex=firstIndex+1;secondIndex<traceConnectedPinComponents.length;secondIndex++){let firstComponent=traceConnectedPinComponents[firstIndex],secondComponent=traceConnectedPinComponents[secondIndex];if(isDirectConnection&&!(firstComponent.pinIds.includes(connection.pinIds[0])&&secondComponent.pinIds.includes(connection.pinIds[1])||firstComponent.pinIds.includes(connection.pinIds[1])&&secondComponent.pinIds.includes(connection.pinIds[0])))continue;let firstLabel=this.input.netLabelPlacements.find(label=>label.globalConnNetId===globalConnNetId&&label.mspConnectionPairIds.length>0&&label.pinIds.some(pinId=>firstComponent.pinIds.includes(pinId))),secondLabel=this.input.netLabelPlacements.find(label=>label.globalConnNetId===globalConnNetId&&label.mspConnectionPairIds.length>0&&label.pinIds.some(pinId=>secondComponent.pinIds.includes(pinId)));if(!firstLabel||!secondLabel||firstLabel===secondLabel)continue;let labelsAreAligned=getPerpendicularOffset(firstLabel.anchorPoint,secondLabel.anchorPoint)<=MAX_ROUTED_COMPONENT_RECOVERY_PERPENDICULAR_OFFSET;if(!labelsAreAligned&&!canRecoverElbow)continue;let bestCandidate,firstPinIds=firstComponent.pinIds,secondPinIds=secondComponent.pinIds;isDirectConnection&&(firstPinIds=connection.pinIds.filter(pinId=>firstComponent.pinIds.includes(pinId)),secondPinIds=connection.pinIds.filter(pinId=>secondComponent.pinIds.includes(pinId)));for(let firstPinId of firstPinIds)for(let secondPinId of secondPinIds){let firstPin=this.pinMap.get(firstPinId),secondPin=this.pinMap.get(secondPinId);if(!firstPin||!secondPin||!this.canRecoverParallelPair(firstPin,secondPin)||isDirectConnection&&firstPin.chipId===secondPin.chipId)continue;let perpendicularOffset=getPerpendicularOffset(firstPin,secondPin),simpleConnectionPath=canRecoverElbow&&(!labelsAreAligned||perpendicularOffset>MAX_ROUTED_COMPONENT_RECOVERY_PERPENDICULAR_OFFSET)?getSimpleConnectionPath(firstPin,secondPin):void 0;if((!labelsAreAligned||perpendicularOffset>MAX_ROUTED_COMPONENT_RECOVERY_PERPENDICULAR_OFFSET)&&!simpleConnectionPath||arePinsCoFacingAlongSeparationAxis(firstPin,secondPin)||arePinsInDifferentSchematicSections(this.inputProblem,firstPin,secondPin)||doesPairCrossRestrictedCenterLines({inputProblem:this.inputProblem,chipMap:this.chipMap,pinIdMap:this.pinMap,p1:firstPin,p2:secondPin}))continue;let routeDistance=Math.abs(firstPin.x-secondPin.x)+Math.abs(firstPin.y-secondPin.y),recoveryMode="routed_components";isDirectConnection&&(recoveryMode="routed_direct_connection");let candidate={firstLabel,secondLabel,pins:[firstPin,secondPin],perpendicularOffset,routeDistance,key:getCanonicalPairKey(firstPin.pinId,secondPin.pinId),recoveryMode,netConnectionPinIds:connectionPinIds,simpleConnectionPath};(!bestCandidate||candidate.routeDistance<bestCandidate.routeDistance||candidate.routeDistance===bestCandidate.routeDistance&&(candidate.perpendicularOffset<bestCandidate.perpendicularOffset||candidate.perpendicularOffset===bestCandidate.perpendicularOffset&&candidate.key.localeCompare(bestCandidate.key)<0))&&(bestCandidate=candidate)}bestCandidate&&candidates.push(bestCandidate)}}return candidates}isSupersededConnectorTrace(trace,candidate){return!this.input.netLabelConnectorTraceIds?.has(trace.mspPairId)||trace.pinIds.length!==1?!1:candidate.pins.some(pin=>pin.pinId===trace.pinIds[0])}routeIntersectsRemainingLabels(tracePath,candidate){for(let label of this.outputNetLabelPlacements)if(!(label===candidate.firstLabel||label===candidate.secondLabel)&&pathIntersectsRenderedLabel(tracePath,label))return!0;return this.input.inlineNetLabelPlacements.some(label=>pathIntersectsRenderedLabel(tracePath,label))}tryAcceptCurrentRoute(){let candidate=this.currentCandidate,tracePath=this.activeSubSolver?.solvedTracePath;if(!candidate||!tracePath)return;let retainedTraces=this.outputTraces.filter(trace=>!this.isSupersededConnectorTrace(trace,candidate)),collisionTraces=retainedTraces;if(candidate.recoveryMode!=="fallback_labels"&&(collisionTraces=retainedTraces.filter(trace=>trace.globalConnNetId!==candidate.firstLabel.globalConnNetId)),candidate.simpleConnectionPath&&(tracePath=candidate.simpleConnectionPath,findFirstCollision(tracePath,this.activeSubSolver.obstacles)||collisionTraces.reduce((count,trace)=>count+findPerpendicularPathCrossings(tracePath,trace.tracePath,{includeTerminalSegments:!0}).length,0)>1)||doesTraceRecoveryPathConflict(tracePath,collisionTraces)||this.routeIntersectsRemainingLabels(tracePath,candidate))return;tracePath=reduceTraceCrossings({tracePath,globalConnNetId:candidate.firstLabel.globalConnNetId,otherTraces:collisionTraces,isCandidateValid:candidatePath=>findFirstCollision(candidatePath,this.activeSubSolver.obstacles)===null&&!doesTraceRecoveryPathConflict(candidatePath,collisionTraces)&&!this.routeIntersectsRemainingLabels(candidatePath,candidate)});let[firstPin,secondPin]=candidate.pins,mspPairId=`${RECOVERED_TRACE_PREFIX}${candidate.key}`,recoveredTrace={mspPairId,dcConnNetId:candidate.firstLabel.globalConnNetId,globalConnNetId:candidate.firstLabel.globalConnNetId,pins:[firstPin,secondPin],tracePath,mspConnectionPairIds:[mspPairId],pinIds:[firstPin.pinId,secondPin.pinId]};this.recoveredTraceIds.add(mspPairId),this.outputTraces=[...retainedTraces,recoveredTrace],candidate.recoveryMode!=="routed_components"&&(this.outputNetLabelPlacements=this.outputNetLabelPlacements.filter(label=>label!==candidate.firstLabel&&label!==candidate.secondLabel)),this.stats.recoveredTraceCount++}areCandidatePinsAlreadyConnected(candidate){return candidate.netConnectionPinIds?getTraceConnectedPinComponents({pinIds:candidate.netConnectionPinIds,traces:this.outputTraces}).some(component=>component.pinIds.includes(candidate.pins[0].pinId)&&component.pinIds.includes(candidate.pins[1].pinId)):!1}_step(){if(this.activeSubSolver){this.activeSubSolver.step(),this.activeSubSolver.solved?(this.tryAcceptCurrentRoute(),this.activeSubSolver=null,this.currentCandidate=null):this.activeSubSolver.failed&&(this.activeSubSolver=null,this.currentCandidate=null);return}let candidate=this.queuedCandidates.shift();for(;candidate&&(!this.outputNetLabelPlacements.includes(candidate.firstLabel)||!this.outputNetLabelPlacements.includes(candidate.secondLabel)||this.areCandidatePinsAlreadyConnected(candidate));)candidate=this.queuedCandidates.shift();if(!candidate){this.solved=!0;return}this.currentCandidate=candidate,this.activeSubSolver=new SchematicTraceSingleLineSolver2({inputProblem:this.inputProblem,pins:candidate.pins,chipMap:this.chipMap})}getOutput(){return{traces:this.outputTraces,netLabelPlacements:this.outputNetLabelPlacements,inlineNetLabelPlacements:this.input.inlineNetLabelPlacements}}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();let graphics=visualizeInlineNetLabelOutput({inputProblem:this.inputProblem,...this.getOutput()});for(let trace of this.outputTraces)this.recoveredTraceIds.has(trace.mspPairId)&&graphics.lines.push({points:trace.tracePath,strokeColor:"green",label:`recovered from net labels: ${trace.pinIds.join(" -> ")}`});return graphics}};function definePipelineStep22(solverName,solverClass,getConstructorParams,opts={}){return{solverName,solverClass,getConstructorParams,onSolved:opts.onSolved,shouldSkip:opts.shouldSkip}}var SchematicTracePipelineSolver=class extends BaseSolver11{constructor(inputProblem,opts){super();__publicField(this,"mspConnectionPairSolver");__publicField(this,"schematicTraceLinesSolver");__publicField(this,"longDistancePairSolver");__publicField(this,"unroutedTraceRecoverySolver");__publicField(this,"traceOverlapShiftSolver");__publicField(this,"netLabelPlacementSolver");__publicField(this,"labelMergingSolver");__publicField(this,"traceLabelOverlapAvoidanceSolver");__publicField(this,"traceCleanupSolver");__publicField(this,"example28Solver");__publicField(this,"availableNetOrientationSolver");__publicField(this,"postLabelTraceOverlapShiftSolver");__publicField(this,"railNetLabelCornerPlacementSolver");__publicField(this,"traceAnchoredNetLabelOverlapSolver");__publicField(this,"finalTraceAnchoredNetLabelOverlapSolver");__publicField(this,"preAlignmentNetLabelTraceCollisionSolver");__publicField(this,"netLabelTraceCollisionSolver");__publicField(this,"traceCleanupSolver2");__publicField(this,"netLabelNetLabelCollisionSolver");__publicField(this,"finalRailNetLabelCornerPlacementSolver");__publicField(this,"traceElbowTransitionSimplificationSolver");__publicField(this,"preAlignmentTraceElbowTransitionSimplificationSolver");__publicField(this,"finalTraceElbowTransitionSimplificationSolver");__publicField(this,"sameNetJunctionAlignmentSolver");__publicField(this,"inlineDirectTraceRecoverySolver");__publicField(this,"inlineNetLabelSolver");__publicField(this,"netLabelToTraceSolver");__publicField(this,"startTimeOfPhase");__publicField(this,"endTimeOfPhase");__publicField(this,"timeSpentOnPhase");__publicField(this,"firstIterationOfPhase");__publicField(this,"inputProblem");__publicField(this,"hideRatsNet");__publicField(this,"pipelineDef",[definePipelineStep22("mspConnectionPairSolver",MspConnectionPairSolver,()=>[{inputProblem:this.inputProblem}],{onSolved:mspSolver=>{}}),definePipelineStep22("schematicTraceLinesSolver",SchematicTraceLinesSolver,()=>[{mspConnectionPairs:this.mspConnectionPairSolver.mspConnectionPairs,dcConnMap:this.mspConnectionPairSolver.dcConnMap,globalConnMap:this.mspConnectionPairSolver.globalConnMap,inputProblem:this.inputProblem,chipMap:this.mspConnectionPairSolver.chipMap}]),definePipelineStep22("longDistancePairSolver",LongDistancePairSolver,instance=>[{inputProblem:instance.inputProblem,primaryMspConnectionPairs:instance.mspConnectionPairSolver.mspConnectionPairs,alreadySolvedTraces:instance.schematicTraceLinesSolver.solvedTracePaths,failedConnectionPairs:instance.schematicTraceLinesSolver.failedConnectionPairs}],{onSolved:schematicTraceLinesSolver=>{}}),definePipelineStep22("unroutedTraceRecoverySolver",UnroutedTraceRecoverySolver,instance=>[{inputProblem:instance.inputProblem,failedConnectionPairs:instance.schematicTraceLinesSolver.failedConnectionPairs,alreadySolvedTraces:instance.longDistancePairSolver.getOutput().allTracesMerged}]),definePipelineStep22("traceOverlapShiftSolver",TraceOverlapShiftSolver,()=>[{inputProblem:this.inputProblem,inputTracePaths:this.unroutedTraceRecoverySolver?.getOutput().allTracesMerged,globalConnMap:this.mspConnectionPairSolver.globalConnMap}],{onSolved:_solver=>{}}),definePipelineStep22("netLabelPlacementSolver",NetLabelPlacementSolver,()=>[{inputProblem:this.inputProblem,inputTraceMap:this.traceOverlapShiftSolver?.correctedTraceMap??Object.fromEntries(this.unroutedTraceRecoverySolver.getOutput().allTracesMerged.map(p23=>[p23.mspPairId,p23]))}],{onSolved:_solver=>{}}),definePipelineStep22("traceLabelOverlapAvoidanceSolver",TraceLabelOverlapAvoidanceSolver,instance=>{let traceMap=instance.traceOverlapShiftSolver?.correctedTraceMap??Object.fromEntries(instance.unroutedTraceRecoverySolver.getOutput().allTracesMerged.map(p23=>[p23.mspPairId,p23])),traces=Object.values(traceMap),netLabelPlacements=instance.netLabelPlacementSolver.netLabelPlacements;return[{inputProblem:instance.inputProblem,traces,netLabelPlacements}]}),definePipelineStep22("traceElbowTransitionSimplificationSolver",TraceElbowTransitionSimplificationSolver,instance=>{let overlapAvoidanceOutput=instance.traceLabelOverlapAvoidanceSolver.getOutput();return[{inputProblem:instance.inputProblem,traces:overlapAvoidanceOutput.traces,completedReroutes:overlapAvoidanceOutput.completedReroutes,netLabelPlacements:instance.traceLabelOverlapAvoidanceSolver.netLabelPlacements,paddingBuffer:.1}]}),definePipelineStep22("traceCleanupSolver",TraceCleanupSolver,instance=>{let traces=instance.traceElbowTransitionSimplificationSolver.getOutput().traces,overlapShiftSolver=instance.traceOverlapShiftSolver,inlineLabelNetIds=new Set([...instance.inputProblem.directConnections,...instance.inputProblem.netConnections].filter(connection=>connection.allowInlineNetLabel).map(connection=>connection.netId)),traceIdsInNewCrossingsAfterOverlapShift=new Set;for(let traceIndex=0;traceIndex<overlapShiftSolver.inputTracePaths.length;traceIndex++){let inputTrace=overlapShiftSolver.inputTracePaths[traceIndex],shiftedTrace=overlapShiftSolver.correctedTraceMap[inputTrace.mspPairId];for(let otherTraceIndex=traceIndex+1;otherTraceIndex<overlapShiftSolver.inputTracePaths.length;otherTraceIndex++){let otherInputTrace=overlapShiftSolver.inputTracePaths[otherTraceIndex];if(inputTrace.globalConnNetId===otherInputTrace.globalConnNetId||!inlineLabelNetIds.has(inputTrace.userNetId??"")&&!inlineLabelNetIds.has(otherInputTrace.userNetId??""))continue;let otherShiftedTrace=overlapShiftSolver.correctedTraceMap[otherInputTrace.mspPairId],crossingCountBeforeShift=findPerpendicularPathCrossings(inputTrace.tracePath,otherInputTrace.tracePath).length;findPerpendicularPathCrossings(shiftedTrace.tracePath,otherShiftedTrace.tracePath).length>crossingCountBeforeShift&&(traceIdsInNewCrossingsAfterOverlapShift.add(inputTrace.mspPairId),traceIdsInNewCrossingsAfterOverlapShift.add(otherInputTrace.mspPairId))}}let labelMergingOutput=instance.traceLabelOverlapAvoidanceSolver.labelMergingSolver.getOutput();return[{inputProblem:instance.inputProblem,allTraces:traces,allLabelPlacements:labelMergingOutput.netLabelPlacements,mergedLabelNetIdMap:labelMergingOutput.mergedLabelNetIdMap,paddingBuffer:.1,eligibleTraceIds:traceIdsInNewCrossingsAfterOverlapShift}]}),definePipelineStep22("netLabelPlacementSolver",NetLabelPlacementSolver,instance=>{let traces=instance.traceCleanupSolver?.getOutput().traces??instance.traceLabelOverlapAvoidanceSolver.getOutput().traces;return[{inputProblem:instance.inputProblem,inputTraceMap:Object.fromEntries(traces.map(trace=>[trace.mspPairId,trace]))}]}),definePipelineStep22("example28Solver",Example28Solver,instance=>{let traces=instance.traceCleanupSolver?.getOutput().traces??instance.traceLabelOverlapAvoidanceSolver.getOutput().traces;return[{inputProblem:instance.inputProblem,traces,netLabelPlacements:instance.netLabelPlacementSolver.netLabelPlacements}]}),definePipelineStep22("availableNetOrientationSolver",AvailableNetOrientationSolver,instance=>[{inputProblem:instance.inputProblem,traces:instance.example28Solver.outputTraces,netLabelPlacements:instance.example28Solver.outputNetLabelPlacements}]),definePipelineStep22("postLabelTraceOverlapShiftSolver",TraceOverlapShiftSolver,instance=>[{inputProblem:instance.inputProblem,inputTracePaths:instance.availableNetOrientationSolver.traces,globalConnMap:instance.mspConnectionPairSolver.globalConnMap,traceIdsToShift:new Set(instance.availableNetOrientationSolver.netLabelConnectorTraceIds)}]),definePipelineStep22("railNetLabelCornerPlacementSolver",RailNetLabelCornerPlacementSolver,instance=>[{inputProblem:instance.inputProblem,traces:Object.values(instance.postLabelTraceOverlapShiftSolver.correctedTraceMap),netLabelPlacements:instance.availableNetOrientationSolver.outputNetLabelPlacements,netLabelConnectorTraceIds:instance.availableNetOrientationSolver.netLabelConnectorTraceIds}]),definePipelineStep22("traceAnchoredNetLabelOverlapSolver",TraceAnchoredNetLabelOverlapSolver,instance=>[{inputProblem:instance.inputProblem,netLabelConnectorTraceIds:instance.availableNetOrientationSolver.netLabelConnectorTraceIds,traces:instance.railNetLabelCornerPlacementSolver.getOutput().traces,netLabelPlacements:instance.railNetLabelCornerPlacementSolver.outputNetLabelPlacements}]),definePipelineStep22("preAlignmentNetLabelTraceCollisionSolver",NetLabelTraceCollisionSolver,instance=>[{inputProblem:instance.inputProblem,traces:instance.railNetLabelCornerPlacementSolver.getOutput().traces,netLabelPlacements:instance.traceAnchoredNetLabelOverlapSolver.outputNetLabelPlacements}]),definePipelineStep22("preAlignmentTraceElbowTransitionSimplificationSolver",TraceElbowTransitionSimplificationSolver,instance=>{let collisionOutput=instance.preAlignmentNetLabelTraceCollisionSolver.getOutput();return[{inputProblem:instance.inputProblem,traces:collisionOutput.traces,completedReroutes:collisionOutput.completedReroutes,netLabelPlacements:collisionOutput.netLabelPlacements,paddingBuffer:.1,allowShorterPaths:!0}]}),definePipelineStep22("traceCleanupSolver2",TraceCleanupSolver,instance=>{let collisionOutput=instance.preAlignmentTraceElbowTransitionSimplificationSolver.getOutput(),labelMergingOutput=instance.traceLabelOverlapAvoidanceSolver.labelMergingSolver.getOutput();return[{inputProblem:instance.inputProblem,allTraces:collisionOutput.traces,allLabelPlacements:collisionOutput.netLabelPlacements,mergedLabelNetIdMap:labelMergingOutput.mergedLabelNetIdMap,paddingBuffer:.1,operations:["rerouting_generated_net_label_connector_crossings","aligning_same_net_rails"],eligibleTraceIds:new Set(instance.traceCleanupSolver.getOutput().traces.map(trace=>trace.mspPairId)),netLabelConnectorTraceIds:instance.availableNetOrientationSolver.netLabelConnectorTraceIds}]}),definePipelineStep22("netLabelTraceCollisionSolver",NetLabelTraceCollisionSolver,instance=>{let previousOutput=instance.preAlignmentNetLabelTraceCollisionSolver.getOutput(),alignmentOutput=instance.traceCleanupSolver2.getOutput(),connectorMovement=moveNetLabelConnectorsToReroutedTraces({originalTraces:previousOutput.traces,reroutedTraces:alignmentOutput.traces,netLabelPlacements:previousOutput.netLabelPlacements}),previousTraceMap=new Map(previousOutput.traces.map(trace=>[trace.mspPairId,trace])),netLabelPlacements=connectorMovement.netLabelPlacements;for(let trace of connectorMovement.traces){let previousTrace=previousTraceMap.get(trace.mspPairId);if(!previousTrace||previousTrace.tracePath===trace.tracePath)continue;let currentLabels=netLabelPlacements;netLabelPlacements=moveAttachedLabelsToReroutedTrace({trace:previousTrace,originalTracePath:previousTrace.tracePath,reroutedTracePath:trace.tracePath,netLabelPlacements:currentLabels}).map((movedLabel,labelIndex)=>{let label=currentLabels[labelIndex];return label.orientation==="y+"||label.orientation==="y-"?movedLabel:label})}return[{inputProblem:instance.inputProblem,traces:connectorMovement.traces,netLabelPlacements}]}),definePipelineStep22("finalTraceElbowTransitionSimplificationSolver",TraceElbowTransitionSimplificationSolver,instance=>{let collisionOutput=instance.netLabelTraceCollisionSolver.getOutput(),completedReroutes=[...instance.traceLabelOverlapAvoidanceSolver.getOutput().completedReroutes,...instance.preAlignmentNetLabelTraceCollisionSolver.getOutput().completedReroutes,...collisionOutput.completedReroutes];return[{inputProblem:instance.inputProblem,traces:collisionOutput.traces,completedReroutes,netLabelPlacements:collisionOutput.netLabelPlacements,paddingBuffer:.1,allowShorterPaths:!0}]}),definePipelineStep22("finalRailNetLabelCornerPlacementSolver",RailNetLabelCornerPlacementSolver,instance=>[{inputProblem:instance.inputProblem,...instance.finalTraceElbowTransitionSimplificationSolver.getOutput(),originalTraces:instance.railNetLabelCornerPlacementSolver.getOutput().traces,netLabelConnectorTraceIds:instance.availableNetOrientationSolver.netLabelConnectorTraceIds,onlyOverlappingLabels:!0}]),definePipelineStep22("netLabelNetLabelCollisionSolver",NetLabelNetLabelCollisionSolver,instance=>{let placementOutput=instance.finalRailNetLabelCornerPlacementSolver.getOutput();return[{inputProblem:instance.inputProblem,traces:placementOutput.traces,netLabelPlacements:placementOutput.netLabelPlacements,preserveNonInlineLabelsAgainstInlineEligibleCollisions:!0}]}),definePipelineStep22("finalTraceAnchoredNetLabelOverlapSolver",TraceAnchoredNetLabelOverlapSolver,instance=>[{inputProblem:instance.inputProblem,netLabelConnectorTraceIds:instance.availableNetOrientationSolver.netLabelConnectorTraceIds,traces:instance.netLabelNetLabelCollisionSolver.traces,netLabelPlacements:instance.netLabelNetLabelCollisionSolver.getOutput().netLabelPlacements,overlapMode:"traces"}]),definePipelineStep22("sameNetJunctionAlignmentSolver",SameNetJunctionAlignmentSolver,instance=>{let collisionOutput=instance.finalTraceAnchoredNetLabelOverlapSolver.getOutput();return[{inputProblem:instance.inputProblem,traces:instance.netLabelNetLabelCollisionSolver.traces,netLabelPlacements:collisionOutput.netLabelPlacements,netLabelConnectorTraceIds:instance.availableNetOrientationSolver.netLabelConnectorTraceIds}]}),definePipelineStep22("inlineDirectTraceRecoverySolver",NetLabelToTraceSolver,instance=>[{inputProblem:instance.inputProblem,...instance.sameNetJunctionAlignmentSolver.getOutput(),inlineNetLabelPlacements:[],netLabelConnectorTraceIds:instance.availableNetOrientationSolver.netLabelConnectorTraceIds},{onlyInlineConnections:!0}]),definePipelineStep22("inlineNetLabelSolver",InlineNetLabelSolver,instance=>{let recoveredOutput=instance.inlineDirectTraceRecoverySolver.getOutput(),completedReroutes=[...instance.traceLabelOverlapAvoidanceSolver.getOutput().completedReroutes,...instance.preAlignmentNetLabelTraceCollisionSolver.getOutput().completedReroutes,...instance.netLabelTraceCollisionSolver.getOutput().completedReroutes];return[{inputProblem:instance.inputProblem,traces:recoveredOutput.traces,netLabelPlacements:recoveredOutput.netLabelPlacements,completedReroutes,resolveTraceCollisions:!0,netLabelConnectorTraceIds:instance.availableNetOrientationSolver.netLabelConnectorTraceIds}]}),definePipelineStep22("netLabelToTraceSolver",NetLabelToTraceSolver,instance=>{let inlineOutput=instance.inlineNetLabelSolver.getOutput();return[{inputProblem:instance.inputProblem,...inlineOutput}]})]);__publicField(this,"currentPipelineStepIndex",0);this.hideRatsNet=opts?.hideRatsNet??!1,this.inputProblem=this.cloneAndCorrectInputProblem(inputProblem),this.MAX_ITERATIONS=1e6,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={},this.firstIterationOfPhase={}}getSolverName(){return"SchematicTracePipelineSolver"}getConstructorParams(){return[this.inputProblem,{hideRatsNet:this.hideRatsNet}]}cloneAndCorrectInputProblem(original){let cloned=structuredClone({...original,_chipObstacleSpatialIndex:void 0,_hideRatsNet:this.hideRatsNet});return correctPinsInsideChips(cloned),cloned}_step(){let pipelineStepDef=this.pipelineDef[this.currentPipelineStepIndex];if(!pipelineStepDef){this.solved=!0;return}if(this.activeSubSolver){this.activeSubSolver.step(),this.activeSubSolver.solved?(this.endTimeOfPhase[pipelineStepDef.solverName]=performance.now(),this.timeSpentOnPhase[pipelineStepDef.solverName]=this.endTimeOfPhase[pipelineStepDef.solverName]-this.startTimeOfPhase[pipelineStepDef.solverName],pipelineStepDef.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null);return}let constructorParams=pipelineStepDef.getConstructorParams(this);this.activeSubSolver=new pipelineStepDef.solverClass(...constructorParams),this[pipelineStepDef.solverName]=this.activeSubSolver,this.timeSpentOnPhase[pipelineStepDef.solverName]=0,this.startTimeOfPhase[pipelineStepDef.solverName]=performance.now(),this.firstIterationOfPhase[pipelineStepDef.solverName]=this.iterations}solveUntilPhase(phase){for(;this.getCurrentPhase().toLowerCase()!==phase.toLowerCase();)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();let visualizations=[visualizeInputProblem2(this.inputProblem,{hideRatsNet:this.hideRatsNet}),...this.pipelineDef.map(p23=>this[p23.solverName]?.visualize()).filter(Boolean).map((viz,stepIndex)=>{for(let rect of viz.rects??[])rect.step=stepIndex;for(let point12 of viz.points??[])point12.step=stepIndex;for(let circle32 of viz.circles??[])circle32.step=stepIndex;for(let text4 of viz.texts??[])text4.step=stepIndex;for(let line4 of viz.lines??[])line4.step=stepIndex;return viz})];if(visualizations.length===1)return visualizations[0];let finalGraphics={points:visualizations.flatMap(v23=>v23.points||[]),rects:visualizations.flatMap(v23=>v23.rects||[]),lines:visualizations.flatMap(v23=>v23.lines||[]),circles:visualizations.flatMap(v23=>v23.circles||[]),texts:visualizations.flatMap(v23=>v23.texts||[])};return colorAvailableNetOrientationLabels(finalGraphics,this.inputProblem),finalGraphics}preview(){return this.activeSubSolver?this.activeSubSolver.preview():super.preview()}},POINT_EPSILON2=1e-8,isPointOnSegment32=(point12,start,end)=>{let cross52=(point12.y-start.y)*(end.x-start.x)-(point12.x-start.x)*(end.y-start.y);if(Math.abs(cross52)>POINT_EPSILON2)return!1;let dot23=(point12.x-start.x)*(end.x-start.x)+(point12.y-start.y)*(end.y-start.y);if(dot23<-POINT_EPSILON2)return!1;let squaredLength6=(end.x-start.x)**2+(end.y-start.y)**2;return dot23<=squaredLength6+POINT_EPSILON2},isPointInRing=(point12,ring23)=>{let isInside2=!1;for(let currentIndex=0,previousIndex=ring23.vertices.length-1;currentIndex<ring23.vertices.length;previousIndex=currentIndex++){let current23=ring23.vertices[currentIndex],previous=ring23.vertices[previousIndex];if(isPointOnSegment32(point12,previous,current23))return!0;current23.y>point12.y!=previous.y>point12.y&&point12.x<(previous.x-current23.x)*(point12.y-current23.y)/(previous.y-current23.y)+current23.x&&(isInside2=!isInside2)}return isInside2},isPointInShape=(point12,shape50)=>isPointInRing(point12,shape50.outer_ring)&&!shape50.inner_rings.some(innerRing=>isPointInRing(point12,innerRing)),isPointInShapeUnion=(point12,shapes)=>shapes.some(shape50=>isPointInShape(point12,shape50)),getShapeUnionBounds=shapes=>{let vertices=shapes.flatMap(shape50=>shape50.outer_ring.vertices);if(vertices.length!==0)return{minX:Math.min(...vertices.map(vertex=>vertex.x)),maxX:Math.max(...vertices.map(vertex=>vertex.x)),minY:Math.min(...vertices.map(vertex=>vertex.y)),maxY:Math.max(...vertices.map(vertex=>vertex.y))}},isViaAnnulusInsideShapeUnion=({center:center2,radius,shapes})=>{let samplePoints=[center2];for(let sampleIndex=0;sampleIndex<32;sampleIndex++){let angle3=sampleIndex/32*Math.PI*2;samplePoints.push({x:center2.x+Math.cos(angle3)*radius,y:center2.y+Math.sin(angle3)*radius})}return samplePoints.every(samplePoint=>isPointInShapeUnion(samplePoint,shapes))},layerMatches=(layer,layers)=>layers.some(candidateLayer=>String(candidateLayer)===String(layer)),componentToObstacle=component=>{if(!(component.do_not_place||!component.obstructs_within_bounds))return{kind:"rect",center:component.center,width:component.width,height:component.height,ccwRotation:component.rotation}},smtPadToObstacle=smtPad2=>smtPad2.shape==="circle"?{kind:"circle",center:{x:smtPad2.x,y:smtPad2.y},radius:smtPad2.radius}:smtPad2.shape==="polygon"?{kind:"polygon",points:smtPad2.points}:{kind:"rect",center:{x:smtPad2.x,y:smtPad2.y},width:smtPad2.width,height:smtPad2.height,ccwRotation:smtPad2.shape==="rotated_rect"||smtPad2.shape==="rotated_pill"?smtPad2.ccw_rotation:0},platedHoleToObstacle=platedHole2=>{if(platedHole2.shape==="circle")return{kind:"circle",center:{x:platedHole2.x,y:platedHole2.y},radius:platedHole2.outer_diameter/2};if("outer_width"in platedHole2)return{kind:"rect",center:{x:platedHole2.x,y:platedHole2.y},width:platedHole2.outer_width,height:platedHole2.outer_height,ccwRotation:platedHole2.ccw_rotation};if(platedHole2.shape==="hole_with_polygon_pad"){let rotationRadians=(platedHole2.ccw_rotation??0)*Math.PI/180,cosine=Math.cos(rotationRadians),sine=Math.sin(rotationRadians);return{kind:"polygon",points:platedHole2.pad_outline.map(point12=>({x:platedHole2.x+point12.x*cosine-point12.y*sine,y:platedHole2.y+point12.x*sine+point12.y*cosine}))}}return{kind:"rect",center:{x:platedHole2.x,y:platedHole2.y},width:platedHole2.rect_pad_width,height:platedHole2.rect_pad_height,ccwRotation:"rect_ccw_rotation"in platedHole2?platedHole2.rect_ccw_rotation??0:0}},holeToObstacle=hole=>"hole_diameter"in hole?hole.hole_shape==="circle"?{kind:"circle",center:{x:hole.x,y:hole.y},radius:hole.hole_diameter/2}:{kind:"rect",center:{x:hole.x,y:hole.y},width:hole.hole_diameter,height:hole.hole_diameter,ccwRotation:0}:{kind:"rect",center:{x:hole.x,y:hole.y},width:hole.hole_width,height:hole.hole_height,ccwRotation:hole.hole_shape==="rotated_pill"?hole.ccw_rotation:0},getDistanceToSegment=(point12,start,end)=>{let segmentX=end.x-start.x,segmentY=end.y-start.y,squaredLength6=segmentX**2+segmentY**2;if(squaredLength6===0)return Math.hypot(point12.x-start.x,point12.y-start.y);let projection2=Math.max(0,Math.min(1,((point12.x-start.x)*segmentX+(point12.y-start.y)*segmentY)/squaredLength6));return Math.hypot(point12.x-(start.x+projection2*segmentX),point12.y-(start.y+projection2*segmentY))},isPointInPolygon4=(point12,polygon32)=>{let isInside2=!1;for(let currentIndex=0,previousIndex=polygon32.length-1;currentIndex<polygon32.length;previousIndex=currentIndex++){let current23=polygon32[currentIndex],previous=polygon32[previousIndex];current23.y>point12.y!=previous.y>point12.y&&point12.x<(previous.x-current23.x)*(point12.y-current23.y)/(previous.y-current23.y)+current23.x&&(isInside2=!isInside2)}return isInside2},doesCircleIntersectObstacle=(center2,radius,obstacle)=>{if(obstacle.kind==="circle")return Math.hypot(center2.x-obstacle.center.x,center2.y-obstacle.center.y)<radius+obstacle.radius;if(obstacle.kind==="polygon")return isPointInPolygon4(center2,obstacle.points)?!0:obstacle.points.some((point12,pointIndex)=>getDistanceToSegment(center2,point12,obstacle.points[(pointIndex+1)%obstacle.points.length])<radius);let rotationRadians=-obstacle.ccwRotation*Math.PI/180,deltaX=center2.x-obstacle.center.x,deltaY=center2.y-obstacle.center.y,localX=deltaX*Math.cos(rotationRadians)-deltaY*Math.sin(rotationRadians),localY=deltaX*Math.sin(rotationRadians)+deltaY*Math.cos(rotationRadians),outsideX=Math.max(Math.abs(localX)-obstacle.width/2,0),outsideY=Math.max(Math.abs(localY)-obstacle.height/2,0);return Math.hypot(outsideX,outsideY)<radius},getStitchingObstacles=(circuitJson,layers)=>circuitJson.flatMap(element2=>{if(element2.type==="pcb_component"&&layerMatches(element2.layer,layers)){let obstacle=componentToObstacle(element2);return obstacle?[obstacle]:[]}return element2.type==="pcb_smtpad"&&layerMatches(element2.layer,layers)?[smtPadToObstacle(element2)]:element2.type==="pcb_plated_hole"&&element2.layers.some(layer=>layerMatches(layer,layers))?[platedHoleToObstacle(element2)]:element2.type==="pcb_hole"?[holeToObstacle(element2)]:[]}),doesViaIntersectStitchingObstacle=({center:center2,radius,obstacles})=>obstacles.some(obstacle=>doesCircleIntersectObstacle(center2,radius,obstacle)),resolveOptions=(options={})=>{let resolvedOptions={sourceNetIds:options.sourceNetIds?new Set(options.sourceNetIds):void 0,layers:options.layers??["top","bottom"],viaStitchPitch:options.viaStitchPitch??1,viaHoleDiameter:options.viaHoleDiameter??.3,viaOuterDiameter:options.viaOuterDiameter??.6,pourEdgeClearance:options.pourEdgeClearance??.2,obstacleClearance:options.obstacleClearance??.2,minimumViaSeparation:options.minimumViaSeparation??Math.max(options.viaOuterDiameter??.6,.8),gridOrigin:options.gridOrigin??{x:0,y:0},isTented:options.isTented??!0};for(let[optionName,optionValue]of[["viaStitchPitch",resolvedOptions.viaStitchPitch],["viaHoleDiameter",resolvedOptions.viaHoleDiameter],["viaOuterDiameter",resolvedOptions.viaOuterDiameter],["minimumViaSeparation",resolvedOptions.minimumViaSeparation]])if(!Number.isFinite(optionValue)||optionValue<=0)throw new Error(`${optionName} must be a finite number greater than zero`);if(!Number.isFinite(resolvedOptions.pourEdgeClearance)||resolvedOptions.pourEdgeClearance<0)throw new Error("pourEdgeClearance must be a finite non-negative number");if(!Number.isFinite(resolvedOptions.obstacleClearance)||resolvedOptions.obstacleClearance<0)throw new Error("obstacleClearance must be a finite non-negative number");if(!Number.isFinite(resolvedOptions.gridOrigin.x)||!Number.isFinite(resolvedOptions.gridOrigin.y))throw new Error("gridOrigin coordinates must be finite numbers");if(resolvedOptions.viaHoleDiameter>=resolvedOptions.viaOuterDiameter)throw new Error("viaHoleDiameter must be smaller than viaOuterDiameter");if(String(resolvedOptions.layers[0])===String(resolvedOptions.layers[1]))throw new Error("layers must contain two distinct PCB layers");return resolvedOptions},isBrepCopperPour=element2=>element2.type==="pcb_copper_pour"&&element2.shape==="brep",getCopperPourPairContexts=(input2,options)=>{let sourceNetsById=new Map(input2.circuitJson.filter(element2=>element2.type==="source_net").map(sourceNet=>[sourceNet.source_net_id,sourceNet])),poursBySourceNetId=new Map;for(let element2 of input2.circuitJson){if(!isBrepCopperPour(element2)||!element2.source_net_id||options.sourceNetIds&&!options.sourceNetIds.has(element2.source_net_id))continue;let sourceNetPours=poursBySourceNetId.get(element2.source_net_id)??[];sourceNetPours.push(element2),poursBySourceNetId.set(element2.source_net_id,sourceNetPours)}let[fromLayer,toLayer]=options.layers,contexts=[];for(let[sourceNetId,sourceNetPours]of poursBySourceNetId){let fromLayerPours=sourceNetPours.filter(copperPour=>String(copperPour.layer)===String(fromLayer)),toLayerPours=sourceNetPours.filter(copperPour=>String(copperPour.layer)===String(toLayer));fromLayerPours.length===0||toLayerPours.length===0||contexts.push({sourceNetId,sourceNet:sourceNetsById.get(sourceNetId),fromLayerPours,toLayerPours})}return contexts},getPcbTraceViaRadius=(routePoint3,fallbackRadius)=>(routePoint3.outer_diameter??fallbackRadius*2)/2,isTooCloseToOccupiedVia=({center:center2,radius,occupiedVias,minimumViaSeparation})=>occupiedVias.some(occupiedVia=>Math.hypot(center2.x-occupiedVia.center.x,center2.y-occupiedVia.center.y)<Math.max(minimumViaSeparation,radius+occupiedVia.radius)),getGridCoordinates=({minimum,maximum,origin,pitch})=>{let coordinates=[],firstGridIndex=Math.ceil((minimum-origin)/pitch),lastGridIndex=Math.floor((maximum-origin)/pitch);for(let gridIndex=firstGridIndex;gridIndex<=lastGridIndex;gridIndex++)coordinates.push(origin+gridIndex*pitch);return coordinates},ViaStitchSolver=class extends BaseSolver{constructor(input2){super();__publicField(this,"input");__publicField(this,"options");__publicField(this,"copperPourPairContexts");__publicField(this,"pcbVias",[]);__publicField(this,"occupiedVias",[]);__publicField(this,"existingPcbViaIds",new Set);__publicField(this,"stitchingObstacles");__publicField(this,"nextCopperPourPairIndex",0);__publicField(this,"nextViaId",0);this.input=input2,this.options=resolveOptions(input2.options),this.copperPourPairContexts=getCopperPourPairContexts(input2,this.options),this.stitchingObstacles=getStitchingObstacles(input2.circuitJson,this.options.layers);let fallbackViaRadius=this.options.viaOuterDiameter/2;for(let element2 of input2.circuitJson)if(element2.type==="pcb_via"){let pcbVia=element2;this.existingPcbViaIds.add(pcbVia.pcb_via_id),this.occupiedVias.push({center:{x:pcbVia.x,y:pcbVia.y},radius:pcbVia.outer_diameter/2})}else if(element2.type==="pcb_trace")for(let routePoint3 of element2.route)routePoint3.route_type==="via"&&this.occupiedVias.push({center:{x:routePoint3.x,y:routePoint3.y},radius:getPcbTraceViaRadius(routePoint3,fallbackViaRadius)})}_step(){let copperPourPairContext=this.copperPourPairContexts[this.nextCopperPourPairIndex];if(!copperPourPairContext){this.solved=!0,this.progress=1;return}this.processCopperPourPair(copperPourPairContext),this.nextCopperPourPairIndex+=1,this.progress=this.copperPourPairContexts.length===0?1:this.nextCopperPourPairIndex/this.copperPourPairContexts.length,this.solved=this.nextCopperPourPairIndex===this.copperPourPairContexts.length}processCopperPourPair(context){let[fromLayer,toLayer]=this.options.layers,fromLayerShapes=context.fromLayerPours.map(copperPour=>copperPour.brep_shape),toLayerShapes=context.toLayerPours.map(copperPour=>copperPour.brep_shape),fromBounds=getShapeUnionBounds(fromLayerShapes),toBounds=getShapeUnionBounds(toLayerShapes);if(!fromBounds||!toBounds)return;let overlapBounds={minX:Math.max(fromBounds.minX,toBounds.minX),maxX:Math.min(fromBounds.maxX,toBounds.maxX),minY:Math.max(fromBounds.minY,toBounds.minY),maxY:Math.min(fromBounds.maxY,toBounds.maxY)};if(overlapBounds.minX>overlapBounds.maxX||overlapBounds.minY>overlapBounds.maxY)return;let viaRadius=this.options.viaOuterDiameter/2,requiredCopperRadius=viaRadius+this.options.pourEdgeClearance,requiredObstacleRadius=viaRadius+this.options.obstacleClearance,xCoordinates=getGridCoordinates({minimum:overlapBounds.minX+requiredCopperRadius,maximum:overlapBounds.maxX-requiredCopperRadius,origin:this.options.gridOrigin.x,pitch:this.options.viaStitchPitch}),yCoordinates=getGridCoordinates({minimum:overlapBounds.minY+requiredCopperRadius,maximum:overlapBounds.maxY-requiredCopperRadius,origin:this.options.gridOrigin.y,pitch:this.options.viaStitchPitch});for(let y23 of yCoordinates)for(let x23 of xCoordinates){let center2={x:x23,y:y23};if(isTooCloseToOccupiedVia({center:center2,radius:viaRadius,occupiedVias:this.occupiedVias,minimumViaSeparation:this.options.minimumViaSeparation})||doesViaIntersectStitchingObstacle({center:center2,radius:requiredObstacleRadius,obstacles:this.stitchingObstacles})||!isViaAnnulusInsideShapeUnion({center:center2,radius:requiredCopperRadius,shapes:fromLayerShapes})||!isViaAnnulusInsideShapeUnion({center:center2,radius:requiredCopperRadius,shapes:toLayerShapes}))continue;let pcbViaId=`via_stitch_via_${this.nextViaId++}`;for(;this.existingPcbViaIds.has(pcbViaId);)pcbViaId=`via_stitch_via_${this.nextViaId++}`;let referencePour=context.fromLayerPours[0],pcbVia={type:"pcb_via",pcb_via_id:pcbViaId,x:x23,y:y23,hole_diameter:this.options.viaHoleDiameter,outer_diameter:this.options.viaOuterDiameter,layers:[fromLayer,toLayer],from_layer:fromLayer,to_layer:toLayer,source_net_id:context.sourceNetId,subcircuit_id:referencePour.subcircuit_id,pcb_group_id:referencePour.pcb_group_id,subcircuit_connectivity_map_key:context.sourceNet?.subcircuit_connectivity_map_key,is_tented:this.options.isTented};this.pcbVias.push(pcbVia),this.existingPcbViaIds.add(pcbViaId),this.occupiedVias.push({center:center2,radius:viaRadius})}}getOutput(){return{processedCopperPourPairCount:this.copperPourPairContexts.length,pcbVias:this.pcbVias}}},SOLVERS={DogboneFanoutSolver,BusLanesSolver,BusLanesPipelineSolver,PackSolver2,LayoutPipelineSolver,AutoroutingPipelineSolver:dse,AssignableAutoroutingPipeline2:u$2,AssignableAutoroutingPipeline3:PU,AutoroutingPipeline1_OriginalUnravel:BY,AutoroutingPipelineSolver3_HgPortPointPathing:qU,AutoroutingPipelineSolver4:H22,AutoroutingPipelineSolver5:t5,AutoroutingPipelineSolver7_MultiGraph:Lne,AutoroutingPipelineSolver8:Yne,AutoroutingPipelineSolver9_PreloadedTraceGraph:dse,AutoroutingPipelineSolver9_Networked:zse,AutoroutingPipelineSolver11_Simplification:She,CopperPourPipelineSolver,CreateFdmEnclosureSolver,FanoutSolver,ImplicitCopperPourPipelineSolver,SchematicTracePipelineSolver,ViaStitchSolver},AUTOROUTER_CACHE_KEY_PREFIX="capacity-autorouter:",cacheProvidersByLocalCacheEngine=new WeakMap;function isPromiseLike(value){return typeof value=="object"&&value!==null&&"then"in value&&typeof value.then=="function"}function isAsyncFunction(fn3){return fn3.constructor.name==="AsyncFunction"}var LocalCacheEngineCacheProvider=class{constructor(localCacheEngine3){__publicField(this,"localCacheEngine");__publicField(this,"isSyncCache");__publicField(this,"cacheHits",0);__publicField(this,"cacheMisses",0);__publicField(this,"cacheHitsByPrefix",{});__publicField(this,"cacheMissesByPrefix",{});__publicField(this,"knownCacheKeys",new Set);this.localCacheEngine=localCacheEngine3,this.isSyncCache=!isAsyncFunction(localCacheEngine3.getItem)&&!isAsyncFunction(localCacheEngine3.setItem)}getCachedSolutionSync(cacheKey){if(this.isSyncCache){this.knownCacheKeys.add(cacheKey);try{let cachedItem=this.localCacheEngine.getItem(this.getLocalCacheEngineKey(cacheKey));if(isPromiseLike(cachedItem)){this.isSyncCache=!1,Promise.resolve(cachedItem).catch(()=>{}),this.recordCacheMiss(cacheKey);return}return this.parseCachedItem(cacheKey,cachedItem)}catch{this.recordCacheMiss(cacheKey);return}}}async getCachedSolution(cacheKey){this.knownCacheKeys.add(cacheKey);try{let cachedItem=await this.localCacheEngine.getItem(this.getLocalCacheEngineKey(cacheKey));return this.parseCachedItem(cacheKey,cachedItem)}catch{this.recordCacheMiss(cacheKey);return}}setCachedSolutionSync(cacheKey,cachedSolution){if(this.isSyncCache){this.knownCacheKeys.add(cacheKey);try{let serializedSolution=JSON.stringify(cachedSolution);if(serializedSolution===void 0)return;let writeResult=this.localCacheEngine.setItem(this.getLocalCacheEngineKey(cacheKey),serializedSolution);isPromiseLike(writeResult)&&(this.isSyncCache=!1,Promise.resolve(writeResult).catch(()=>{}))}catch{}}}async setCachedSolution(cacheKey,cachedSolution){this.knownCacheKeys.add(cacheKey);try{let serializedSolution=JSON.stringify(cachedSolution);if(serializedSolution===void 0)return;await this.localCacheEngine.setItem(this.getLocalCacheEngineKey(cacheKey),serializedSolution)}catch{}}getAllCacheKeys(){return[...this.knownCacheKeys]}clearCache(){for(let cacheKey of this.knownCacheKeys){let localCacheEngineKey=this.getLocalCacheEngineKey(cacheKey);try{let clearResult=this.localCacheEngine.removeItem?this.localCacheEngine.removeItem(localCacheEngineKey):this.localCacheEngine.setItem(localCacheEngineKey,"null");isPromiseLike(clearResult)&&Promise.resolve(clearResult).catch(()=>{})}catch{}}this.knownCacheKeys.clear(),this.cacheHits=0,this.cacheMisses=0,this.cacheHitsByPrefix={},this.cacheMissesByPrefix={}}getLocalCacheEngineKey(cacheKey){return`${AUTOROUTER_CACHE_KEY_PREFIX}${cacheKey}`}parseCachedItem(cacheKey,cachedItem){if(cachedItem===null){this.recordCacheMiss(cacheKey);return}try{let cachedSolution=JSON.parse(cachedItem);if(cachedSolution===null){this.recordCacheMiss(cacheKey);return}return this.recordCacheHit(cacheKey),cachedSolution}catch{this.recordCacheMiss(cacheKey);return}}recordCacheHit(cacheKey){this.cacheHits++;let prefix=cacheKey.split(":")[0];this.cacheHitsByPrefix[prefix]=(this.cacheHitsByPrefix[prefix]??0)+1}recordCacheMiss(cacheKey){this.cacheMisses++;let prefix=cacheKey.split(":")[0];this.cacheMissesByPrefix[prefix]=(this.cacheMissesByPrefix[prefix]??0)+1}};function getCacheProviderForLocalCacheEngine(localCacheEngine3){let cacheProvider=cacheProvidersByLocalCacheEngine.get(localCacheEngine3);return cacheProvider||(cacheProvider=new LocalCacheEngineCacheProvider(localCacheEngine3),cacheProvidersByLocalCacheEngine.set(localCacheEngine3,cacheProvider)),cacheProvider}async function createAutorouterRuntime(workerCount){if(typeof process>"u"||!process.versions?.node)return;let runtimeModule=process.versions.bun?"@tscircuit/capacity-autorouter/runtime/bun":"@tscircuit/capacity-autorouter/runtime/node",{createAutorouterSolverRuntime}=await import(runtimeModule);return createAutorouterSolverRuntime({workerCount,requireWorker:!0})}async function runThreadedAutorouter(solver,workerCount,run,onProgress){let progressTimer,progressError,progressThrew=!1;try{let runtime=await createAutorouterRuntime(workerCount);if(run.runtime=runtime,run.stopped)return"stopped";if(!runtime)return"inline";let previousIterations=solver.iterations,previousTime=performance.now();progressTimer=setInterval(()=>{if(run.stopped||progressThrew)return;let now2=performance.now();try{onProgress({type:"progress",iterationsPerSecond:(solver.iterations-previousIterations)/(now2-previousTime)*1e3,progress:solver.progress,phase:solver.getCurrentPhase(),debugGraphics:solver.preview()||void 0}),previousIterations=solver.iterations,previousTime=now2}catch(error2){progressThrew=!0,progressError=error2,run.disposal??(run.disposal=runtime.dispose()),run.disposal.catch(()=>{})}},250);try{await solver.solveAsync(runtime)}catch(error2){throw progressThrew?progressError:error2}if(progressThrew)throw progressError;if(run.stopped)return"stopped";if(!solver.solved&&!solver.failed)throw new Error("Asynchronous autorouting did not finish");return"complete"}finally{progressTimer!==void 0&&clearInterval(progressTimer),run.runtime&&(run.disposal??(run.disposal=run.runtime.dispose()),await run.disposal)}}var getAutorouterSolverName=({useAssignableSolver=!1,useAutoJumperSolver=!1,autorouterVersion:autorouterVersion22,useLaserPrefabSolver=!1,useTraceSimplificationSolver=!1,platformConfig:platformConfig3,effort})=>{let pipeline9SolverName=platformConfig3?.useCloudAutorouter&&(effort===void 0||effort===1)?"AutoroutingPipelineSolver9_Networked":"AutoroutingPipelineSolver9_PreloadedTraceGraph";return useTraceSimplificationSolver?"AutoroutingPipelineSolver11_Simplification":autorouterVersion22==="beta_pipeline1"?"AutoroutingPipeline1_OriginalUnravel":autorouterVersion22==="beta_pipeline3"?"AutoroutingPipelineSolver3_HgPortPointPathing":autorouterVersion22==="beta_pipeline4"?"AutoroutingPipelineSolver4":autorouterVersion22==="beta_pipeline5"?"AutoroutingPipelineSolver5":autorouterVersion22==="beta_pipeline7"?"AutoroutingPipelineSolver7_MultiGraph":autorouterVersion22==="beta_pipeline9"||autorouterVersion22==="latest"?pipeline9SolverName:useLaserPrefabSolver?"AutoroutingPipelineSolver8":useAutoJumperSolver?"AssignableAutoroutingPipeline3":useAssignableSolver?"AssignableAutoroutingPipeline2":pipeline9SolverName};function getCapacityAutorouterCacheProvider(platformConfig3){return platformConfig3?.localCacheEngine?getCacheProviderForLocalCacheEngine(platformConfig3.localCacheEngine):null}var TscircuitAutorouter=class{constructor(input2,options={}){__publicField(this,"input");__publicField(this,"isRouting",!1);__publicField(this,"solver");__publicField(this,"eventHandlers",{complete:[],error:[],progress:[]});__publicField(this,"cycleCount",0);__publicField(this,"stepDelay");__publicField(this,"timeoutId");__publicField(this,"autorouterThreads");__publicField(this,"solverName");__publicField(this,"threadedRun");this.input=input2;let{capacityDepth,targetMinCapacity,stepDelay=0,useAssignableSolver=!1,useAutoJumperSolver=!1,autorouterVersion:autorouterVersion22,useLaserPrefabSolver=!1,useTraceSimplificationSolver=!1,effort,platformConfig:platformConfig3,onSolverStarted}=options,solverName=getAutorouterSolverName({useAssignableSolver,useAutoJumperSolver,autorouterVersion:autorouterVersion22,useLaserPrefabSolver,useTraceSimplificationSolver,platformConfig:platformConfig3,effort});if(this.solverName=solverName,this.autorouterThreads=platformConfig3?.autorouterThreads,this.autorouterThreads!==void 0&&(!Number.isSafeInteger(this.autorouterThreads)||this.autorouterThreads<1))throw new AutorouterError("autorouterThreads must be a positive integer");let solverCacheProvider=getCapacityAutorouterCacheProvider(platformConfig3),solverOptions={capacityDepth,targetMinCapacity,cacheProvider:solverCacheProvider,effort};this.solver=solverName==="AutoroutingPipelineSolver9_Networked"?new zse(input2,{...solverOptions,effort:1}):new SOLVERS[solverName](input2,solverOptions),onSolverStarted?.({solverName,solverParams:{input:input2,options:{capacityDepth,targetMinCapacity,cacheProvider:solverCacheProvider,effort}}}),this.stepDelay=stepDelay}start(){if(!(this.isRouting||this.threadedRun)){if(this.isRouting=!0,this.cycleCount=0,this.autorouterThreads!==void 0&&this.autorouterThreads>1&&this.solverName==="AutoroutingPipelineSolver9_PreloadedTraceGraph"){this.runThreadedSolver(this.autorouterThreads);return}this.runCycleAndQueueNextCycle()}}async runThreadedSolver(workerCount){let run={stopped:!1};this.threadedRun=run;try{let status=await runThreadedAutorouter(this.solver,workerCount,run,progress=>{this.cycleCount++;let computeCostSummary=this.getComputeCostSummary();this.emitEvent({...progress,steps:this.cycleCount,...computeCostSummary!==void 0?{computeCostSummary}:{}})});if(run.stopped)return;if(status==="inline"){this.runCycleAndQueueNextCycle();return}if(this.isRouting=!1,this.solver.failed)throw new AutorouterError(this.solver.error||"Routing failed");this.emitEvent({type:"complete",traces:this.solver.getOutputSimplifiedPcbTraces()})}catch(error2){if(run.stopped)return;this.isRouting=!1,this.emitEvent({type:"error",error:new AutorouterError(error2 instanceof Error?error2.message:String(error2))})}finally{this.threadedRun=void 0}}async stepSolver(){if("stepAsync"in this.solver&&typeof this.solver.stepAsync=="function"){await this.solver.stepAsync();return}this.solver.step()}async runCycleAndQueueNextCycle(){if(this.isRouting)try{if(this.solver.solved||this.solver.failed){this.solver.failed?this.emitEvent({type:"error",error:new AutorouterError(this.solver.error||"Routing failed")}):this.emitEvent({type:"complete",traces:this.solver.getOutputSimplifiedPcbTraces()}),this.isRouting=!1;return}let startTime=Date.now(),startIterations=this.solver.iterations;for(;Date.now()-startTime<250&&!this.solver.failed&&!this.solver.solved;)await this.stepSolver();let iterationsPerSecond=(this.solver.iterations-startIterations)/(Date.now()-startTime)*1e3;this.cycleCount++;let debugGraphics=this.solver?.preview()||void 0,progress=this.solver.progress,computeCostSummary=this.getComputeCostSummary();this.emitEvent({type:"progress",steps:this.cycleCount,iterationsPerSecond,progress,phase:"getCurrentPhase"in this.solver?this.solver.getCurrentPhase():this.solver.activeSubSolver?.getSolverName()??this.solver.getSolverName(),debugGraphics,...computeCostSummary!==void 0?{computeCostSummary}:{}}),this.stepDelay>0?this.timeoutId=setTimeout(()=>{this.runCycleAndQueueNextCycle()},this.stepDelay):this.timeoutId=setTimeout(()=>{this.runCycleAndQueueNextCycle()},0)}catch(error2){this.emitEvent({type:"error",error:error2 instanceof Error?new AutorouterError(error2.message):new AutorouterError(String(error2))}),this.isRouting=!1}}stop(){if(this.isRouting){if(this.isRouting=!1,this.threadedRun){let run=this.threadedRun;run.stopped=!0,run.runtime&&(run.disposal??(run.disposal=run.runtime.dispose()),run.disposal.catch(()=>{}))}this.timeoutId!==void 0&&(clearTimeout(this.timeoutId),this.timeoutId=void 0)}}on(event,callback){event==="complete"?this.eventHandlers.complete.push(callback):event==="error"?this.eventHandlers.error.push(callback):event==="progress"&&this.eventHandlers.progress.push(callback)}emitEvent(event){if(event.type==="complete")for(let handler of this.eventHandlers.complete)handler(event);else if(event.type==="error")for(let handler of this.eventHandlers.error)handler(event);else if(event.type==="progress")for(let handler of this.eventHandlers.progress)handler(event)}solveSync(){if(this.isRouting||this.threadedRun)throw new AutorouterError("Cannot solve synchronously while autorouting is active");if(this.solver.solve(),this.solver.failed)throw new AutorouterError(this.solver.error||"Routing failed");return this.solver.getOutputSimplifiedPcbTraces()}getComputeCostSummary(){return this.solver.getComputeCostSummary?.()}getConnectedOffboardObstacles(){return"getConnectedOffboardObstacles"in this.solver?this.solver.getConnectedOffboardObstacles():{}}},createTscircuitAutorouterStrategy=(name,strategyOptions)=>({name,cacheable:!0,getSolverName:options=>getAutorouterSolverName({...options,...strategyOptions}),create:({simpleRouteJson,commonAutorouterOptions,onSolverStarted})=>new TscircuitAutorouter(simpleRouteJson,{...commonAutorouterOptions,...strategyOptions,onSolverStarted:details=>onSolverStarted?.({...details,solverConstructorArgs:[details.solverParams]})})}),defaultLocalAutorouterStrategy=createTscircuitAutorouterStrategy("tscircuit",{}),simplificationLocalAutorouterStrategy=createTscircuitAutorouterStrategy("tscircuit_simplify",{useTraceSimplificationSolver:!0}),createFanoutAutorouterStrategy=mode=>({name:mode,cacheable:!1,followUpAutorouter:"default",getSolverName:()=>"FanoutSolver",create:({simpleRouteJson,busFanoutDirections,fanoutBounds,fanoutRoutingLayers,allowBlindAndBuriedVias,componentNamesById,onSolverStarted})=>new FanoutAutorouter(simpleRouteJson,{mode,busFanoutDirections,fanoutBounds,fanoutRoutingLayers,allowBlindAndBuriedVias,componentNamesById,onSolverStarted})}),localAutorouterStrategies=new Map([["single_layer_fanout",createFanoutAutorouterStrategy("single_layer_fanout")],["fanout",createFanoutAutorouterStrategy("fanout")],["dogbone",{name:"dogbone",preserveOutputTraces:!0,followUpAutorouter:"default",cacheable:!1,getSolverName:()=>"DogboneFanoutSolver",create:({simpleRouteJson,fanoutRoutingLayers,onSolverStarted,onSolverEnded})=>new DogboneAutorouter({input:simpleRouteJson,fanoutRoutingLayers},{onSolverStarted,onSolverEnded})}],["bus_lanes",{name:"bus_lanes",preserveOutputTraces:!0,cacheable:!1,getSolverName:()=>"BusLanesPipelineSolver",create:({simpleRouteJson,onSolverStarted})=>(onSolverStarted?.({solverName:"BusLanesPipelineSolver",solverParams:simpleRouteJson,solverConstructorArgs:[simpleRouteJson]}),new BusLanesAutorouter(simpleRouteJson))}],["simplify",simplificationLocalAutorouterStrategy]]),getLocalAutorouterStrategy=preset=>localAutorouterStrategies.get(preset??"")??defaultLocalAutorouterStrategy,getLocalAutoroutingStages=(autorouterConfig3,platformConfig3)=>{let strategy=getLocalAutorouterStrategy(autorouterConfig3.preset),stages=[{autorouterConfig:autorouterConfig3,strategy,usesPreviousStageOutput:!1}];if(strategy.followUpAutorouter&&!autorouterConfig3.algorithmFn){let followUpAutorouterConfig=getPresetAutoroutingConfig(strategy.followUpAutorouter,platformConfig3);stages.push({autorouterConfig:followUpAutorouterConfig,strategy:getLocalAutorouterStrategy(followUpAutorouterConfig.preset),usesPreviousStageOutput:!0})}return stages},applyPcbEditEventsToManualEditsFile=({circuitJson,editEvents,manualEditsFile})=>{let updatedManualEditsFile={...manualEditsFile,pcb_placements:[...manualEditsFile.pcb_placements??[]]};for(let editEvent of editEvents)if(editEvent.edit_event_type==="edit_pcb_component_location"){let{pcb_component_id,new_center}=editEvent,pcb_component23=su(circuitJson).pcb_component.get(pcb_component_id);if(!pcb_component23)continue;let source_component=su(circuitJson).source_component.get(pcb_component23.source_component_id);if(!source_component)continue;let existingPlacementIndex=updatedManualEditsFile.pcb_placements?.findIndex(p23=>p23.selector===source_component.name),newPlacement={selector:source_component.name,center:new_center,relative_to:"group_center"};existingPlacementIndex>=0?updatedManualEditsFile.pcb_placements[existingPlacementIndex]=newPlacement:updatedManualEditsFile.pcb_placements.push(newPlacement)}return updatedManualEditsFile},applySchematicEditEventsToManualEditsFile=({circuitJson,editEvents,manualEditsFile})=>{let updatedManualEditsFile={...manualEditsFile,schematic_placements:[...manualEditsFile.schematic_placements??[]]};for(let editEvent of editEvents)if(editEvent.edit_event_type==="edit_schematic_component_location"){let{schematic_component_id,new_center}=editEvent,schematic_component32=su(circuitJson).schematic_component.get(schematic_component_id);if(!schematic_component32||!schematic_component32.source_component_id)continue;let source_component=su(circuitJson).source_component.get(schematic_component32.source_component_id);if(!source_component)continue;let existingPlacementIndex=updatedManualEditsFile.schematic_placements?.findIndex(p23=>p23.selector===source_component.name),newPlacement={selector:source_component.name,center:new_center,relative_to:"group_center"};existingPlacementIndex>=0?updatedManualEditsFile.schematic_placements[existingPlacementIndex]=newPlacement:updatedManualEditsFile.schematic_placements.push(newPlacement)}return updatedManualEditsFile},applyEditEventsToManualEditsFile=({circuitJson,editEvents,manualEditsFile})=>{let schematicEditEvents=editEvents.filter(event=>event.edit_event_type==="edit_schematic_component_location"),pcbEditEvents=editEvents.filter(event=>event.edit_event_type==="edit_pcb_component_location"),updatedManualEditsFile=manualEditsFile;return schematicEditEvents.length>0&&(updatedManualEditsFile=applySchematicEditEventsToManualEditsFile({circuitJson,editEvents:schematicEditEvents,manualEditsFile:updatedManualEditsFile})),pcbEditEvents.length>0&&(updatedManualEditsFile=applyPcbEditEventsToManualEditsFile({circuitJson,editEvents:pcbEditEvents,manualEditsFile:updatedManualEditsFile})),updatedManualEditsFile},applyTraceHintEditEvent=(circuitJson,edit_event)=>{if(su(circuitJson).pcb_trace_hint.get(edit_event.pcb_trace_hint_id))circuitJson=circuitJson.map(e211=>e211.pcb_trace_hint_id===edit_event.pcb_trace_hint_id?{...e211,route:edit_event.route}:e211);else{let pcbPort=su(circuitJson).pcb_port.get(edit_event.pcb_port_id);circuitJson=circuitJson.filter(e211=>!(e211.type==="pcb_trace_hint"&&e211.pcb_port_id===edit_event.pcb_port_id)).concat([{type:"pcb_trace_hint",pcb_trace_hint_id:edit_event.pcb_trace_hint_id,route:edit_event.route,pcb_port_id:edit_event.pcb_port_id,pcb_component_id:pcbPort?.pcb_component_id}])}return circuitJson},applyEditEvents=({circuitJson,editEvents})=>{circuitJson=JSON.parse(JSON.stringify(circuitJson));for(let editEvent of editEvents)if(editEvent.edit_event_type==="edit_pcb_component_location"){let component=circuitJson.find(e211=>e211.type==="pcb_component"&&e211.pcb_component_id===editEvent.pcb_component_id);if((!component||component.center.x!==editEvent.new_center.x||component.center.y!==editEvent.new_center.y)&&editEvent.original_center){let mat=translate8(editEvent.new_center.x-editEvent.original_center.x,editEvent.new_center.y-editEvent.original_center.y);circuitJson=circuitJson.map(e211=>e211.pcb_component_id!==editEvent.pcb_component_id?e211:transformPCBElement(e211,mat))}}else editEvent.edit_event_type==="edit_schematic_component_location"?circuitJson=circuitJson.map(e211=>e211.type==="schematic_component"&&e211.schematic_component_id===editEvent.schematic_component_id?{...e211,center:editEvent.new_center}:e211):editEvent.edit_event_type==="edit_pcb_trace_hint"&&(circuitJson=applyTraceHintEditEvent(circuitJson,editEvent));return circuitJson},getBusSourceTraceIdOrThrow=({bus,busSourceTraces,traceNameOrPortSelector})=>{let sourceTracesWithMatchingName=busSourceTraces.filter(sourceTrace2=>sourceTrace2.name===traceNameOrPortSelector),selectedSourcePortId=(sourceTracesWithMatchingName.length===0?bus.getSubcircuit().selectOne(traceNameOrPortSelector,{type:"port"}):null)?.source_port_id??void 0,matchingSourceTraces=selectedSourcePortId?busSourceTraces.filter(sourceTrace2=>sourceTrace2.connected_source_port_ids.includes(selectedSourcePortId)):sourceTracesWithMatchingName;if(matchingSourceTraces.length===0)throw new Error(`Could not find source trace for trace name or port selector "${traceNameOrPortSelector}" in bus "${bus.name}"`);if(matchingSourceTraces.length>1)throw new Error(`Trace name or port selector "${traceNameOrPortSelector}" matches multiple source traces in bus "${bus.name}"`);return matchingSourceTraces[0].source_trace_id},getSourceBusRouteLength=({bus,busSourceTraces,property})=>{let routeLength3=bus._parsedProps[property];return routeLength3===void 0||typeof routeLength3=="number"?routeLength3:{reference:routeLength3.reference,offset:routeLength3.offset,source_trace_ids:routeLength3.of?.map(traceNameOrPortSelector=>getBusSourceTraceIdOrThrow({bus,busSourceTraces,traceNameOrPortSelector}))}},Bus=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"source_bus_id")}get config(){return{componentName:"Bus",zodProps:busProps}}doInitialSourceAddConnectivityMapKey(){let{db:db22}=this.root,subcircuit_id=this.getSubcircuit().subcircuit_id,busSourceTraces=db22.source_trace.list().filter(sourceTrace=>sourceTrace.subcircuit_id===subcircuit_id),source_trace_ids=this._parsedProps.connections.map(traceNameOrPortSelector=>getBusSourceTraceIdOrThrow({bus:this,busSourceTraces,traceNameOrPortSelector}));if(new Set(source_trace_ids).size!==source_trace_ids.length)throw new Error(`Bus "${this.name}" resolves multiple entries to one trace`);let sourceBus=db22.source_bus.insert({name:this._parsedProps.name,source_trace_ids,max_length_skew:this._parsedProps.maxLengthSkew,min_length:getSourceBusRouteLength({bus:this,busSourceTraces,property:"minLength"}),max_length:getSourceBusRouteLength({bus:this,busSourceTraces,property:"maxLength"}),target_length:getSourceBusRouteLength({bus:this,busSourceTraces,property:"targetLength"}),length_tolerance:this._parsedProps.lengthTolerance,subcircuit_id});this.source_bus_id=sourceBus.source_bus_id}},resolvePointToPointConnection=(differentialPair,connectionSelector)=>{let{db:db22}=differentialPair.root,subcircuit=differentialPair.getSubcircuit(),subcircuitSourceTraces=db22.source_trace.list().filter(sourceTrace=>sourceTrace.subcircuit_id===subcircuit.subcircuit_id),matchingSourceTraces=subcircuitSourceTraces.filter(sourceTrace=>sourceTrace.name===connectionSelector),namedSourceTrace=matchingSourceTraces[0];if(matchingSourceTraces.length===1&&namedSourceTrace?.connected_source_port_ids.length===2)return{sourceTraceIds:[namedSourceTrace.source_trace_id],sourcePorts:db22.source_port.list().filter(sourcePort=>namedSourceTrace.connected_source_port_ids.includes(sourcePort.source_port_id)),sourceTraceName:connectionSelector};let connectivityMapKeys=new Set;if(matchingSourceTraces.length>0)for(let sourceTrace of matchingSourceTraces)sourceTrace.subcircuit_connectivity_map_key&&connectivityMapKeys.add(sourceTrace.subcircuit_connectivity_map_key);else{let selectedPort=subcircuit.selectOne(connectionSelector,{type:"port"});if(selectedPort?.source_port_id){let sourcePort=db22.source_port.get(selectedPort.source_port_id);sourcePort?.subcircuit_connectivity_map_key&&connectivityMapKeys.add(sourcePort.subcircuit_connectivity_map_key)}}if(connectivityMapKeys.size!==1)return;let connectivityMapKey=connectivityMapKeys.values().next().value;if(!connectivityMapKey)return;let sourcePorts=db22.source_port.list().filter(sourcePort=>sourcePort.subcircuit_connectivity_map_key===connectivityMapKey);return{sourceTraceIds:subcircuitSourceTraces.filter(trace=>trace.subcircuit_connectivity_map_key===connectivityMapKey).map(trace=>trace.source_trace_id),sourcePorts,sourceTraceName:matchingSourceTraces.length>0?connectionSelector:void 0}},formatTerminalPinList=terminalPinSelectors=>terminalPinSelectors.length<=1?terminalPinSelectors.join(""):terminalPinSelectors.length===2?`${terminalPinSelectors[0]} and ${terminalPinSelectors[1]}`:`${terminalPinSelectors.slice(0,-1).join(", ")}, and ${terminalPinSelectors.at(-1)}`,getTerminalPinSelector=(sourcePort,sourceComponentsById)=>{let sourceComponent;if(sourcePort.source_component_id&&(sourceComponent=sourceComponentsById.get(sourcePort.source_component_id)),!sourceComponent?.name)return sourcePort.source_port_id;let portName=sourcePort.most_frequently_referenced_by_name??sourcePort.name;return`.${sourceComponent.name} > .${portName}`},getPointToPointWarningMessage=({differentialPairName,connectionPolarity,connectionSelector,sourceTraceName,terminalPinSelectors})=>{let terminalList=formatTerminalPinList(terminalPinSelectors),terminalListDescription=terminalList?`: ${terminalList}`:"";return sourceTraceName&&terminalPinSelectors.length>2?`Differential pair "${differentialPairName}" ${connectionPolarity}Connection uses the ambiguous trace name "${sourceTraceName}": its connection has more than 2 terminal pins${terminalListDescription}.`:`Differential pair "${differentialPairName}" ${connectionPolarity}Connection="${connectionSelector}" is not point-to-point: expected exactly 2 terminal pins, found ${terminalPinSelectors.length}${terminalListDescription}.`},DifferentialPair_doInitialSourceDesignRuleChecks=differentialPair=>{let{db:db22}=differentialPair.root,sourceComponentsById=new Map;for(let sourceComponent of db22.source_component.list())sourceComponentsById.set(sourceComponent.source_component_id,{name:sourceComponent.name});let memberTraceIds=[],pointToPointTraceIds={},resolvedPolarityCount=0;for(let connectionPolarity of["positive","negative"]){let connectionSelector=differentialPair._parsedProps.negativeConnection;connectionPolarity==="positive"&&(connectionSelector=differentialPair._parsedProps.positiveConnection);let resolvedConnection=resolvePointToPointConnection(differentialPair,connectionSelector);if(!resolvedConnection)continue;resolvedPolarityCount++,memberTraceIds.push(...resolvedConnection.sourceTraceIds);let terminalSourcePorts=resolvedConnection.sourcePorts;if(terminalSourcePorts.length===2){pointToPointTraceIds[connectionPolarity]=resolvedConnection.sourceTraceIds[0];continue}let warningSourceComponentId="",firstTerminalSourcePort=terminalSourcePorts[0];if(firstTerminalSourcePort){if(!firstTerminalSourcePort.source_component_id)throw new Error(`Differential pair "${differentialPair.name}" resolved terminal port "${firstTerminalSourcePort.source_port_id}" without a source_component_id`);warningSourceComponentId=firstTerminalSourcePort.source_component_id}let terminalPinSelectors=terminalSourcePorts.map(sourcePort=>getTerminalPinSelector(sourcePort,sourceComponentsById)).sort((selectorA,selectorB)=>selectorA.localeCompare(selectorB));db22.source_property_ignored_warning.insert({source_component_id:warningSourceComponentId,property_name:`${connectionPolarity}Connection`,error_type:"source_property_ignored_warning",message:getPointToPointWarningMessage({differentialPairName:differentialPair.name,connectionPolarity,connectionSelector,sourceTraceName:resolvedConnection.sourceTraceName,terminalPinSelectors}),subcircuit_id:differentialPair.getSubcircuit().subcircuit_id??void 0})}resolvedPolarityCount===2&&memberTraceIds.length>0&&db22.source_bus.insert({name:differentialPair.name,source_trace_ids:[...new Set(memberTraceIds)],max_length_skew:differentialPair._parsedProps.maxLengthSkew,target_differential_impedance:differentialPair._parsedProps.targetDifferentialImpedance,...pointToPointTraceIds.positive&&pointToPointTraceIds.negative?{differential_pair:{positive_source_trace_id:pointToPointTraceIds.positive,negative_source_trace_id:pointToPointTraceIds.negative,trace_gap:differentialPair._parsedProps.pcbTraceGap,max_uncoupled_length:differentialPair._parsedProps.maxUncoupledLength}}:{},subcircuit_id:differentialPair.getSubcircuit().subcircuit_id??void 0})},DifferentialPair=class extends PrimitiveComponent{get config(){return{componentName:"DifferentialPair",zodProps:differentialPairProps}}doInitialSourceDesignRuleChecks(){DifferentialPair_doInitialSourceDesignRuleChecks(this)}},GEOMETRY_SCALE=1e6,CONTACT_TOLERANCE=1e-7*GEOMETRY_SCALE,getRouteEndpoint2=(routePoint3,side)=>routePoint3.route_type==="wire"?{point:routePoint3,layer:routePoint3.layer}:routePoint3.route_type==="via"?{point:routePoint3,layer:side==="start"?routePoint3.from_layer:routePoint3.to_layer}:{point:routePoint3[side],layer:side==="start"?routePoint3.start_layer:routePoint3.end_layer},getExplicitWireTaperPolygon=(start,end)=>{let startWidth=start.start_width,endWidth=start.end_width,dx22=end.x-start.x,dy22=end.y-start.y,length93=Math.hypot(dx22,dy22),delta=Math.abs(endWidth-startWidth),steps=start.width_interpolation_mode==="linear"?1:Math.max(1,Math.ceil(Math.sqrt(delta/(.001+delta*1e-6)*(3/8)))),left=[],right=[];for(let i23=0;i23<=steps;i23++){let t48=i23/steps,u23=startWidth<=endWidth?t48:1-t48,width10=start.width_interpolation_mode==="quadratic"?Math.min(startWidth,endWidth)+delta*u23*u23:startWidth+(endWidth-startWidth)*t48,x23=start.x+dx22*t48,y23=start.y+dy22*t48,offsetX=-dy22/length93*(width10/2),offsetY=dx22/length93*(width10/2);left.push(point2(x23+offsetX,y23+offsetY)),right.push(point2(x23-offsetX,y23-offsetY))}return new Polygon$1([...right,...left.reverse()])},findFloatingCopper=(circuitJson,generatedStitchingViaIds=new Set)=>{let floatingPourIds=new Set,floatingViaIds=new Set,copperConnectedPointGroups=[],pours=circuitJson.filter(e211=>e211.type==="pcb_copper_pour");if(pours.length===0)return{floatingPourIds,floatingViaIds,copperConnectedPointGroups};let connectivity=getFullConnectivityMapFromCircuitJson(circuitJson),pouredNets=new Set(pours.flatMap(pour=>pour.source_net_id?[connectivity.getNetConnectedToId(pour.source_net_id)??pour.source_net_id]:[])),conductors=[],add10=conductor=>{pouredNets.has(conductor.netId)&&!conductor.polygon.isEmpty()&&conductors.push({...conductor,polygon:conductor.polygon.scale(GEOMETRY_SCALE,GEOMETRY_SCALE)})},components=new Map(circuitJson.filter(e211=>e211.type==="pcb_component").map(e211=>[e211.pcb_component_id,e211])),vias=circuitJson.filter(e211=>e211.type==="pcb_via"),board=circuitJson.find(e211=>e211.type==="pcb_board");for(let pour of pours)pour.source_net_id&&add10({polygon:getPourPolygon(pour),layers:[pour.layer],netId:connectivity.getNetConnectedToId(pour.source_net_id)??pour.source_net_id,isTerminal:!1,pourId:pour.pcb_copper_pour_id});for(let element2 of circuitJson)if(element2.type==="pcb_smtpad"){let netId=connectivity.getNetConnectedToId(element2.pcb_smtpad_id);netId&&pouredNets.has(netId)&&add10({polygon:getSmtPadPolygon(element2),layers:[element2.layer],netId,isTerminal:!!element2.pcb_port_id,pcbPortIds:element2.pcb_port_id?[element2.pcb_port_id]:[]})}else if(element2.type==="pcb_plated_hole"){let netId=connectivity.getNetConnectedToId(element2.pcb_plated_hole_id);netId&&pouredNets.has(netId)&&add10({polygon:getPlatedHolePolygon(element2,element2.pcb_component_id?components.get(element2.pcb_component_id)?.rotation:0),layers:element2.layers,netId,isTerminal:!!element2.pcb_port_id,pcbPortIds:element2.pcb_port_id?[element2.pcb_port_id]:[]})}else if(element2.type==="pcb_via"){let netId=connectivity.getNetConnectedToId(element2.pcb_via_id);netId&&pouredNets.has(netId)&&add10({polygon:getViaPolygon(element2,element2.outer_diameter,element2.hole_diameter),layers:element2.layers,netId,isTerminal:!generatedStitchingViaIds.has(element2.pcb_via_id),viaId:element2.pcb_via_id,viaCenter:element2,pcbPortIds:element2.pcb_port_ids})}else if(element2.type==="pcb_trace"){let netId=connectivity.getNetConnectedToId(element2.pcb_trace_id);if(!netId||!pouredNets.has(netId))continue;for(let i23=0;i23<element2.route.length;i23++){let routePoint3=element2.route[i23];if(routePoint3.route_type==="via"){let actualVia=vias.find(via=>via.x===routePoint3.x&&via.y===routePoint3.y&&via.layers.includes(routePoint3.from_layer)&&via.layers.includes(routePoint3.to_layer));add10({polygon:getViaPolygon(routePoint3,actualVia?.outer_diameter??routePoint3.outer_diameter??board?.min_via_pad_diameter??.3,actualVia?.hole_diameter??routePoint3.hole_diameter??board?.min_via_hole_diameter??.2),layers:actualVia?.layers??getViaSpanLayers({fromLayer:routePoint3.from_layer,toLayer:routePoint3.to_layer,layerCount:board?.num_layers??2}),netId,isTerminal:!1,viaCenter:routePoint3})}let next2=element2.route[i23+1];if(!next2)continue;let start=getRouteEndpoint2(routePoint3,"end"),end=getRouteEndpoint2(next2,"start");if(start.layer!==end.layer)continue;let startWidth=routePoint3.route_type==="via"?next2.route_type==="via"?void 0:next2.width:routePoint3.width;if(startWidth===void 0)continue;let endWidth=element2.route_thickness_mode==="interpolated"&&next2.route_type!=="via"?next2.width:startWidth;add10({polygon:routePoint3.route_type==="wire"&&routePoint3.width_interpolation_mode?getExplicitWireTaperPolygon(routePoint3,end.point):getTraceSegmentPolygon(start.point,end.point,startWidth,endWidth),layers:[start.layer],netId,isTerminal:!1})}}if(conductors.length===0)return{floatingPourIds,floatingViaIds,copperConnectedPointGroups};let parent=conductors.map((_23,i23)=>i23),find2=i23=>{for(;parent[i23]!==i23;)parent[i23]=parent[parent[i23]],i23=parent[i23];return i23},bounds=conductors.map(conductor=>conductor.polygon.box),spatialIndex=new Flatbush(conductors.length);for(let box32 of bounds)spatialIndex.add(box32.xmin,box32.ymin,box32.xmax,box32.ymax);spatialIndex.finish();for(let[i23,conductor]of conductors.entries()){let box32=bounds[i23];for(let j23 of spatialIndex.search(box32.xmin-CONTACT_TOLERANCE,box32.ymin-CONTACT_TOLERANCE,box32.xmax+CONTACT_TOLERANCE,box32.ymax+CONTACT_TOLERANCE)){if(j23<=i23||find2(i23)===find2(j23))continue;let neighbor=conductors[j23];conductor.netId!==neighbor.netId||!conductor.layers.some(layer=>neighbor.layers.includes(layer))||copperPolygonsTouch(conductor.polygon,neighbor.polygon,CONTACT_TOLERANCE)&&(parent[find2(j23)]=find2(i23))}}let netsWithTerminals=new Set(conductors.flatMap(conductor=>conductor.isTerminal?[conductor.netId]:[])),terminalRoots=new Set(conductors.flatMap((conductor,i23)=>conductor.isTerminal?[find2(i23)]:[])),pointIdsByPourRoot=new Map;for(let[i23,conductor]of conductors.entries())conductor.pourId&&pointIdsByPourRoot.set(find2(i23),new Set);for(let[i23,conductor]of conductors.entries()){let root=find2(i23),connectedPointIds=pointIdsByPourRoot.get(root);for(let pcbPortId of conductor.pcbPortIds??[])connectedPointIds?.add(pcbPortId);!netsWithTerminals.has(conductor.netId)||terminalRoots.has(root)||(conductor.pourId&&floatingPourIds.add(conductor.pourId),conductor.viaId&&floatingViaIds.add(conductor.viaId))}let pcbPortsBySourcePortId=new Map(circuitJson.filter(element2=>element2.type==="pcb_port").map(port=>[port.source_port_id,port]));for(let breakout of circuitJson){if(breakout.type!=="pcb_breakout_point")continue;let sourceId=breakout.source_port_id??breakout.source_net_id??breakout.source_trace_id;if(!sourceId)continue;let netId=connectivity.getNetConnectedToId(sourceId)??sourceId,sourcePcbPort=breakout.source_port_id?pcbPortsBySourcePortId.get(breakout.source_port_id):void 0,layer=breakout.layer??sourcePcbPort?.layers[0]??"top",position22=point2(breakout.x*GEOMETRY_SCALE,breakout.y*GEOMETRY_SCALE);for(let i23 of spatialIndex.search(position22.x-CONTACT_TOLERANCE,position22.y-CONTACT_TOLERANCE,position22.x+CONTACT_TOLERANCE,position22.y+CONTACT_TOLERANCE)){let conductor=conductors[i23],connectedPointIds=pointIdsByPourRoot.get(find2(i23));if(!connectedPointIds||conductor.netId!==netId||!conductor.layers.includes(layer))continue;(conductor.viaCenter&&Math.hypot(position22.x-conductor.viaCenter.x*GEOMETRY_SCALE,position22.y-conductor.viaCenter.y*GEOMETRY_SCALE)<=CONTACT_TOLERANCE||conductor.polygon.contains(position22)||position22.distanceTo(conductor.polygon)[0]<=CONTACT_TOLERANCE)&&connectedPointIds.add(breakout.pcb_breakout_point_id)}}for(let pointIds of pointIdsByPourRoot.values())pointIds.size>1&&copperConnectedPointGroups.push([...pointIds]);return{floatingPourIds,floatingViaIds,copperConnectedPointGroups}},expandSrjBoundsToIncludeConnectionPoints=input2=>{let expandedBounds={...input2.bounds};for(let connection of input2.connections)if(!connection.isOffBoard)for(let point12 of connection.pointsToConnect)expandedBounds.minX=Math.min(expandedBounds.minX,point12.x),expandedBounds.maxX=Math.max(expandedBounds.maxX,point12.x),expandedBounds.minY=Math.min(expandedBounds.minY,point12.y),expandedBounds.maxY=Math.max(expandedBounds.maxY,point12.y);return expandedBounds},getSrjOutlineForRoutingBounds=({bounds,outline},routingBounds2)=>{if(outline)return outline;if(!(bounds.minX===routingBounds2.minX&&bounds.maxX===routingBounds2.maxX&&bounds.minY===routingBounds2.minY&&bounds.maxY===routingBounds2.maxY))return new Box(bounds.minX,bounds.minY,bounds.maxX,bounds.maxY).toPoints().map(({x:x23,y:y23})=>({x:x23,y:y23}))},getBusTargetLengthBounds=bus=>{if(!bus.source_bus_id)return{};let{db:db22}=bus.root,sourceBus=db22.source_bus.get(bus.source_bus_id),resolveLength=(routeLength3,property)=>{if(routeLength3===void 0||typeof routeLength3=="number")return routeLength3;let reference4=routeLength3,manhattanLengths=(reference4.source_trace_ids??sourceBus.source_trace_ids).map(sourceTraceId=>{let sourceTrace=db22.source_trace.get(sourceTraceId),pcbPorts=db22.pcb_port.list().filter(port=>sourceTrace.connected_source_port_ids.includes(port.source_port_id));if(pcbPorts.length!==2)throw new Error(`Bus "${bus.name}" ${property} requires two placed endpoint pads per reference trace`);return Math.abs(pcbPorts[0].x-pcbPorts[1].x)+Math.abs(pcbPorts[0].y-pcbPorts[1].y)});return Math.max(...manhattanLengths)+(reference4.offset??0)},minLength=resolveLength(sourceBus.min_length,"minLength"),maxLength=resolveLength(sourceBus.max_length,"maxLength"),targetLength=resolveLength(sourceBus.target_length,"targetLength");if(targetLength!==void 0){let tolerance=sourceBus.length_tolerance;if(tolerance===void 0)throw new Error(`Bus "${bus.name}" requires lengthTolerance with targetLength`);minLength=Math.max(minLength??0,targetLength-tolerance),maxLength=Math.min(maxLength??1/0,targetLength+tolerance)}if(minLength!==void 0&&(minLength=Math.max(0,minLength)),maxLength!==void 0&&maxLength<(minLength??0))throw new Error(`Bus "${bus.name}" has incompatible length bounds: minimum ${minLength??0} mm exceeds maximum ${maxLength} mm`);return{...minLength!==void 0?{minLength}:{},...maxLength!==void 0?{maxLength}:{}}},getBusSrjConnectionNamesOrThrow=({srjConnections,bus,sourceTraceId,traceNameOrPortSelector,busSourceTraces})=>{let directSrjConnections=srjConnections.filter(srjConnection=>srjConnection.source_trace_id===sourceTraceId);if(directSrjConnections.length>0)return directSrjConnections.map(srjConnection=>srjConnection.name);let sourceTrace=busSourceTraces.find(trace=>trace.source_trace_id===sourceTraceId),connectedSourceTraces=busSourceTraces.filter(trace=>trace.source_trace_id===sourceTraceId||sourceTrace.subcircuit_connectivity_map_key!==void 0&&trace.subcircuit_connectivity_map_key===sourceTrace.subcircuit_connectivity_map_key),connectedSourceNetIds=new Set(connectedSourceTraces.flatMap(trace=>trace.connected_source_net_ids??[])),matchingSrjConnections=srjConnections.filter(srjConnection=>connectedSourceNetIds.has(srjConnection.name));if(matchingSrjConnections.length===0)throw new Error(`Could not find an SRJ connection for "${traceNameOrPortSelector}" in bus "${bus.name}"`);return matchingSrjConnections.map(srjConnection=>srjConnection.name)},normalizeNetName=netNameOrSelector=>netNameOrSelector.trim().replace(/^net\./,"").replace(/^\./,""),getPlaneTerminatedSourceTraceLayers=({fanoutPourNetMap,sourceNets,sourceTraces,subcircuitId})=>{let traceLayers=new Map;if(!fanoutPourNetMap)return traceLayers;let planeLayerBySourceNetId=new Map;for(let[layer,netOrNets]of Object.entries(fanoutPourNetMap)){let netNames=Array.isArray(netOrNets)?netOrNets:[netOrNets];for(let netNameOrSelector of netNames){let netName=normalizeNetName(netNameOrSelector);for(let sourceNet of sourceNets){if(sourceNet.name!==netName)continue;let previousLayer=planeLayerBySourceNetId.get(sourceNet.source_net_id);if(previousLayer&&previousLayer!==layer)throw new Error(`Fanout plane net "${netName}" maps to multiple layers ("${previousLayer}" and "${layer}"); use fanoutPourNetMap to select one`);planeLayerBySourceNetId.set(sourceNet.source_net_id,layer)}}}for(let sourceTrace of sourceTraces){if(subcircuitId&&sourceTrace.subcircuit_id!==subcircuitId||sourceTrace.connected_source_port_ids.length!==1)continue;let mappedLayers=new Set((sourceTrace.connected_source_net_ids??[]).map(sourceNetId=>planeLayerBySourceNetId.get(sourceNetId)).filter(layer2=>layer2!==void 0));if(mappedLayers.size>1)throw new Error(`Source trace "${sourceTrace.name??sourceTrace.source_trace_id}" connects to fanout planes on multiple layers`);let layer=mappedLayers.values().next().value;layer&&traceLayers.set(sourceTrace.source_trace_id,layer)}return traceLayers},getBusesForSimpleRouteJson=({srjConnections,buses,sourceTraces,subcircuitId,planeTerminatedSourceTraceLayers,preservedSourceTraceIds})=>{let declaredSrjBuses=[];for(let bus of buses){let busSubcircuitId=bus.getSubcircuit().subcircuit_id;if(subcircuitId&&busSubcircuitId!==subcircuitId)continue;let busSourceTraces=sourceTraces.filter(sourceTrace=>sourceTrace.subcircuit_id===busSubcircuitId),connectionNames=bus._parsedProps.connections.flatMap(traceNameOrPortSelector=>{let sourceTraceId=getBusSourceTraceIdOrThrow({bus,busSourceTraces,traceNameOrPortSelector});return preservedSourceTraceIds?.has(sourceTraceId)?[]:getBusSrjConnectionNamesOrThrow({srjConnections,bus,sourceTraceId,traceNameOrPortSelector,busSourceTraces})});if(new Set(connectionNames).size!==connectionNames.length)throw new Error(`Bus "${bus.name}" resolves multiple entries to one trace`);connectionNames.length!==0&&declaredSrjBuses.push({busId:bus.name,name:bus.name,connectionNames,...getBusTargetLengthBounds(bus),...bus._parsedProps.maxLengthSkew!==void 0?{maxLengthSkew:bus._parsedProps.maxLengthSkew}:{},...bus._parsedProps.pcbTraceWidth!==void 0?{traceWidth:bus._parsedProps.pcbTraceWidth}:{},...bus._parsedProps.pcbAllowedLayers!==void 0?{allowedLayers:bus._parsedProps.pcbAllowedLayers}:{},...bus._parsedProps.preferredLayer!==void 0?{preferredLayer:bus._parsedProps.preferredLayer}:{},...bus._parsedProps.preferredLayers!==void 0?{preferredLayers:bus._parsedProps.preferredLayers}:{}})}let planeSrjBuses=[];for(let[sourceTraceId,layer]of planeTerminatedSourceTraceLayers??[]){let sourceTrace=sourceTraces.find(candidate=>candidate.source_trace_id===sourceTraceId),srjConnection=srjConnections.find(connection=>connection.source_trace_id===sourceTraceId);if(!sourceTrace||!srjConnection)continue;let busId=sourceTrace.name??sourceTrace.source_trace_id;if([...declaredSrjBuses,...planeSrjBuses].some(bus=>bus.busId===busId))throw new Error(`Fanout plane trace "${busId}" conflicts with an existing bus name`);planeSrjBuses.push({busId,name:busId,connectionNames:[srjConnection.name],termination:{type:"plane",layer}})}let srjBuses=[...planeSrjBuses,...declaredSrjBuses];return srjBuses.length>0?srjBuses:void 0},getDifferentialPairSourceTracesByTraceName=(differentialPairSourceTraces,traceName)=>differentialPairSourceTraces.filter(sourceTrace=>sourceTrace.name===traceName),getDifferentialPairSourceTracesByPortId=(differentialPairSourceTraces,sourcePortId)=>differentialPairSourceTraces.filter(sourceTrace=>sourceTrace.connected_source_port_ids.includes(sourcePortId)),getDifferentialPairSourceTraceOrThrow=({differentialPair,differentialPairSourceTraces,traceNameOrPortSelector})=>{let differentialPairSubcircuit=differentialPair.getSubcircuit(),sourceTracesWithMatchingName=getDifferentialPairSourceTracesByTraceName(differentialPairSourceTraces,traceNameOrPortSelector),selectedSourcePortId=(sourceTracesWithMatchingName.length===0?differentialPairSubcircuit.selectOne(traceNameOrPortSelector,{type:"port"}):null)?.source_port_id??void 0,matchingSourceTraces=selectedSourcePortId?getDifferentialPairSourceTracesByPortId(differentialPairSourceTraces,selectedSourcePortId):sourceTracesWithMatchingName;if(matchingSourceTraces.length===0)throw new Error(`Could not find source trace for trace name or port selector "${traceNameOrPortSelector}" in differential pair "${differentialPair.name}"`);if(matchingSourceTraces.length>1)throw new Error(`Trace name or port selector "${traceNameOrPortSelector}" matches multiple source traces for differential pair "${differentialPair.name}"`);let sourceTrace=matchingSourceTraces[0];if(!sourceTrace)throw new Error(`Expected one source trace for trace name or port selector "${traceNameOrPortSelector}" in differential pair "${differentialPair.name}"`);let subcircuitConnectivityMapKey=sourceTrace.subcircuit_connectivity_map_key;if(!subcircuitConnectivityMapKey)throw new Error(`Source trace "${traceNameOrPortSelector}" does not have a subcircuit connectivity map key for differential pair "${differentialPair.name}"`);return{sourceTraceId:sourceTrace.source_trace_id,subcircuitConnectivityMapKey}},getDifferentialPairSrjConnectionNamesByCohortOrThrow=({srjConnections,differentialPairName,differentialPairSourceTraces,sourceTraceId,traceSubcircuitConnectivityMapKey,traceNameOrPortSelector})=>{let differentialPairSourcePortIds=new Set,differentialPairSourceNetIds=new Set;for(let sourceTrace of differentialPairSourceTraces)if(sourceTrace.subcircuit_connectivity_map_key===traceSubcircuitConnectivityMapKey){for(let sourcePortId of sourceTrace.connected_source_port_ids)differentialPairSourcePortIds.add(sourcePortId);for(let sourceNetId of sourceTrace.connected_source_net_ids??[])differentialPairSourceNetIds.add(sourceNetId)}let matchingSrjConnections=srjConnections.filter(connection=>connection.source_trace_id===sourceTraceId);if(matchingSrjConnections.length===0&&differentialPairSourcePortIds.size===2&&(matchingSrjConnections=srjConnections.filter(connection=>differentialPairSourceNetIds.has(connection.name))),matchingSrjConnections.length===0)throw new Error(`Could not find an SRJ connection for trace name or port selector "${traceNameOrPortSelector}" in differential pair "${differentialPairName}"`);let connectionNamesByCohort=new Map;for(let srjConnection of matchingSrjConnections){let cohort=srjConnection.routingPcbGroupId;if(connectionNamesByCohort.has(cohort)){let cohortLabel=cohort===void 0?"the global routing cohort":"one local routing region";throw new Error(`Trace name or port selector "${traceNameOrPortSelector}" matches multiple SRJ connections in ${cohortLabel} for differential pair "${differentialPairName}"`)}connectionNamesByCohort.set(cohort,srjConnection.name)}return connectionNamesByCohort},getDifferentialPairCohortLabel=cohort=>cohort===void 0?"the global routing cohort":`routing PCB group "${cohort}"`,getDifferentialPairsForSimpleRouteJson=({srjConnections,differentialPairs,sourceTraces,subcircuitId})=>{let srjDifferentialPairs=[];for(let differentialPair of differentialPairs){let differentialPairSubcircuitId=differentialPair.getSubcircuit().subcircuit_id;if(subcircuitId&&differentialPairSubcircuitId!==subcircuitId)continue;let differentialPairSourceTraces=sourceTraces.filter(sourceTrace=>sourceTrace.subcircuit_id===differentialPairSubcircuitId),positiveTraceNameOrPortSelector=differentialPair._parsedProps.positiveConnection,negativeTraceNameOrPortSelector=differentialPair._parsedProps.negativeConnection,positiveSourceTrace=getDifferentialPairSourceTraceOrThrow({differentialPair,differentialPairSourceTraces,traceNameOrPortSelector:positiveTraceNameOrPortSelector}),negativeSourceTrace=getDifferentialPairSourceTraceOrThrow({differentialPair,differentialPairSourceTraces,traceNameOrPortSelector:negativeTraceNameOrPortSelector}),positiveSrjConnectionNamesByCohort=getDifferentialPairSrjConnectionNamesByCohortOrThrow({srjConnections,differentialPairName:differentialPair.name,differentialPairSourceTraces,sourceTraceId:positiveSourceTrace.sourceTraceId,traceSubcircuitConnectivityMapKey:positiveSourceTrace.subcircuitConnectivityMapKey,traceNameOrPortSelector:positiveTraceNameOrPortSelector}),negativeSrjConnectionNamesByCohort=getDifferentialPairSrjConnectionNamesByCohortOrThrow({srjConnections,differentialPairName:differentialPair.name,differentialPairSourceTraces,sourceTraceId:negativeSourceTrace.sourceTraceId,traceSubcircuitConnectivityMapKey:negativeSourceTrace.subcircuitConnectivityMapKey,traceNameOrPortSelector:negativeTraceNameOrPortSelector}),lengthTolerance=differentialPair._parsedProps.maxLengthSkew??.1;for(let cohort of positiveSrjConnectionNamesByCohort.keys())if(!negativeSrjConnectionNamesByCohort.has(cohort))throw new Error(`Differential pair "${differentialPair.name}" has a positive SRJ connection in ${getDifferentialPairCohortLabel(cohort)} without a matching negative SRJ connection`);for(let cohort of negativeSrjConnectionNamesByCohort.keys())if(!positiveSrjConnectionNamesByCohort.has(cohort))throw new Error(`Differential pair "${differentialPair.name}" has a negative SRJ connection in ${getDifferentialPairCohortLabel(cohort)} without a matching positive SRJ connection`);for(let[cohort,positiveSrjConnectionName]of positiveSrjConnectionNamesByCohort){let negativeSrjConnectionName=negativeSrjConnectionNamesByCohort.get(cohort),getTerminalCount=connectionName=>srjConnections.find(({name})=>name===connectionName)?.path?.length??2;if(getTerminalCount(positiveSrjConnectionName)!==getTerminalCount(negativeSrjConnectionName))throw new Error(`Differential pair "${differentialPair.name}" members have paths with different numbers of terminals`);srjDifferentialPairs.push({connectionNames:[positiveSrjConnectionName,negativeSrjConnectionName],lengthTolerance,...differentialPair._parsedProps.pcbTraceGap!==void 0?{traceGap:differentialPair._parsedProps.pcbTraceGap}:{},...differentialPair._parsedProps.maxUncoupledLength!==void 0?{maxUncoupledLength:differentialPair._parsedProps.maxUncoupledLength}:{}})}}return srjDifferentialPairs.length>0?srjDifferentialPairs:void 0},getDifferentialPairSourceTraceIds=({differentialPairs,sourceTraces,subcircuitId})=>{let sourceTraceIds=new Set;for(let differentialPair of differentialPairs){let pairSubcircuitId=differentialPair.getSubcircuit().subcircuit_id;if(subcircuitId&&pairSubcircuitId!==subcircuitId)continue;let differentialPairSourceTraces=sourceTraces.filter(trace=>trace.subcircuit_id===pairSubcircuitId);for(let traceNameOrPortSelector of[differentialPair._parsedProps.positiveConnection,differentialPair._parsedProps.negativeConnection])sourceTraceIds.add(getDifferentialPairSourceTraceOrThrow({differentialPair,differentialPairSourceTraces,traceNameOrPortSelector}).sourceTraceId)}return sourceTraceIds},getLayerName=layer=>typeof layer=="string"?layer:layer.name,getPreservedTraceConnectionName=trace=>trace.source_trace_id??trace.connection_name??trace.pcb_trace_id,getPhysicalConnectionIdsForPreservedTrace=trace=>{let physicallyConnectedIds=new Set(trace.connectsTo??[]);for(let routePoint3 of trace.route)if(routePoint3.route_type==="wire")for(let pcbPortId of[routePoint3.start_pcb_port_id,routePoint3.end_pcb_port_id])pcbPortId&&physicallyConnectedIds.add(pcbPortId);return Array.from(physicallyConnectedIds)},getSimpleRouteForPreservedTrace=trace=>trace.route.map(routePoint3=>{if(routePoint3.route_type==="wire")return{route_type:"wire",x:routePoint3.x,y:routePoint3.y,width:routePoint3.width,layer:getLayerName(routePoint3.layer)};if(routePoint3.route_type==="via"){let preservedViaRoutePoint=routePoint3,viaDiameter=preservedViaRoutePoint.outer_diameter??preservedViaRoutePoint.via_diameter,viaHoleDiameter=preservedViaRoutePoint.hole_diameter??preservedViaRoutePoint.via_hole_diameter;return{route_type:"via",x:routePoint3.x,y:routePoint3.y,from_layer:getLayerName(routePoint3.from_layer),to_layer:getLayerName(routePoint3.to_layer),...viaDiameter!==void 0?{via_diameter:viaDiameter}:{},...viaHoleDiameter!==void 0?{via_hole_diameter:viaHoleDiameter}:{}}}return{route_type:"through_obstacle",start:routePoint3.start,end:routePoint3.end,from_layer:getLayerName(routePoint3.start_layer),to_layer:getLayerName(routePoint3.end_layer),width:routePoint3.width}}),getPreservedRoutedSubcircuitTraces=({scopedDb,relevantSubcircuitIds})=>scopedDb.pcb_trace.list().filter(trace=>!trace.subcircuit_id||trace.pcb_component_id&&!trace.source_trace_id?!1:relevantSubcircuitIds===null||relevantSubcircuitIds.has(trace.subcircuit_id)).map(trace=>{let preservedTrace=trace,connectionName=getPreservedTraceConnectionName(preservedTrace);return{type:"pcb_trace",pcb_trace_id:trace.pcb_trace_id,source_trace_id:trace.source_trace_id,connection_name:connectionName,connectsTo:getPhysicalConnectionIdsForPreservedTrace(preservedTrace),route:getSimpleRouteForPreservedTrace(preservedTrace)}}).filter(trace=>trace.route.length>=2),COPPER_POUR_RECT_HEIGHT=.5,dedupeStrings2=values2=>Array.from(new Set(values2.filter(value=>!!value))),getLayerName2=layer=>typeof layer=="string"?layer:layer.name,createCopperPourObstacle=({layer,connectedTo,center:center2,width:width10,height:height10})=>({type:"rect",layers:[layer],center:center2,width:width10,height:height10,connectedTo,isCopperPour:!0}),getCopperPourBoundary=({outline,group:group2,board})=>outline&&outline.length>=3?outline:group2?.outline&&group2.outline.length>=3?group2.outline:board?.outline&&board.outline.length>=3?board.outline:null,getCopperPourBoundsRect=({group:group2,board})=>group2?.width&&group2.height?{center:group2.center,width:group2.width,height:group2.height}:board?.width&&board.height?{center:board.center,width:board.width,height:board.height}:null,getCopperPourConnectedTo=(net,connMap)=>dedupeStrings2([net.source_net_id,net.subcircuit_connectivity_map_key,net.source_net_id?connMap.getNetConnectedToId(net.source_net_id):null]),getUnbrokenCopperPourObstacles=({connMap,subcircuitComponent,board,group:group2})=>{if(!subcircuitComponent)return[];let obstacles=[],copperPours=subcircuitComponent.selectAll("copperpour");for(let copperPour of copperPours){let props=copperPour._parsedProps;if(!props.unbroken)continue;let net=copperPour.getSubcircuit().selectOne(props.connectsTo);if(!net?.source_net_id)continue;let layer=getLayerName2(props.layer),connectedTo=getCopperPourConnectedTo(net,connMap);if(connectedTo.length===0)continue;let boundary=getCopperPourBoundary({outline:props.outline,group:group2,board});if(boundary){let rects=fillPolygonWithRects(boundary,{rectHeight:COPPER_POUR_RECT_HEIGHT});if(rects.length>0){obstacles.push(...rects.map(rect=>createCopperPourObstacle({layer,connectedTo,center:rect.center,width:rect.width,height:rect.height})));continue}}let boundsRect=getCopperPourBoundsRect({group:group2,board});boundsRect&&obstacles.push(createCopperPourObstacle({layer,connectedTo,center:boundsRect.center,width:boundsRect.width,height:boundsRect.height}))}return obstacles},reduceNetConnectionPointsForDifferentialPairPaths=({netConnections,differentialPairConnections})=>{if(differentialPairConnections.length===0)return;let parentPointId=new Map,root=pointId=>{let parent=parentPointId.get(pointId);if(parent===void 0||parent===pointId)return pointId;let representative=root(parent);return parentPointId.set(pointId,representative),representative};for(let connection of differentialPairConnections){let pointIds=connection.pointsToConnect.flatMap(point12=>point12.pointId?[point12.pointId]:[]);for(let pointId of pointIds.slice(1))parentPointId.set(root(pointId),root(pointIds[0]))}for(let netConnection of netConnections){let representedPointIds=new Set;netConnection.pointsToConnect=netConnection.pointsToConnect.filter(point12=>{if(!point12.pointId)return!0;let representative=root(point12.pointId);return representedPointIds.has(representative)?!1:(representedPointIds.add(representative),!0)})}},getSrjConnectionPointsFromPcbTraceHints=(connectedPcbPorts,pcbTraceHints)=>{let connectedPcbPortById=new Map(connectedPcbPorts.map(pcbPort=>[pcbPort.pcb_port_id,pcbPort]));return pcbTraceHints.flatMap(pcbTraceHint=>{let pcbPort=connectedPcbPortById.get(pcbTraceHint.pcb_port_id);if(!pcbPort)return[];let layer=pcbPort.layers?.[0]??"top";return pcbTraceHint.route.map(routePoint3=>({x:routePoint3.x,y:routePoint3.y,layer}))})},getOwningPcbBoardForSubcircuit=(db22,subcircuitId)=>{let visitedSubcircuitIds=new Set,currentSubcircuitId=subcircuitId,isRequestedSubcircuit=!0;for(;currentSubcircuitId&&!visitedSubcircuitIds.has(currentSubcircuitId);){visitedSubcircuitIds.add(currentSubcircuitId);let sourceGroup=db22.source_group.getWhere({subcircuit_id:currentSubcircuitId}),sourceBoard=sourceGroup?db22.source_board.getWhere({source_group_id:sourceGroup.source_group_id}):void 0;if(sourceBoard)return{board:db22.pcb_board.getWhere({source_board_id:sourceBoard.source_board_id})??null,subcircuitIsBoard:isRequestedSubcircuit};currentSubcircuitId=sourceGroup?.parent_subcircuit_id??null,isRequestedSubcircuit=!1}return{board:null,subcircuitIsBoard:!1}},getSimpleRouteJsonFromCircuitJson=({db:db22,circuitJson,allowViaInPad,subcircuit_id,minTraceWidth,minTraceToPadEdgeClearance,minTraceToHoleEdgeClearance,minViaEdgeToPadEdgeClearance,minViaHoleEdgeToViaHoleEdgeClearance,minPlatedHoleDrillEdgeToDrillEdgeClearance,minPadEdgeToPadEdgeClearance,minBoardEdgeClearance,minViaHoleDiameter,minViaPadDiameter,nominalTraceWidth,subcircuitComponent,routingPcbGroupId,pcb_panel_id,fanoutPourNetMap,ignoreExistingTopLevelPcbRouteState=!1})=>{if(!db22&&circuitJson&&(db22=su(circuitJson)),!db22)throw new Error("db or circuitJson is required");let traceHints=db22.pcb_trace_hint.list(),relevantSubcircuitIds=subcircuit_id?new Set([subcircuit_id]):null;if(subcircuit_id){let descendantSubcircuitIds=getDescendantSubcircuitIds2(db22,subcircuit_id);for(let id3 of descendantSubcircuitIds)relevantSubcircuitIds.add(id3)}let allElements=circuitJson??db22.toArray(),sourceTraceById=new Map(allElements.flatMap(element2=>element2.type==="source_trace"?[[element2.source_trace_id,element2]]:[])),subcircuitElements=allElements.map(element2=>{if(ignoreExistingTopLevelPcbRouteState||element2.type!=="pcb_trace"||element2.subcircuit_id||!element2.source_trace_id)return element2;let inheritedSubcircuitId=sourceTraceById.get(element2.source_trace_id)?.subcircuit_id;return inheritedSubcircuitId?{...element2,subcircuit_id:inheritedSubcircuitId}:element2}).filter(e211=>!subcircuit_id||"subcircuit_id"in e211&&relevantSubcircuitIds.has(e211.subcircuit_id)),board=null,subcircuitIsBoard=!1;if(subcircuit_id){let owningBoard=getOwningPcbBoardForSubcircuit(db22,subcircuit_id);board=owningBoard.board,subcircuitIsBoard=owningBoard.subcircuitIsBoard&&board!==null}let panel=pcb_panel_id?db22.pcb_panel.get(pcb_panel_id):void 0;!board&&!panel&&(board=db22.pcb_board.list()[0]),db22=su(subcircuitElements);let getPortSelector=sourcePort=>{if(!sourcePort?.source_component_id)return;let sourceComponent=db22.source_component.get(sourcePort.source_component_id);if(sourceComponent?.name)return`${sourceComponent.name}.${sourcePort.name}`},pcbGroup=routingPcbGroupId?db22.pcb_group.get(routingPcbGroupId):subcircuit_id&&!subcircuitIsBoard?db22.pcb_group.getWhere({subcircuit_id}):void 0,activeRoutingPcbGroupId=subcircuitComponent?.pcb_group_id;activeRoutingPcbGroupId==null&&!subcircuitIsBoard&&(activeRoutingPcbGroupId=pcbGroup?.pcb_group_id);let sharedConnMap=getFullConnectivityMapFromCircuitJson(subcircuitElements),breakoutPoints=db22.pcb_breakout_point.list().filter(bp22=>!subcircuit_id||relevantSubcircuitIds?.has(bp22.subcircuit_id)),breakoutPointIsInActiveRoutingGroup=breakoutPoint=>breakoutPoint.subcircuit_id===subcircuit_id&&(activeRoutingPcbGroupId?breakoutPoint.pcb_group_id===activeRoutingPcbGroupId:!subcircuitIsBoard),preservedRoutedSubcircuitTraces=getPreservedRoutedSubcircuitTraces({scopedDb:db22,relevantSubcircuitIds}),preservedSrjTraceByPcbTraceId=new Map(preservedRoutedSubcircuitTraces.map(trace=>[trace.pcb_trace_id,trace])),isPcbViaRepresentedByPreservedSrjTrace=via=>{if(!via.pcb_trace_id)return!1;let preservedTrace=preservedSrjTraceByPcbTraceId.get(via.pcb_trace_id);if(!preservedTrace)return!1;let pcbViaLayerNames=new Set(via.layers);return preservedTrace.route.some(routePoint3=>{if(routePoint3.route_type!=="via"||routePoint3.x!==via.x||routePoint3.y!==via.y)return!1;let routeViaLayerNames=new Set(getViaSpanLayers({fromLayer:routePoint3.from_layer,toLayer:routePoint3.to_layer,layerCount:board?.num_layers??2}));return routeViaLayerNames.size===pcbViaLayerNames.size&&[...routeViaLayerNames].every(layer=>pcbViaLayerNames.has(layer))})},obstacles=getObstaclesFromCircuitJson2([...board?[board]:[],...db22.source_component.list(),...db22.source_port.list(),...db22.pcb_port.list(),...db22.pcb_component.list(),...db22.pcb_smtpad.list(),...db22.pcb_plated_hole.list(),...db22.pcb_hole.list(),...db22.pcb_trace.list().filter(trace=>!trace.source_trace_id),...db22.pcb_via.list().filter(via=>(!ignoreExistingTopLevelPcbRouteState||!!via.subcircuit_id)&&!isPcbViaRepresentedByPreservedSrjTrace(via)),...db22.pcb_keepout.list(),...db22.pcb_cutout.list()].filter(e211=>e211.type==="pcb_board"||panel&&"pcb_panel_id"in e211&&e211.pcb_panel_id===panel.pcb_panel_id||!subcircuit_id||relevantSubcircuitIds?.has(e211.subcircuit_id)),sharedConnMap);obstacles.push(...getUnbrokenCopperPourObstacles({connMap:sharedConnMap,subcircuitComponent,board,group:pcbGroup}));for(let obstacle of obstacles){let additionalIds=obstacle.connectedTo.flatMap(id3=>sharedConnMap.getIdsConnectedToNet(id3));obstacle.connectedTo=[...new Set([...obstacle.connectedTo,...additionalIds])]}let internalConnections=db22.source_component_internal_connection.list(),sourcePortIdToInternalConnectionId=new Map;for(let ic3 of internalConnections)for(let sourcePortId of ic3.source_port_ids)sourcePortIdToInternalConnectionId.set(sourcePortId,ic3.source_component_internal_connection_id);let pcbElementIdToSourcePortId=new Map;for(let pcbPort of db22.pcb_port.list())if(pcbPort.source_port_id){let smtpad2=db22.pcb_smtpad.getWhere({pcb_port_id:pcbPort.pcb_port_id});smtpad2&&pcbElementIdToSourcePortId.set(smtpad2.pcb_smtpad_id,pcbPort.source_port_id);let platedHole2=db22.pcb_plated_hole.getWhere({pcb_port_id:pcbPort.pcb_port_id});platedHole2&&pcbElementIdToSourcePortId.set(platedHole2.pcb_plated_hole_id,pcbPort.source_port_id)}for(let obstacle of obstacles)for(let connectedId of obstacle.connectedTo){let sourcePortId=pcbElementIdToSourcePortId.get(connectedId);if(sourcePortId){let internalConnectionId=sourcePortIdToInternalConnectionId.get(sourcePortId);if(internalConnectionId){obstacle.offBoardConnectsTo=[internalConnectionId],obstacle.netIsAssignable=!0;break}}}let allPoints=obstacles.flatMap(o23=>[{x:o23.center.x-o23.width/2,y:o23.center.y-o23.height/2},{x:o23.center.x+o23.width/2,y:o23.center.y+o23.height/2}]).concat(board?.outline??[]),boardBounds=board&&!board.outline?{minX:board.center.x-board.width/2,maxX:board.center.x+board.width/2,minY:board.center.y-board.height/2,maxY:board.center.y+board.height/2}:void 0,bounds,useGroupBoundsAsSrjBounds=!!(pcbGroup?.width&&pcbGroup.height&&subcircuit_id&&!subcircuitIsBoard);if(useGroupBoundsAsSrjBounds?bounds={minX:pcbGroup.center.x-pcbGroup.width/2,maxX:pcbGroup.center.x+pcbGroup.width/2,minY:pcbGroup.center.y-pcbGroup.height/2,maxY:pcbGroup.center.y+pcbGroup.height/2}:panel?bounds={minX:panel.center.x-panel.width/2,maxX:panel.center.x+panel.width/2,minY:panel.center.y-panel.height/2,maxY:panel.center.y+panel.height/2}:boardBounds?bounds=boardBounds:bounds={minX:Math.min(...allPoints.map(p23=>p23.x))-1,maxX:Math.max(...allPoints.map(p23=>p23.x))+1,minY:Math.min(...allPoints.map(p23=>p23.y))-1,maxY:Math.max(...allPoints.map(p23=>p23.y))+1},pcbGroup?.width&&pcbGroup.height&&!useGroupBoundsAsSrjBounds){let groupBounds={minX:pcbGroup.center.x-pcbGroup.width/2,maxX:pcbGroup.center.x+pcbGroup.width/2,minY:pcbGroup.center.y-pcbGroup.height/2,maxY:pcbGroup.center.y+pcbGroup.height/2};bounds={minX:Math.min(bounds.minX,groupBounds.minX),maxX:Math.max(bounds.maxX,groupBounds.maxX),minY:Math.min(bounds.minY,groupBounds.minY),maxY:Math.max(bounds.maxY,groupBounds.maxY)}}let sourceTraceIdsAlreadyPreservedAsSrjTraces=new Set(db22.pcb_trace.list().filter(t48=>t48.source_trace_id?subcircuit_id?t48.subcircuit_id===subcircuit_id:t48.subcircuit_id?db22.source_trace.get(t48.source_trace_id)?.subcircuit_id===t48.subcircuit_id:!1:!1).map(t48=>t48.source_trace_id).filter(id3=>!!id3)),sourcePortIdToBreakoutPoint=new Map;for(let bp22 of breakoutPoints){let spId=bp22.source_port_id;spId&&sourcePortIdToBreakoutPoint.set(spId,bp22)}let getPcbPortRoutePoint=pcbPort=>{let layer=pcbPort.layers?.[0]??"top",breakoutPoint=sourcePortIdToBreakoutPoint.get(pcbPort.source_port_id),portSelector=getPortSelector(db22.source_port.get(pcbPort.source_port_id));return breakoutPoint&&!breakoutPointIsInActiveRoutingGroup(breakoutPoint)?{x:breakoutPoint.x,y:breakoutPoint.y,layer:breakoutPoint.layer??layer,pointId:breakoutPoint.pcb_breakout_point_id,port_selector:portSelector}:{x:pcbPort.x,y:pcbPort.y,layer,pointId:pcbPort.pcb_port_id,pcb_port_id:pcbPort.pcb_port_id,port_selector:portSelector}},sourceTraces=db22.source_trace.list(),differentialPairs=subcircuitComponent?.selectAll("differentialpair")??[],differentialPairSourceTraceIds=getDifferentialPairSourceTraceIds({differentialPairs,sourceTraces,subcircuitId:subcircuit_id}),exposedBridgeSourceTraceIds=new Set,orderedPathsBySourceTraceId=new Map;for(let trace of subcircuitComponent?.selectAll("trace")??[]){let sourceTraceId=trace.source_trace_id;if(!sourceTraceId||(trace._exposesSubcircuitConnection&&exposedBridgeSourceTraceIds.add(sourceTraceId),sourceTraceIdsAlreadyPreservedAsSrjTraces.has(sourceTraceId)||!("path"in trace.props)))continue;let sourceTrace=sourceTraceById.get(sourceTraceId);if(!sourceTrace||sourceTrace.name!==trace._parsedProps.name||sourceTrace.connected_source_port_ids.length<=2)continue;let path=sourceTrace.connected_source_port_ids.flatMap(source_port_id=>{let port=db22.pcb_port.getWhere({source_port_id});return!port||port.x===void 0||port.y===void 0?[]:[getPcbPortRoutePoint(port).pointId]});path.length===sourceTrace.connected_source_port_ids.length&&new Set(path).size===path.length&&orderedPathsBySourceTraceId.set(sourceTraceId,path)}let explicitPathSourceTraceIds=new Set([...sourceTraces.filter(trace=>differentialPairSourceTraceIds.has(trace.source_trace_id)&&trace.connected_source_port_ids.length===2).map(trace=>trace.source_trace_id),...orderedPathsBySourceTraceId.keys()]),planeTerminatedSourceTraceLayers=getPlaneTerminatedSourceTraceLayers({fanoutPourNetMap,sourceNets:db22.source_net.list(),sourceTraces:sourceTraces.filter(sourceTrace=>!sourceTrace.connected_source_port_ids.some(sourcePortId=>sourcePortIdToBreakoutPoint.has(sourcePortId))),subcircuitId:subcircuit_id}),directTraceConnections=sourceTraces.filter(trace=>!sourceTraceIdsAlreadyPreservedAsSrjTraces.has(trace.source_trace_id)).filter(trace=>!subcircuit_id||trace.subcircuit_id===subcircuit_id).filter(sourceTrace=>sourceTrace.connected_source_net_ids.length===0||explicitPathSourceTraceIds.has(sourceTrace.source_trace_id)||planeTerminatedSourceTraceLayers.has(sourceTrace.source_trace_id)).map(trace=>{let connectedPcbPorts=trace.connected_source_port_ids.map(sourcePortId=>db22.pcb_port.getWhere({source_port_id:sourcePortId})).filter(pcbPort=>pcbPort!==null),isPlaneTerminatedSourceTrace=planeTerminatedSourceTraceLayers.has(trace.source_trace_id);if(connectedPcbPorts.length<2&&!(isPlaneTerminatedSourceTrace&&connectedPcbPorts.length===1))return null;for(let connectedPort of connectedPcbPorts)if(connectedPort.x===void 0||connectedPort.y===void 0)return console.error(`(source_port_id: ${connectedPort.source_port_id}) for trace ${trace.source_trace_id} does not have x/y coordinates. Skipping this trace.`),null;let srjTraceHintConnectionPoints=getSrjConnectionPointsFromPcbTraceHints(connectedPcbPorts,traceHints),connectedPortRoutePoints=connectedPcbPorts.map(port=>getPcbPortRoutePoint(port)),path=orderedPathsBySourceTraceId.get(trace.source_trace_id),[firstConnectedPortRoutePoint,...remainingPortRoutePoints]=connectedPortRoutePoints;return{name:trace.source_trace_id??sharedConnMap.getNetConnectedToId(trace.source_trace_id)??"",source_trace_id:trace.source_trace_id,nominalTraceWidth:trace.min_trace_thickness,width:trace.min_trace_thickness,pointsToConnect:[firstConnectedPortRoutePoint,...srjTraceHintConnectionPoints,...remainingPortRoutePoints],...path?{path}:{}}}).filter(c23=>c23!==null),explicitPathConnections=directTraceConnections.filter(connection=>connection.source_trace_id!==void 0&&explicitPathSourceTraceIds.has(connection.source_trace_id)),explicitPathSourcePortIds=new Set(explicitPathConnections.flatMap(connection=>sourceTraceById.get(connection.source_trace_id).connected_source_port_ids)),source_nets=db22.source_net.list().filter(e211=>!subcircuit_id||e211.subcircuit_id===subcircuit_id),connectionsFromNets=[],connectionFromNetId=new Map,handledNetConnectivityKeys=new Set,sourceNetIds=new Set(source_nets.map(net=>net.source_net_id)),currentSubcircuitSourceTraces=db22.source_trace.list().filter(trace=>!subcircuit_id||trace.subcircuit_id===subcircuit_id),exposedDescendantSourceNetIds=new Set;for(let trace of currentSubcircuitSourceTraces)if(exposedBridgeSourceTraceIds.has(trace.source_trace_id))for(let sourceNetId of trace.connected_source_net_ids??[])sourceNetIds.has(sourceNetId)||exposedDescendantSourceNetIds.add(sourceNetId);let routedDescendantSourceTraceIds=new Set(subcircuit_id?db22.pcb_trace.list().filter(trace=>trace.subcircuit_id&&trace.subcircuit_id!==subcircuit_id&&relevantSubcircuitIds?.has(trace.subcircuit_id)).map(trace=>trace.source_trace_id).filter(id3=>!!id3):[]),sourceTracesEligibleForNetConnections=db22.source_trace.list().filter(trace=>!planeTerminatedSourceTraceLayers.has(trace.source_trace_id)).filter(trace=>!sourceTraceIdsAlreadyPreservedAsSrjTraces.has(trace.source_trace_id)||subcircuit_id!=null&&trace.subcircuit_id===subcircuit_id).filter(trace=>!subcircuit_id||trace.subcircuit_id===subcircuit_id||(trace.connected_source_net_ids?.some(id3=>sourceNetIds.has(id3))??!1)||(trace.connected_source_net_ids?.some(id3=>exposedDescendantSourceNetIds.has(id3))??!1)&&!routedDescendantSourceTraceIds.has(trace.source_trace_id)),getSourceConnectivityKey=id3=>id3?sharedConnMap.getNetConnectedToId(id3)??id3:null;for(let net of source_nets){let netConnectivityKey=getSourceConnectivityKey(net.source_net_id);if(!netConnectivityKey||handledNetConnectivityKeys.has(netConnectivityKey))continue;handledNetConnectivityKeys.add(netConnectivityKey);let connectedSourceNets=source_nets.filter(sourceNet=>getSourceConnectivityKey(sourceNet.source_net_id)===netConnectivityKey),connectedSourceNetIds=connectedSourceNets.map(sourceNet=>sourceNet.source_net_id),connectedSourceTraces=sourceTracesEligibleForNetConnections.filter(st22=>[st22.source_trace_id,...st22.connected_source_net_ids??[]].some(id3=>getSourceConnectivityKey(id3)===netConnectivityKey)),nominalTraceWidthForConnection;for(let sourceNet of connectedSourceNets)sourceNet.trace_width!==void 0&&(nominalTraceWidthForConnection=Math.max(nominalTraceWidthForConnection??0,sourceNet.trace_width));for(let sourceTrace of connectedSourceTraces)sourceTrace.min_trace_thickness!==void 0&&(nominalTraceWidthForConnection=Math.max(nominalTraceWidthForConnection??0,sourceTrace.min_trace_thickness));let connectedSourceTraceIds=new Set(connectedSourceTraces.map(trace=>trace.source_trace_id));for(let connection2 of explicitPathConnections)connectedSourceTraceIds.has(connection2.source_trace_id)&&(connection2.netConnectionName=net.source_net_id,connection2.nominalTraceWidth=nominalTraceWidthForConnection,connection2.width=nominalTraceWidthForConnection);let pointsToConnect=[],addedPointIds=new Set,connectedPcbPorts=[];for(let st22 of connectedSourceTraces){let pcb_ports=db22.pcb_port.list().filter(p23=>st22.connected_source_port_ids.includes(p23.source_port_id));for(let p23 of pcb_ports){let routePoint3=getPcbPortRoutePoint(p23);addedPointIds.has(routePoint3.pointId)||(addedPointIds.add(routePoint3.pointId),connectedPcbPorts.push(p23),pointsToConnect.push(routePoint3))}}pointsToConnect.push(...getSrjConnectionPointsFromPcbTraceHints(connectedPcbPorts.filter(port=>!explicitPathSourcePortIds.has(port.source_port_id)),traceHints));let connection={name:net.source_net_id??sharedConnMap.getNetConnectedToId(net.source_net_id),nominalTraceWidth:nominalTraceWidthForConnection,width:nominalTraceWidthForConnection,pointsToConnect};if(pointsToConnect.length!==0){connectionsFromNets.push(connection);for(let sourceNetId of connectedSourceNetIds)connectionFromNetId.set(sourceNetId,connection)}}let connectionsFromBreakoutPoints=[];for(let bp22 of breakoutPoints){let bpSourcePortId=bp22.source_port_id,pt22={x:bp22.x,y:bp22.y,layer:bp22.layer??"top",pointId:bp22.pcb_breakout_point_id};if(bpSourcePortId){let pcb_port23=db22.pcb_port.getWhere({source_port_id:bpSourcePortId});if(!pcb_port23)continue;let portPt={x:pcb_port23.x,y:pcb_port23.y,layer:pcb_port23.layers?.[0]??"top",pointId:pcb_port23.pcb_port_id,pcb_port_id:pcb_port23.pcb_port_id,port_selector:getPortSelector(db22.source_port.get(pcb_port23.source_port_id))},isInActiveRoutingGroup=breakoutPointIsInActiveRoutingGroup(bp22),isInTransparentChildRoutingGroup=!isInActiveRoutingGroup&&bp22.subcircuit_id===subcircuit_id;if(isInActiveRoutingGroup||isInTransparentChildRoutingGroup){connectionsFromBreakoutPoints.push({name:isInTransparentChildRoutingGroup?`breakout:${bp22.pcb_breakout_point_id}`:bpSourcePortId,source_trace_id:bp22.source_trace_id,routingPcbGroupId:isInTransparentChildRoutingGroup?bp22.pcb_group_id:void 0,pointsToConnect:[portPt,pt22]});continue}bp22.source_trace_id||connectionsFromBreakoutPoints.push({name:bpSourcePortId,pointsToConnect:[portPt,pt22]});continue}if(bp22.source_net_id){let conn=connectionFromNetId.get(bp22.source_net_id);conn?conn.pointsToConnect.push(pt22):connectionsFromBreakoutPoints.push({name:bp22.source_net_id,pointsToConnect:[pt22]})}}reduceNetConnectionPointsForDifferentialPairPaths({netConnections:connectionsFromNets,differentialPairConnections:explicitPathConnections});let routableConnectionsFromNets=connectionsFromNets.filter(connection=>connection.pointsToConnect.length>=2),allConns=[...directTraceConnections,...routableConnectionsFromNets,...connectionsFromBreakoutPoints],defaultTraceWidth=minTraceWidth??board?.min_trace_width??.1;for(let conn of allConns)conn.nominalTraceWidth??(conn.nominalTraceWidth=nominalTraceWidth??defaultTraceWidth),conn.width??(conn.width=nominalTraceWidth??defaultTraceWidth);let retainedCopperElements=subcircuitElements.filter(element2=>element2.type==="pcb_trace"?!element2.source_trace_id||preservedSrjTraceByPcbTraceId.has(element2.pcb_trace_id):element2.type==="pcb_via"?!ignoreExistingTopLevelPcbRouteState||!!element2.subcircuit_id:!0),{copperConnectedPointGroups}=findFloatingCopper(retainedCopperElements);for(let copperPointIds of copperConnectedPointGroups){let connectedPointIds=new Set(copperPointIds);for(let connection of allConns){let pointIds=[...new Set(connection.pointsToConnect.flatMap(point12=>point12.pointId&&connectedPointIds.has(point12.pointId)?[point12.pointId]:[]))];pointIds.length<2||(connection.externallyConnectedPointIds??(connection.externallyConnectedPointIds=[]),connection.externallyConnectedPointIds.push(pointIds))}}bounds=expandSrjBoundsToIncludeConnectionPoints({bounds,connections:allConns});let buses=subcircuitComponent?.selectAll("bus")??[],srjDifferentialPairs=getDifferentialPairsForSimpleRouteJson({srjConnections:allConns,differentialPairs,sourceTraces:db22.source_trace.list(),subcircuitId:subcircuit_id}),srjBuses=getBusesForSimpleRouteJson({srjConnections:allConns,buses,sourceTraces:db22.source_trace.list(),subcircuitId:subcircuit_id,planeTerminatedSourceTraceLayers,preservedSourceTraceIds:sourceTraceIdsAlreadyPreservedAsSrjTraces});if(subcircuit_id){let pointIdToConn=new Map;for(let conn of allConns)for(let pt22 of conn.pointsToConnect)pt22.pointId&&pointIdToConn.set(pt22.pointId,conn);let existingTraces=db22.pcb_trace.list().filter(t48=>relevantSubcircuitIds?.has(t48.subcircuit_id));for(let tr3 of existingTraces){let tracePortIds=new Set;for(let seg of tr3.route)seg.start_pcb_port_id&&tracePortIds.add(seg.start_pcb_port_id),seg.end_pcb_port_id&&tracePortIds.add(seg.end_pcb_port_id);if(tracePortIds.size<2)continue;let firstId=tracePortIds.values().next().value;if(!firstId)continue;let conn=pointIdToConn.get(firstId);conn&&[...tracePortIds].every(pid=>pointIdToConn.get(pid)===conn)&&(conn.externallyConnectedPointIds??(conn.externallyConnectedPointIds=[]),conn.externallyConnectedPointIds.push([...tracePortIds]))}}let resolvedMinViaHoleDiameter=minViaHoleDiameter??board?.min_via_hole_diameter,resolvedMinViaPadDiameter=minViaPadDiameter??board?.min_via_pad_diameter,resolvedMinTraceToHoleEdgeClearance=minTraceToHoleEdgeClearance??board?.min_trace_to_hole_edge_clearance,resolvedMinTraceToPadEdgeClearance=minTraceToPadEdgeClearance??board?.min_trace_to_pad_edge_clearance,resolvedMinViaEdgeToPadEdgeClearance=minViaEdgeToPadEdgeClearance??board?.min_via_edge_to_pad_edge_clearance,resolvedMinViaHoleEdgeToViaHoleEdgeClearance=minViaHoleEdgeToViaHoleEdgeClearance??board?.min_via_hole_edge_to_via_hole_edge_clearance,resolvedMinPlatedHoleDrillEdgeToDrillEdgeClearance=minPlatedHoleDrillEdgeToDrillEdgeClearance??board?.min_plated_hole_drill_edge_to_drill_edge_clearance,resolvedMinPadEdgeToPadEdgeClearance=minPadEdgeToPadEdgeClearance??board?.min_pad_edge_to_pad_edge_clearance,resolvedMinBoardEdgeClearance=minBoardEdgeClearance??board?.min_board_edge_clearance;return{simpleRouteJson:{bounds,obstacles,connections:allConns,differentialPairs:srjDifferentialPairs,...srjBuses?{buses:srjBuses}:{},traces:preservedRoutedSubcircuitTraces.length>0?preservedRoutedSubcircuitTraces:void 0,layerCount:board?.num_layers??2,allowBlindAndBuriedVias:board?.allow_blind_and_buried_vias??!1,allowViaInPad:allowViaInPad??board?.is_via_in_pad_allowed??!1,minTraceWidth:Math.min(defaultTraceWidth,...allConns.map(c23=>c23.width)),minViaDiameter:resolvedMinViaPadDiameter,minViaHoleDiameter:resolvedMinViaHoleDiameter,minViaPadDiameter:resolvedMinViaPadDiameter,min_via_hole_diameter:resolvedMinViaHoleDiameter,min_via_pad_diameter:resolvedMinViaPadDiameter,minTraceToPadEdgeClearance:resolvedMinTraceToPadEdgeClearance,minTraceToHoleEdgeClearance:resolvedMinTraceToHoleEdgeClearance,minViaEdgeToPadEdgeClearance:resolvedMinViaEdgeToPadEdgeClearance,minViaHoleEdgeToViaHoleEdgeClearance:resolvedMinViaHoleEdgeToViaHoleEdgeClearance,minPlatedHoleDrillEdgeToDrillEdgeClearance:resolvedMinPlatedHoleDrillEdgeToDrillEdgeClearance,minPadEdgeToPadEdgeClearance:resolvedMinPadEdgeToPadEdgeClearance,minBoardEdgeClearance:resolvedMinBoardEdgeClearance,nominalTraceWidth,outline:getSrjOutlineForRoutingBounds({bounds:boardBounds??bounds,outline:board?.outline?.map(point12=>({...point12}))},bounds)},connMap:sharedConnMap}},unroutedElementTypes=new Set(["pcb_trace","pcb_trace_error"]),unrouteCircuitJson=circuitJson=>circuitJson.filter(element2=>!unroutedElementTypes.has(element2.type)),getPhaseTimingsFromRenderEvents=renderEvents=>{let phaseTimings={};if(!renderEvents)return phaseTimings;for(let renderPhase of orderedRenderPhases)phaseTimings[renderPhase]=0;let startEvents=new Map;for(let event of renderEvents){let[,,phase,eventType]=event.type.split(":");if(eventType==="start"){startEvents.set(`${phase}:${event.renderId}`,event);continue}if(eventType==="end"){let startEvent=startEvents.get(`${phase}:${event.renderId}`);if(startEvent){let duration=event.createdAt-startEvent.createdAt;phaseTimings[phase]=(phaseTimings[phase]||0)+duration}}}return phaseTimings},normalizePinLabels=inputPinLabels=>{let unqInputPinLabels=inputPinLabels.map(labels=>[...new Set(labels)]),result=unqInputPinLabels.map(()=>[]),desiredNumbers=unqInputPinLabels.map(()=>null);for(let i23=0;i23<unqInputPinLabels.length;i23++)for(let label of unqInputPinLabels[i23])if(/^\d+$/.test(label)){desiredNumbers[i23]=Number.parseInt(label);break}let highestPinNumber=0,alreadyAcceptedDesiredNumbers=new Set;for(let i23=0;i23<desiredNumbers.length;i23++){let desiredNumber=desiredNumbers[i23];if(desiredNumber===null||desiredNumber<1)continue;if(!alreadyAcceptedDesiredNumbers.has(desiredNumber)){alreadyAcceptedDesiredNumbers.add(desiredNumber),result[i23].push(`pin${desiredNumber}`),highestPinNumber=Math.max(highestPinNumber,desiredNumber);continue}let existingAltsForPin=0;for(let label of result[i23])label.startsWith(`pin${desiredNumber}_alt`)&&existingAltsForPin++;result[i23].push(`pin${desiredNumber}_alt${existingAltsForPin+1}`)}for(let i23=0;i23<result.length;i23++)result[i23][0]?.includes("_alt")&&(highestPinNumber++,result[i23].unshift(`pin${highestPinNumber}`));for(let i23=0;i23<result.length;i23++)result[i23].length===0&&(highestPinNumber++,result[i23].push(`pin${highestPinNumber}`));let totalLabelCounts={};for(let inputLabels of unqInputPinLabels)for(let label of inputLabels)/^\d+$/.test(label)||(totalLabelCounts[label]=(totalLabelCounts[label]??0)+1);let incrementalLabelCounts={};for(let i23=0;i23<unqInputPinLabels.length;i23++){let inputLabels=unqInputPinLabels[i23];for(let label of inputLabels)/^\d+$/.test(label)||(totalLabelCounts[label]===1?result[i23].push(label):(incrementalLabelCounts[label]=(incrementalLabelCounts[label]??0)+1,result[i23].push(`${label}${incrementalLabelCounts[label]}`)))}return result},TraceHint=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"matchedPort",null)}get config(){return{componentName:"TraceHint",zodProps:traceHintProps}}doInitialPortMatching(){let{db:db22}=this.root,{_parsedProps:props,parent}=this;if(!parent)return;if(parent.componentName==="Trace"){this.renderError(`Port inference inside trace is not yet supported (${this})`);return}if(!parent)throw new Error("TraceHint has no parent");if(!props.for){this.renderError(`TraceHint has no for property (${this})`);return}let port=parent.selectOne(props.for,{type:"port"});port||this.renderError(`${this} could not find port for selector "${props.for}"`),this.matchedPort=port,port.registerMatch(this)}getPcbRouteHints(){let{_parsedProps:props}=this,offsets=props.offset?[props.offset]:props.offsets;if(!offsets)return[];let globalTransform=this._computePcbGlobalTransformBeforeLayout();return offsets.map(offset3=>({...applyToPoint3(globalTransform,offset3),via:offset3.via,to_layer:offset3.to_layer,trace_width:offset3.trace_width}))}doInitialPcbTraceHintRender(){if(this.root?.pcbDisabled)return;let{db:db22}=this.root,{_parsedProps:props}=this;db22.pcb_trace_hint.insert({pcb_component_id:this.matchedPort?.pcb_component_id,pcb_port_id:this.matchedPort?.pcb_port_id,route:this.getPcbRouteHints()})}};function getTitleAnchorAndPosition({anchor:anchor3,x:x23,y:y23,width:width10,height:height10,isInside:isInside2}){switch(anchor3){case"top_left":return{x:x23,y:y23+height10,textAnchor:isInside2?"top_left":"bottom_left"};case"top_center":return{x:x23+width10/2,y:y23+height10,textAnchor:isInside2?"top_center":"bottom_center"};case"top_right":return{x:x23+width10,y:y23+height10,textAnchor:isInside2?"top_right":"bottom_right"};case"center_left":return{x:x23,y:y23+height10/2,textAnchor:isInside2?"center_left":"center_right"};case"center":return{x:x23+width10/2,y:y23+height10/2,textAnchor:"center"};case"center_right":return{x:x23+width10,y:y23+height10/2,textAnchor:isInside2?"center_right":"center_left"};case"bottom_left":return{x:x23,y:y23,textAnchor:isInside2?"bottom_left":"top_left"};case"bottom_center":return{x:x23+width10/2,y:y23,textAnchor:isInside2?"bottom_center":"top_center"};case"bottom_right":return{x:x23+width10,y:y23,textAnchor:isInside2?"bottom_right":"top_right"};default:return{x:x23+width10/2,y:y23+height10,textAnchor:"center"}}}var getSchematicBoxPinLabels=pinLabels=>pinLabels?Object.entries(getNumericPinLabels(pinLabels)).map(([pinKey,pinLabel])=>{let pinNumber2=getPinNumberFromPinLabelsKey(pinKey);if(pinNumber2===null)throw new Error(`Invalid schematicbox pinLabels key "${pinKey}". Expected pin<number>.`);let pinAliases=typeof pinLabel=="string"?[pinLabel]:[...pinLabel];return{pinNumber:pinNumber2,displayPinLabel:pinAliases[0]??pinKey,pinAliases}}):[],getSchematicBoxPinStyleFromReferencedChip=({referencedChip,schematicBoxPins})=>{let referencedChipPinStyle=getNumericSchPinStyle(referencedChip._parsedProps.schPinStyle,referencedChip._parsedProps.pinLabels);if(!referencedChipPinStyle)return;let schematicBoxPinStyle={};for(let{pinNumber:pinNumber2,referencedSourcePort}of schematicBoxPins){if(referencedSourcePort.pin_number===void 0)continue;let pinStyle=referencedChipPinStyle[`pin${referencedSourcePort.pin_number}`];pinStyle&&(schematicBoxPinStyle[`pin${pinNumber2}`]=pinStyle)}return Object.keys(schematicBoxPinStyle).length>0?schematicBoxPinStyle:void 0},mergeSchematicBoxPinStyles=({inheritedPinStyle,overridePinStyle})=>{if(!inheritedPinStyle&&!overridePinStyle)return;let mergedPinStyle={...inheritedPinStyle};for(let[pinKey,pinStyle]of Object.entries(overridePinStyle??{}))mergedPinStyle[pinKey]={...mergedPinStyle[pinKey],...pinStyle};return Object.keys(mergedPinStyle).length>0?mergedPinStyle:void 0},SchematicBox_doInitialSchematicComponentRender=schematicBox=>{if(schematicBox.root?.schematicDisabled)return;let{db:db22}=schematicBox.root,props=schematicBox._parsedProps;if(!props.chipRef)return;let referencedChip=schematicBox.getSubcircuit().selectOne(props.chipRef);if(!referencedChip?.source_component_id)throw new Error(`Could not resolve chipRef "${props.chipRef}" for ${schematicBox.getString()}`);let schematicBoxPinLabels=getSchematicBoxPinLabels(props.pinLabels),pinLabelsByPinKey=Object.fromEntries(schematicBoxPinLabels.map(({pinNumber:pinNumber2,displayPinLabel})=>[`pin${pinNumber2}`,displayPinLabel])),sourcePorts=db22.source_port.list({source_component_id:referencedChip.source_component_id}),schematicBoxPins=schematicBoxPinLabels.map(schematicBoxPin=>{let referencedSourcePort=sourcePorts.find(sourcePort=>schematicBoxPin.pinAliases.some(pinAlias=>sourcePort.name===pinAlias||sourcePort.port_hints?.includes(pinAlias)));if(!referencedSourcePort)throw new Error(`Could not find pin "${schematicBoxPin.displayPinLabel}" on chipRef "${props.chipRef}"`);return{...schematicBoxPin,referencedSourcePort}}),inheritedPinStyle=getSchematicBoxPinStyleFromReferencedChip({referencedChip,schematicBoxPins}),schematicBoxPinStyle=mergeSchematicBoxPinStyles({inheritedPinStyle,overridePinStyle:getNumericSchPinStyle(props.schPinStyle,props.pinLabels)}),dimensions6=getAllDimensionsForSchematicBox({schWidth:props.width,schHeight:props.height,schPinSpacing:.2,pinCount:schematicBoxPinLabels.length,schPortArrangement:props.schPinArrangement,numericSchPinStyle:getNumericSchPinStyle(schematicBoxPinStyle),pinLabels:pinLabelsByPinKey}),center2=schematicBox._getGlobalSchematicPositionBeforeLayout(),size23=dimensions6.getSize(),schematicSheetId=schematicBox._resolveSchematicSheetId(),portLabels=Object.fromEntries(schematicBoxPinLabels.map(({pinNumber:pinNumber2,displayPinLabel})=>[String(pinNumber2),displayPinLabel])),schematicComponent=db22.schematic_component.insert({center:center2,size:size23,source_component_id:referencedChip.source_component_id,is_box_with_pins:!0,port_arrangement:underscorifyPortArrangement(props.schPinArrangement),port_labels:portLabels,pin_spacing:.2,pin_styles:underscorifyPinStyles(schematicBoxPinStyle),schematic_sheet_id:schematicSheetId});schematicBox.schematic_component_id=schematicComponent.schematic_component_id;for(let{pinNumber:pinNumber2,displayPinLabel,referencedSourcePort}of schematicBoxPins){let portPosition=dimensions6.getPortPositionByPinNumber(pinNumber2);if(!portPosition)throw new Error(`Could not determine schematic position for ${schematicBox.getString()} pin${pinNumber2}`);let facingDirection={left:"left",right:"right",top:"up",bottom:"down"}[portPosition.side];db22.schematic_port.insert({schematic_component_id:schematicComponent.schematic_component_id,center:{x:center2.x+portPosition.x,y:center2.y+portPosition.y},source_port_id:referencedSourcePort.source_port_id,facing_direction:facingDirection,distance_from_component_edge:.4,side_of_component:portPosition.side,pin_number:pinNumber2,true_ccw_index:portPosition.trueIndex,display_pin_label:displayPinLabel,is_connected:!1,schematic_sheet_id:schematicSheetId})}let sectionName=props.name??props.chipRef;db22.schematic_text.insert({text:sectionName,schematic_component_id:schematicComponent.schematic_component_id,anchor:"left",rotation:0,position:{x:center2.x-size23.width/2,y:center2.y+size23.height/2+.13},color:"#006464",font_size:.18,schematic_sheet_id:schematicSheetId});let referencedSourceComponent=db22.source_component.get(referencedChip.source_component_id);db22.schematic_text.insert({text:referencedSourceComponent?.manufacturer_part_number??"",schematic_component_id:schematicComponent.schematic_component_id,anchor:"left",rotation:0,position:{x:center2.x-size23.width/2,y:center2.y-size23.height/2-.13},color:"#006464",font_size:.18,schematic_sheet_id:schematicSheetId})},SchematicBox=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"isSchematicPrimitive",!0)}get config(){return{componentName:"SchematicBox",zodProps:schematicBoxProps,shouldRenderAsSchematicBox:!0}}doInitialSchematicComponentRender(){SchematicBox_doInitialSchematicComponentRender(this)}doInitialSchematicPrimitiveRender(){if(this.root?.schematicDisabled||this.getCollapsedSchematicBoxAncestor())return;let{db:db22}=this.root,{_parsedProps:props}=this;if(props.chipRef)return;let basePadding=.6,generalPadding=typeof props.padding=="number"?props.padding:0,paddingTop=typeof props.paddingTop=="number"?props.paddingTop:generalPadding,paddingBottom=typeof props.paddingBottom=="number"?props.paddingBottom:generalPadding,paddingLeft=typeof props.paddingLeft=="number"?props.paddingLeft:generalPadding,paddingRight=typeof props.paddingRight=="number"?props.paddingRight:generalPadding,hasOverlay=props.overlay&&props.overlay.length>0,hasFixedSize=typeof props.width=="number"&&typeof props.height=="number",width10,height10,x23,y23,centerX,centerY;if(hasOverlay){let portsWithPosition=props.overlay.map(selector2=>({selector:selector2,port:this.getSubcircuit().selectOne(selector2,{type:"port"})})).filter(({port})=>port!=null).map(({port})=>({position:port._getGlobalSchematicPositionAfterLayout()}));if(portsWithPosition.length===0)return;let xs3=portsWithPosition.map(p23=>p23.position.x),ys3=portsWithPosition.map(p23=>p23.position.y),minX=Math.min(...xs3),maxX=Math.max(...xs3),minY=Math.min(...ys3),maxY=Math.max(...ys3),rawWidth=maxX-minX,rawHeight=maxY-minY,defaultHorizontalPadding=rawWidth===0?basePadding:0,defaultVerticalPadding=rawHeight===0?basePadding:0,finalPaddingLeft=paddingLeft+defaultHorizontalPadding/2,finalPaddingRight=paddingRight+defaultHorizontalPadding/2,finalPaddingTop=paddingTop+defaultVerticalPadding/2,finalPaddingBottom=paddingBottom+defaultVerticalPadding/2,left=minX-finalPaddingLeft,right=maxX+finalPaddingRight,top=minY-finalPaddingBottom,bottom=maxY+finalPaddingTop;width10=right-left,height10=bottom-top,x23=left+(props.schX??0),y23=top+(props.schY??0),centerX=x23+width10/2,centerY=y23+height10/2}else if(hasFixedSize){width10=props.width,height10=props.height;let center2=this._getGlobalSchematicPositionBeforeLayout();centerX=center2.x,centerY=center2.y,x23=centerX-width10/2,y23=centerY-height10/2}else return;if(db22.schematic_box.insert({height:height10,width:width10,x:x23,y:y23,is_dashed:props.strokeStyle==="dashed",schematic_sheet_id:this._resolveSchematicSheetId()}),props.title){let isInside2=props.titleInside,TITLE_PADDING=.1,anchor3=props.titleAlignment,anchorPos=getTitleAnchorAndPosition({anchor:anchor3,x:x23,y:y23,width:width10,height:height10,isInside:isInside2}),titleOffsetY,titleOffsetX,textAnchor=anchorPos.textAnchor;isInside2?(titleOffsetY=anchor3.includes("top")?-TITLE_PADDING:anchor3.includes("bottom")?TITLE_PADDING:0,titleOffsetX=anchor3.includes("left")?TITLE_PADDING:anchor3.includes("right")?-TITLE_PADDING:0):(titleOffsetY=anchor3.includes("top")?TITLE_PADDING:anchor3.includes("bottom")?-TITLE_PADDING:0,titleOffsetX=anchor3.includes("center_left")?-TITLE_PADDING:anchor3.includes("center_right")?TITLE_PADDING:0);let titleX=anchorPos.x+titleOffsetX,titleY=anchorPos.y+titleOffsetY;db22.schematic_text.insert({anchor:textAnchor,text:props.title,font_size:props.titleFontSize??.18,color:props.titleColor??"#000000",position:{x:titleX,y:titleY},rotation:0,schematic_sheet_id:this._resolveSchematicSheetId()})}}},Group_doInitialAssignSchematicSheetToConnectedComponents=group2=>{if(!group2.isSubcircuit||group2.root?.schematicDisabled)return;let{db:db22}=group2.root,schematicSheetIdsBySubcircuitConnectivityMapKey=new Map,schematicBoxReferencedSourceComponentIds=new Set,schematicBoxes=group2.getDescendants().filter(component=>component instanceof SchematicBox&&component.getSubcircuit()===group2);for(let schematicBox of schematicBoxes){let{chipRef,pinLabels}=schematicBox._parsedProps,schematicSheetId=schematicBox._resolveSchematicSheetId();if(!chipRef||!schematicSheetId)continue;let referencedComponent=schematicBox.getSubcircuit().selectOne(chipRef);if(!(referencedComponent instanceof NormalComponent)||!referencedComponent.source_component_id)continue;schematicBoxReferencedSourceComponentIds.add(referencedComponent.source_component_id);let referencedSourcePorts=db22.source_port.list({source_component_id:referencedComponent.source_component_id});for(let{pinAliases}of getSchematicBoxPinLabels(pinLabels)){let subcircuitConnectivityMapKey=referencedSourcePorts.find(sourcePort=>pinAliases.some(pinAlias=>sourcePort.name===pinAlias||sourcePort.port_hints?.includes(pinAlias)))?.subcircuit_connectivity_map_key;if(!subcircuitConnectivityMapKey)continue;let schematicSheetIds=schematicSheetIdsBySubcircuitConnectivityMapKey.get(subcircuitConnectivityMapKey)??new Set;schematicSheetIds.add(schematicSheetId),schematicSheetIdsBySubcircuitConnectivityMapKey.set(subcircuitConnectivityMapKey,schematicSheetIds)}}let normalComponents=group2.getDescendants().filter(component=>component instanceof NormalComponent&&component.getSubcircuit()===group2);for(let normalComponent of normalComponents){if(!normalComponent.source_component_id||schematicBoxReferencedSourceComponentIds.has(normalComponent.source_component_id)||normalComponent._resolveSchematicSheetId())continue;let connectedSchematicSheetIds=new Set,sourcePorts=db22.source_port.list({source_component_id:normalComponent.source_component_id});for(let sourcePort of sourcePorts){let subcircuitConnectivityMapKey=sourcePort.subcircuit_connectivity_map_key;if(!subcircuitConnectivityMapKey)continue;let schematicSheetIds=schematicSheetIdsBySubcircuitConnectivityMapKey.get(subcircuitConnectivityMapKey);if(schematicSheetIds)for(let schematicSheetId of schematicSheetIds)connectedSchematicSheetIds.add(schematicSheetId)}if(connectedSchematicSheetIds.size!==1)continue;let[inferredSchematicSheetId]=connectedSchematicSheetIds;inferredSchematicSheetId&&(normalComponent.schematic_sheet_id=inferredSchematicSheetId)}},SUPPORTED_COMPONENT_FIELDS=new Set(["x","y","minx","maxx","miny","maxy","width","height"]);function Group_doInitialPcbCalcPlacementResolution(group2){if(group2.root?.pcbDisabled||!group2.isSubcircuit)return;let{db:db22}=group2.root,normalComponentNameMap=group2.getNormalComponentNameMap?.()??new Map,allNormalComponents=collectNormalComponentsInSubcircuit(group2);if(!allNormalComponents.some(shouldResolvePlacementInCalcPhase))return;let namedComponentVars={};for(let component of allNormalComponents)updateVarsForNamedComponent(component,namedComponentVars);let candidatesByName=new Map,inDegree=new Map,dependents=new Map;for(let component of allNormalComponents){if(!shouldResolvePlacementInCalcPhase(component))continue;let refs=getComponentRefsForCalcPlacement(component);if(!component.name)throw new Error(`Invalid pcb position expression for ${component.getString()}: component-relative calc requires the component to have a name`);candidatesByName.set(component.name,{component,refs}),inDegree.set(component.name,0)}for(let[candidateName,candidate]of candidatesByName.entries()){let referencedCandidateNames=new Set;for(let token of candidate.refs){let{referencePath,field}=parseComponentReferenceToken(token);if(!SUPPORTED_COMPONENT_FIELDS.has(field))throw new Error(`Invalid pcb position expression for ${candidate.component.getString()}: unsupported component field "${field}" in "${token}"`);let referencedComponentName=resolveReferencedComponentName({token,referencePath,candidate,normalComponentNameMap});candidatesByName.has(referencedComponentName)&&referencedComponentName!==candidateName&&referencedCandidateNames.add(referencedComponentName)}for(let referencedComponentName of referencedCandidateNames)inDegree.set(candidateName,(inDegree.get(candidateName)??0)+1),dependents.has(referencedComponentName)||dependents.set(referencedComponentName,new Set),dependents.get(referencedComponentName).add(candidateName)}let queue=[...inDegree.entries()].filter(([,degree2])=>degree2===0).map(([name])=>name),resolvedCount=0;for(;queue.length>0;){let name=queue.shift(),candidate=candidatesByName.get(name);if(candidate){resolveCandidatePlacement(candidate.component,namedComponentVars),resolvedCount++;for(let dependentName of dependents.get(name)??[]){let nextDegree=(inDegree.get(dependentName)??0)-1;inDegree.set(dependentName,nextDegree),nextDegree===0&&queue.push(dependentName)}}}if(resolvedCount<candidatesByName.size){let unresolvedNames=[...candidatesByName.keys()].filter(name=>(inDegree.get(name)??0)>0);throw new Error(`Circular pcb position calc references detected among: ${unresolvedNames.join(", ")}`)}function resolveCandidatePlacement(component,componentVars){if(!component.pcb_component_id)return;let pcbComponent=db22.pcb_component.get(component.pcb_component_id);if(!pcbComponent)return;let rawPcbX=component._parsedProps.pcbX,rawPcbY=component._parsedProps.pcbY,rawComponentProps=component.props,rawPcbLeftEdgeX=component._parsedProps.pcbLeftEdgeX??rawComponentProps.pcbLeftEdgeX,rawPcbRightEdgeX=component._parsedProps.pcbRightEdgeX??rawComponentProps.pcbRightEdgeX,rawPcbTopEdgeY=component._parsedProps.pcbTopEdgeY??rawComponentProps.pcbTopEdgeY,rawPcbBottomEdgeY=component._parsedProps.pcbBottomEdgeY??rawComponentProps.pcbBottomEdgeY;if(rawPcbLeftEdgeX!==void 0&&rawPcbRightEdgeX!==void 0)throw new Error(`${component.componentName} cannot set both pcbLeftEdgeX and pcbRightEdgeX`);if(rawPcbTopEdgeY!==void 0&&rawPcbBottomEdgeY!==void 0)throw new Error(`${component.componentName} cannot set both pcbTopEdgeY and pcbBottomEdgeY`);let componentWidth=pcbComponent.width??0,componentHeight=pcbComponent.height??0,nextCenter={x:pcbComponent.center.x,y:pcbComponent.center.y};if(rawPcbX!==void 0){let resolvedPcbX=component.resolvePcbCoordinate({rawValue:rawPcbX,axis:"pcbX",allowComponentVariables:!0,componentVariables:componentVars});component._resolvedPcbCalcOffsetX=resolvedPcbX,nextCenter.x=resolvedPcbX}else if(rawPcbLeftEdgeX!==void 0){let resolvedPcbX=component.resolvePcbCoordinate({rawValue:rawPcbLeftEdgeX,axis:"pcbX",allowComponentVariables:!0,componentVariables:componentVars,propertyName:"pcbLeftEdgeX"})+componentWidth/2;component._resolvedPcbCalcOffsetX=resolvedPcbX,nextCenter.x=resolvedPcbX}else if(rawPcbRightEdgeX!==void 0){let resolvedPcbX=component.resolvePcbCoordinate({rawValue:rawPcbRightEdgeX,axis:"pcbX",allowComponentVariables:!0,componentVariables:componentVars,propertyName:"pcbRightEdgeX"})-componentWidth/2;component._resolvedPcbCalcOffsetX=resolvedPcbX,nextCenter.x=resolvedPcbX}if(rawPcbY!==void 0){let resolvedPcbY=component.resolvePcbCoordinate({rawValue:rawPcbY,axis:"pcbY",allowComponentVariables:!0,componentVariables:componentVars});component._resolvedPcbCalcOffsetY=resolvedPcbY,nextCenter.y=resolvedPcbY}else if(rawPcbTopEdgeY!==void 0){let resolvedPcbY=component.resolvePcbCoordinate({rawValue:rawPcbTopEdgeY,axis:"pcbY",allowComponentVariables:!0,componentVariables:componentVars,propertyName:"pcbTopEdgeY"})-componentHeight/2;component._resolvedPcbCalcOffsetY=resolvedPcbY,nextCenter.y=resolvedPcbY}else if(rawPcbBottomEdgeY!==void 0){let resolvedPcbY=component.resolvePcbCoordinate({rawValue:rawPcbBottomEdgeY,axis:"pcbY",allowComponentVariables:!0,componentVariables:componentVars,propertyName:"pcbBottomEdgeY"})+componentHeight/2;component._resolvedPcbCalcOffsetY=resolvedPcbY,nextCenter.y=resolvedPcbY}component._repositionOnPcb(nextCenter),updateVarsForNamedComponent(component,componentVars)}}function shouldResolvePlacementInCalcPhase(component){let parsedProps=component._parsedProps,rawProps=component.props,pcbX=parsedProps.pcbX,pcbY=parsedProps.pcbY,pcbLeftEdgeX=parsedProps.pcbLeftEdgeX??rawProps.pcbLeftEdgeX,pcbRightEdgeX=parsedProps.pcbRightEdgeX??rawProps.pcbRightEdgeX,pcbTopEdgeY=parsedProps.pcbTopEdgeY??rawProps.pcbTopEdgeY,pcbBottomEdgeY=parsedProps.pcbBottomEdgeY??rawProps.pcbBottomEdgeY;return pcbLeftEdgeX!==void 0||pcbRightEdgeX!==void 0||pcbTopEdgeY!==void 0||pcbBottomEdgeY!==void 0?!0:typeof pcbX=="string"||typeof pcbY=="string"}function collectNormalComponentsInSubcircuit(group2){let components=[],walk=node2=>{node2._isNormalComponent&&components.push(node2);for(let child of node2.children)child.isSubcircuit||walk(child)};for(let child of group2.children)child.isSubcircuit||walk(child);return components}function getComponentRefsForCalcPlacement(component){let refs=new Set,rawPcbX=component._parsedProps.pcbX,rawPcbY=component._parsedProps.pcbY,rawComponentProps=component.props,rawPcbLeftEdgeX=component._parsedProps.pcbLeftEdgeX??rawComponentProps.pcbLeftEdgeX,rawPcbRightEdgeX=component._parsedProps.pcbRightEdgeX??rawComponentProps.pcbRightEdgeX,rawPcbTopEdgeY=component._parsedProps.pcbTopEdgeY??rawComponentProps.pcbTopEdgeY,rawPcbBottomEdgeY=component._parsedProps.pcbBottomEdgeY??rawComponentProps.pcbBottomEdgeY,addRefs=rawValue=>{if(typeof rawValue!="string")return;let identifiers=extractCalcIdentifiers(rawValue);for(let identifier of identifiers)identifier.startsWith("board.")||refs.add(identifier)};return addRefs(rawPcbX),addRefs(rawPcbY),addRefs(rawPcbLeftEdgeX),addRefs(rawPcbRightEdgeX),addRefs(rawPcbTopEdgeY),addRefs(rawPcbBottomEdgeY),refs}function parseComponentReferenceToken(token){let dotIndex=token.lastIndexOf(".");if(dotIndex<=0||dotIndex===token.length-1)throw new Error(`Invalid component reference token: "${token}"`);return{referencePath:token.slice(0,dotIndex),field:token.slice(dotIndex+1).toLowerCase()}}function resolveReferencedComponentName(params){let{token,referencePath,candidate,normalComponentNameMap}=params,directComponents=normalComponentNameMap.get(referencePath);if(directComponents&&directComponents.length>0){if(directComponents.length>1)throw new Error(`Invalid pcb position expression for ${candidate.component.getString()}: ambiguous component reference "${referencePath}" in "${token}"`);return referencePath}let bestMatch=null;for(let componentName of normalComponentNameMap.keys())referencePath.startsWith(`${componentName}.`)&&(!bestMatch||componentName.length>bestMatch.length)&&(bestMatch=componentName);if(!bestMatch)throw new Error(`Invalid pcb position expression for ${candidate.component.getString()}: unknown component reference "${referencePath}" in "${token}"`);return bestMatch}function updateVarsForNamedComponent(component,vars){if(!component.name||!component.pcb_component_id||!component.root)return;let pcbComponent=component.root.db.pcb_component.get(component.pcb_component_id);if(!pcbComponent)return;let width10=pcbComponent.width??0,height10=pcbComponent.height??0,x23=pcbComponent.center.x,y23=pcbComponent.center.y;setSubcircuitPcbComponentCalcVariables({vars,componentName:component.name,position:{x:x23,y:y23},size:{width:width10,height:height10}});let padElementsByReference=collectPadElementsByReference(component);for(let[referencePath,elements]of padElementsByReference.entries()){let bounds=getBoundsOfPcbElements(elements),minX=bounds.minX,maxX=bounds.maxX,minY=bounds.minY,maxY=bounds.maxY;vars[`${referencePath}.x`]=(minX+maxX)/2,vars[`${referencePath}.y`]=(minY+maxY)/2,vars[`${referencePath}.width`]=maxX-minX,vars[`${referencePath}.height`]=maxY-minY,vars[`${referencePath}.minX`]=minX,vars[`${referencePath}.maxX`]=maxX,vars[`${referencePath}.minY`]=minY,vars[`${referencePath}.maxY`]=maxY}}function collectPadElementsByReference(component){let refsToElements=new Map;if(!component.name||!component.pcb_component_id||!component.root)return refsToElements;let{db:db22}=component.root,padElements=[...db22.pcb_smtpad.list({pcb_component_id:component.pcb_component_id}),...db22.pcb_plated_hole.list({pcb_component_id:component.pcb_component_id})];for(let pad2 of padElements){let aliases23=new Set;for(let hint of pad2.port_hints??[])typeof hint=="string"&&hint.length>0&&aliases23.add(hint);let pcbPortId=pad2.pcb_port_id;if(pcbPortId){let pcbPort=db22.pcb_port.get(pcbPortId),sourcePort=pcbPort?.source_port_id?db22.source_port.get(pcbPort.source_port_id):null;sourcePort?.name&&aliases23.add(sourcePort.name),sourcePort?.pin_number!=null&&aliases23.add(`pin${sourcePort.pin_number}`)}for(let alias of aliases23){let referencePath=`${component.name}.${alias}`;refsToElements.has(referencePath)||refsToElements.set(referencePath,[]),refsToElements.get(referencePath).push(pad2)}}return refsToElements}function Group_doInitialPcbComponentAnchorAlignment(group2){if(group2.root?.pcbDisabled||!group2.pcb_group_id)return;let pcbPositionAnchor=group2._parsedProps?.pcbPositionAnchor;if(!pcbPositionAnchor)return;let targetPosition=group2._getGlobalPcbPositionBeforeLayout(),{pcbX,pcbY}=group2._parsedProps;if(pcbX===void 0&&pcbY===void 0)return;let{db:db22}=group2.root,pcbGroup=db22.pcb_group.get(group2.pcb_group_id);if(!pcbGroup)return;let width10=pcbGroup.width,height10=pcbGroup.height,{center:center2}=pcbGroup;if(pcbGroup.outline&&pcbGroup.outline.length>0){let bounds2=getBoundsFromPoints3(pcbGroup.outline);bounds2&&(width10=bounds2.maxX-bounds2.minX,height10=bounds2.maxY-bounds2.minY)}if(!width10||!height10)return;let bounds={left:center2.x-width10/2,right:center2.x+width10/2,top:center2.y+height10/2,bottom:center2.y-height10/2},currentCenter={...center2},anchorPos=null;if(new Set(["center","top_left","top_center","top_right","center_left","center_right","bottom_left","bottom_center","bottom_right"]).has(pcbPositionAnchor))switch(pcbPositionAnchor){case"center":anchorPos=currentCenter;break;case"top_left":anchorPos={x:bounds.left,y:bounds.top};break;case"top_center":anchorPos={x:currentCenter.x,y:bounds.top};break;case"top_right":anchorPos={x:bounds.right,y:bounds.top};break;case"center_left":anchorPos={x:bounds.left,y:currentCenter.y};break;case"center_right":anchorPos={x:bounds.right,y:currentCenter.y};break;case"bottom_left":anchorPos={x:bounds.left,y:bounds.bottom};break;case"bottom_center":anchorPos={x:currentCenter.x,y:bounds.bottom};break;case"bottom_right":anchorPos={x:bounds.right,y:bounds.bottom};break}if(!anchorPos)return;let newCenter={...currentCenter};targetPosition.x!==void 0&&(newCenter.x+=targetPosition.x-anchorPos.x),targetPosition.y!==void 0&&(newCenter.y+=targetPosition.y-anchorPos.y),(Math.abs(newCenter.x-currentCenter.x)>1e-6||Math.abs(newCenter.y-currentCenter.y)>1e-6)&&(group2._repositionOnPcb(newCenter),db22.pcb_group.update(group2.pcb_group_id,{center:newCenter})),db22.pcb_group.update(group2.pcb_group_id,{anchor_position:targetPosition,anchor_alignment:pcbPositionAnchor,display_offset_x:formatPcbDisplayOffset(pcbX),display_offset_y:formatPcbDisplayOffset(pcbY)})}var Group_doInitialPcbLayoutFlex=group2=>{let{db:db22}=group2.root,{_parsedProps:props}=group2,pcbChildren=group2.children.filter(c23=>c23.pcb_component_id||c23.pcb_group_id);if(pcbChildren.some(child=>{let childProps=child._parsedProps;return childProps?.pcbX!==void 0||childProps?.pcbY!==void 0}))return;let rawJustify=props.pcbJustifyContent??props.justifyContent,rawAlign=props.pcbAlignItems??props.alignItems,rawGap=props.pcbFlexGap??props.pcbGap??props.gap,direction4=props.pcbFlexDirection??"row",justifyContent={start:"flex-start",end:"flex-end","flex-start":"flex-start","flex-end":"flex-end",stretch:"space-between","space-between":"space-between","space-around":"space-around","space-evenly":"space-evenly",center:"center"}[rawJustify??"space-between"],alignItems={start:"flex-start",end:"flex-end","flex-start":"flex-start","flex-end":"flex-end",stretch:"stretch",center:"center"}[rawAlign??"center"];if(!justifyContent)throw new Error(`Invalid justifyContent value: "${rawJustify}"`);if(!alignItems)throw new Error(`Invalid alignItems value: "${rawAlign}"`);let rowGap=0,columnGap=0;typeof rawGap=="object"?(rowGap=rawGap.y??0,columnGap=rawGap.x??0):typeof rawGap=="number"?(rowGap=rawGap,columnGap=rawGap):typeof rawGap=="string"&&(rowGap=length6.parse(rawGap),columnGap=length6.parse(rawGap));let minFlexContainer,width10=props.width??props.pcbWidth??void 0,height10=props.height??props.pcbHeight??void 0;(width10===void 0||height10===void 0)&&(minFlexContainer=getMinimumFlexContainer(pcbChildren.map(child=>child._getMinimumFlexContainerSize()).filter(size23=>size23!==null),{alignItems,justifyContent,direction:direction4,rowGap,columnGap}),width10=minFlexContainer.width,height10=minFlexContainer.height);let flexBox=new RootFlexBox(width10,height10,{alignItems,justifyContent,direction:direction4,rowGap,columnGap});for(let child of pcbChildren){let size23=child._getMinimumFlexContainerSize();flexBox.addChild({metadata:child,width:size23?.width??0,height:size23?.height??0,flexBasis:size23?direction4==="row"?size23.width:size23.height:void 0})}flexBox.build();let bounds={minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0,width:0,height:0};for(let child of flexBox.children)bounds.minX=Math.min(bounds.minX,child.position.x),bounds.minY=Math.min(bounds.minY,child.position.y),bounds.maxX=Math.max(bounds.maxX,child.position.x+child.size.width),bounds.maxY=Math.max(bounds.maxY,child.position.y+child.size.height);bounds.width=bounds.maxX-bounds.minX,bounds.height=bounds.maxY-bounds.minY;let groupCenter=group2._getGlobalPcbPositionBeforeLayout(),offset3={x:groupCenter.x-(bounds.maxX+bounds.minX)/2,y:groupCenter.y-(bounds.maxY+bounds.minY)/2};for(let child of flexBox.children)child.metadata._repositionOnPcb({x:child.position.x+child.size.width/2+offset3.x,y:child.position.y+child.size.height/2+offset3.y});db22.pcb_group.update(group2.pcb_group_id,{width:bounds.width,height:bounds.height,center:groupCenter})},MIN_GAP=1;function Group_doInitialPcbLayoutGrid(group2){let{db:db22}=group2.root,props=group2._parsedProps,pcbChildren=getPcbChildren(group2);if(pcbChildren.length===0)return;let childDimensions=calculateChildDimensions({db:db22,pcbChildren}),gridConfig=parseGridConfiguration(props),gridLayout=createGridLayout({props,pcbChildren,childDimensions,gridConfig}),cssGrid=createCssGrid({pcbChildren,childDimensions,gridLayout,gridConfig}),{itemCoordinates}=cssGrid.layout();positionChildren({db:db22,group:group2,pcbChildren,itemCoordinates,gridLayout}),updateGroupDimensions({db:db22,group:group2,props,gridLayout})}function getPcbChildren(group2){return group2.children.filter(child=>child.pcb_component_id||child.pcb_group_id)}function calculateChildDimensions(params){let{db:db22,pcbChildren}=params,maxWidth=0,maxHeight=0;for(let child of pcbChildren){let width10=0,height10=0;if(child.pcb_group_id){let pcbGroup=db22.pcb_group.get(child.pcb_group_id);width10=pcbGroup?.width??0,height10=pcbGroup?.height??0}else if(child.pcb_component_id){let pcbComp=db22.pcb_component.get(child.pcb_component_id);width10=pcbComp?.width??0,height10=pcbComp?.height??0}maxWidth=Math.max(maxWidth,width10),maxHeight=Math.max(maxHeight,height10)}return{width:maxWidth,height:maxHeight}}function parseGridConfiguration(props){let cols=props.pcbGridCols??props.gridCols??props.pcbLayout?.grid?.cols,rows=props.pcbGridRows??props.pcbLayout?.grid?.rows,templateColumns=props.pcbGridTemplateColumns,templateRows=props.pcbGridTemplateRows,parseGap=gapValue=>gapValue===void 0?MIN_GAP:typeof gapValue=="number"?gapValue:length6.parse(gapValue),gridGapOption=props.pcbGridGap??props.gridGap??props.pcbLayout?.gridGap,rowGapOption=props.pcbGridRowGap??props.gridRowGap??props.pcbLayout?.gridRowGap,colGapOption=props.pcbGridColumnGap??props.gridColumnGap??props.pcbLayout?.gridColumnGap,gapX=MIN_GAP,gapY=MIN_GAP;if(rowGapOption!==void 0||colGapOption!==void 0){let fallbackX=typeof gridGapOption=="object"?gridGapOption?.x:gridGapOption,fallbackY=typeof gridGapOption=="object"?gridGapOption?.y:gridGapOption;gapX=parseGap(colGapOption??fallbackX),gapY=parseGap(rowGapOption??fallbackY)}else if(typeof gridGapOption=="object"&&gridGapOption!==null)gapX=parseGap(gridGapOption.x),gapY=parseGap(gridGapOption.y);else{let gap=parseGap(gridGapOption);gapX=gap,gapY=gap}return{cols,rows,gapX,gapY,templateColumns,templateRows}}function createGridLayout(params){let{props,pcbChildren,childDimensions,gridConfig}=params;return props.pcbGridTemplateColumns||props.pcbGridTemplateRows?createTemplateBasedLayout({props,gridConfig,pcbChildren,childDimensions}):createDefaultLayout({gridConfig,pcbChildren,childDimensions})}function createTemplateBasedLayout(params){let{props,gridConfig,pcbChildren,childDimensions}=params,gridTemplateColumns=props.pcbGridTemplateColumns??"",gridTemplateRows=props.pcbGridTemplateRows??"",extractRepeatCount=template=>{let match2=template.match(/repeat\((\d+),/);return match2?parseInt(match2[1]):Math.ceil(Math.sqrt(pcbChildren.length))},numCols=props.pcbGridTemplateColumns?extractRepeatCount(gridTemplateColumns):Math.ceil(Math.sqrt(pcbChildren.length)),numRows=props.pcbGridTemplateRows?extractRepeatCount(gridTemplateRows):Math.ceil(pcbChildren.length/numCols),containerWidth=numCols*childDimensions.width+Math.max(0,numCols-1)*gridConfig.gapX,containerHeight=numRows*childDimensions.height+Math.max(0,numRows-1)*gridConfig.gapY;return{gridTemplateColumns,gridTemplateRows,containerWidth,containerHeight}}function createDefaultLayout(params){let{gridConfig,pcbChildren,childDimensions}=params,numCols,numRows;gridConfig.cols!==void 0&&gridConfig.rows!==void 0?(numCols=gridConfig.cols,numRows=gridConfig.rows):gridConfig.cols!==void 0?(numCols=gridConfig.cols,numRows=Math.ceil(pcbChildren.length/numCols)):gridConfig.rows!==void 0?(numRows=gridConfig.rows,numCols=Math.ceil(pcbChildren.length/numRows)):(numCols=Math.ceil(Math.sqrt(pcbChildren.length)),numRows=Math.ceil(pcbChildren.length/numCols)),numCols=Math.max(1,numCols),numRows=Math.max(1,numRows);let containerWidth=numCols*childDimensions.width+Math.max(0,numCols-1)*gridConfig.gapX,containerHeight=numRows*childDimensions.height+Math.max(0,numRows-1)*gridConfig.gapY,gridTemplateColumns=`repeat(${numCols}, ${childDimensions.width}px)`,gridTemplateRows=`repeat(${numRows}, ${childDimensions.height}px)`;return{gridTemplateColumns,gridTemplateRows,containerWidth,containerHeight}}function createCssGrid(params){let{pcbChildren,childDimensions,gridLayout,gridConfig}=params,gridChildren=pcbChildren.map((child,index2)=>({key:child.getString()||`child-${index2}`,contentWidth:childDimensions.width,contentHeight:childDimensions.height}));return new CssGrid({containerWidth:gridLayout.containerWidth,containerHeight:gridLayout.containerHeight,gridTemplateColumns:gridLayout.gridTemplateColumns,gridTemplateRows:gridLayout.gridTemplateRows,gap:[gridConfig.gapY,gridConfig.gapX],children:gridChildren})}function positionChildren(params){let{db:db22,group:group2,pcbChildren,itemCoordinates,gridLayout}=params,groupCenter=group2._getGlobalPcbPositionBeforeLayout(),allCircuitJson=db22.toArray();for(let i23=0;i23<pcbChildren.length;i23++){let child=pcbChildren[i23],childKey=child.getString()||`child-${i23}`,coordinates=itemCoordinates[childKey];if(!coordinates){console.warn(`PCB grid layout: No coordinates found for child ${childKey}`);continue}let targetX=groupCenter.x-gridLayout.containerWidth/2+coordinates.x+coordinates.width/2,targetY=groupCenter.y+gridLayout.containerHeight/2-coordinates.y-coordinates.height/2;if(child.pcb_component_id)repositionPcbComponentTo(allCircuitJson,child.pcb_component_id,{x:targetX,y:targetY});else{let groupChild=child;groupChild.pcb_group_id&&groupChild.source_group_id&&repositionPcbGroupTo(allCircuitJson,groupChild.source_group_id,{x:targetX,y:targetY})}}}function updateGroupDimensions(params){let{db:db22,group:group2,props,gridLayout}=params;if(group2.pcb_group_id){let groupCenter=group2._getGlobalPcbPositionBeforeLayout();db22.pcb_group.update(group2.pcb_group_id,{width:props.width??gridLayout.containerWidth,height:props.height??gridLayout.containerHeight,center:groupCenter})}}var solvePackSolverWithTimeout=(solver,timeoutMs,getCurrentTime=()=>performance.now())=>{if(timeoutMs===void 0||!Number.isFinite(timeoutMs)||timeoutMs<=0)return solver.solve(),{elapsedMs:0,timedOut:!1};let startedAt=getCurrentTime(),elapsedMs=0;for(;!solver.solved&&!solver.failed&&(solver.step(),!(solver.solved||solver.failed));)if(elapsedMs=getCurrentTime()-startedAt,elapsedMs>=timeoutMs)return{elapsedMs,timedOut:!0};return{elapsedMs,timedOut:!1}},applyComponentConstraintClusters=(group2,packInput)=>{let constraints=group2.children.filter(c23=>c23.componentName==="Constraint"&&c23._parsedProps.pcb),clusterByRoot=new Map,parent={},find2=x23=>(parent[x23]!==x23&&(parent[x23]=find2(parent[x23])),parent[x23]),union3=(a23,b23)=>{let ra3=find2(a23),rb22=find2(b23);ra3!==rb22&&(parent[rb22]=ra3)},makeSet=x23=>{x23 in parent||(parent[x23]=x23)},getIdFromSelector=sel2=>{let name=sel2.startsWith(".")?sel2.slice(1):sel2;return group2.children.find(c23=>c23.name===name)?.pcb_component_id??void 0};for(let constraint of constraints){let props=constraint._parsedProps;if("left"in props&&"right"in props){let a23=getIdFromSelector(props.left),b23=getIdFromSelector(props.right);a23&&b23&&(makeSet(a23),makeSet(b23),union3(a23,b23))}else if("top"in props&&"bottom"in props){let a23=getIdFromSelector(props.top),b23=getIdFromSelector(props.bottom);a23&&b23&&(makeSet(a23),makeSet(b23),union3(a23,b23))}else if("for"in props&&Array.isArray(props.for)){let ids=props.for.map(s23=>getIdFromSelector(s23)).filter(s23=>!!s23);for(let id3 of ids)makeSet(id3);for(let i23=1;i23<ids.length;i23++)union3(ids[0],ids[i23])}}for(let id3 of Object.keys(parent)){let rootId=find2(id3);clusterByRoot.has(rootId)||clusterByRoot.set(rootId,{componentIds:[],constraints:[]}),clusterByRoot.get(rootId).componentIds.push(id3)}for(let constraint of constraints){let props=constraint._parsedProps,compId;if("left"in props?compId=getIdFromSelector(props.left):"top"in props?compId=getIdFromSelector(props.top):"for"in props&&(compId=getIdFromSelector(props.for[0])),!compId)continue;let root=find2(compId);clusterByRoot.get(root)?.constraints.push(constraint)}let clusterMap={},packCompById=Object.fromEntries(packInput.components.map(c23=>[c23.componentId,c23]));for(let[rootId,info]of clusterByRoot.entries()){if(info.componentIds.length<=1)continue;let solver=new Solver,kVars={},getVar=(id3,axis)=>{let key=`${id3}_${axis}`;return kVars[key]||(kVars[key]=new Variable(key)),kVars[key]},anchor3=info.componentIds[0];solver.addConstraint(new Constraint(getVar(anchor3,"x"),Operator.Eq,0,Strength.required)),solver.addConstraint(new Constraint(getVar(anchor3,"y"),Operator.Eq,0,Strength.required));for(let constraint of info.constraints){let props=constraint._parsedProps;if("xDist"in props){let left=getIdFromSelector(props.left),right=getIdFromSelector(props.right);left&&right&&solver.addConstraint(new Constraint(new Expression(getVar(right,"x"),[-1,getVar(left,"x")]),Operator.Eq,props.xDist,Strength.required))}else if("yDist"in props){let top=getIdFromSelector(props.top),bottom=getIdFromSelector(props.bottom);top&&bottom&&solver.addConstraint(new Constraint(new Expression(getVar(top,"y"),[-1,getVar(bottom,"y")]),Operator.Eq,props.yDist,Strength.required))}else if("sameX"in props&&Array.isArray(props.for)){let ids=props.for.map(s23=>getIdFromSelector(s23)).filter(s23=>!!s23);if(ids.length>1){let base=getVar(ids[0],"x");for(let i23=1;i23<ids.length;i23++)solver.addConstraint(new Constraint(new Expression(getVar(ids[i23],"x"),[-1,base]),Operator.Eq,0,Strength.required))}}else if("sameY"in props&&Array.isArray(props.for)){let ids=props.for.map(s23=>getIdFromSelector(s23)).filter(s23=>!!s23);if(ids.length>1){let base=getVar(ids[0],"y");for(let i23=1;i23<ids.length;i23++)solver.addConstraint(new Constraint(new Expression(getVar(ids[i23],"y"),[-1,base]),Operator.Eq,0,Strength.required))}}}solver.updateVariables();let positions={};for(let id3 of info.componentIds)positions[id3]={x:getVar(id3,"x").value(),y:getVar(id3,"y").value()};let minX=1/0,minY=1/0,maxX=-1/0,maxY=-1/0;for(let id3 of info.componentIds){let comp=packCompById[id3],pos=positions[id3];if(comp)for(let pad2 of comp.pads){let ax22=pos.x+pad2.offset.x,ay22=pos.y+pad2.offset.y;minX=Math.min(minX,ax22-pad2.size.x/2),maxX=Math.max(maxX,ax22+pad2.size.x/2),minY=Math.min(minY,ay22-pad2.size.y/2),maxY=Math.max(maxY,ay22+pad2.size.y/2)}}let clusterCenter={x:(minX+maxX)/2,y:(minY+maxY)/2},mergedPads=[],relCenters={};for(let id3 of info.componentIds){let comp=packCompById[id3],pos=positions[id3];if(comp){relCenters[id3]={x:pos.x-clusterCenter.x,y:pos.y-clusterCenter.y};for(let pad2 of comp.pads)mergedPads.push({padId:pad2.padId,networkId:pad2.networkId,type:pad2.type,size:pad2.size,offset:{x:pos.x+pad2.offset.x-clusterCenter.x,y:pos.y+pad2.offset.y-clusterCenter.y}})}}packInput.components=packInput.components.filter(c23=>!info.componentIds.includes(c23.componentId)),packInput.components.push({componentId:info.componentIds[0],pads:mergedPads,availableRotationDegrees:[0]}),info.relativeCenters=relCenters,clusterMap[info.componentIds[0]]=info}return clusterMap},updateCadRotation=({db:db22,pcbComponentId,rotationDegrees,layer})=>{if(rotationDegrees==null||!db22?.cad_component?.list)return;let cadComponent=db22.cad_component.getWhere({pcb_component_id:pcbComponentId});if(!cadComponent)return;let delta=layer?.toLowerCase?.()==="bottom"?-rotationDegrees:rotationDegrees,currentRotationZ=cadComponent.rotation?.z??0,nextRotation={...cadComponent.rotation??{x:0,y:0,z:0},z:normalizeDegrees(currentRotationZ+delta)};db22.cad_component.update(cadComponent.cad_component_id,{rotation:nextRotation}),cadComponent.rotation=nextRotation},isDescendantGroup=(db22,groupId,ancestorId)=>{if(groupId===ancestorId)return!0;let group2=db22.source_group.get(groupId);return!group2||!group2.parent_source_group_id?!1:isDescendantGroup(db22,group2.parent_source_group_id,ancestorId)},applyPackOutput=(group2,packOutput,clusterMap,initialPackOutput)=>{let{db:db22}=group2.root;for(let packedComponent of packOutput.components){if(packedComponent.isStatic)continue;let{center:center2,componentId,ccwRotationOffset,ccwRotationDegrees}=packedComponent,cluster=clusterMap[componentId];if(cluster){let rotationDegrees2=ccwRotationDegrees??ccwRotationOffset??0,angleRad=rotationDegrees2*Math.PI/180;for(let memberId of cluster.componentIds){let rel=cluster.relativeCenters[memberId];if(!rel)continue;db22.pcb_component.update(memberId,{position_mode:"packed"});let rotatedRel={x:rel.x*Math.cos(angleRad)-rel.y*Math.sin(angleRad),y:rel.x*Math.sin(angleRad)+rel.y*Math.cos(angleRad)},member=db22.pcb_component.get(memberId);if(!member)continue;let originalCenter2=member.center,transformMatrix2=compose3(group2._computePcbGlobalTransformBeforeLayout(),translate8(center2.x+rotatedRel.x,center2.y+rotatedRel.y),rotate8(angleRad),translate8(-originalCenter2.x,-originalCenter2.y)),related=db22.toArray().filter(elm=>"pcb_component_id"in elm&&elm.pcb_component_id===memberId);transformPCBElements(related,transformMatrix2),updateCadRotation({db:db22,pcbComponentId:memberId,rotationDegrees:rotationDegrees2,layer:member.layer})}continue}let pcbComponent=db22.pcb_component.get(componentId);if(pcbComponent){db22.pcb_component.update(componentId,{position_mode:"packed"});let currentGroupId=group2.source_group_id,componentGroupId=db22.source_component.get(pcbComponent.source_component_id)?.source_group_id;if(componentGroupId!==void 0&&!isDescendantGroup(db22,componentGroupId,currentGroupId))continue;let originalCenter2=pcbComponent.center,rotationDegrees2=ccwRotationDegrees??ccwRotationOffset??0,transformMatrix2=compose3(group2._computePcbGlobalTransformBeforeLayout(),translate8(center2.x,center2.y),rotate8(rotationDegrees2*Math.PI/180),translate8(-originalCenter2.x,-originalCenter2.y)),related=db22.toArray().filter(elm=>"pcb_component_id"in elm&&elm.pcb_component_id===componentId);transformPCBElements(related,transformMatrix2),updateCadRotation({db:db22,pcbComponentId:componentId,rotationDegrees:rotationDegrees2,layer:pcbComponent.layer});continue}let pcbGroup=db22.pcb_group.list().find(g23=>g23.source_group_id===componentId);if(!pcbGroup)continue;let originalCenter=initialPackOutput.components.find(component=>component.componentId===componentId)?.center??pcbGroup.center,rotationDegrees=ccwRotationDegrees??ccwRotationOffset??0,transformMatrix=compose3(group2._computePcbGlobalTransformBeforeLayout(),translate8(center2.x,center2.y),rotate8(rotationDegrees*Math.PI/180),translate8(-originalCenter.x,-originalCenter.y)),relatedElements=db22.toArray().filter(elm=>{if("source_group_id"in elm&&elm.source_group_id&&(elm.source_group_id===componentId||isDescendantGroup(db22,elm.source_group_id,componentId)))return!0;if("source_component_id"in elm&&elm.source_component_id){let sourceComponent=db22.source_component.get(elm.source_component_id);if(sourceComponent?.source_group_id&&(sourceComponent.source_group_id===componentId||isDescendantGroup(db22,sourceComponent.source_group_id,componentId)))return!0}if("pcb_component_id"in elm&&elm.pcb_component_id){let pcbComp=db22.pcb_component.get(elm.pcb_component_id);if(pcbComp?.source_component_id){let sourceComp=db22.source_component.get(pcbComp.source_component_id);if(sourceComp?.source_group_id&&(sourceComp.source_group_id===componentId||isDescendantGroup(db22,sourceComp.source_group_id,componentId)))return!0}}return!1});for(let elm of relatedElements)elm.type==="pcb_component"&&db22.pcb_component.update(elm.pcb_component_id,{position_mode:"packed"});transformPCBElements(relatedElements,transformMatrix),db22.pcb_group.update(pcbGroup.pcb_group_id,{center:center2})}if(group2.pcb_group_id){let groupPcbComponents=db22.pcb_component.list({pcb_group_id:group2.pcb_group_id});group2.calculatePcbGroupBounds(findBoundsAndCenter(groupPcbComponents))}},normalizeLayer=layer=>(layer??"top").toLowerCase(),getPackComponentPcbLayer=(component,db22)=>{let layers=new Set,directPcbComponent=db22.pcb_component.get(component.componentId);directPcbComponent&&layers.add(normalizeLayer(directPcbComponent.layer));for(let pad2 of component.pads){let via=db22.pcb_via.get(pad2.padId),pcbComponentId=db22.pcb_smtpad.get(pad2.padId)?.pcb_component_id??db22.pcb_plated_hole.get(pad2.padId)?.pcb_component_id??via?.pcb_component_id;if(!pcbComponentId)continue;let pcbComponent=db22.pcb_component.get(pcbComponentId);pcbComponent&&layers.add(normalizeLayer(pcbComponent.layer))}return layers.size===1?layers.values().next().value:void 0},getPackInputsByPcbLayer=(packInput,db22)=>{let componentsByLayer=new Map;for(let component of packInput.components){let layer=getPackComponentPcbLayer(component,db22);if(!layer)return[packInput];let components=componentsByLayer.get(layer)??[];components.push(component),componentsByLayer.set(layer,components)}if(componentsByLayer.size<=1)return[packInput];let layerPriority=layer=>layer==="top"?0:layer==="bottom"?1:2;return Array.from(componentsByLayer.entries()).sort(([layerA],[layerB])=>layerPriority(layerA)-layerPriority(layerB)||layerA.localeCompare(layerB)).map(([,components])=>({...packInput,components}))},DEFAULT_MIN_GAP="1mm",debug42=(0,import_debug12.default)("Group_doInitialPcbLayoutPack"),getCollisionObstacleForStaticComponent=component=>{if(component.courtyard&&component.center)return{obstacleId:component.componentId,absoluteCenter:{x:component.center.x+component.courtyard.offsetFromCenter.x,y:component.center.y+component.courtyard.offsetFromCenter.y},width:component.courtyard.width,height:component.courtyard.height};if(component.pads.length===0)return;let minX=1/0,minY=1/0,maxX=-1/0,maxY=-1/0;for(let pad2 of component.pads){let absoluteCenter=pad2.absoluteCenter??(component.center?{x:component.center.x+pad2.offset.x,y:component.center.y+pad2.offset.y}:pad2.offset);minX=Math.min(minX,absoluteCenter.x-pad2.size.x/2),minY=Math.min(minY,absoluteCenter.y-pad2.size.y/2),maxX=Math.max(maxX,absoluteCenter.x+pad2.size.x/2),maxY=Math.max(maxY,absoluteCenter.y+pad2.size.y/2)}return{obstacleId:component.componentId,absoluteCenter:{x:(minX+maxX)/2,y:(minY+maxY)/2},width:maxX-minX,height:maxY-minY}},getCrossLayerPadObstacles=({components,targetLayer:targetLayer2,db:db22})=>components.flatMap(component=>component.pads.flatMap(pad2=>{let platedHole2=db22.pcb_plated_hole.get(pad2.padId),via=db22.pcb_via.get(pad2.padId);if(!(platedHole2?.layers??via?.layers)?.includes(targetLayer2))return[];let absoluteCenter=pad2.absoluteCenter??(component.center?{x:component.center.x+pad2.offset.x,y:component.center.y+pad2.offset.y}:pad2.offset);return[{obstacleId:`cross_layer_${targetLayer2}_${pad2.padId}`,absoluteCenter,width:pad2.size.x,height:pad2.size.y}]})),Group_doInitialPcbLayoutPack=group2=>{let{db:db22}=group2.root,{_parsedProps:props}=group2;group2.root?.emit("packing:start",{subcircuit_id:group2.subcircuit_id,componentDisplayName:group2.getString()});let{packOrderStrategy,packPlacementStrategy,gap:gapProp,pcbGap,pcbPackGap}=props,gap=pcbPackGap??pcbGap??gapProp,gapMm=length6.parse(gap??DEFAULT_MIN_GAP),chipMarginsMap={},staticPcbComponentIds=new Set,collectMargins=comp=>{if(comp?.pcb_component_id&&comp?._parsedProps){let props2=comp._parsedProps,left=length6.parse(props2.pcbMarginLeft??props2.pcbMarginX??0),right=length6.parse(props2.pcbMarginRight??props2.pcbMarginX??0),top=length6.parse(props2.pcbMarginTop??props2.pcbMarginY??0),bottom=length6.parse(props2.pcbMarginBottom??props2.pcbMarginY??0);(left||right||top||bottom)&&(chipMarginsMap[comp.pcb_component_id]={left,right,top,bottom})}comp?.children&&comp.children.forEach(collectMargins)};collectMargins(group2);let excludedPcbGroupIds=new Set;for(let child of group2.children){let childIsGroupOrNormalComponent=child;childIsGroupOrNormalComponent._isNormalComponent&&childIsGroupOrNormalComponent.isRelativelyPositioned?.()&&(childIsGroupOrNormalComponent.pcb_component_id&&staticPcbComponentIds.add(childIsGroupOrNormalComponent.pcb_component_id),childIsGroupOrNormalComponent.pcb_group_id&&excludedPcbGroupIds.add(childIsGroupOrNormalComponent.pcb_group_id))}let isDescendantGroup2=(db3,groupId,ancestorId)=>{if(groupId===ancestorId)return!0;let group22=db3.source_group.get(groupId);return!group22||!group22.parent_source_group_id?!1:isDescendantGroup2(db3,group22.parent_source_group_id,ancestorId)};if(excludedPcbGroupIds.size>0)for(let element2 of db22.toArray()){if(element2.type!=="pcb_component")continue;let sourceComponent=db22.source_component.get(element2.source_component_id);if(sourceComponent?.source_group_id)for(let groupId of excludedPcbGroupIds)isDescendantGroup2(db22,sourceComponent.source_group_id,groupId)&&staticPcbComponentIds.add(element2.pcb_component_id)}let filteredCircuitJson=db22.toArray(),bounds;if(props.width!==void 0&&props.height!==void 0){let widthMm=length6.parse(props.width),heightMm=length6.parse(props.height);bounds={minX:-widthMm/2,maxX:widthMm/2,minY:-heightMm/2,maxY:heightMm/2}}let initialPackOutput=convertCircuitJsonToPackOutput(filteredCircuitJson,{source_group_id:group2.source_group_id,chipMarginsMap,staticPcbComponentIds:Array.from(staticPcbComponentIds)}),packInput={...convertPackOutputToPackInput(initialPackOutput),packOrderStrategy:packOrderStrategy??"largest_to_smallest",packPlacementStrategy:packPlacementStrategy??"minimum_sum_squared_distance_to_network",minGap:gapMm,bounds},clusterMap=applyComponentConstraintClusters(group2,packInput);debug42.enabled&&(group2.root?.emit("debug:logOutput",{type:"debug:logOutput",name:`packInput-circuitjson-${group2.name}`,content:JSON.stringify(db22.toArray())}),group2.root?.emit("debug:logOutput",{type:"debug:logOutput",name:`packInput-${group2.name}`,content:packInput}));let packInputs=getPackInputsByPcbLayer(packInput,db22),packOutput={...packInput,components:[]},packingFailed=!1,reportPackingError=solverErrorMessage=>{let message=`Unable to pack all PCB components within the layout bounds: ${solverErrorMessage}`;db22.pcb_packing_error.insert({error_type:"pcb_packing_error",message,pcb_group_id:group2.pcb_group_id??void 0,subcircuit_id:group2.subcircuit_id??void 0}),group2.root?.emit("packing:error",{subcircuit_id:group2.subcircuit_id,componentDisplayName:group2.getString(),error:{message}})};try{for(let layerPackInput of packInputs){let targetLayer2=getPackComponentPcbLayer(layerPackInput.components[0],db22),componentIdsForLayer=new Set(layerPackInput.components.map(component=>component.componentId)),staticLayerObstacles=layerPackInput.components.flatMap(component=>{if(!component.isStatic)return[];let obstacle=getCollisionObstacleForStaticComponent(component);return obstacle?[obstacle]:[]}),canUseCrossLayerNetworkReferences=layerPackInput.components.every(component=>!!db22.pcb_component.get(component.componentId)&&!clusterMap[component.componentId]),crossLayerStaticComponents=packInput.components.filter(component=>component.isStatic&&!componentIdsForLayer.has(component.componentId)),fallbackCrossLayerObstacles=canUseCrossLayerNetworkReferences?[]:crossLayerStaticComponents.flatMap(component=>{let obstacle=getCollisionObstacleForStaticComponent(component);return obstacle?[obstacle]:[]}),collisionOnlyPadIds=new Set([...layerPackInput.components.filter(component=>component.isStatic),...canUseCrossLayerNetworkReferences?[]:crossLayerStaticComponents].flatMap(component=>component.pads.map(pad2=>pad2.padId))),networkReferenceSources=new Map([...packOutput.components.map(component=>[component.componentId,{component,courtyardSize:Number.EPSILON}]),...canUseCrossLayerNetworkReferences?crossLayerStaticComponents.map(component=>[component.componentId,{component,courtyardSize:1e-6}]):[]]),networkReferenceComponents=Array.from(networkReferenceSources.values(),({component,courtyardSize})=>({...component,componentId:`network_reference_${component.componentId}`,isStatic:!0,courtyard:{offsetFromCenter:{x:0,y:0},width:courtyardSize,height:courtyardSize}})),crossLayerPadObstacles=targetLayer2?getCrossLayerPadObstacles({components:Array.from(networkReferenceSources.values(),({component})=>component),targetLayer:targetLayer2,db:db22}):[],solverInput={...layerPackInput,weightedConnections:layerPackInput.weightedConnections?.filter(connection=>connection.padIds.every(padId=>!collisionOnlyPadIds.has(padId))),obstacles:[...layerPackInput.obstacles??[],...staticLayerObstacles,...fallbackCrossLayerObstacles,...crossLayerPadObstacles],components:[...networkReferenceComponents,...layerPackInput.components.filter(component=>!component.isStatic)]},solver=new PackSolver2(solverInput),solverParams=solver.getConstructorParams();group2.root?.emit("solver:started",{type:"solver:started",solverName:"PackSolver2",solverParams,solverConstructorArgs:[solverParams],componentName:group2.getString()});let pcbPackSolverTimeoutMs=group2.root?.platform?.pcbPackSolverTimeoutMs,{timedOut}=solvePackSolverWithTimeout(solver,pcbPackSolverTimeoutMs);if(timedOut&&(packingFailed=!0,reportPackingError(`PackSolver2 timed out after ${pcbPackSolverTimeoutMs}ms`)),solver.failed){packingFailed=!0;let solverErrorMessage=solver.error??solver.activeSubSolver?.error??"No valid packing solution found";reportPackingError(solverErrorMessage)}if(packOutput.components.push(...solver.packedComponents.filter(component=>componentIdsForLayer.has(component.componentId))),timedOut)break}}catch(error2){throw reportPackingError(error2 instanceof Error?error2.message:String(error2)),error2}if(debug42.enabled&&global?.debugGraphics){let graphics=getGraphicsFromPackOutput(packOutput);graphics.title=`packOutput-${group2.name}`,global.debugGraphics?.push(graphics)}applyPackOutput(group2,packOutput,clusterMap,initialPackOutput),!packingFailed&&group2.root?.emit("packing:end",{subcircuit_id:group2.subcircuit_id,componentDisplayName:group2.getString()})},parsePinNumberFromPortName=name=>{if(!name)return null;let match2=name.match(/^pin(\d+)$/i)??name.match(/^(\d+)$/);if(!match2)return null;let pinNumber2=Number(match2[1]);return Number.isFinite(pinNumber2)&&pinNumber2>0?pinNumber2:null},getDirectGroupPorts=group2=>group2.children.filter(child=>child.componentName==="Port"),normalizeGroupSchematicBoxPorts=group2=>{let{db:db22}=group2.root,ports=getDirectGroupPorts(group2);for(let port of ports){if(port._parsedProps.pinNumber!==void 0)continue;let pinNumber2=parsePinNumberFromPortName(port._parsedProps.name);pinNumber2!==null&&(port._parsedProps.pinNumber=pinNumber2)}let usedPinNumbers=new Set(ports.map(port=>port._parsedProps.pinNumber).filter(pinNumber2=>pinNumber2!==void 0)),nextPinNumber=1;for(let port of ports){if(port._parsedProps.pinNumber===void 0){for(;usedPinNumbers.has(nextPinNumber);)nextPinNumber++;port._parsedProps.pinNumber=nextPinNumber,usedPinNumbers.add(nextPinNumber)}port.source_port_id&&db22.source_port.update(port.source_port_id,{pin_number:port._parsedProps.pinNumber,port_hints:port.getNameAndAliases()})}},getGroupSchematicBoxPinLabels=group2=>{let pinLabels={};for(let port of getDirectGroupPorts(group2)){let pinNumber2=port._parsedProps.pinNumber,name=port._parsedProps.name;pinNumber2===void 0||!name||name===`pin${pinNumber2}`||name===String(pinNumber2)||(pinLabels[`pin${pinNumber2}`]=name)}return pinLabels},Group_doInitialSchematicBoxComponentRender=group2=>{if(group2.root?.schematicDisabled)return;let{db:db22}=group2.root,props=group2._parsedProps;props.schPinSpacing!==void 0&&db22.source_property_ignored_warning.insert({source_component_id:group2.source_group_id??"",property_name:"schPinSpacing",error_type:"source_property_ignored_warning",message:"schPinSpacing is deprecated and will be ignored. Pin spacing is always 0.2."}),normalizeGroupSchematicBoxPorts(group2);let dimensions6=group2._getSchematicBoxDimensions();if(!dimensions6)return;let center2=group2._getGlobalSchematicPositionBeforeLayout(),size23=dimensions6.getSize(),portLabels=group2._getPinLabelsFromPorts(),schPortArrangement=group2._getSchematicPortArrangement(),schematicComponent=db22.schematic_component.insert({center:center2,size:size23,source_group_id:group2.source_group_id,schematic_group_id:group2.schematic_group_id??void 0,subcircuit_id:group2.subcircuit_id??group2.getSubcircuit()?.subcircuit_id??void 0,is_schematic_group:!0,is_box_with_pins:!0,port_arrangement:underscorifyPortArrangement(schPortArrangement),pin_spacing:.2,pin_styles:underscorifyPinStyles(props.schPinStyle,portLabels),port_labels:portLabels,schematic_sheet_id:group2._resolveSchematicSheetId()});group2.schematic_component_id=schematicComponent.schematic_component_id,group2.schematic_group_id&&db22.schematic_group.update(group2.schematic_group_id,{center:center2,width:size23.width,height:size23.height,schematic_component_ids:[schematicComponent.schematic_component_id]});let title=props.schTitle??props.name;title&&db22.schematic_text.insert({text:title,schematic_component_id:schematicComponent.schematic_component_id,anchor:"left",rotation:0,position:{x:center2.x-size23.width/2,y:center2.y+size23.height/2+.13},color:"#006464",font_size:.18,schematic_sheet_id:group2._resolveSchematicSheetId()})};function getSchematicTextWidth2({text:text4,fontSize}){let charWidth=.12*(fontSize/.18);return text4.length*charWidth}var ASCII_ADVANCES=[28,28,35,56,56,89,67,19,33,33,39,58,28,33,28,28,56,56,56,56,56,56,56,56,56,56,28,28,58,58,58,56,102,67,67,72,72,67,61,78,72,28,50,67,56,83,72,78,67,78,72,67,61,72,67,94,67,67,61,28,28,28,47,56,33,56,56,50,56,56,28,56,56,22,22,50,22,83,56,56,56,56,33,50,28,56,50,72,50,50,50,33,26,33,58];function getSchematicTextObstacleWidth({text:text4,fontSize}){let totalAdvance=0;for(let character of text4){let advance2=ASCII_ADVANCES[character.charCodeAt(0)-32];if(advance2===void 0)return getSchematicTextWidth2({text:text4,fontSize});totalAdvance+=advance2}return totalAdvance*(fontSize/100)}var DEFAULT_SCHEMATIC_TEXT_FONT_SIZE=.18;function getSchematicTextBounds(text4){let fontSize=text4.font_size??DEFAULT_SCHEMATIC_TEXT_FONT_SIZE,width10=getSchematicTextObstacleWidth({text:text4.text??"",fontSize}),height10=fontSize,anchor3=text4.anchor??"center",minX,maxX;anchor3.includes("left")?(minX=0,maxX=width10):anchor3.includes("right")?(minX=-width10,maxX=0):(minX=-width10/2,maxX=width10/2);let minY,maxY;anchor3.includes("top")?(minY=-height10,maxY=0):anchor3.includes("bottom")?(minY=0,maxY=height10):(minY=-height10/2,maxY=height10/2);let rotation6=(text4.rotation??0)*Math.PI/180,cos32=Math.cos(rotation6),sin32=Math.sin(rotation6),corners=[{x:minX,y:minY},{x:minX,y:maxY},{x:maxX,y:minY},{x:maxX,y:maxY}].map(corner=>({x:text4.position.x+corner.x*cos32-corner.y*sin32,y:text4.position.y+corner.x*sin32+corner.y*cos32}));return getBoundsFromPoints3(corners)}var getSizeOfTreeNodeChild=(db22,child)=>{let{sourceComponent,sourceGroup}=child;if(child.nodeType==="component"){let schComponent=db22.schematic_component.getWhere({source_component_id:sourceComponent?.source_component_id});return schComponent?.size?{width:schComponent.size.width,height:schComponent.size.height}:null}if(child.nodeType==="group"){let schGroup=db22.schematic_group.getWhere({source_group_id:sourceGroup?.source_group_id});if(schGroup?.width&&schGroup?.height)return{width:schGroup.width,height:schGroup.height};let groupComponents=db22.schematic_component.list({schematic_group_id:schGroup?.schematic_group_id});if(groupComponents.length===0)return{width:0,height:0};let minX=1/0,maxX=-1/0,minY=1/0,maxY=-1/0;for(let comp of groupComponents)if(comp.center&&comp.size){let halfWidth=comp.size.width/2,halfHeight=comp.size.height/2;minX=Math.min(minX,comp.center.x-halfWidth),maxX=Math.max(maxX,comp.center.x+halfWidth),minY=Math.min(minY,comp.center.y-halfHeight),maxY=Math.max(maxY,comp.center.y+halfHeight)}let groupWidth=maxX-minX,groupHeight=maxY-minY;return{width:groupWidth,height:groupHeight}}return null},Group_doInitialSchematicLayoutFlex=group2=>{let{db:db22}=group2.root,props=group2._parsedProps,tree=getCircuitJsonTree(db22.toArray(),{source_group_id:group2.source_group_id}),textOnlyGroupLayouts=group2.getDescendants().filter(child=>child instanceof Group).filter(child=>tree.childNodes.some(node2=>node2.sourceGroup?.source_group_id===child.source_group_id)).flatMap(childGroup=>{let descendants2=childGroup.getDescendants();if(descendants2.some(child=>!(child instanceof Group)&&!(child instanceof SchematicText)))return[];let schematicGroup=db22.schematic_group.get(childGroup.schematic_group_id);if(!schematicGroup)return[];let texts=descendants2.filter(child=>child instanceof SchematicText).flatMap(child=>{let text4=db22.schematic_text.get(child.schematic_text_id);return text4?[text4]:[]}),bounds2=getBoundsFromPoints3(texts.flatMap(text4=>{let bounds3=getSchematicTextBounds(text4);return[{x:bounds3.minX,y:bounds3.minY},{x:bounds3.maxX,y:bounds3.maxY}]}));return[{schematicGroup,texts,schematicGroups:[childGroup,...descendants2.filter(child=>child instanceof Group)].flatMap(child=>{let schematicGroup2=db22.schematic_group.get(child.schematic_group_id);return schematicGroup2?[schematicGroup2]:[]}),center:bounds2?{x:(bounds2.minX+bounds2.maxX)/2,y:(bounds2.minY+bounds2.maxY)/2}:schematicGroup.center,width:childGroup._parsedProps.schWidth??(bounds2?bounds2.maxX-bounds2.minX:0),height:childGroup._parsedProps.schHeight??(bounds2?bounds2.maxY-bounds2.minY:0)}]});for(let layout of textOnlyGroupLayouts)db22.schematic_group.update(layout.schematicGroup.schematic_group_id,{center:layout.center,width:layout.width,height:layout.height});let rawJustify=props.schJustifyContent??props.justifyContent,rawAlign=props.schAlignItems??props.alignItems,rawGap=props.schFlexGap??props.schGap??props.gap,direction4=props.schFlexDirection??"row",justifyContent={start:"flex-start",end:"flex-end","flex-start":"flex-start","flex-end":"flex-end",stretch:"space-between","space-between":"space-between","space-around":"space-around","space-evenly":"space-evenly",center:"center"}[rawJustify??"space-between"],alignItems={start:"flex-start",end:"flex-end","flex-start":"flex-start","flex-end":"flex-end",stretch:"stretch",center:"center"}[rawAlign??"center"];if(!justifyContent)throw new Error(`Invalid justifyContent value: "${rawJustify}"`);if(!alignItems)throw new Error(`Invalid alignItems value: "${rawAlign}"`);let rowGap=0,columnGap=0;typeof rawGap=="object"?(rowGap=rawGap.y??0,columnGap=rawGap.x??0):typeof rawGap=="number"?(rowGap=rawGap,columnGap=rawGap):typeof rawGap=="string"&&(rowGap=length6.parse(rawGap),columnGap=length6.parse(rawGap));let minFlexContainer,width10=props.width??props.schWidth??void 0,height10=props.height??props.schHeight??void 0;(width10===void 0||height10===void 0)&&(minFlexContainer=getMinimumFlexContainer(tree.childNodes.map(child=>getSizeOfTreeNodeChild(db22,child)).filter(size23=>size23!==null),{alignItems,justifyContent,direction:direction4,rowGap,columnGap}),width10=minFlexContainer.width,height10=minFlexContainer.height);let flexBox=new RootFlexBox(width10,height10,{alignItems,justifyContent,direction:direction4,rowGap,columnGap});for(let child of tree.childNodes){let size23=getSizeOfTreeNodeChild(db22,child);flexBox.addChild({metadata:child,width:size23?.width??0,height:size23?.height??0,flexBasis:size23?direction4==="row"?size23.width:size23.height:void 0})}flexBox.build();let bounds={minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0,width:0,height:0};for(let child of flexBox.children)bounds.minX=Math.min(bounds.minX,child.position.x),bounds.minY=Math.min(bounds.minY,child.position.y),bounds.maxX=Math.max(bounds.maxX,child.position.x+child.size.width),bounds.maxY=Math.max(bounds.maxY,child.position.y+child.size.height);bounds.width=bounds.maxX-bounds.minX,bounds.height=bounds.maxY-bounds.minY;let offset3={x:-(bounds.maxX+bounds.minX)/2,y:-(bounds.maxY+bounds.minY)/2},allCircuitJson=db22.toArray();for(let child of flexBox.children){let{sourceComponent,sourceGroup}=child.metadata;if(sourceComponent){let schComponent=db22.schematic_component.getWhere({source_component_id:sourceComponent.source_component_id});if(!schComponent)continue;repositionSchematicComponentTo(allCircuitJson,schComponent.schematic_component_id,{x:child.position.x+child.size.width/2+offset3.x,y:child.position.y+child.size.height/2+offset3.y})}if(sourceGroup){if(!db22.schematic_group.getWhere({source_group_id:sourceGroup.source_group_id}))continue;let textOnlyLayout=textOnlyGroupLayouts.find(layout=>layout.schematicGroup.source_group_id===sourceGroup.source_group_id);if(textOnlyLayout){let transform22=translate8(child.position.x+child.size.width/2+offset3.x-textOnlyLayout.center.x,child.position.y+child.size.height/2+offset3.y-textOnlyLayout.center.y);for(let text4 of textOnlyLayout.texts)db22.schematic_text.update(text4.schematic_text_id,{position:applyToPoint3(transform22,text4.position)});for(let schematicGroup of textOnlyLayout.schematicGroups){let currentGroup=db22.schematic_group.get(schematicGroup.schematic_group_id);db22.schematic_group.update(schematicGroup.schematic_group_id,{center:applyToPoint3(transform22,currentGroup.center)})}continue}repositionSchematicGroupTo(allCircuitJson,sourceGroup.source_group_id,{x:child.position.x+child.size.width/2+offset3.x,y:child.position.y+child.size.height/2+offset3.y})}}group2.schematic_group_id&&db22.schematic_group.update(group2.schematic_group_id,{width:bounds.width,height:bounds.height})};function updateSchematicPrimitivesForLayoutShift({db:db22,schematicComponentId,deltaX,deltaY}){let rects=db22.schematic_rect.list({schematic_component_id:schematicComponentId});for(let rect of rects)rect.center.x+=deltaX,rect.center.y+=deltaY;let lines=db22.schematic_line.list({schematic_component_id:schematicComponentId});for(let line4 of lines)line4.x1+=deltaX,line4.y1+=deltaY,line4.x2+=deltaX,line4.y2+=deltaY;let circles=db22.schematic_circle.list({schematic_component_id:schematicComponentId});for(let circle32 of circles)circle32.center.x+=deltaX,circle32.center.y+=deltaY;let arcs=db22.schematic_arc.list({schematic_component_id:schematicComponentId});for(let arc32 of arcs)arc32.center.x+=deltaX,arc32.center.y+=deltaY;let paths=db22.schematic_path.list({schematic_component_id:schematicComponentId});for(let path of paths)for(let point12 of path.points)point12.x+=deltaX,point12.y+=deltaY}function Group_doInitialSchematicLayoutGrid(group2){let{db:db22}=group2.root,props=group2._parsedProps,schematicChildren=group2.children.filter(child=>{let isExplicitlyPositioned=child._parsedProps?.schX!==void 0||child._parsedProps?.schY!==void 0;return child.schematic_component_id&&!isExplicitlyPositioned});if(schematicChildren.length===0)return;let maxCellWidth=0,maxCellHeight=0;for(let child of schematicChildren){let schComp=db22.schematic_component.get(child.schematic_component_id);schComp?.size&&(maxCellWidth=Math.max(maxCellWidth,schComp.size.width),maxCellHeight=Math.max(maxCellHeight,schComp.size.height))}maxCellWidth===0&&schematicChildren.length>0&&(maxCellWidth=1),maxCellHeight===0&&schematicChildren.length>0&&(maxCellHeight=1);let gridColsOption=props.schGridCols??props.gridCols,gridRowsOption,gridGapOption=props.schGridGap??props.gridGap,gridRowGapOption=props.gridRowGap,gridColumnGapOption=props.gridColumnGap;props.schLayout?.grid&&(gridColsOption=props.schLayout.grid.cols??gridColsOption,gridRowsOption=props.schLayout.grid.rows,gridGapOption=props.schLayout.gridGap??gridGapOption,gridRowGapOption=props.schLayout.gridRowGap??gridRowGapOption,gridColumnGapOption=props.schLayout.gridColumnGap??gridColumnGapOption);let numCols,numRows;gridColsOption!==void 0&&gridRowsOption!==void 0?(numCols=gridColsOption,numRows=gridRowsOption):gridColsOption!==void 0?(numCols=gridColsOption,numRows=Math.ceil(schematicChildren.length/numCols)):gridRowsOption!==void 0?(numRows=gridRowsOption,numCols=Math.ceil(schematicChildren.length/numRows)):(numCols=Math.ceil(Math.sqrt(schematicChildren.length)),numRows=Math.ceil(schematicChildren.length/numCols)),numCols===0&&schematicChildren.length>0&&(numCols=1),numRows===0&&schematicChildren.length>0&&(numRows=schematicChildren.length);let gridGapX,gridGapY,parseGap=val=>{if(val!==void 0)return typeof val=="number"?val:length6.parse(val)};if(gridRowGapOption!==void 0||gridColumnGapOption!==void 0){let fallbackX=typeof gridGapOption=="object"&&gridGapOption!==null?gridGapOption.x:gridGapOption,fallbackY=typeof gridGapOption=="object"&&gridGapOption!==null?gridGapOption.y:gridGapOption;gridGapX=parseGap(gridColumnGapOption??fallbackX)??1,gridGapY=parseGap(gridRowGapOption??fallbackY)??1}else if(typeof gridGapOption=="number")gridGapX=gridGapOption,gridGapY=gridGapOption;else if(typeof gridGapOption=="string"){let parsed=length6.parse(gridGapOption);gridGapX=parsed,gridGapY=parsed}else if(typeof gridGapOption=="object"&&gridGapOption!==null){let xRaw=gridGapOption.x,yRaw=gridGapOption.y;gridGapX=typeof xRaw=="number"?xRaw:length6.parse(xRaw??"0mm"),gridGapY=typeof yRaw=="number"?yRaw:length6.parse(yRaw??"0mm")}else gridGapX=1,gridGapY=1;let totalGridWidth=numCols*maxCellWidth+Math.max(0,numCols-1)*gridGapX,totalGridHeight=numRows*maxCellHeight+Math.max(0,numRows-1)*gridGapY,groupCenter=group2._getGlobalSchematicPositionBeforeLayout(),firstCellCenterX=groupCenter.x-totalGridWidth/2+maxCellWidth/2,firstCellCenterY=groupCenter.y+totalGridHeight/2-maxCellHeight/2;for(let i23=0;i23<schematicChildren.length;i23++){let child=schematicChildren[i23];if(!child.schematic_component_id)continue;let row=Math.floor(i23/numCols),col=i23%numCols;if(row>=numRows||col>=numCols){console.warn(`Schematic grid layout: Child ${child.getString()} at index ${i23} (row ${row}, col ${col}) exceeds specified grid dimensions (${numRows}x${numCols}). Skipping placement.`);continue}let targetCellCenterX=firstCellCenterX+col*(maxCellWidth+gridGapX),targetCellCenterY=firstCellCenterY-row*(maxCellHeight+gridGapY),schComp=db22.schematic_component.get(child.schematic_component_id);if(schComp){let oldChildCenter=schComp.center,newChildCenter={x:targetCellCenterX,y:targetCellCenterY};db22.schematic_component.update(child.schematic_component_id,{center:newChildCenter});let deltaX=newChildCenter.x-oldChildCenter.x,deltaY=newChildCenter.y-oldChildCenter.y,schPorts=db22.schematic_port.list({schematic_component_id:child.schematic_component_id});for(let port of schPorts)db22.schematic_port.update(port.schematic_port_id,{center:{x:port.center.x+deltaX,y:port.center.y+deltaY}});let schTexts=db22.schematic_text.list({schematic_component_id:child.schematic_component_id});for(let text4 of schTexts)db22.schematic_text.update(text4.schematic_text_id,{position:{x:text4.position.x+deltaX,y:text4.position.y+deltaY}});updateSchematicPrimitivesForLayoutShift({db:db22,schematicComponentId:child.schematic_component_id,deltaX,deltaY})}}group2.schematic_group_id&&db22.schematic_group.update(group2.schematic_group_id,{width:totalGridWidth,height:totalGridHeight,center:groupCenter})}var debug52=(0,import_debug13.default)("Group_doInitialSchematicLayoutMatchAdapt");function Group_doInitialSchematicLayoutMatchAdapt(group2){let{db:db22}=group2.root,subtreeCircuitJson=buildSubtree(db22.toArray(),{source_group_id:group2.source_group_id});if(subtreeCircuitJson.filter(item=>item.type==="source_component").length<=1)return;let floatingGraph=convertCircuitJsonToBpc(subtreeCircuitJson);debug52.enabled&&global?.debugGraphics&&global.debugGraphics?.push(getGraphicsForBpcGraph(floatingGraph,{title:`floatingBpcGraph-${group2.name}`}));let floatingGraphNoNotConnected={boxes:floatingGraph.boxes,pins:floatingGraph.pins.map(p23=>({...p23,color:p23.color.replace("not_connected","normal")}))},{result:laidOutBpcGraph}=layoutSchematicGraphVariants([{variantName:"default",floatingGraph},{variantName:"noNotConnected",floatingGraph:floatingGraphNoNotConnected}],{singletonKeys:["vcc/2","gnd/2"],centerPinColors:["netlabel_center","component_center"],floatingBoxIdsWithMutablePinOffsets:new Set(floatingGraph.boxes.filter(box32=>floatingGraph.pins.filter(p23=>p23.boxId===box32.boxId).filter(bp22=>!bp22.color.includes("center")).length<=2).map(b23=>b23.boxId)),corpus:{}});debug52.enabled&&global?.debugGraphics&&global.debugGraphics?.push(getGraphicsForBpcGraph(laidOutBpcGraph,{title:`laidOutBpcGraph-${group2.name}`}));let groupOffset=group2._getGlobalSchematicPositionBeforeLayout();for(let box32 of laidOutBpcGraph.boxes){if(!box32.center)continue;let schematic_component32=db22.schematic_component.get(box32.boxId);if(schematic_component32){let newCenter={x:box32.center.x+groupOffset.x,y:box32.center.y+groupOffset.y},ports=db22.schematic_port.list({schematic_component_id:schematic_component32.schematic_component_id}),texts=db22.schematic_text.list({schematic_component_id:schematic_component32.schematic_component_id}),positionDelta={x:newCenter.x-schematic_component32.center.x,y:newCenter.y-schematic_component32.center.y};for(let port of ports)port.center.x+=positionDelta.x,port.center.y+=positionDelta.y;for(let text4 of texts)text4.position.x+=positionDelta.x,text4.position.y+=positionDelta.y;updateSchematicPrimitivesForLayoutShift({db:db22,schematicComponentId:schematic_component32.schematic_component_id,deltaX:positionDelta.x,deltaY:positionDelta.y}),schematic_component32.center=newCenter;continue}let schematic_net_label23=db22.schematic_net_label.get(box32.boxId);if(schematic_net_label23){let pin=laidOutBpcGraph.pins.find(p23=>p23.boxId===box32.boxId&&p23.color==="netlabel_center");if(!pin)throw new Error(`No pin found for net label: ${box32.boxId}`);let finalCenter={x:box32.center.x+groupOffset.x,y:box32.center.y+groupOffset.y};schematic_net_label23.center=finalCenter,schematic_net_label23.anchor_position={x:finalCenter.x+pin.offset.x,y:finalCenter.y+pin.offset.y};continue}console.error(`No schematic element found for box: ${box32.boxId}. This is a bug in the matchAdapt binding with @tscircuit/core`)}}var SYMBOL_TEXT_FONT_SIZE=.18,TEXT_BOX_ENABLED_FTYPES=new Set(["simple_resistor","simple_capacitor","simple_inductor","simple_crystal","simple_resonator","simple_potentiometer","simple_fuse","simple_diode","simple_led","simple_transistor","simple_mosfet","simple_op_amp","simple_voltage_source","simple_test_point"]);function getSchematicTextBounds2({text:text4,position:position22,anchor:anchor3,fontSize}){let width10=getSchematicTextWidth2({text:text4,fontSize}),height10=fontSize,relMinX,relMaxX;anchor3.includes("left")?(relMinX=0,relMaxX=width10):anchor3.includes("right")?(relMinX=-width10,relMaxX=0):(relMinX=-width10/2,relMaxX=width10/2);let relMinY,relMaxY;return anchor3.includes("top")?(relMinY=-height10,relMaxY=0):anchor3.includes("bottom")?(relMinY=0,relMaxY=height10):(relMinY=-height10/2,relMaxY=height10/2),{minX:position22.x+relMinX,maxX:position22.x+relMaxX,minY:position22.y+relMinY,maxY:position22.y+relMaxY}}function getSymbolTextBounds({schematicComponent,sourceComponent}){if(!schematicComponent.symbol_name)return[];let symbol=cc[schematicComponent.symbol_name];if(!symbol?.primitives||!symbol.center)return[];let textBounds=[];for(let primitive of symbol.primitives){if(primitive.type!=="text")continue;let value;primitive.text==="{REF}"?value=sourceComponent?.display_name??sourceComponent?.name??"":primitive.text==="{VAL}"?value=schematicComponent.symbol_display_value??"":value=primitive.text??"",value&&textBounds.push(getSchematicTextBounds2({text:value,position:{x:primitive.x-symbol.center.x+schematicComponent.center.x,y:primitive.y-symbol.center.y+schematicComponent.center.y},anchor:primitive.anchor??"center",fontSize:SYMBOL_TEXT_FONT_SIZE}))}return textBounds}function getSymbolBoxBounds(schematicComponent){return getBoundFromCenteredRect({center:schematicComponent.center,width:schematicComponent.size.width,height:schematicComponent.size.height})}function getSchematicComponentTextInclusiveBounds(db22,schematicComponent){if(!schematicComponent.center||!schematicComponent.size)return null;let sourceComponent=schematicComponent.source_component_id?db22.source_component.get(schematicComponent.source_component_id):void 0;if(!sourceComponent||!TEXT_BOX_ENABLED_FTYPES.has(sourceComponent.ftype))return null;let textBounds=getSymbolTextBounds({schematicComponent,sourceComponent});if(textBounds.length===0)return null;let boxBounds=getSymbolBoxBounds(schematicComponent),bounds={...boxBounds};for(let textBound of textBounds)bounds.minX=Math.min(bounds.minX,textBound.minX),bounds.maxX=Math.max(bounds.maxX,textBound.maxX),bounds.minY=Math.min(bounds.minY,textBound.minY),bounds.maxY=Math.max(bounds.maxY,textBound.maxY);return bounds.minX===boxBounds.minX&&bounds.maxX===boxBounds.maxX&&bounds.minY===boxBounds.minY&&bounds.maxY===boxBounds.maxY?null:bounds}function getOrientedSchematicComponent(schematicComponent,ccwRotationDegrees){let size23=schematicComponent.size;return size23&&(size23=getRotatedSize2(size23,ccwRotationDegrees)),{...schematicComponent,symbol_name:getRotatedSymbolName(schematicComponent.symbol_name,ccwRotationDegrees),size:size23}}function getSchematicComponentWithTextBounds({db:db22,schematicComponent,ccwRotationDegrees=0}){let orientedComponent=getOrientedSchematicComponent(schematicComponent,ccwRotationDegrees),textBounds=getSchematicComponentTextInclusiveBounds(db22,orientedComponent);if(!textBounds)return null;let boxBounds=getSymbolBoxBounds(orientedComponent);if(orientedComponent.size.height>orientedComponent.size.width)return textBounds;let padLeft=Math.max(0,boxBounds.minX-textBounds.minX),padRight=Math.max(0,textBounds.maxX-boxBounds.maxX),padTop=Math.max(0,textBounds.maxY-boxBounds.maxY),padBottom=Math.max(0,boxBounds.minY-textBounds.minY),left=padLeft,right=padRight;padLeft>0&&padRight>0&&(left=Math.max(padLeft,padRight),right=left);let top=padTop,bottom=padBottom;return padTop>0&&padBottom>0&&(top=Math.max(padTop,padBottom),bottom=top),{minX:boxBounds.minX-left,maxX:boxBounds.maxX+right,minY:boxBounds.minY-bottom,maxY:boxBounds.maxY+top}}var debug6=(0,import_debug14.default)("Group_doInitialSchematicLayoutMatchpack"),DEFAULT_AVAILABLE_ROTATIONS=[0,90,180,270],ROTATION_TO_PLACE_SIDE_ON_TOP={"y+":0,"x+":90,"y-":180,"x-":270};function facingDirectionToSide(facingDirection){switch(facingDirection){case"up":return"y+";case"down":return"y-";case"left":return"x-";case"right":return"x+";default:return"y+"}}function getPowerGroundForcedRotation(db22,ports){if(ports.length!==2)return null;let powerGroundRotations=new Set;for(let port of ports){let connectivityKey=db22.source_port.get(port.source_port_id)?.subcircuit_connectivity_map_key;if(!connectivityKey)continue;let net=db22.source_net.getWhere({subcircuit_connectivity_map_key:connectivityKey});if(!net)continue;let isGround=net.is_ground??!1,isPositiveVoltageSource=net.is_power===!0||net.is_positive_voltage_source===!0;if(isPositiveVoltageSource===isGround)continue;let rotationToPlacePinOnTop=ROTATION_TO_PLACE_SIDE_ON_TOP[facingDirectionToSide(port.facing_direction)],rotation6=isPositiveVoltageSource?rotationToPlacePinOnTop:(rotationToPlacePinOnTop+180)%360;powerGroundRotations.add(rotation6)}return powerGroundRotations.size===1?powerGroundRotations.values().next().value:null}function getChipSize({db:db22,schematicComponent,component,ccwRotationDegrees}){let orientedSymbolSize=schematicComponent.size;orientedSymbolSize&&(orientedSymbolSize=getRotatedSize2(orientedSymbolSize,ccwRotationDegrees));let componentWithTextBounds=getSchematicComponentWithTextBounds({db:db22,schematicComponent,ccwRotationDegrees}),textPadLeft=0,textPadRight=0,textPadTop=0,textPadBottom=0;if(componentWithTextBounds&&schematicComponent.center){let halfWidth=(orientedSymbolSize?.width??0)/2,halfHeight=(orientedSymbolSize?.height??0)/2;textPadLeft=schematicComponent.center.x-halfWidth-componentWithTextBounds.minX,textPadRight=componentWithTextBounds.maxX-(schematicComponent.center.x+halfWidth),textPadTop=componentWithTextBounds.maxY-(schematicComponent.center.y+halfHeight),textPadBottom=schematicComponent.center.y-halfHeight-componentWithTextBounds.minY}let marginLeft=(component?._parsedProps?.schMarginLeft??component?._parsedProps?.schMarginX??0)+textPadLeft,marginRight=(component?._parsedProps?.schMarginRight??component?._parsedProps?.schMarginX??0)+textPadRight,marginTop=(component?._parsedProps?.schMarginTop??component?._parsedProps?.schMarginY??0)+textPadTop,marginBottom=(component?._parsedProps?.schMarginBottom??component?._parsedProps?.schMarginY??0)+textPadBottom;component?.config.shouldRenderAsSchematicBox&&(marginTop+=.4,marginBottom+=.4);let orientedFootprint={width:(orientedSymbolSize?.width||1)+marginLeft+marginRight,height:(orientedSymbolSize?.height||1)+marginTop+marginBottom},chipSize=getRotatedSize2(orientedFootprint,ccwRotationDegrees);return{x:chipSize.width,y:chipSize.height}}function getReservedChipSize({db:db22,schematicComponent,component,ccwRotationDegrees,chipGap}){let unrotatedSize=getChipSize({db:db22,schematicComponent,component,ccwRotationDegrees:0});if(!shouldSwapOrientation(ccwRotationDegrees))return unrotatedSize;let rotatedSize=getChipSize({db:db22,schematicComponent,component,ccwRotationDegrees});return rotatedSize.x-unrotatedSize.x>=chipGap||rotatedSize.y-unrotatedSize.y>=chipGap?rotatedSize:unrotatedSize}function getNestedGroupMatchpackProxy({db:db22,schematicGroup,groupComponents,groupInstance}){let minX=1/0,maxX=-1/0,minY=1/0,maxY=-1/0,hasValidBounds=!1;for(let component of groupComponents){if(!component.center||!component.size)continue;hasValidBounds=!0;let componentBounds=getSchematicComponentWithTextBounds({db:db22,schematicComponent:component})??getBoundFromCenteredRect({center:component.center,width:component.size.width,height:component.size.height});minX=Math.min(minX,componentBounds.minX),maxX=Math.max(maxX,componentBounds.maxX),minY=Math.min(minY,componentBounds.minY),maxY=Math.max(maxY,componentBounds.maxY)}let marginLeft=groupInstance?._parsedProps?.schMarginLeft??groupInstance?._parsedProps?.schMarginX??0,marginRight=groupInstance?._parsedProps?.schMarginRight??groupInstance?._parsedProps?.schMarginX??0,marginTop=groupInstance?._parsedProps?.schMarginTop??groupInstance?._parsedProps?.schMarginY??0,marginBottom=groupInstance?._parsedProps?.schMarginBottom??groupInstance?._parsedProps?.schMarginY??0,contentCenter=hasValidBounds?{x:(minX+maxX)/2,y:(minY+maxY)/2}:schematicGroup.center??{x:0,y:0};return{center:{x:contentCenter.x+(marginRight-marginLeft)/2,y:contentCenter.y+(marginTop-marginBottom)/2},size:{x:(hasValidBounds?maxX-minX:2)+marginLeft+marginRight,y:(hasValidBounds?maxY-minY:2)+marginTop+marginBottom}}}function isTreeChildExplicitlyPositioned(treeChild,group2){if(treeChild.nodeType==="component"&&treeChild.sourceComponent){let component=group2.children.find(groupChild=>groupChild.source_component_id===treeChild.sourceComponent?.source_component_id);return component?._parsedProps?.schX!==void 0||component?._parsedProps?.schY!==void 0}if(treeChild.nodeType==="group"&&treeChild.sourceGroup){let nestedGroup=group2.children.find(groupChild=>groupChild.source_group_id===treeChild.sourceGroup?.source_group_id);return nestedGroup?._parsedProps?.schX!==void 0||nestedGroup?._parsedProps?.schY!==void 0}return!1}function getTreeChildChipId(child,index2){return child.nodeType==="component"&&child.sourceComponent?child.sourceComponent.name||`chip_${index2}`:child.nodeType==="group"&&child.sourceGroup?child.sourceGroup.name||`group_${index2}`:null}var getSchematicComponentForSourceComponent=({db:db22,sourceComponentId,schematicSheetId})=>db22.schematic_component.getWhere({source_component_id:sourceComponentId,...schematicSheetId?{schematic_sheet_id:schematicSheetId}:{}});function convertTreeToMatchPackInputProblem(tree,db22,group2,opts={}){let problem={chipMap:{},chipPinMap:{},netMap:{},pinStrongConnMap:{},netConnMap:{},chipGap:.6,decouplingCapsGap:.4,partitionGap:1.2},nestedGroupMatchpackProxyMap={},groupOffset=group2._getGlobalSchematicPositionBeforeLayout();debug6(`[${group2.name}] Processing ${tree.childNodes.length} child nodes for input problem`),tree.childNodes.forEach((child,index2)=>{let explicitlyPositioned=isTreeChildExplicitlyPositioned(child,group2);if(debug6(explicitlyPositioned?`[${group2.name}] Child ${index2} explicitly positioned, including as fixed chip`:`[${group2.name}] Processing child ${index2}: nodeType=${child.nodeType}`),child.nodeType==="component"?debug6(`[${group2.name}] - Component: ${child.sourceComponent?.name}`):child.nodeType==="group"&&debug6(`[${group2.name}] - Group: ${child.sourceGroup?.name}`),child.nodeType==="component"&&child.sourceComponent){let chipId=getTreeChildChipId(child,index2),schematicComponent=getSchematicComponentForSourceComponent({db:db22,sourceComponentId:child.sourceComponent.source_component_id,schematicSheetId:opts.schematicSheetId});if(!schematicComponent)return;let component=group2.children.find(groupChild=>groupChild.source_component_id===child.sourceComponent?.source_component_id),ports=db22.schematic_port.list({schematic_component_id:schematicComponent.schematic_component_id}),availableRotations=[...DEFAULT_AVAILABLE_ROTATIONS];if(component?._parsedProps?.schOrientation&&(availableRotations=[0]),component?._parsedProps?.schRotation!==void 0&&(availableRotations=[0]),component?._parsedProps?.facingDirection&&(availableRotations=[0]),component?._parsedProps?.schFacingDirection&&(availableRotations=[0]),component?.componentName==="Chip"&&(availableRotations=[0]),availableRotations.length===DEFAULT_AVAILABLE_ROTATIONS.length){let forcedRotation=getPowerGroundForcedRotation(db22,ports);forcedRotation!==null&&(availableRotations=[forcedRotation])}let ccwRotationDegrees=availableRotations.length===1?availableRotations[0]:0;problem.chipMap[chipId]={chipId,pins:[],size:getReservedChipSize({db:db22,schematicComponent,component,ccwRotationDegrees,chipGap:problem.chipGap}),isCapacitor:child.sourceComponent.ftype==="simple_capacitor",isCrystal:child.sourceComponent.ftype==="simple_crystal",isResistor:child.sourceComponent.ftype==="simple_resistor",isTestPoint:child.sourceComponent.ftype==="simple_test_point",availableRotations,...explicitlyPositioned&&{fixedPosition:{x:schematicComponent.center.x-groupOffset.x,y:schematicComponent.center.y-groupOffset.y}}};for(let port of ports){let sourcePort=db22.source_port.get(port.source_port_id);if(!sourcePort)continue;let pinId=`${chipId}.${sourcePort.pin_number||sourcePort.name||port.schematic_port_id}`;problem.chipMap[chipId].pins.push(pinId);let side=facingDirectionToSide(port.facing_direction);problem.chipPinMap[pinId]={pinId,offset:{x:(port.center?.x||0)-(schematicComponent.center.x||0),y:(port.center?.y||0)-(schematicComponent.center.y||0)},side}}}else if(child.nodeType==="group"&&child.sourceGroup){let groupId=getTreeChildChipId(child,index2);debug6(`[${group2.name}] Processing nested group: ${groupId}`);let schematicGroup=db22.schematic_group?.getWhere?.({source_group_id:child.sourceGroup.source_group_id}),groupInstance=group2.children.find(groupChild=>groupChild.source_group_id===child.sourceGroup?.source_group_id);if(debug6(`[${group2.name}] Found schematic_group for ${groupId}:`,schematicGroup),schematicGroup){debug6(`[${group2.name}] Treating group ${groupId} as composite chip`);let groupComponents=db22.schematic_component.list({schematic_group_id:schematicGroup.schematic_group_id});debug6(`[${group2.name}] Group ${groupId} has ${groupComponents.length} components:`,groupComponents.map(c23=>c23.source_component_id));let matchpackProxy=getNestedGroupMatchpackProxy({db:db22,schematicGroup,groupComponents,groupInstance});nestedGroupMatchpackProxyMap[groupId]=matchpackProxy,debug6(`[${group2.name}] Group ${groupId} computed proxy: ${matchpackProxy.size.x} x ${matchpackProxy.size.y} centered at (${matchpackProxy.center.x}, ${matchpackProxy.center.y})`);let groupPins=[];for(let comp of groupComponents){let ports=db22.schematic_port.list({schematic_component_id:comp.schematic_component_id});for(let port of ports){let sourcePort=db22.source_port.get(port.source_port_id);if(!sourcePort)continue;let pinId=`${groupId}.${sourcePort.pin_number||sourcePort.name||port.schematic_port_id}`;groupPins.push(pinId);let side=facingDirectionToSide(port.facing_direction);problem.chipPinMap[pinId]={pinId,offset:{x:(port.center?.x||0)-matchpackProxy.center.x,y:(port.center?.y||0)-matchpackProxy.center.y},side}}}debug6(`[${group2.name}] Group ${groupId} has ${groupPins.length} pins:`,groupPins),problem.chipMap[groupId]={chipId:groupId,pins:groupPins,size:matchpackProxy.size},debug6(`[${group2.name}] Added group ${groupId} to chipMap`)}else debug6(`[${group2.name}] Warning: No schematic_group found for group ${groupId}`)}}),debug6(`[${group2.name}] Creating connections using connectivity keys`);let connectivityGroups=new Map;for(let[chipId,chip]of Object.entries(problem.chipMap))for(let pinId of chip.pins){let pinNumber2=pinId.split(".").pop(),treeNode=tree.childNodes.find(child=>getTreeChildChipId(child,tree.childNodes.indexOf(child))===chipId);if(treeNode?.nodeType==="group"&&treeNode.sourceGroup){let schematicGroup=db22.schematic_group?.getWhere?.({source_group_id:treeNode.sourceGroup.source_group_id});if(schematicGroup){let groupComponents=db22.schematic_component.list({schematic_group_id:schematicGroup.schematic_group_id});for(let comp of groupComponents){let sourcePorts=db22.source_port.list({source_component_id:comp.source_component_id});for(let sourcePort of sourcePorts){let portNumber=sourcePort.pin_number||sourcePort.name;if(String(portNumber)===String(pinNumber2))if(sourcePort.subcircuit_connectivity_map_key){let connectivityKey=sourcePort.subcircuit_connectivity_map_key;connectivityGroups.has(connectivityKey)||connectivityGroups.set(connectivityKey,[]),connectivityGroups.get(connectivityKey).push(pinId),debug6(`[${group2.name}] \u2713 Pin ${pinId} has connectivity key: ${connectivityKey}`)}else debug6(`[${group2.name}] Pin ${pinId} has no connectivity key`)}}}}else if(treeNode?.nodeType==="component"&&treeNode.sourceComponent){let sourcePorts=db22.source_port.list({source_component_id:treeNode.sourceComponent.source_component_id});for(let sourcePort of sourcePorts){let portNumber=sourcePort.pin_number||sourcePort.name;if(String(portNumber)===String(pinNumber2)&&sourcePort.subcircuit_connectivity_map_key){let connectivityKey=sourcePort.subcircuit_connectivity_map_key;connectivityGroups.has(connectivityKey)||connectivityGroups.set(connectivityKey,[]),connectivityGroups.get(connectivityKey).push(pinId),debug6(`[${group2.name}] Pin ${pinId} has connectivity key: ${connectivityKey}`)}}}}debug6(`[${group2.name}] Found ${connectivityGroups.size} connectivity groups:`,Array.from(connectivityGroups.entries()).map(([key,pins])=>({key,pins})));for(let[connectivityKey,pins]of connectivityGroups){let tracesWithThisKey=db22.source_trace.list().filter(trace=>trace.subcircuit_connectivity_map_key===connectivityKey),hasNetConnections=tracesWithThisKey.some(trace=>trace.connected_source_net_ids&&trace.connected_source_net_ids.length>0),hasDirectConnections=tracesWithThisKey.some(trace=>trace.connected_source_port_ids&&trace.connected_source_port_ids.length>=2);if(debug6(`[${group2.name}] Connectivity ${connectivityKey}: hasNetConnections=${hasNetConnections}, hasDirectConnections=${hasDirectConnections}`),pins.length>=2&&hasDirectConnections){for(let trace of tracesWithThisKey)if(trace.connected_source_port_ids&&trace.connected_source_port_ids.length>=2){let directlyConnectedPins=[];for(let portId of trace.connected_source_port_ids)for(let pinId of pins){let pinNumber2=pinId.split(".").pop(),sourcePort=db22.source_port.get(portId);if(sourcePort&&String(sourcePort.pin_number||sourcePort.name)===String(pinNumber2)){let chipId=pinId.split(".")[0],treeNode=tree.childNodes.find(child=>getTreeChildChipId(child,tree.childNodes.indexOf(child))===chipId);treeNode?.nodeType==="component"&&treeNode.sourceComponent&&db22.source_port.list({source_component_id:treeNode.sourceComponent.source_component_id}).some(p23=>p23.source_port_id===portId)&&directlyConnectedPins.push(pinId)}}for(let i23=0;i23<directlyConnectedPins.length;i23++)for(let j23=i23+1;j23<directlyConnectedPins.length;j23++){let pin1=directlyConnectedPins[i23],pin2=directlyConnectedPins[j23];problem.pinStrongConnMap[`${pin1}-${pin2}`]=!0,problem.pinStrongConnMap[`${pin2}-${pin1}`]=!0,debug6(`[${group2.name}] Created strong connection: ${pin1} <-> ${pin2}`)}}}if(hasNetConnections){let source_net23=db22.source_net.getWhere({subcircuit_connectivity_map_key:connectivityKey}),isGround=source_net23?.is_ground??!1,isPositiveVoltageSource=source_net23?.is_power===!0||source_net23?.is_positive_voltage_source===!0;problem.netMap[connectivityKey]={netId:connectivityKey,isGround,isPositiveVoltageSource};for(let pinId of pins)problem.netConnMap[`${pinId}-${connectivityKey}`]=!0;debug6(`[${group2.name}] Created net ${connectivityKey} with ${pins.length} pins:`,pins)}}return{inputProblem:problem,nestedGroupMatchpackProxyMap}}function applySchematicMatchPackLayoutToTree(group2,tree,opts={}){let{db:db22}=group2.root;if(debug6(`[${group2.name}] Starting matchpack layout with ${tree.childNodes.length} children`),debug6(`[${group2.name}] Tree structure:`,JSON.stringify(tree,null,2)),tree.childNodes.length<=1){debug6(`[${group2.name}] Only ${tree.childNodes.length} children, skipping layout`);return}debug6("Converting circuit tree to InputProblem...");let{inputProblem,nestedGroupMatchpackProxyMap}=convertTreeToMatchPackInputProblem(tree,db22,group2,opts);debug6.enabled&&group2.root?.emit("debug:logOutput",{type:"debug:logOutput",name:`matchpack-input-problem-${group2.name}`,content:JSON.stringify(inputProblem,null,2)});let solver=new LayoutPipelineSolver(inputProblem);if(group2.root?.emit("solver:started",{type:"solver:started",solverName:"LayoutPipelineSolver",solverParams:inputProblem,solverConstructorArgs:[inputProblem],componentName:group2.getString()}),debug6("Starting LayoutPipelineSolver..."),debug6.enabled&&global?.debugGraphics){let initialViz=solver.visualize();global.debugGraphics.push({...initialViz,title:`matchpack-initial-${group2.name}`})}if(solver.solve(),group2.root?.emit("solver:ended",{type:"solver:ended",solverName:"LayoutPipelineSolver",componentName:group2.getString(),solved:solver.solved,failed:solver.failed,iterations:solver.iterations,error:solver.error}),debug6(`Solver completed in ${solver.iterations} iterations`),debug6(`Solved: ${solver.solved}, Failed: ${solver.failed}`),solver.failed){let solverError=solver.error??"Unknown Matchpack failure";debug6(`Solver failed with error: ${solverError}`),db22.schematic_layout_error.insert({error_type:"schematic_layout_error",message:`Matchpack layout solver failed: ${solverError}`,is_fatal:!1,source_group_id:group2.source_group_id,schematic_group_id:group2.schematic_group_id,subcircuit_id:group2.subcircuit_id??void 0});return}let outputLayout=solver.getOutputLayout();if(debug6("OutputLayout:",JSON.stringify(outputLayout,null,2)),debug6("Solver completed successfully:",!solver.failed),debug6.enabled&&global?.debugGraphics){let finalViz=solver.visualize();global.debugGraphics.push({...finalViz,title:`matchpack-final-${group2.name}`})}let overlaps=solver.checkForOverlaps(outputLayout);if(overlaps.length>0){debug6(`Warning: Found ${overlaps.length} overlapping components:`);for(let overlap of overlaps)debug6(` ${overlap.chip1} overlaps ${overlap.chip2} (area: ${overlap.overlapArea})`)}let groupOffset=group2._getGlobalSchematicPositionBeforeLayout();debug6(`Group offset: x=${groupOffset.x}, y=${groupOffset.y}`),debug6(`Applying layout results for ${Object.keys(outputLayout.chipPlacements).length} chip placements`);for(let[chipId,placement]of Object.entries(outputLayout.chipPlacements)){debug6(`Processing placement for chip: ${chipId} at (${placement.x}, ${placement.y})`);let treeNode=tree.childNodes.find(child=>{let expectedChipId=getTreeChildChipId(child,tree.childNodes.indexOf(child)),matches=expectedChipId===chipId;return debug6(` Checking child ${expectedChipId}: matches=${matches}`),matches});if(!treeNode){debug6(`Warning: No tree node found for chip: ${chipId}`),debug6("Available tree nodes:",tree.childNodes.map((child,idx)=>({type:child.nodeType,name:child.nodeType==="component"?child.sourceComponent?.name:child.sourceGroup?.name,expectedChipId:getTreeChildChipId(child,idx)})));continue}let newCenter={x:placement.x+groupOffset.x,y:placement.y+groupOffset.y};if(treeNode.nodeType==="component"&&treeNode.sourceComponent){let groupChild=group2.children.find(c23=>c23.source_component_id===treeNode.sourceComponent?.source_component_id);if(groupChild?._parsedProps?.schX!==void 0||groupChild?._parsedProps?.schY!==void 0){debug6(`Skipping position update for fixed chip ${chipId}`);continue}let schematicComponent=getSchematicComponentForSourceComponent({db:db22,sourceComponentId:treeNode.sourceComponent.source_component_id,schematicSheetId:opts.schematicSheetId});if(schematicComponent){debug6(`Moving component ${chipId} to (${newCenter.x}, ${newCenter.y})`);let ports=db22.schematic_port.list({schematic_component_id:schematicComponent.schematic_component_id}),texts=db22.schematic_text.list({schematic_component_id:schematicComponent.schematic_component_id}),positionDelta={x:newCenter.x-schematicComponent.center.x,y:newCenter.y-schematicComponent.center.y};for(let port of ports)port.center.x+=positionDelta.x,port.center.y+=positionDelta.y;for(let text4 of texts)text4.position.x+=positionDelta.x,text4.position.y+=positionDelta.y;if(updateSchematicPrimitivesForLayoutShift({db:db22,schematicComponentId:schematicComponent.schematic_component_id,deltaX:positionDelta.x,deltaY:positionDelta.y}),schematicComponent.center=newCenter,placement.ccwRotationDegrees!==0){debug6(`Component ${chipId} has rotation: ${placement.ccwRotationDegrees}\xB0`);let normalizedRotation=(Math.round(placement.ccwRotationDegrees)%360+360)%360;if((normalizedRotation===90||normalizedRotation===270)&&schematicComponent.size){let prevWidth=schematicComponent.size.width;schematicComponent.size.width=schematicComponent.size.height,schematicComponent.size.height=prevWidth}let angleRad=placement.ccwRotationDegrees*Math.PI/180,cos32=Math.cos(angleRad),sin32=Math.sin(angleRad);for(let port of ports){let dx22=port.center.x-newCenter.x,dy22=port.center.y-newCenter.y,rotatedDx=dx22*cos32-dy22*sin32,rotatedDy=dx22*sin32+dy22*cos32;port.center.x=newCenter.x+rotatedDx,port.center.y=newCenter.y+rotatedDy;let originalDirection=port.facing_direction||"right";port.facing_direction=rotateDirection2(originalDirection,placement.ccwRotationDegrees),port.side_of_component=(port.facing_direction==="up"?"top":port.facing_direction==="down"?"bottom":port.facing_direction)||port.side_of_component}for(let text4 of texts){let dx22=text4.position.x-newCenter.x,dy22=text4.position.y-newCenter.y,rotatedDx=dx22*cos32-dy22*sin32,rotatedDy=dx22*sin32+dy22*cos32;text4.position.x=newCenter.x+rotatedDx,text4.position.y=newCenter.y+rotatedDy}schematicComponent.symbol_name&&(schematicComponent.symbol_name=getRotatedSymbolName(schematicComponent.symbol_name,placement.ccwRotationDegrees))}}}else if(treeNode.nodeType==="group"&&treeNode.sourceGroup){let schematicGroup=db22.schematic_group?.getWhere?.({source_group_id:treeNode.sourceGroup.source_group_id});if(schematicGroup){debug6(`Moving group ${chipId} to (${newCenter.x}, ${newCenter.y}) from (${schematicGroup.center?.x}, ${schematicGroup.center?.y})`);let groupComponents=db22.schematic_component.list({schematic_group_id:schematicGroup.schematic_group_id});debug6(`Group ${chipId} has ${groupComponents.length} components to move`);let matchpackProxy=nestedGroupMatchpackProxyMap[chipId],oldCenter=matchpackProxy?.center??schematicGroup.center??{x:0,y:0},positionDelta={x:newCenter.x-oldCenter.x,y:newCenter.y-oldCenter.y};debug6(`Position delta for group ${chipId}: (${positionDelta.x}, ${positionDelta.y})`);for(let component of groupComponents)if(component.center){let oldComponentCenter={...component.center};component.center.x+=positionDelta.x,component.center.y+=positionDelta.y,debug6(`Moved component ${component.source_component_id} from (${oldComponentCenter.x}, ${oldComponentCenter.y}) to (${component.center.x}, ${component.center.y})`);let ports=db22.schematic_port.list({schematic_component_id:component.schematic_component_id}),texts=db22.schematic_text.list({schematic_component_id:component.schematic_component_id});for(let port of ports)port.center&&(port.center.x+=positionDelta.x,port.center.y+=positionDelta.y);for(let text4 of texts)text4.position&&(text4.position.x+=positionDelta.x,text4.position.y+=positionDelta.y);updateSchematicPrimitivesForLayoutShift({db:db22,schematicComponentId:component.schematic_component_id,deltaX:positionDelta.x,deltaY:positionDelta.y})}schematicGroup.center=newCenter,matchpackProxy&&(schematicGroup.width=matchpackProxy.size.x,schematicGroup.height=matchpackProxy.size.y),debug6(`Updated group ${chipId} center to (${newCenter.x}, ${newCenter.y})`)}}}debug6("Matchpack layout completed successfully")}function getSchematicSheetIdsBySourceGroupId({circuitJson,schematicSheetIdsBySourceComponentId}){let parentBySourceGroupId=new Map;for(let element2 of circuitJson)element2.type==="source_group"&&parentBySourceGroupId.set(element2.source_group_id,element2.parent_source_group_id);let schematicSheetIdsBySourceGroupId=new Map;for(let element2 of circuitJson){if(element2.type!=="source_component"||!element2.source_group_id)continue;let schematicSheetIds=schematicSheetIdsBySourceComponentId.get(element2.source_component_id);if(schematicSheetIds!==void 0)for(let schematicSheetId of schematicSheetIds){let sourceGroupId=element2.source_group_id,visitedSourceGroupIds=new Set;for(;sourceGroupId&&!visitedSourceGroupIds.has(sourceGroupId);){visitedSourceGroupIds.add(sourceGroupId);let groupSchematicSheetIds=schematicSheetIdsBySourceGroupId.get(sourceGroupId)??new Set;groupSchematicSheetIds.add(schematicSheetId),schematicSheetIdsBySourceGroupId.set(sourceGroupId,groupSchematicSheetIds),sourceGroupId=parentBySourceGroupId.get(sourceGroupId)}}}return schematicSheetIdsBySourceGroupId}function getCircuitJsonScopedToSchematicSheet({circuitJson,schematicSheetId,rootSourceGroupId,schematicSheetIdsBySourceComponentId,schematicSheetIdsBySourceGroupId}){let isGroupOnSheet=sourceGroupId=>sourceGroupId===rootSourceGroupId||schematicSheetIdsBySourceGroupId.get(sourceGroupId)?.has(schematicSheetId)===!0;return circuitJson.filter(element2=>element2.type==="source_group"?isGroupOnSheet(element2.source_group_id):element2.type==="source_component"?schematicSheetIdsBySourceComponentId.get(element2.source_component_id)?.has(schematicSheetId)!==!0?!1:element2.source_group_id?isGroupOnSheet(element2.source_group_id):!0:!0)}function getSchematicCircuitJsonTrees(circuitJson,opts){let{source_group_id}=opts,schematicSheetIdsBySourceComponentId=new Map;for(let element2 of circuitJson){if(element2.type!=="schematic_component"||!element2.source_component_id||!element2.schematic_sheet_id)continue;let schematicSheetIds2=schematicSheetIdsBySourceComponentId.get(element2.source_component_id)??new Set;schematicSheetIds2.add(element2.schematic_sheet_id),schematicSheetIdsBySourceComponentId.set(element2.source_component_id,schematicSheetIds2)}let schematicSheetIds=new Set;for(let componentSchematicSheetIds of schematicSheetIdsBySourceComponentId.values())for(let schematicSheetId of componentSchematicSheetIds)schematicSheetIds.add(schematicSheetId);if(schematicSheetIds.size<=1)return[{tree:getCircuitJsonTree(circuitJson,{source_group_id}),schematicSheetId:schematicSheetIds.values().next().value}];let schematicSheetIdsBySourceGroupId=getSchematicSheetIdsBySourceGroupId({circuitJson,schematicSheetIdsBySourceComponentId});return Array.from(schematicSheetIds).map(schematicSheetId=>({tree:getCircuitJsonTree(getCircuitJsonScopedToSchematicSheet({circuitJson,schematicSheetId,rootSourceGroupId:source_group_id,schematicSheetIdsBySourceComponentId,schematicSheetIdsBySourceGroupId}),{source_group_id}),schematicSheetId}))}function Group_doInitialSchematicLayoutMatchPack(group2){let{db:db22}=group2.root,trees=getSchematicCircuitJsonTrees(db22.toArray(),{source_group_id:group2.source_group_id});for(let{tree,schematicSheetId}of trees)applySchematicMatchPackLayoutToTree(group2,tree,{schematicSheetId})}var SECTION_GAP=1,MARGIN2=1.5;function computeSchematicSectionLayoutUsingRows({sectionBlocks,groupSchPositionBeforeLayout:groupOffset}){let totalArea=sectionBlocks.reduce((sum,block)=>{let paddedWidth=Math.max(block.size.x,.5)+MARGIN2*2,paddedHeight=Math.max(block.size.y,.5)+MARGIN2*2;return sum+paddedWidth*paddedHeight},0),targetRowWidth=Math.sqrt(totalArea)*2,computedSectionsMatrix=[],currentSectionRow=[],currentRowSectionWidth=0;for(let section of sectionBlocks){let paddedWidth=Math.max(section.size.x,.5)+MARGIN2*2,paddedHeight=Math.max(section.size.y,.5)+MARGIN2*2,neededWidth=currentRowSectionWidth>0?currentRowSectionWidth+SECTION_GAP+paddedWidth:paddedWidth;currentSectionRow.length>0&&neededWidth>targetRowWidth&&(computedSectionsMatrix.push(currentSectionRow),currentSectionRow=[],currentRowSectionWidth=0);let xOffsetInRow=currentRowSectionWidth>0?currentRowSectionWidth+SECTION_GAP:0;currentSectionRow.push({sectionName:section.sectionName,rowOffset:xOffsetInRow,width:paddedWidth,height:paddedHeight}),currentRowSectionWidth=xOffsetInRow+paddedWidth}currentSectionRow.length>0&&computedSectionsMatrix.push(currentSectionRow);let sectionPlacements=new Map,rowY=0;for(let sectionRow of computedSectionsMatrix){let rowHeight=Math.max(...sectionRow.map(rowEntry=>rowEntry.height)),rowCenteringOffsetX=-(sectionRow[sectionRow.length-1].rowOffset+sectionRow[sectionRow.length-1].width)/2;for(let section of sectionRow)sectionPlacements.set(section.sectionName,{x:rowCenteringOffsetX+section.rowOffset+section.width/2+groupOffset.x,y:rowY-rowHeight/2+groupOffset.y});rowY-=rowHeight+SECTION_GAP}return sectionPlacements}var debug7=(0,import_debug15.default)("Group_doInitialSchematicLayoutSections");function Group_doInitialSchematicLayoutSections(group2){let{db:db22}=group2.root,sectionNamesUsedByChildren=new Set,hasChildrenWithoutSection=!1;for(let child of group2.children){if(!child.source_component_id)continue;let sectionName=child.getSchematicSectionName();sectionName!==null?sectionNamesUsedByChildren.add(sectionName):hasChildrenWithoutSection=!0}let sectionNamesToLayout=Array.from(sectionNamesUsedByChildren);if(hasChildrenWithoutSection&&sectionNamesToLayout.push(null),sectionNamesToLayout.length===0)return;for(let sectionName of sectionNamesToLayout){let sectionTree=getCircuitJsonTree(db22.toArray(),{source_group_id:group2.source_group_id});sectionTree.childNodes=sectionTree.childNodes.filter(child=>child.nodeType!=="component"||!child.sourceComponent?!1:(group2.children.find(c23=>c23.source_component_id===child.sourceComponent?.source_component_id)?.getSchematicSectionName()??null)===sectionName),applySchematicMatchPackLayoutToTree(group2,sectionTree)}if(sectionNamesToLayout.length<=1)return;let sectionNameToBoundsWithChildren=new Map;for(let sectionName of sectionNamesToLayout){let minX=1/0,maxX=-1/0,minY=1/0,maxY=-1/0,sourceCompIds=new Set;for(let child of group2.children){let sourceComponentId=child.source_component_id;if(!sourceComponentId||child.getSchematicSectionName()!==sectionName)continue;let schComp=db22.schematic_component.getWhere({source_component_id:sourceComponentId});if(!schComp)continue;sourceCompIds.add(sourceComponentId);let hw22=schComp.size.width/2,hh22=schComp.size.height/2;minX=Math.min(minX,schComp.center.x-hw22),maxX=Math.max(maxX,schComp.center.x+hw22),minY=Math.min(minY,schComp.center.y-hh22),maxY=Math.max(maxY,schComp.center.y+hh22)}!Number.isFinite(minX)||sourceCompIds.size===0||sectionNameToBoundsWithChildren.set(sectionName,{sectionName,center:{x:(minX+maxX)/2,y:(minY+maxY)/2},size:{x:maxX-minX,y:maxY-minY},sourceCompIds})}if(sectionNameToBoundsWithChildren.size<=1)return;let anchoredSections=new Set;for(let child of group2.children){if(!child.source_component_id)continue;let props=child._parsedProps;(props?.schX!==void 0||props?.schY!==void 0)&&anchoredSections.add(child.getSchematicSectionName())}let groupSchPositionBeforeLayout=group2._getGlobalSchematicPositionBeforeLayout(),sectionPlacements=computeSchematicSectionLayoutUsingRows({sectionBlocks:Array.from(sectionNameToBoundsWithChildren.values()).map(bounds=>({sectionName:bounds.sectionName,size:bounds.size})),groupSchPositionBeforeLayout});for(let[sectionName,placement]of sectionPlacements){let boundsWithChildren=sectionNameToBoundsWithChildren.get(sectionName);if(!boundsWithChildren)continue;if(anchoredSections.has(sectionName)){debug7(`[${group2.name}] Section "${sectionName}" anchored by manual position, skipping shift`);continue}let delta={x:placement.x-boundsWithChildren.center.x,y:placement.y-boundsWithChildren.center.y};for(let sourceComponentId of boundsWithChildren.sourceCompIds){let schComp=db22.schematic_component.getWhere({source_component_id:sourceComponentId});if(!schComp)continue;let ports=db22.schematic_port.list({schematic_component_id:schComp.schematic_component_id}),texts=db22.schematic_text.list({schematic_component_id:schComp.schematic_component_id});for(let port of ports)port.center.x+=delta.x,port.center.y+=delta.y;for(let text4 of texts)text4.position.x+=delta.x,text4.position.y+=delta.y;updateSchematicPrimitivesForLayoutShift({db:db22,schematicComponentId:schComp.schematic_component_id,deltaX:delta.x,deltaY:delta.y}),schComp.center={x:schComp.center.x+delta.x,y:schComp.center.y+delta.y}}}}var updateMissingSchematicSheetWarning=({db:db22,schematicDisabled})=>{let existingWarning=db22.schematic_missing_sheet_warning.list()[0],hasSchematicComponents=db22.schematic_component.list().length>0;if(!(!schematicDisabled&&hasSchematicComponents&&db22.schematic_sheet.list().length===0)){existingWarning&&db22.schematic_missing_sheet_warning.delete(existingWarning.schematic_missing_sheet_warning_id);return}existingWarning||db22.schematic_missing_sheet_warning.insert({warning_type:"schematic_missing_sheet_warning",message:"No <schematicsheet> was found. Add a <schematicsheet> to define the schematic drawing area."})},Group_doInitialSchematicSheetRender=group2=>{let root=group2.root;if(!root?.isRootCircuit)return;let isRootGroup=root.firstChild===group2,isRootAssemblyChild=isAssemblyDeviceContainer(root.firstChild)&&group2.parent===root.firstChild;!isRootGroup&&!isRootAssemblyChild||updateMissingSchematicSheetWarning({db:root.db,schematicDisabled:root.schematicDisabled})},Group_updateSchematicSheetRender=group2=>{Group_doInitialSchematicSheetRender(group2)},NetLabel=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"source_net_label_id");__publicField(this,"schematic_net_label_id")}get config(){return{componentName:"NetLabel",zodProps:netLabelProps}}_getAnchorSide(){let{_parsedProps:props}=this;if(props.anchorSide)return props.anchorSide;if(!this._resolveConnectsTo())return"right";let net=this.getSubcircuit().selectOne(`net.${this._getNetName()}`),sourceNet;if(net?.source_net_id&&(sourceNet=this.root?.db.source_net.get(net.source_net_id)),sourceNet?.is_ground)return"top";if(sourceNet?.is_power)return"bottom";let anchorPos=this._getGlobalSchematicPositionBeforeLayout(),connectedPorts=this._getConnectedPorts();if(connectedPorts.length===0)return"right";let port=connectedPorts[0];if(port.facingDirection)return getEnteringEdgeFromDirection(port.facingDirection);let connectedPortPosition=port._getGlobalSchematicPositionBeforeLayout(),dx22=connectedPortPosition.x-anchorPos.x,dy22=connectedPortPosition.y-anchorPos.y;if(Math.abs(dx22)>Math.abs(dy22)){if(dx22>0)return"right";if(dx22<0)return"left"}else{if(dy22>0)return"top";if(dy22<0)return"bottom"}return"right"}_getConnectedPorts(){let connectsTo=this._resolveConnectsTo();if(!connectsTo)return[];let connectedPorts=[];for(let connection of connectsTo){let port=this.getSubcircuit().selectOne(connection);port&&connectedPorts.push(port)}return connectedPorts}computeSchematicPropsTransform(){let{_parsedProps:props}=this;if(props.schX===void 0&&props.schY===void 0){let connectedPorts=this._getConnectedPorts();if(connectedPorts.length>0){let portPos=connectedPorts[0]._getGlobalSchematicPositionBeforeLayout(),parentCenter=applyToPoint3(this.parent?.computeSchematicGlobalTransform?.()??identity7(),{x:0,y:0});return translate8(portPos.x-parentCenter.x,portPos.y-parentCenter.y)}}return super.computeSchematicPropsTransform()}doInitialSchematicPrimitiveRender(){if(this.root?.schematicDisabled||this.getCollapsedSchematicBoxAncestor())return;let{db:db22}=this.root,{_parsedProps:props}=this;if(props.inline&&this.root?._featureMspSchematicTraceRouting&&this._getConnectedPorts().length>0)return;let anchorPos=this._getGlobalSchematicPositionBeforeLayout(),net=this.getSubcircuit().selectOne(`net.${this._getNetName()}`),anchorSide=this._getAnchorSide(),center2=computeSchematicNetLabelCenter({anchor_position:anchorPos,anchor_side:anchorSide,text:props.net}),netLabel=db22.schematic_net_label.insert({text:props.net,source_net_id:net.source_net_id,anchor_position:anchorPos,center:center2,anchor_side:anchorSide,schematic_sheet_id:this._resolveSchematicSheetId()});this.source_net_label_id=netLabel.source_net_id,this.schematic_net_label_id=netLabel.schematic_net_label_id}_resolveConnectsTo(){let{_parsedProps:props}=this,connectsTo=props.connectsTo??props.connection;if(Array.isArray(connectsTo))return connectsTo;if(typeof connectsTo=="string")return[connectsTo]}_getNetName(){let{_parsedProps:props}=this;return props.net}doInitialCreateNetsFromProps(){let{_parsedProps:props}=this;props.net&&createNetsFromProps(this,[`net.${props.net}`])}doInitialCreateTracesFromNetLabels(){let connectsTo=this._resolveConnectsTo();if(connectsTo)for(let connection of connectsTo)this.add(new Trace({from:connection,to:`net.${this._getNetName()}`}))}doInitialSchematicTraceRender(){if(!this.root?._featureMspSchematicTraceRouting||this.root?.schematicDisabled||this.getCollapsedSchematicBoxAncestor()||this._parsedProps.inline)return;let{schX,schY}=this._parsedProps;if(schX===void 0&&schY===void 0)return;let{db:db22}=this.root,connectsTo=this._resolveConnectsTo();if(!connectsTo||connectsTo.length===0)return;let anchorPos=this._getGlobalSchematicPositionBeforeLayout(),anchorSide=this._getAnchorSide(),anchorFacing={left:"x-",right:"x+",top:"y+",bottom:"y-"}[anchorSide],net=this.getSubcircuit().selectOne(`net.${this._getNetName()}`);for(let connection of connectsTo){let port=this.getSubcircuit().selectOne(connection,{type:"port"});if(!port||!port.schematic_port_id)continue;let existingTraceForThisConnection=!1;if(net?.source_net_id){let candidateSourceTrace=db22.source_trace.list().find(st22=>st22.connected_source_net_ids?.includes(net.source_net_id)&&st22.connected_source_port_ids?.includes(port.source_port_id??""));if(candidateSourceTrace&&(existingTraceForThisConnection=db22.schematic_trace.list().some(t48=>t48.source_trace_id===candidateSourceTrace.source_trace_id)),existingTraceForThisConnection)continue}let portPos=port._getGlobalSchematicPositionAfterLayout(),portFacing=convertFacingDirectionToElbowDirection(port.facingDirection??"right")??"x+",path=calculateElbow({x:portPos.x,y:portPos.y,facingDirection:portFacing},{x:anchorPos.x,y:anchorPos.y,facingDirection:anchorFacing});if(!Array.isArray(path)||path.length<2)continue;let edges=[];for(let i23=0;i23<path.length-1;i23++)edges.push({from:{x:path[i23].x,y:path[i23].y},to:{x:path[i23+1].x,y:path[i23+1].y}});let source_trace_id,subcircuit_connectivity_map_key;if(net?.source_net_id&&port.source_port_id){let st22=db22.source_trace.list().find(s23=>s23.connected_source_net_ids?.includes(net.source_net_id)&&s23.connected_source_port_ids?.includes(port.source_port_id));source_trace_id=st22?.source_trace_id,subcircuit_connectivity_map_key=st22?.subcircuit_connectivity_map_key||db22.source_net.get(net.source_net_id)?.subcircuit_connectivity_map_key}db22.schematic_trace.insert({source_trace_id,edges,junctions:[],subcircuit_connectivity_map_key,schematic_sheet_id:this._resolveSchematicSheetId()}),db22.schematic_port.update(port.schematic_port_id,{is_connected:!0})}}},getNetNameFromPorts=ports=>{let directlyConnectedTraces=[...new Set(ports.flatMap(port=>port._getDirectlyConnectedTraces()))],displayLabel=directlyConnectedTraces.find(trace=>trace._parsedProps.schDisplayLabel)?._parsedProps.schDisplayLabel??directlyConnectedTraces.find(trace=>trace._parsedProps.displayName)?._parsedProps.displayName??directlyConnectedTraces.find(trace=>trace._parsedProps.name)?._parsedProps.name;if(displayLabel)return{name:displayLabel,wasAssignedDisplayLabel:!0};let db22=ports.find(port=>port.root)?.root?.db,sourcePortIds=ports.map(port=>port.source_port_id).filter(sourcePortId=>!!sourcePortId);return{name:(db22?getNetNameFromSourcePorts(db22,sourcePortIds):ports.map(port=>port._getNetLabelText()).filter(name=>!!name).sort((a23,b23)=>a23.localeCompare(b23,void 0,{numeric:!0,sensitivity:"base"}))[0])??"",wasAssignedDisplayLabel:!1}},appendToMap=(map,key,value)=>{let values2=map.get(key);values2?values2.push(value):map.set(key,[value])},createCanonicalSchematicNetLabelTextResolver=group2=>{let{db:db22}=group2.root,sourceNetByConnectionKey=new Map,portsByConnectionKey=new Map,sourcePortIdsByConnectionKey=new Map,resolvedTextByConnectionKey=new Map;for(let sourceNet of db22.source_net.list())sourceNet.subcircuit_connectivity_map_key&&sourceNetByConnectionKey.set(sourceNet.subcircuit_connectivity_map_key,sourceNet);for(let port of group2.selectAll("port")){let connectionKey=port._getSubcircuitConnectivityKey();connectionKey&&appendToMap(portsByConnectionKey,connectionKey,port)}for(let sourcePort of db22.source_port.list())sourcePort.subcircuit_connectivity_map_key&&appendToMap(sourcePortIdsByConnectionKey,sourcePort.subcircuit_connectivity_map_key,sourcePort.source_port_id);return({subcircuitConnectivityMapKey})=>{let cached=resolvedTextByConnectionKey.get(subcircuitConnectivityMapKey);if(cached)return cached;let resolvedSourceNet=sourceNetByConnectionKey.get(subcircuitConnectivityMapKey);if(resolvedSourceNet?.name){let result2={name:resolvedSourceNet.name,wasAssignedDisplayLabel:!0};return resolvedTextByConnectionKey.set(subcircuitConnectivityMapKey,result2),result2}let portLabel=getNetNameFromPorts(portsByConnectionKey.get(subcircuitConnectivityMapKey)??[]);if(portLabel.name)return resolvedTextByConnectionKey.set(subcircuitConnectivityMapKey,portLabel),portLabel;let result={name:getNetNameFromSourcePorts(db22,sourcePortIdsByConnectionKey.get(subcircuitConnectivityMapKey)??[])??"",wasAssignedDisplayLabel:!1};return resolvedTextByConnectionKey.set(subcircuitConnectivityMapKey,result),result}},asSchematicPortId=id3=>id3,asSourcePortId=id3=>id3,debug8=(0,import_debug17.default)("Group_doInitialSchematicTraceRender"),INLINE_NET_LABEL_COLOR="rgb(132, 0, 0)",VERTICAL_INLINE_NET_LABEL_ROTATION=-90;function applyInlineNetLabelPlacements(args){let{group:group2,solver,userNetIdToConnKey,sourceTraceIdByPinPairKey,crossScopeSourceTraceIdBySchematicPortIdAndNetId}=args,{db:db22}=group2.root,inlineNetLabelPlacements=solver.inlineNetLabelSolver?.getOutput().inlineNetLabelPlacements??[];if(inlineNetLabelPlacements.length===0)return;let resolveCanonicalNetLabelText=createCanonicalSchematicNetLabelTextResolver(group2),globalConnMap=solver.mspConnectionPairSolver.globalConnMap;for(let placement of inlineNetLabelPlacements){let schematicPortIds=placement.pinIds.map(asSchematicPortId),placementUserNetId=globalConnMap.getIdsConnectedToNet(placement.globalConnNetId).find(id3=>userNetIdToConnKey.has(id3)),crossScopeSourceTraceId=schematicPortIds.length===1?crossScopeSourceTraceIdBySchematicPortIdAndNetId.get(schematicPortIds[0])?.get(placement.netId??placement.globalConnNetId):void 0,connKey=(crossScopeSourceTraceId?db22.source_trace.get(crossScopeSourceTraceId)?.subcircuit_connectivity_map_key:void 0)??(placementUserNetId?userNetIdToConnKey.get(placementUserNetId):void 0),text4=placement.netLabelText??(connKey?resolveCanonicalNetLabelText({subcircuitConnectivityMapKey:connKey}).name:placement.netId??placement.globalConnNetId);if(!text4){debug8(`skipping inline net label for "${placement.netId}" REASON:no resolvable text`);continue}let sourceTraceId=crossScopeSourceTraceId??sourceTraceIdByPinPairKey.get([...schematicPortIds].sort().join("::"));if(!sourceTraceId&&connKey){let sourcePortIds=schematicPortIds.flatMap(schematicPortId=>{let sourcePortId=db22.schematic_port.get(schematicPortId)?.source_port_id;return sourcePortId?[sourcePortId]:[]});sourceTraceId=db22.source_trace.list().find(sourceTrace=>sourceTrace.subcircuit_connectivity_map_key===connKey&&sourcePortIds.some(sourcePortId=>sourceTrace.connected_source_port_ids.includes(sourcePortId)))?.source_trace_id}let schematicSheetId=group2._resolveSchematicSheetId(),schematicPort=db22.schematic_port.get(schematicPortIds[0]);schematicPort?.schematic_sheet_id&&(schematicSheetId=schematicPort.schematic_sheet_id);let placementOffset={x:0,y:0},stubTracePath=placement.stubTracePath?.map(point12=>({...point12}));if(stubTracePath&&schematicPortIds.length===1){let portCenter=db22.schematic_port.get(schematicPortIds[0])?.center;portCenter&&(placementOffset={x:portCenter.x-stubTracePath[0].x,y:portCenter.y-stubTracePath[0].y},stubTracePath=stubTracePath.map(point12=>({x:point12.x+placementOffset.x,y:point12.y+placementOffset.y})))}let position22={x:placement.anchorPoint.x+placementOffset.x,y:placement.anchorPoint.y+placementOffset.y},textAnchor=placement.textAnchor??"center";if(stubTracePath&&stubTracePath.length===2){let[start,end]=stubTracePath;if(placement.axis==="x"){let extendsRight=end.x>start.x;textAnchor=extendsRight?"left":"right",position22.x=placement.center.x+placementOffset.x+(extendsRight?-placement.width/2:placement.width/2)}else{let extendsUp=end.y>start.y;textAnchor=extendsUp?"left":"right",position22.y=placement.center.y+placementOffset.y+(extendsUp?-placement.width/2:placement.width/2)}}stubTracePath&&stubTracePath.length===2&&(db22.schematic_trace.insert({source_trace_id:sourceTraceId,edges:[{from:stubTracePath[0],to:stubTracePath[1]}],junctions:[],subcircuit_connectivity_map_key:connKey,schematic_sheet_id:schematicSheetId}),db22.schematic_port.update(schematicPortIds[0],{is_connected:!0})),db22.schematic_text.insert({text:text4,source_trace_id:sourceTraceId,anchor:placement.side==="y+"||placement.side==="x-"?`bottom_${textAnchor}`:`top_${textAnchor}`,position:position22,rotation:placement.axis==="y"?VERTICAL_INLINE_NET_LABEL_ROTATION:0,font_size:placement.height,color:INLINE_NET_LABEL_COLOR,schematic_sheet_id:schematicSheetId})}}var NET_LABEL_TEXT_HEIGHT=.18,getNetLabelTextBounds=({center:center2,text:text4})=>{let halfWidth=getSchematicNetLabelTextWidth2({text:text4})/2,halfHeight=NET_LABEL_TEXT_HEIGHT/2;return{minX:center2.x-halfWidth,maxX:center2.x+halfWidth,minY:center2.y-halfHeight,maxY:center2.y+halfHeight}},oppositeSide2=input2=>{switch(input2){case"x+":return"left";case"x-":return"right";case"y+":return"bottom";case"y-":return"top";case"left":return"right";case"top":return"bottom";case"right":return"left";case"bottom":return"top"}},debug9=(0,import_debug18.default)("Group_doInitialSchematicTraceRender"),isSameNet=(label,sourceNet)=>label.schematicNetLabel.source_net_id!=null&&label.schematicNetLabel.source_net_id===sourceNet.source_net_id,isUserDefinedNetLabelRedundantWithPlacement=(label,solverPlacement)=>isSameNet(label,solverPlacement.sourceNet)?label.schematicPortIds.some(id3=>solverPlacement.schematicPortIds.has(id3))?!0:label.schematicNetLabel.center?doBoundsOverlap(getNetLabelTextBounds({center:label.schematicNetLabel.center,text:label.schematicNetLabel.text}),solverPlacement.bounds):!1:!1;function applyNetLabelPlacements(args){let{group:group2,routedSchematicPortIdBySchematicPortId,solver,connKeyToSourceNet,userNetIdToConnKey,crossScopeSourceTraceIdBySchematicPortIdAndNetId,sourceTraceIdByPortOnlyLabelSchematicPortId,connKeysWithExplicitPortNetTraces,schematicPortIdsWithPreExistingNetLabels,schematicPortIdsWithRoutedTraces,netLabels}=args,{db:db22}=group2.root,resolveCanonicalNetLabelText=createCanonicalSchematicNetLabelTextResolver(group2),netLabelPlacements=solver.inlineNetLabelSolver?.getOutput().netLabelPlacements??solver.netLabelNetLabelCollisionSolver?.getOutput().netLabelPlacements??solver.netLabelTraceCollisionSolver?.getOutput().netLabelPlacements??solver.netLabelPlacementSolver?.netLabelPlacements??solver.traceLabelOverlapAvoidanceSolver?.getOutput().netLabelPlacements??[],dedupedNetLabelPlacements=[],netLabelPlacementKeys=new Set;for(let placement of netLabelPlacements){let pinIds=[...placement.pinIds??[]].sort(),key=`${placement.globalConnNetId}|${pinIds.join("::")}|${placement.netId??""}`;if(netLabelPlacementKeys.has(key)){debug9(`skipping duplicate placement for "${placement.netId}" REASON:identical net label placement`);continue}netLabelPlacementKeys.add(key),dedupedNetLabelPlacements.push(placement)}let netLabelPlacementCountByGlobalNetId=new Map,routedPairKeysByGlobalNetId=new Map,globalNetIdsWithPortOnlyPlacements=new Set;for(let placement of dedupedNetLabelPlacements)netLabelPlacementCountByGlobalNetId.set(placement.globalConnNetId,(netLabelPlacementCountByGlobalNetId.get(placement.globalConnNetId)??0)+1),(placement.pinIds?.length??0)>1&&(routedPairKeysByGlobalNetId.has(placement.globalConnNetId)||routedPairKeysByGlobalNetId.set(placement.globalConnNetId,new Set),routedPairKeysByGlobalNetId.get(placement.globalConnNetId).add(placement.pinIds.slice().sort().join("::"))),(placement.pinIds?.length??0)<=1&&globalNetIdsWithPortOnlyPlacements.add(placement.globalConnNetId);let globalConnMap=solver.mspConnectionPairSolver.globalConnMap,userDefinedNetLabels=netLabels.map(label=>{if(!label.schematic_net_label_id)return null;let dbLabel=db22.schematic_net_label.get(label.schematic_net_label_id);return dbLabel?{schematicNetLabel:dbLabel,schematicPortIds:label._getConnectedPorts().map(port=>port.schematic_port_id).filter(id3=>!!id3).map(id3=>routedSchematicPortIdBySchematicPortId.get(id3)??id3),shouldUseSchematicTraceSolver:label._parsedProps.schX===void 0&&label._parsedProps.schY===void 0}:null}).filter(label=>label!==null);for(let placement of dedupedNetLabelPlacements){debug9(`processing placement: ${placement.netId}`);let schPortIds=placement.pinIds.map(asSchematicPortId),placementSourceTraceId=(schPortIds.length===1?crossScopeSourceTraceIdBySchematicPortIdAndNetId.get(schPortIds[0])?.get(placement.netId??placement.globalConnNetId):void 0)??(schPortIds.length===1?sourceTraceIdByPortOnlyLabelSchematicPortId.get(schPortIds[0]):void 0),placementSourceTrace=placementSourceTraceId?db22.source_trace.get(placementSourceTraceId):void 0,placementUserNetId=globalConnMap.getIdsConnectedToNet(placement.globalConnNetId).find(id3=>userNetIdToConnKey.get(id3)),placementConnKey=placementSourceTrace?.subcircuit_connectivity_map_key??userNetIdToConnKey.get(placementUserNetId),orientation32=placement.orientation,anchor_side=oppositeSide2(orientation32),sourceNet;placementConnKey&&(sourceNet=connKeyToSourceNet.get(placementConnKey));let resolvedCanonicalNetLabel=placementConnKey?resolveCanonicalNetLabelText({subcircuitConnectivityMapKey:placementConnKey}):{name:placement.netId??placement.globalConnNetId,wasAssignedDisplayLabel:!1},canonicalNetLabel=placement.netLabelText?{name:placement.netLabelText,wasAssignedDisplayLabel:!0}:resolvedCanonicalNetLabel,schematicSheetId=group2._resolveSchematicSheetId(),schematicPort=db22.schematic_port.get(schPortIds[0]);schematicPort?.schematic_sheet_id&&(schematicSheetId=schematicPort.schematic_sheet_id);let anchor_position=placement.anchorPoint;if(schPortIds.length===1&&schPortIds[0]){let anchorSchPort=db22.schematic_port.get(schPortIds[0]);anchorSchPort?.center&&!anchorSchPort.is_connected&&(anchor_position=anchorSchPort.center)}if(schPortIds.some(schPortId=>schematicPortIdsWithPreExistingNetLabels.has(schPortId))){debug9(`skipping net label placement for "${placement.netId}" REASON:schematic port has pre-existing net label`);continue}if(sourceNet){let isPowerOrGroundNet=sourceNet.is_ground||sourceNet.is_power,hasExplicitPortNetTrace=connKeysWithExplicitPortNetTraces.has(placementConnKey),hasRoutedTraceForPlacementPort=schPortIds.some(id3=>schematicPortIdsWithRoutedTraces.has(id3)),hasSingleLabelPlacement=(netLabelPlacementCountByGlobalNetId.get(placement.globalConnNetId)??0)<=1;if(!hasExplicitPortNetTrace&&!isPowerOrGroundNet&&hasRoutedTraceForPlacementPort&&hasSingleLabelPlacement){debug9(`skipping net label placement for "${placement.netId}" REASON:schematic port has routed trace`);continue}let text22=canonicalNetLabel.name,center22=computeSchematicNetLabelCenter({anchor_position,anchor_side,text:text22}),solverManagedUserNetLabel=userDefinedNetLabels.find(label=>label.shouldUseSchematicTraceSolver&&isSameNet(label,sourceNet)&&label.schematicPortIds.some(id3=>schPortIds.includes(id3)));if(solverManagedUserNetLabel){db22.schematic_net_label.update(solverManagedUserNetLabel.schematicNetLabel.schematic_net_label_id,{anchor_position,center:center22,anchor_side,schematic_sheet_id:schematicSheetId,source_trace_id:placementSourceTraceId});continue}if(!isPowerOrGroundNet){let solverPlacement={sourceNet,text:text22,schematicPortIds:new Set(schPortIds),bounds:getNetLabelTextBounds({center:center22,text:text22})};if(userDefinedNetLabels.some(label=>isUserDefinedNetLabelRedundantWithPlacement(label,solverPlacement)))continue}let netLabel2={text:text22,source_net_id:sourceNet.source_net_id,anchor_position,center:center22,anchor_side,schematic_sheet_id:schematicSheetId,source_trace_id:placementSourceTraceId};db22.schematic_net_label.insert(netLabel2);continue}let{name:text4,wasAssignedDisplayLabel}=canonicalNetLabel,shouldKeepRoutedPairLabel=(placement.pinIds?.length??0)>1&&(globalNetIdsWithPortOnlyPlacements.has(placement.globalConnNetId)||(routedPairKeysByGlobalNetId.get(placement.globalConnNetId)?.size??0)>1);if(!wasAssignedDisplayLabel&&!shouldKeepRoutedPairLabel&&schPortIds.some(schPortId=>schematicPortIdsWithRoutedTraces.has(schPortId))){debug9(`skipping net label placement for "${placement.netId}" REASON:schematic port has routed traces and no display label`);continue}let center2=computeSchematicNetLabelCenter({anchor_position,anchor_side,text:text4}),netLabel={text:text4,source_net_id:placementConnKey??placement.netId??placement.globalConnNetId,anchor_position,center:center2,anchor_side,schematic_sheet_id:schematicSheetId,source_trace_id:placementSourceTraceId};db22.schematic_net_label.insert(netLabel)}}var cross42=(ax22,ay22,bx22,by22)=>ax22*by22-ay22*bx22;function segmentIntersection(p13,p23,q13,q23,tol){let r23={x:p23.x-p13.x,y:p23.y-p13.y},s23={x:q23.x-q13.x,y:q23.y-q13.y},rxs=cross42(r23.x,r23.y,s23.x,s23.y),q_p={x:q13.x-p13.x,y:q13.y-p13.y},q_pxr=cross42(q_p.x,q_p.y,r23.x,r23.y);if(Math.abs(rxs)<tol&&Math.abs(q_pxr)<tol||Math.abs(rxs)<tol&&Math.abs(q_pxr)>=tol)return null;let t48=cross42(q_p.x,q_p.y,s23.x,s23.y)/rxs,u23=cross42(q_p.x,q_p.y,r23.x,r23.y)/rxs;return t48<-tol||t48>1+tol||u23<-tol||u23>1+tol?null:{x:p13.x+t48*r23.x,y:p13.y+t48*r23.y}}var TOL4=1e-6;function isHorizontalEdge(edge){let dx22=Math.abs(edge.to.x-edge.from.x),dy22=Math.abs(edge.to.y-edge.from.y);return dx22>=dy22}function length83(a23,b23){return Math.hypot(b23.x-a23.x,b23.y-a23.y)}function pointAt(a23,b23,t48){return{x:a23.x+(b23.x-a23.x)*t48,y:a23.y+(b23.y-a23.y)*t48}}function paramAlong(a23,b23,p23){let L23=length83(a23,b23);if(L23<TOL4)return 0;let t48=((p23.x-a23.x)*(b23.x-a23.x)+(p23.y-a23.y)*(b23.y-a23.y))/((b23.x-a23.x)*(b23.x-a23.x)+(b23.y-a23.y)*(b23.y-a23.y));return Math.max(0,Math.min(1,t48))*L23}function mergeIntervals(intervals,tol=TOL4){if(intervals.length===0)return intervals;intervals.sort((a23,b23)=>a23.start-b23.start);let merged=[],cur={...intervals[0]};for(let i23=1;i23<intervals.length;i23++){let nxt=intervals[i23];nxt.start<=cur.end+tol?cur.end=Math.max(cur.end,nxt.end):(merged.push(cur),cur={...nxt})}return merged.push(cur),merged}function splitEdgeByCrossings(edge,crossingDistances,crossLen){let L23=length83(edge.from,edge.to);if(L23<TOL4||crossingDistances.length===0)return[edge];let half=crossLen/2,rawIntervals=crossingDistances.map(d23=>({start:Math.max(0,d23-half),end:Math.min(L23,d23+half)})).filter(iv22=>iv22.end-iv22.start>TOL4),intervals=mergeIntervals(rawIntervals),result=[],cursor=0,dir2={x:edge.to.x-edge.from.x,y:edge.to.y-edge.from.y},addSeg=(d03,d13,isCrossing)=>{if(d13-d03<=TOL4)return;let t03=d03/L23,t110=d13/L23;result.push({from:pointAt(edge.from,edge.to,t03),to:pointAt(edge.from,edge.to,t110),...isCrossing?{is_crossing:!0}:{}})};for(let iv22 of intervals)iv22.start-cursor>TOL4&&addSeg(cursor,iv22.start,!1),addSeg(iv22.start,iv22.end,!0),cursor=iv22.end;return L23-cursor>TOL4&&addSeg(cursor,L23,!1),result.length>0?result:[edge]}function computeCrossings(traces,opts={}){let crossLen=opts.crossSegmentLength??.075,tol=opts.tolerance??TOL4,crossingsByEdge=new Map,keyOf=ref=>`${ref.traceIdx}:${ref.edgeIdx}`,getEdge=ref=>traces[ref.traceIdx].edges[ref.edgeIdx];for(let ti3=0;ti3<traces.length;ti3++){let A23=traces[ti3];for(let ei3=0;ei3<A23.edges.length;ei3++){let eA22=A23.edges[ei3];for(let tj2=ti3;tj2<traces.length;tj2++){let B23=traces[tj2];for(let ej2=tj2===ti3?ei3+1:0;ej2<B23.edges.length;ej2++){let eB2=B23.edges[ej2];if(A23.connectivity_key!==void 0&&A23.connectivity_key===B23.connectivity_key)continue;let P23=segmentIntersection(eA22.from,eA22.to,eB2.from,eB2.to,tol);if(!P23)continue;let LA22=length83(eA22.from,eA22.to),LB2=length83(eB2.from,eB2.to);if(LA22<tol||LB2<tol)continue;let dA22=paramAlong(eA22.from,eA22.to,P23),dB2=paramAlong(eB2.from,eB2.to,P23),nearEndpointA=dA22<=tol||Math.abs(LA22-dA22)<=tol||Number.isNaN(dA22),nearEndpointB=dB2<=tol||Math.abs(LB2-dB2)<=tol||Number.isNaN(dB2);if(!nearEndpointA&&!nearEndpointB){let aIsHorizontal=isHorizontalEdge(eA22),bIsHorizontal=isHorizontalEdge(eB2),assignToA;if(aIsHorizontal!==bIsHorizontal)assignToA=aIsHorizontal;else{let ax22=Math.abs(eA22.to.x-eA22.from.x),ay22=Math.abs(eA22.to.y-eA22.from.y),bx22=Math.abs(eB2.to.x-eB2.from.x),by22=Math.abs(eB2.to.y-eB2.from.y),aScore=ax22-ay22,bScore=bx22-by22;assignToA=aScore===bScore?!0:aScore>bScore}let chosenKey=keyOf({traceIdx:assignToA?ti3:tj2,edgeIdx:assignToA?ei3:ej2}),chosenList=crossingsByEdge.get(chosenKey)??[];chosenList.push(assignToA?dA22:dB2),crossingsByEdge.set(chosenKey,chosenList)}}}}}let out=traces.map(trace=>({...trace,edges:[]}));for(let ti3=0;ti3<traces.length;ti3++){let trace=traces[ti3];for(let ei3=0;ei3<trace.edges.length;ei3++){let eRefKey=keyOf({traceIdx:ti3,edgeIdx:ei3}),splittingDistances=crossingsByEdge.get(eRefKey)??[];if(splittingDistances.length===0){out[ti3].edges.push(trace.edges[ei3]);continue}let uniqueSorted3=Array.from(new Set(splittingDistances.map(d23=>Number(d23.toFixed(6))))).sort((a23,b23)=>a23-b23),split=splitEdgeByCrossings(trace.edges[ei3],uniqueSorted3,crossLen);out[ti3].edges.push(...split)}}return out}var TOL22=1e-6;function nearlyEqual2(a23,b23,tol=TOL22){return Math.abs(a23-b23)<=tol}function pointEq(a23,b23,tol=TOL22){return nearlyEqual2(a23.x,b23.x,tol)&&nearlyEqual2(a23.y,b23.y,tol)}function onSegment42(p23,a23,b23,tol=TOL22){let minX=Math.min(a23.x,b23.x)-tol,maxX=Math.max(a23.x,b23.x)+tol,minY=Math.min(a23.y,b23.y)-tol,maxY=Math.max(a23.y,b23.y)+tol;return p23.x<minX||p23.x>maxX||p23.y<minY||p23.y>maxY?!1:Math.abs((b23.x-a23.x)*(p23.y-a23.y)-(b23.y-a23.y)*(p23.x-a23.x))<=tol}function dedupePoints(points,tol=TOL22){let map=new Map;for(let p23 of points){let key=`${p23.x.toFixed(6)},${p23.y.toFixed(6)}`;map.has(key)||map.set(key,p23)}return Array.from(map.values())}function edgeVec(e211){return{x:e211.to.x-e211.from.x,y:e211.to.y-e211.from.y}}function isEndpointOfEdge(p23,e211,tol=TOL22){return pointEq(p23,e211.from,tol)||pointEq(p23,e211.to,tol)}function isParallel(e111,e211,tol=TOL22){let v13=edgeVec(e111),v23=edgeVec(e211),L13=Math.hypot(v13.x,v13.y),L23=Math.hypot(v23.x,v23.y);if(L13<tol||L23<tol)return!0;let cross52=v13.x*v23.y-v13.y*v23.x;return Math.abs(cross52)<=tol*L13*L23}function incidentEdgesAtPoint(trace,p23,tol=TOL22){return trace.edges.filter(e211=>pointEq(e211.from,p23,tol)||pointEq(e211.to,p23,tol))}function nearestEndpointOnTrace(trace,p23,tol=TOL22){for(let e211 of trace.edges){if(pointEq(e211.from,p23,tol))return e211.from;if(pointEq(e211.to,p23,tol))return e211.to}return null}function edgeDirectionFromPoint(e211,p23,tol=TOL22){let other=pointEq(e211.from,p23,tol)||nearlyEqual2(e211.from.x,p23.x,tol)&&nearlyEqual2(e211.from.y,p23.y,tol)?e211.to:e211.from,dx22=other.x-p23.x,dy22=other.y-p23.y;return Math.abs(dx22)<tol&&Math.abs(dy22)<tol?null:Math.abs(dx22)>=Math.abs(dy22)?dx22>=0?"right":"left":dy22>=0?"up":"down"}function getCornerOrientationAtPoint(trace,p23,tol=TOL22){let incident=incidentEdgesAtPoint(trace,p23,tol);if(incident.length<2)return null;let dirs=incident.map(e211=>edgeDirectionFromPoint(e211,p23,tol)),hasUp=dirs.includes("up"),hasDown=dirs.includes("down"),hasLeft=dirs.includes("left"),hasRight=dirs.includes("right"),vertical=hasUp?"up":hasDown?"down":null,horizontal=hasRight?"right":hasLeft?"left":null;return vertical&&horizontal?`${vertical}-${horizontal}`:null}function computeJunctions(traces,opts={}){let tol=opts.tolerance??TOL22,result={};for(let t48 of traces)result[t48.source_trace_id]=[];let endpointsByTrace=traces.map(t48=>{let pts=[];for(let e211 of t48.edges)pts.push(e211.from,e211.to);return dedupePoints(pts,tol)});for(let i23=0;i23<traces.length;i23++){let A23=traces[i23],AEnds=endpointsByTrace[i23];for(let j23=i23+1;j23<traces.length;j23++){let B23=traces[j23],BEnds=endpointsByTrace[j23];if(A23.connectivity_key!==void 0&&A23.connectivity_key===B23.connectivity_key){for(let eA22 of A23.edges)for(let eB2 of B23.edges){let p23=segmentIntersection(eA22.from,eA22.to,eB2.from,eB2.to,tol);p23&&(isEndpointOfEdge(p23,eA22,tol)||isEndpointOfEdge(p23,eB2,tol)||(result[A23.source_trace_id].push(p23),A23.source_trace_id!==B23.source_trace_id&&result[B23.source_trace_id].push(p23)))}for(let pa3 of AEnds)for(let pb22 of BEnds)if(pointEq(pa3,pb22,tol)){let aEdgesAtP=incidentEdgesAtPoint(A23,pa3,tol),bEdgesAtP=incidentEdgesAtPoint(B23,pb22,tol),hasCorner=aEdgesAtP.some(eA22=>bEdgesAtP.some(eB2=>!isParallel(eA22,eB2,tol))),aCorner=getCornerOrientationAtPoint(A23,pa3,tol),bCorner=getCornerOrientationAtPoint(B23,pb22,tol);hasCorner&&!(aCorner!==null&&bCorner!==null&&aCorner===bCorner)&&(result[A23.source_trace_id].push(pa3),A23.source_trace_id!==B23.source_trace_id&&result[B23.source_trace_id].push(pb22))}for(let pa3 of AEnds)for(let eB2 of B23.edges)if(onSegment42(pa3,eB2.from,eB2.to,tol)){let hasCorner=incidentEdgesAtPoint(A23,pa3,tol).some(eA22=>!isParallel(eA22,eB2,tol)),aCorner=getCornerOrientationAtPoint(A23,pa3,tol),bEndpointNearPa=nearestEndpointOnTrace(B23,pa3,tol*1e3),bCorner=bEndpointNearPa?getCornerOrientationAtPoint(B23,bEndpointNearPa,tol):null;hasCorner&&!(aCorner!==null&&bCorner!==null&&aCorner===bCorner)&&(result[A23.source_trace_id].push(pa3),A23.source_trace_id!==B23.source_trace_id&&result[B23.source_trace_id].push(pa3))}for(let pb22 of BEnds)for(let eA22 of A23.edges)if(onSegment42(pb22,eA22.from,eA22.to,tol)){let hasCorner=incidentEdgesAtPoint(B23,pb22,tol).some(eB2=>!isParallel(eA22,eB2,tol)),bCorner=getCornerOrientationAtPoint(B23,pb22,tol),aEndpointNearPb=nearestEndpointOnTrace(A23,pb22,tol*1e3),aCorner=aEndpointNearPb?getCornerOrientationAtPoint(A23,aEndpointNearPb,tol):null;hasCorner&&!(aCorner!==null&&bCorner!==null&&aCorner===bCorner)&&(result[B23.source_trace_id].push(pb22),A23.source_trace_id!==B23.source_trace_id&&result[A23.source_trace_id].push(pb22))}}}}for(let id3 of Object.keys(result))result[id3]=dedupePoints(result[id3],tol);return result}var TOL32=1e-6;function isCollinear(a23,b23,tol=TOL32){let adx=a23.to.x-a23.from.x,ady=a23.to.y-a23.from.y,bdx=b23.to.x-b23.from.x,bdy=b23.to.y-b23.from.y,aLen=Math.hypot(adx,ady),bLen=Math.hypot(bdx,bdy);if(aLen<=tol||bLen<=tol)return!1;let directionCross=adx*bdy-ady*bdx;if(Math.abs(directionCross)>tol*aLen*bLen)return!1;let offsetCross=adx*(b23.from.y-a23.from.y)-ady*(b23.from.x-a23.from.x);return Math.abs(offsetCross)<=tol*aLen}function splitEdgeAroundIntervals(edge,intervals){let merged=mergeIntervals(intervals);if(merged.length===0)return[edge];let edgeLength=length83(edge.from,edge.to);if(edgeLength<=TOL32)return[edge];let result=[],cursor=0;for(let interval of merged)interval.start-cursor>TOL32&&result.push({from:pointAt(edge.from,edge.to,cursor/edgeLength),to:pointAt(edge.from,edge.to,interval.start/edgeLength)}),interval.end-interval.start>TOL32&&result.push({from:pointAt(edge.from,edge.to,interval.start/edgeLength),to:pointAt(edge.from,edge.to,interval.end/edgeLength),is_crossing:!0}),cursor=Math.max(cursor,interval.end);return edgeLength-cursor>TOL32&&result.push({from:pointAt(edge.from,edge.to,cursor/edgeLength),to:edge.to}),result}function removeOverlappingSameNetCrossingSegments(traces){let intervalsToRemove=new Map;for(let crossingTraceIndex=0;crossingTraceIndex<traces.length;crossingTraceIndex++){let crossingTrace=traces[crossingTraceIndex];if(crossingTrace.connectivity_key){for(let crossingEdge of crossingTrace.edges)if(!(!crossingEdge.is_crossing||length83(crossingEdge.from,crossingEdge.to)<=TOL32))for(let traceIndex=0;traceIndex<traces.length;traceIndex++){let candidateTrace=traces[traceIndex];if(!(traceIndex===crossingTraceIndex||candidateTrace.connectivity_key!==crossingTrace.connectivity_key))for(let edgeIndex=0;edgeIndex<candidateTrace.edges.length;edgeIndex++){let candidateEdge=candidateTrace.edges[edgeIndex],candidateLength=length83(candidateEdge.from,candidateEdge.to);if(candidateEdge.is_crossing||candidateLength<=TOL32||!isCollinear(candidateEdge,crossingEdge))continue;let start=Math.max(0,Math.min(paramAlong(candidateEdge.from,candidateEdge.to,crossingEdge.from),paramAlong(candidateEdge.from,candidateEdge.to,crossingEdge.to))),end=Math.min(candidateLength,Math.max(paramAlong(candidateEdge.from,candidateEdge.to,crossingEdge.from),paramAlong(candidateEdge.from,candidateEdge.to,crossingEdge.to)));if(end-start<=TOL32)continue;let key=`${traceIndex}:${edgeIndex}`,intervals=intervalsToRemove.get(key)??[];intervals.push({start,end}),intervalsToRemove.set(key,intervals)}}}}return intervalsToRemove.size===0?traces:traces.map((trace,traceIndex)=>({...trace,edges:trace.edges.flatMap((edge,edgeIndex)=>{let intervals=intervalsToRemove.get(`${traceIndex}:${edgeIndex}`);return intervals?splitEdgeAroundIntervals(edge,intervals):[edge]})}))}var GEOMETRY_TOLERANCE=1e-6;function removeRedundantTracesToNetLabels({traces,existingTraces,netLabelTerminals,terminals,inlineNetLabelTraces=new Set}){let retainedEdgesByOriginalEdge=new Map;for(let connectivityKey of new Set(netLabelTerminals.map(terminal=>terminal.connectivityKey))){let routingNodes=[],getOrCreateRoutingNode=position22=>{let node2=routingNodes.find(node22=>distance7(node22.position,position22)<=GEOMETRY_TOLERANCE);return node2||(node2={position:position22,segments:[],distanceToLabel:1/0},routingNodes.push(node2)),node2},netEdges=[...existingTraces.filter(trace=>trace.subcircuit_connectivity_map_key===connectivityKey).flatMap(trace=>trace.edges.map(edge=>({edge,isPreserved:!0}))),...traces.filter(trace=>trace.subcircuit_connectivity_map_key===connectivityKey).flatMap(trace=>trace.edges.map(edge=>({edge,isPreserved:inlineNetLabelTraces.has(trace)})))];for(let{edge}of netEdges)getOrCreateRoutingNode(edge.from),getOrCreateRoutingNode(edge.to);for(let edgeIndex=0;edgeIndex<netEdges.length;edgeIndex++)for(let otherEdgeIndex=edgeIndex+1;otherEdgeIndex<netEdges.length;otherEdgeIndex++){let firstEdge=netEdges[edgeIndex].edge,secondEdge=netEdges[otherEdgeIndex].edge,contactPoint=segmentIntersection(firstEdge.from,firstEdge.to,secondEdge.from,secondEdge.to,GEOMETRY_TOLERANCE);contactPoint&&getOrCreateRoutingNode(contactPoint)}let terminalNodes=terminals.filter(terminal=>terminal.connectivityKey===connectivityKey).map(terminal=>getOrCreateRoutingNode(terminal.position));for(let terminal of netLabelTerminals)terminal.connectivityKey===connectivityKey&&(getOrCreateRoutingNode(terminal.position).distanceToLabel=0);let routingSegmentsByOriginalEdge=new Map;for(let{edge,isPreserved}of netEdges){let edgeNodes=routingNodes.filter(node2=>pointToSegmentDistance2(node2.position,edge.from,edge.to)<=GEOMETRY_TOLERANCE).sort((firstNode,secondNode)=>distance7(edge.from,firstNode.position)-distance7(edge.from,secondNode.position)),segments2=[];for(let nodeIndex=1;nodeIndex<edgeNodes.length;nodeIndex++){let from=edgeNodes[nodeIndex-1],to3=edgeNodes[nodeIndex],segment5={from,to:to3,cost:isPreserved?0:distance7(from.position,to3.position)};from.segments.push(segment5),to3.segments.push(segment5),segments2.push(segment5)}isPreserved||routingSegmentsByOriginalEdge.set(edge,segments2)}let unvisitedNodes=new Set(routingNodes);for(;unvisitedNodes.size>0;){let nearestNode;for(let node2 of unvisitedNodes)node2.distanceToLabel<(nearestNode?.distanceToLabel??1/0)&&(nearestNode=node2);if(!nearestNode)break;unvisitedNodes.delete(nearestNode);for(let segment5 of nearestNode.segments){let neighborNode=segment5.from===nearestNode?segment5.to:segment5.from,candidateDistance=nearestNode.distanceToLabel+segment5.cost;unvisitedNodes.has(neighborNode)&&candidateDistance<neighborNode.distanceToLabel&&(neighborNode.distanceToLabel=candidateDistance,neighborNode.pathToLabel={node:nearestNode,segment:segment5})}}let retainedSegments=new Set;for(let node2 of terminalNodes)for(;node2.pathToLabel;){let{segment:segment5,node:nextNodeOnPath}=node2.pathToLabel;if(retainedSegments.has(segment5))break;retainedSegments.add(segment5),node2=nextNodeOnPath}for(let[edge,segments2]of routingSegmentsByOriginalEdge){let retainedEdgeSegments=[];for(let segment5 of segments2){if(!retainedSegments.has(segment5)&&Number.isFinite(segment5.from.distanceToLabel))continue;let previousRetainedEdge=retainedEdgeSegments.at(-1);previousRetainedEdge&&distance7(previousRetainedEdge.to,segment5.from.position)<=GEOMETRY_TOLERANCE?previousRetainedEdge.to=segment5.to.position:retainedEdgeSegments.push({...edge,from:segment5.from.position,to:segment5.to.position})}retainedEdgesByOriginalEdge.set(edge,retainedEdgeSegments)}}return traces.map(trace=>({...trace,edges:trace.edges.flatMap(edge=>retainedEdgesByOriginalEdge.get(edge)??[edge])})).filter(trace=>trace.edges.length>0)}var debug10=(0,import_debug19.default)("Group_doInitialSchematicTraceRender"),MAX_PIN_SNAP_GAP=1.5;function extendTraceEndpointsToReachPinsInsideExpandedBoundingBox(params,db22){let{points,schematicPortIds,componentBoundsByPortId}=params,centers=schematicPortIds.map(id3=>{let center2=db22.schematic_port.get(id3)?.center,bounds=componentBoundsByPortId.get(id3);return!center2||!bounds?null:{center:center2,bounds}}).filter(port=>!!port);if(centers.length===0)return points;let result=points.map(p23=>({x:p23.x,y:p23.y})),d23=(a23,b23)=>(a23.x-b23.x)**2+(a23.y-b23.y)**2,usedCenters=new Set;for(let i23=0;i23<centers.length;i23++)result.some(p23=>d23(centers[i23].center,p23)<=1e-12)&&usedCenters.add(i23);let ALIGN_EPS=.001,endpoints=["start","end"],candidates=[];for(let endpoint of endpoints){let endpointPoint=endpoint==="start"?result[0]:result[result.length-1];for(let i23=0;i23<centers.length;i23++){if(usedCenters.has(i23))continue;let{center:center2,bounds}=centers[i23],dist4=d23(center2,endpointPoint);Math.abs(center2.x-endpointPoint.x)>ALIGN_EPS&&Math.abs(center2.y-endpointPoint.y)>ALIGN_EPS||dist4>MAX_PIN_SNAP_GAP**2&&pointToBoundsDistance(endpointPoint,bounds)>ALIGN_EPS||candidates.push({endpoint,centerIndex:i23,dist:dist4})}}candidates.sort((a23,b23)=>a23.dist-b23.dist);let usedEndpoints=new Set;for(let{endpoint,centerIndex,dist:dist4}of candidates){if(usedEndpoints.has(endpoint)||usedCenters.has(centerIndex)||(usedCenters.add(centerIndex),usedEndpoints.add(endpoint),dist4<=1e-12))continue;let center2=centers[centerIndex].center;endpoint==="start"?result.unshift({x:center2.x,y:center2.y}):result.push({x:center2.x,y:center2.y})}return result}function applyTracesFromSolverOutput(args){let{group:group2,solver,userNetIdToConnKey,schematicPortIdsWithPreExistingNetLabels,schematicSheetId}=args,{db:db22}=group2.root,routedPinBySchematicPortId=new Map(solver.inputProblem.chips.flatMap(chip=>chip.pins.map(pin=>[asSchematicPortId(pin.pinId),pin]))),customSymbolPortIds=new Set(group2.selectAll("port").filter(port=>{if(!port._getSymbolAncestor())return!1;let symbol=port.getParentNormalComponent()?._parsedProps.symbol;return(0,import_react9.isValidElement)(symbol)||isCircuitJsonSymbol(symbol)}).map(port=>port.schematic_port_id).filter(schematicPortId=>schematicPortId!=null).map(asSchematicPortId)),componentBoundsByPortId=new Map;for(let schematicComponent of db22.schematic_component.list()){let textInclusiveBounds=getSchematicComponentWithTextBounds({db:db22,schematicComponent}),componentBounds=getBoundFromCenteredRect({center:schematicComponent.center,width:schematicComponent.size.width,height:schematicComponent.size.height});for(let port of db22.schematic_port.list({schematic_component_id:schematicComponent.schematic_component_id})){let isInsideComponentBounds=port.center.x>componentBounds.minX&&port.center.x<componentBounds.maxX&&port.center.y>componentBounds.minY&&port.center.y<componentBounds.maxY,schematicPortId=asSchematicPortId(port.schematic_port_id);!textInclusiveBounds&&!customSymbolPortIds.has(schematicPortId)||!textInclusiveBounds&&isInsideComponentBounds||componentBoundsByPortId.set(schematicPortId,textInclusiveBounds??componentBounds)}}let traces=solver.inlineNetLabelSolver?.getOutput().traces??solver.sameNetJunctionAlignmentSolver?.getOutput().traces??solver.netLabelTraceCollisionSolver?.getOutput().traces??solver.traceCleanupSolver?.getOutput().traces??solver.traceLabelOverlapAvoidanceSolver?.getOutput().traces??solver.schematicTraceLinesSolver?.solvedTracePaths,pendingTraces=[],terminals=[],netLabelTerminals=[];debug10(`Traces inside SchematicTraceSolver output: ${(traces??[]).length}`);for(let solvedTracePath of traces??[]){let solvedTraceSchematicPortIds=Array.from(new Set(solvedTracePath.pinIds??[])).map(asSchematicPortId),points=solvedTracePath?.tracePath;if(!Array.isArray(points)||points.length<2){debug10(`Skipping trace ${solvedTracePath?.pinIds.join(",")} because it has less than 2 points`);continue}let snappedPoints=extendTraceEndpointsToReachPinsInsideExpandedBoundingBox({points,schematicPortIds:solvedTraceSchematicPortIds,componentBoundsByPortId},db22),edges=[];for(let i23=0;i23<snappedPoints.length-1;i23++)edges.push({from:{x:snappedPoints[i23].x,y:snappedPoints[i23].y},to:{x:snappedPoints[i23+1].x,y:snappedPoints[i23+1].y}});let source_trace_id=String(solvedTracePath?.mspPairId),subcircuit_connectivity_map_key;if(Array.isArray(solvedTracePath?.pins)&&solvedTracePath.pins.length===2){let firstPinId=solvedTracePath.pins[0]?.pinId,secondPinId=solvedTracePath.pins[1]?.pinId,pA22=firstPinId?asSchematicPortId(firstPinId):void 0,pB2=secondPinId?asSchematicPortId(secondPinId):void 0;if(pA22&&pB2){let routedSchematicPortIds=new Set([pA22,pB2]);for(let routedSchematicPortId of routedSchematicPortIds)db22.schematic_port.update(routedSchematicPortId,{is_connected:!0});subcircuit_connectivity_map_key=userNetIdToConnKey.get(String(solvedTracePath.userNetId))}}if(subcircuit_connectivity_map_key||(subcircuit_connectivity_map_key=userNetIdToConnKey.get(String(solvedTracePath.userNetId))),!subcircuit_connectivity_map_key){let sourcePortConnKeys=solvedTraceSchematicPortIds.map(schematicPortId=>{let sourcePortId=db22.schematic_port.get(schematicPortId)?.source_port_id;if(sourcePortId)return db22.source_port.get(sourcePortId)?.subcircuit_connectivity_map_key}).filter(key=>!!key);new Set(sourcePortConnKeys).size===1&&(subcircuit_connectivity_map_key=sourcePortConnKeys[0])}if(subcircuit_connectivity_map_key)for(let schematicPortId of solvedTraceSchematicPortIds){let schematicPort=db22.schematic_port.get(schematicPortId);if(!schematicPort)continue;let portTerminal={position:schematicPort.center,connectivityKey:subcircuit_connectivity_map_key};terminals.push(portTerminal);let routedPin=routedPinBySchematicPortId.get(schematicPortId);routedPin&&terminals.push({position:{x:routedPin.x,y:routedPin.y},connectivityKey:subcircuit_connectivity_map_key}),schematicPortIdsWithPreExistingNetLabels.has(schematicPortId)&&netLabelTerminals.push(portTerminal)}let endpointSchematicSheetIds=new Set(solvedTraceSchematicPortIds.map(schematicPortId=>db22.schematic_port.get(schematicPortId)?.schematic_sheet_id).filter(sheetId=>!!sheetId)),schematicSheetId2;endpointSchematicSheetIds.size===1?schematicSheetId2=endpointSchematicSheetIds.values().next().value:endpointSchematicSheetIds.size===0&&(schematicSheetId2=group2._resolveSchematicSheetId()),pendingTraces.push({source_trace_id,edges,subcircuit_connectivity_map_key,schematic_sheet_id:schematicSheetId2})}debug10(`Applying ${pendingTraces.length} traces from SchematicTraceSolver output`);let existingTraces=db22.schematic_trace.list().filter(trace=>trace.schematic_sheet_id===schematicSheetId),netLabelPlacements=solver.inlineNetLabelSolver?.getOutput().netLabelPlacements??solver.netLabelNetLabelCollisionSolver?.getOutput().netLabelPlacements??solver.netLabelTraceCollisionSolver?.getOutput().netLabelPlacements??solver.netLabelPlacementSolver?.netLabelPlacements??solver.traceLabelOverlapAvoidanceSolver?.getOutput().netLabelPlacements??[];for(let placement of netLabelPlacements){if(placement.pinIds.some(pinId=>schematicPortIdsWithPreExistingNetLabels.has(asSchematicPortId(pinId))))continue;let userNetId=solver.mspConnectionPairSolver.globalConnMap.getIdsConnectedToNet(placement.globalConnNetId).find(netId=>userNetIdToConnKey.has(netId)),connectivityKey=userNetId?userNetIdToConnKey.get(userNetId):void 0;connectivityKey&&terminals.push({position:placement.anchorPoint,connectivityKey})}let inlineNetLabelTraceIds=new Set((solver.inlineNetLabelSolver?.getOutput().inlineNetLabelPlacements??[]).flatMap(placement=>placement.mspPairId?[placement.mspPairId]:[])),retainedTraces=removeRedundantTracesToNetLabels({traces:pendingTraces,existingTraces,netLabelTerminals,terminals,inlineNetLabelTraces:new Set(pendingTraces.filter(trace=>inlineNetLabelTraceIds.has(trace.source_trace_id)))}),existingTracesForJunctions=[];for(let t48 of existingTraces){if(t48.edges.length===0)continue;let sourceTrace=t48.source_trace_id?db22.source_trace.get(t48.source_trace_id):void 0;existingTracesForJunctions.push({schematic_trace_id:t48.schematic_trace_id,source_trace_id:t48.source_trace_id??t48.schematic_trace_id,edges:t48.edges,connectivity_key:t48.subcircuit_connectivity_map_key??sourceTrace?.subcircuit_connectivity_map_key})}let withCrossings=computeCrossings([...retainedTraces.map(trace=>({source_trace_id:trace.source_trace_id,edges:trace.edges,connectivity_key:trace.subcircuit_connectivity_map_key})),...existingTracesForJunctions]),tracesWithTrimmedCrossingOverlaps=removeOverlappingSameNetCrossingSegments(withCrossings),visibleTraces=tracesWithTrimmedCrossingOverlaps.slice(0,retainedTraces.length),visibleExistingTraces=tracesWithTrimmedCrossingOverlaps.slice(retainedTraces.length);for(let trace of visibleExistingTraces)trace.schematic_trace_id&&db22.schematic_trace.update(trace.schematic_trace_id,{edges:trace.edges});let junctionsById=computeJunctions([...visibleTraces,...visibleExistingTraces]);for(let t48 of visibleTraces){let pendingTrace=pendingTraces.find(pendingTrace2=>pendingTrace2.source_trace_id===t48.source_trace_id),traceSchematicSheetId=schematicSheetId;pendingTrace?.schematic_sheet_id&&(traceSchematicSheetId=pendingTrace.schematic_sheet_id),db22.schematic_trace.insert({source_trace_id:t48.source_trace_id,edges:t48.edges,junctions:junctionsById[t48.source_trace_id]??[],subcircuit_connectivity_map_key:pendingTrace?.subcircuit_connectivity_map_key,schematic_sheet_id:traceSchematicSheetId})}}var INLINE_NET_LABEL_FONT_SIZE=.12,markConnectionEligibleForInlineNetLabel=(connection,name)=>{connection.anchoredNetLabelWidth??(connection.anchoredNetLabelWidth=Number(getSchematicNetLabelTextWidth2({text:name}).toFixed(2))),connection.allowInlineNetLabel=!0,connection.inlineNetLabelHeight=INLINE_NET_LABEL_FONT_SIZE,connection.inlineNetLabelWidth=Number(getSchematicNetLabelTextWidth2({text:name,font_size:INLINE_NET_LABEL_FONT_SIZE}).toFixed(2))},applyInlineNetLabelEligibility=({directConnections,netConnections,connKeyToSchematicPortIds,connKeyToSourceNet,connKeysWithExplicitPortNetTraces,schematicPortIdsWithExplicitNetLabels,schematicPortIdsWithInlineNetLabels,areSchematicPortsOnDifferentComponents,resolveCanonicalNetLabelText})=>{for(let directConnection of directConnections){let{connKey}=directConnection;if(!connKey||connKeyToSchematicPortIds.get(connKey)?.length!==2)continue;let sourceNet=connKeyToSourceNet.get(connKey);if(sourceNet?.is_power||sourceNet?.is_ground)continue;let{name,wasAssignedDisplayLabel}=resolveCanonicalNetLabelText({subcircuitConnectivityMapKey:connKey});!name||!wasAssignedDisplayLabel||markConnectionEligibleForInlineNetLabel(directConnection,name)}for(let netConnection of netConnections){let{schematicPortIds}=netConnection,{isSameSheetCrossSectionConnection}=netConnection,hasInlineNetLabel=schematicPortIds.some(schematicPortId=>schematicPortIdsWithInlineNetLabels.has(schematicPortId)),isSinglePort=schematicPortIds.length===1,firstSchematicPortId=schematicPortIds[0],hasPortsOnDifferentComponents=firstSchematicPortId!==void 0&&schematicPortIds.slice(1).some(otherSchematicPortId=>areSchematicPortsOnDifferentComponents([firstSchematicPortId,otherSchematicPortId]));if(!hasInlineNetLabel&&!isSameSheetCrossSectionConnection&&!isSinglePort&&!hasPortsOnDifferentComponents||!hasInlineNetLabel&&schematicPortIds.some(schematicPortId=>schematicPortIdsWithExplicitNetLabels.has(schematicPortId)))continue;let{connKey}=netConnection;if(!connKey&&!isSameSheetCrossSectionConnection||connKey&&!isSameSheetCrossSectionConnection&&!connKeysWithExplicitPortNetTraces.has(connKey))continue;let sourceNet=connKey?connKeyToSourceNet.get(connKey):void 0;if(!hasInlineNetLabel&&(netConnection.isPowerOrGroundConnection||sourceNet?.is_power||sourceNet?.is_ground))continue;let name=netConnection.netLabelText??"",wasAssignedDisplayLabel=!!name;if(!isSameSheetCrossSectionConnection){if(!connKey)continue;let resolvedLabel=resolveCanonicalNetLabelText({subcircuitConnectivityMapKey:connKey});name=resolvedLabel.name,wasAssignedDisplayLabel=resolvedLabel.wasAssignedDisplayLabel}!name||!hasInlineNetLabel&&!wasAssignedDisplayLabel||markConnectionEligibleForInlineNetLabel(netConnection,name)}},getPortForSchematicSymbolPort=port=>{let{schX,schY}=port._parsedProps;if(schX!==void 0&&schY!==void 0||!port.getParentNormalComponent()?.getSchematicSymbol())return port;let internallyConnectedPorts=port._getPortsInternallyConnectedToThisPort(),schematicSymbolPortDef=port.schematicSymbolPortDef??internallyConnectedPorts.find(connectedPort=>connectedPort.schematicSymbolPortDef)?.schematicSymbolPortDef;return schematicSymbolPortDef?internallyConnectedPorts.find(connectedPort=>connectedPort.schematicSymbolPortDef===schematicSymbolPortDef)??port:port};function createRoutedSchematicPortIdMap(group2){let{db:db22}=group2.root,routedSchematicPortIdBySchematicPortId=new Map;for(let port of group2.selectAll("port")){if(!port.schematic_port_id)continue;let schematicPort=db22.schematic_port.get(port.schematic_port_id),terminalPort=getPortForSchematicSymbolPort(port),terminalSchematicPort=terminalPort.schematic_port_id?db22.schematic_port.get(terminalPort.schematic_port_id):void 0;!schematicPort||!terminalSchematicPort||schematicPort.schematic_component_id!==terminalSchematicPort.schematic_component_id||schematicPort.schematic_sheet_id!==terminalSchematicPort.schematic_sheet_id||routedSchematicPortIdBySchematicPortId.set(asSchematicPortId(schematicPort.schematic_port_id),asSchematicPortId(terminalSchematicPort.schematic_port_id))}return routedSchematicPortIdBySchematicPortId}var isDirectConnectionEndpointOutsideSchematicScope=({db:db22,sourcePortId,otherSourcePortId,sourcePortIdsInSchematicScope,schematicSheetId})=>{if(sourcePortIdsInSchematicScope.has(otherSourcePortId))return!1;let sourcePort=db22.source_port.get(sourcePortId),otherSourcePort=db22.source_port.get(otherSourcePortId);if(!sourcePort||!otherSourcePort)return!1;if(sourcePort.subcircuit_id!==otherSourcePort.subcircuit_id)return!0;if(!schematicSheetId)return!1;let otherEndpointSchematicPorts=db22.schematic_port.list({source_port_id:otherSourcePortId});return otherEndpointSchematicPorts.some(schematicPort=>schematicPort.schematic_sheet_id===schematicSheetId)?!1:otherEndpointSchematicPorts.some(schematicPort=>schematicPort.schematic_sheet_id!==void 0)},getDirectConnectionOutsideSchematicScopeSourcePortId=({db:db22,sourcePortId,sourcePortIdsInSchematicScope,schematicSheetId})=>{if(db22.source_port.get(sourcePortId))for(let sourceTrace of db22.source_trace.list()){let connectedSourcePortIds=(sourceTrace.connected_source_port_ids??[]).map(asSourcePortId);if(connectedSourcePortIds.length!==2||(sourceTrace.connected_source_net_ids??[]).length>0||!connectedSourcePortIds.includes(sourcePortId))continue;let otherSourcePortId=connectedSourcePortIds.find(portId=>portId!==sourcePortId);if(otherSourcePortId&&isDirectConnectionEndpointOutsideSchematicScope({db:db22,sourcePortId,otherSourcePortId,sourcePortIdsInSchematicScope,schematicSheetId}))return otherSourcePortId}},resolveNetLabelForPortMissingTrace=({group:group2,sourcePortId,connectedSourcePortIdsForKey,sourcePortIdsInSchematicScope,schematicSheetId,connKey,sourceNet})=>{let{db:db22}=group2.root,connectedPortsForKey=group2.selectAll("port").filter(port=>port._getSubcircuitConnectivityKey()===connKey),{name:resolvedPortNetLabelText,wasAssignedDisplayLabel}=getNetNameFromPorts(connectedPortsForKey),assignedPortNetLabelText=wasAssignedDisplayLabel?resolvedPortNetLabelText:void 0,fallbackPortNetLabelText=wasAssignedDisplayLabel?void 0:resolvedPortNetLabelText||void 0,implicitPortLabelText=getNetNameFromSourcePorts(db22,connectedSourcePortIdsForKey),directConnectionOutsideSchematicScopeSourcePortId=getDirectConnectionOutsideSchematicScopeSourcePortId({db:db22,sourcePortId,sourcePortIdsInSchematicScope,schematicSheetId}),directConnectionOutsideSchematicScopeLabelText=directConnectionOutsideSchematicScopeSourcePortId?getSourcePortNetLabelText(db22,directConnectionOutsideSchematicScopeSourcePortId):void 0;return{text:sourceNet?.name||sourceNet?.source_net_id||assignedPortNetLabelText||directConnectionOutsideSchematicScopeLabelText||fallbackPortNetLabelText||implicitPortLabelText||connKey,wasAssignedDisplayLabel,directConnectionOutsideSchematicScopeSourcePortId}},REFDES_TEXT_BOX_CHIP_OVERLAP=.01,REFDES_TEXT_BOX_CLEARANCE=.06;function isReferenceDesignatorText(text4,sourceComponent){return sourceComponent?text4.text===sourceComponent.display_name||text4.text===sourceComponent.name:!1}function schematicTextToTextBox(text4,options={}){if(!text4.text)return null;let bounds=getSchematicTextBounds(text4);if(isReferenceDesignatorText(text4,options.sourceComponent)&&options.schematicComponent?.center&&options.schematicComponent?.size){let componentBounds=getBoundFromCenteredRect({center:options.schematicComponent.center,width:options.schematicComponent.size.width,height:options.schematicComponent.size.height}),textHeight=bounds.maxY-bounds.minY;bounds.minY>componentBounds.maxY&&(bounds.minX-=REFDES_TEXT_BOX_CLEARANCE,bounds.maxX+=REFDES_TEXT_BOX_CLEARANCE,bounds.minY=componentBounds.maxY-REFDES_TEXT_BOX_CHIP_OVERLAP,bounds.maxY=componentBounds.maxY+textHeight+REFDES_TEXT_BOX_CLEARANCE)}return{chipId:text4.schematic_component_id,center:getBoundsCenter2(bounds),width:bounds.maxX-bounds.minX,height:bounds.maxY-bounds.minY,text:text4.text}}var DEFAULT_MAX_MSP_PAIR_DISTANCE2=2.4,SCHEMATIC_RAIL_NET_LABEL_HEIGHT=.42;function createSchematicTraceSolverInputProblem(group2,opts={}){let{db:db22}=group2.root,routedSchematicPortIdBySchematicPortId=createRoutedSchematicPortIdMap(group2),resolveRoutedSchematicPortId=schematicPortId=>routedSchematicPortIdBySchematicPortId.get(schematicPortId)??schematicPortId,sourcePortConnectivityMap=getSourcePortConnectivityMapFromCircuitJson(db22.toArray()),getStableSourceConnectivityNetId=connectivityNetId=>{let canonicalSourceId=[...sourcePortConnectivityMap.getIdsConnectedToNet(connectivityNetId)].sort()[0];return canonicalSourceId?`source_connectivity_${canonicalSourceId}`:`source_${connectivityNetId}`},getSourceConnectivityNetId=sourceTrace=>{let connectivityNetId=[...sourceTrace.connected_source_port_ids,...sourceTrace.connected_source_net_ids].map(sourceId=>sourcePortConnectivityMap.getNetConnectedToId(sourceId)).find(netId=>!!netId);return connectivityNetId?getStableSourceConnectivityNetId(connectivityNetId):sourceTrace.subcircuit_connectivity_map_key??sourceTrace.source_trace_id},powerOrGroundSourceConnectivityNetIds=new Set;for(let sourceNet of db22.source_net.list()){if(!sourceNet.is_power&&!sourceNet.is_ground)continue;let connectivityNetId=sourcePortConnectivityMap.getNetConnectedToId(sourceNet.source_net_id);connectivityNetId&&powerOrGroundSourceConnectivityNetIds.add(getStableSourceConnectivityNetId(connectivityNetId))}let connKeyToSourceNet=new Map,childGroups=[],componentsToVisit=[...group2.children].reverse();for(;componentsToVisit.length>0;){let child=componentsToVisit.pop();if(child instanceof Group){if(child.isSubcircuit){child._parsedProps.showAsSchematicBox&&childGroups.push(child);continue}childGroups.push(child)}componentsToVisit.push(...[...child.children].reverse())}let allSchematicGroupIds=[group2.schematic_group_id,...childGroups.map(a23=>a23.schematic_group_id)],schematicComponents=db22.schematic_component.list().filter(component=>allSchematicGroupIds.includes(component.schematic_group_id)).filter(component=>opts.schematicSheetId===void 0||component.schematic_sheet_id===opts.schematicSheetId),schematicComponentIds=new Set(schematicComponents.map(component=>component.schematic_component_id)),schematicComponentsById=new Map(schematicComponents.map(component=>[component.schematic_component_id,component])),textBoxes=db22.schematic_text.list().filter(text4=>text4.schematic_component_id&&schematicComponentIds.has(text4.schematic_component_id)).map(text4=>{let schematicComponent=schematicComponentsById.get(text4.schematic_component_id);if(!schematicComponent)return;let sourceComponent=db22.source_component.get(schematicComponent.source_component_id);return schematicTextToTextBox(text4,{schematicComponent,sourceComponent})}).filter(textBox=>!!textBox),sectionIdBySchematicComponentId=new Map,boardDescendants=group2._getBoard()?.getDescendants()??[];for(let component of boardDescendants){let schematicComponentId=component.schematic_component_id,sectionId=component.getSchematicSectionName();schematicComponentId&&sectionId&&sectionIdBySchematicComponentId.set(schematicComponentId,sectionId)}let chips=[];for(let schematicComponent of schematicComponents){let chipId=schematicComponent.schematic_component_id,schematicPorts=db22.schematic_port.list({schematic_component_id:schematicComponent.schematic_component_id}),pins=schematicPorts.filter(schematicPort=>{let id3=asSchematicPortId(schematicPort.schematic_port_id);return resolveRoutedSchematicPortId(id3)===id3}).map(schematicPort=>{let schematicPortId=asSchematicPortId(schematicPort.schematic_port_id),sourcePort=schematicPort.source_port_id?db22.source_port.get(schematicPort.source_port_id):void 0;return{pinId:schematicPortId,displayName:schematicPort.display_pin_label??schematicPort.pin_number?.toString()??sourcePort?.name,x:schematicPort.center.x,y:schematicPort.center.y,_facingDirection:convertFacingDirectionToElbowDirection(schematicPort.facing_direction??null)}}),sectionId=sectionIdBySchematicComponentId.get(schematicComponent.schematic_component_id),obstacleBounds=(schematicComponent.is_box_with_pins===!1?void 0:getSchematicComponentWithTextBounds({db:db22,schematicComponent}))??getBoundFromCenteredRect({center:schematicComponent.center,width:schematicComponent.size.width,height:schematicComponent.size.height});for(let port of schematicPorts)obstacleBounds.minX=Math.min(obstacleBounds.minX,port.center.x),obstacleBounds.maxX=Math.max(obstacleBounds.maxX,port.center.x),obstacleBounds.minY=Math.min(obstacleBounds.minY,port.center.y),obstacleBounds.maxY=Math.max(obstacleBounds.maxY,port.center.y);chips.push({chipId,center:getBoundsCenter2(obstacleBounds),width:obstacleBounds.maxX-obstacleBounds.minX,height:obstacleBounds.maxY-obstacleBounds.minY,pins,sectionId})}let schematicPortIdsInScope=new Set,schPortIdToSourcePortId=new Map,sourcePortIdToSchPortId=new Map,userNetIdToConnKey=new Map,componentPortBySchematicPortId=new Map(group2.selectAll("port").filter(port=>port.schematic_port_id).map(port=>[asSchematicPortId(port.schematic_port_id),port])),resolveCanonicalNetLabelText=createCanonicalSchematicNetLabelTextResolver(group2);for(let sc3 of schematicComponents){let ports=db22.schematic_port.list({schematic_component_id:sc3.schematic_component_id});for(let sp22 of ports){let schematicPortId=asSchematicPortId(sp22.schematic_port_id);if(schematicPortIdsInScope.add(schematicPortId),sp22.source_port_id){let sourcePortId=asSourcePortId(sp22.source_port_id);schPortIdToSourcePortId.set(schematicPortId,sourcePortId),sourcePortIdToSchPortId.set(sourcePortId,schematicPortId)}}}let sourcePortIdsInSchematicScope=new Set(sourcePortIdToSchPortId.keys()),netLabelsInScope=(opts.netLabels??[]).filter(netLabel=>netLabel._getConnectedPorts().some(port=>port.schematic_port_id?schematicPortIdsInScope.has(asSchematicPortId(port.schematic_port_id)):!1)),schematicPortIdsWithExplicitNetLabels=new Set(netLabelsInScope.filter(netLabel=>!netLabel._parsedProps.inline).flatMap(netLabel=>netLabel._getConnectedPorts()).map(port=>port.schematic_port_id).filter(schematicPortId=>schematicPortId!=null).map(asSchematicPortId).map(resolveRoutedSchematicPortId)),solverManagedNetLabelSchematicPortIds=new Set(netLabelsInScope.filter(netLabel=>netLabel._parsedProps.inline||netLabel._parsedProps.schX===void 0&&netLabel._parsedProps.schY===void 0).flatMap(netLabel=>netLabel._getConnectedPorts()).map(port=>port.schematic_port_id).filter(schematicPortId=>schematicPortId!=null).map(asSchematicPortId).map(resolveRoutedSchematicPortId)),schematicPortIdsWithInlineNetLabels=new Set(netLabelsInScope.filter(netLabel=>netLabel._parsedProps.inline).flatMap(netLabel=>netLabel._getConnectedPorts()).map(port=>port.schematic_port_id).filter(schematicPortId=>schematicPortId!=null).map(asSchematicPortId).map(resolveRoutedSchematicPortId)),allowedSubcircuitIds=new Set;group2.subcircuit_id&&allowedSubcircuitIds.add(group2.subcircuit_id);for(let cg2 of childGroups)cg2.subcircuit_id&&allowedSubcircuitIds.add(cg2.subcircuit_id);let tracesInScope=db22.source_trace.list().filter(st22=>{if(st22.subcircuit_id===group2.subcircuit_id)return!0;for(let source_port_id of st22.connected_source_port_ids)if(sourcePortIdToSchPortId.has(asSourcePortId(source_port_id)))return!0;return!1}),schematicPortIdsWithExternallyRoutedRepresentations=new Set;for(let sourceTrace of tracesInScope)if(sourceTrace.subcircuit_id!==group2.subcircuit_id&&sourceTrace.connected_source_net_ids.length!==0)for(let sourcePortId of sourceTrace.connected_source_port_ids){let typedSourcePortId=asSourcePortId(sourcePortId),schematicPortId=sourcePortIdToSchPortId.get(typedSourcePortId);!schematicPortId||solverManagedNetLabelSchematicPortIds.has(schematicPortId)||!db22.schematic_port.list({source_port_id:sourcePortId}).some(port=>port.schematic_port_id===schematicPortId?!1:(port.schematic_component_id?db22.schematic_component.get(port.schematic_component_id):void 0)?.schematic_sheet_id===opts.schematicSheetId)||schematicPortIdsWithExternallyRoutedRepresentations.add(schematicPortId)}let externalNetIds=tracesInScope.flatMap(st22=>st22.connected_source_net_ids);for(let netId of externalNetIds){let net=db22.source_net.get(netId);net?.subcircuit_id&&allowedSubcircuitIds.add(net.subcircuit_id)}for(let net of db22.source_net.list().filter(sourceNet=>!sourceNet.subcircuit_id||allowedSubcircuitIds.has(sourceNet.subcircuit_id)))net.subcircuit_connectivity_map_key&&connKeyToSourceNet.set(net.subcircuit_connectivity_map_key,net);let directConnections=[],boundaryTraceNetConnections=[],connectedPairKeys=new Set,crossScopeSourceTraceIdBySchematicPortIdAndNetId=new Map,crossSectionNetConnectionByKey=new Map,setCrossScopeSourceTraceId=({schematicPortId,netId,sourceTraceId,replaceExisting=!1})=>{let sourceTraceIdByNetId=crossScopeSourceTraceIdBySchematicPortIdAndNetId.get(schematicPortId)??new Map;return sourceTraceIdByNetId.has(netId)&&!replaceExisting?!1:(sourceTraceIdByNetId.set(netId,sourceTraceId),crossScopeSourceTraceIdBySchematicPortIdAndNetId.set(schematicPortId,sourceTraceIdByNetId),!0)},addPortToCrossSectionInlineNetConnection=({sourceConnectivityNetId,schematicPortId,text:text4,sourceTraceId,connKey,preferInScopeTraceMetadata=!1})=>{let netId=sourceConnectivityNetId;if(setCrossScopeSourceTraceId({schematicPortId,netId,sourceTraceId,replaceExisting:preferInScopeTraceMetadata}),schematicPortIdsWithExplicitNetLabels.has(schematicPortId))return;let connection=crossSectionNetConnectionByKey.get(sourceConnectivityNetId);connection?preferInScopeTraceMetadata&&(connection.netLabelText=text4,connection.netLabelWidth=Number(getSchematicNetLabelTextWidth2({text:text4}).toFixed(2)),connection.connKey=connKey??connection.connKey):(connection={netId,netLabelText:text4,schematicPortIds:[],netLabelWidth:Number(getSchematicNetLabelTextWidth2({text:text4}).toFixed(2)),connKey,isSameSheetCrossSectionConnection:!0,isPowerOrGroundConnection:powerOrGroundSourceConnectivityNetIds.has(netId)},crossSectionNetConnectionByKey.set(sourceConnectivityNetId,connection),boundaryTraceNetConnections.push(connection)),connection.schematicPortIds.includes(schematicPortId)||connection.schematicPortIds.push(schematicPortId)},sourceTraceIdsByPortOnlyLabelSchematicPortId=new Map,sourceTraceIdByPinPairKey=new Map,connKeysWithExplicitPortNetTraces=new Set;for(let sourceTrace of tracesInScope)sourceTrace?.subcircuit_connectivity_map_key&&(sourceTrace.connected_source_port_ids?.length??0)>0&&(sourceTrace.connected_source_net_ids?.length??0)>0&&connKeysWithExplicitPortNetTraces.add(sourceTrace.subcircuit_connectivity_map_key);let areSchematicPortsInDifferentSectionsOnSameSheet=(firstSchematicPortId,secondSchematicPortId)=>{let firstSchematicPort=db22.schematic_port.get(firstSchematicPortId),secondSchematicPort=db22.schematic_port.get(secondSchematicPortId);if(!firstSchematicPort||!secondSchematicPort||!(firstSchematicPort.schematic_sheet_id===secondSchematicPort.schematic_sheet_id))return!1;let firstSectionId=firstSchematicPort.schematic_component_id?sectionIdBySchematicComponentId.get(firstSchematicPort.schematic_component_id):void 0,secondSectionId=secondSchematicPort.schematic_component_id?sectionIdBySchematicComponentId.get(secondSchematicPort.schematic_component_id):void 0;return firstSectionId!==secondSectionId&&(firstSectionId!==void 0||secondSectionId!==void 0)},doesSourcePortCrossSectionOnSameSheet=({schematicPortId,otherSourcePortId})=>db22.schematic_port.list({source_port_id:otherSourcePortId}).some(otherSchematicPort=>areSchematicPortsInDifferentSectionsOnSameSheet(schematicPortId,asSchematicPortId(otherSchematicPort.schematic_port_id)));for(let st22 of tracesInScope){let connected=Array.from(new Set((st22.connected_source_port_ids??[]).map(sourcePortId=>sourcePortIdToSchPortId.get(asSourcePortId(sourcePortId))).filter(schematicPortId=>!!schematicPortId&&schematicPortIdsInScope.has(schematicPortId)).map(resolveRoutedSchematicPortId))),sourcePortIdForSingleConnectedEndpoint=connected.length===1?schPortIdToSourcePortId.get(connected[0]):void 0,otherSourcePortId=sourcePortIdForSingleConnectedEndpoint?st22.connected_source_port_ids.map(asSourcePortId).find(sourcePortId=>sourcePortId!==sourcePortIdForSingleConnectedEndpoint):void 0,crossesSchematicScopeBoundary=!!(sourcePortIdForSingleConnectedEndpoint&&otherSourcePortId&&isDirectConnectionEndpointOutsideSchematicScope({db:db22,sourcePortId:sourcePortIdForSingleConnectedEndpoint,otherSourcePortId,sourcePortIdsInSchematicScope,schematicSheetId:opts.schematicSheetId})),crossesSchematicSectionOnSameSheet=!!(connected.length===1&&otherSourcePortId&&doesSourcePortCrossSectionOnSameSheet({schematicPortId:connected[0],otherSourcePortId}));if(connected.length===1&&st22.connected_source_port_ids.length===2&&crossesSchematicScopeBoundary&&st22.connected_source_net_ids.length===0&&st22.subcircuit_connectivity_map_key){let schematicPortId=connected[0],sourcePortId=schPortIdToSourcePortId.get(schematicPortId);if(sourcePortId){let connKey=st22.subcircuit_connectivity_map_key,sourcePortConnKey=db22.source_port.get(sourcePortId)?.subcircuit_connectivity_map_key,sourceNetInCurrentSubcircuit=db22.source_net.list().find(sourceNet=>sourceNet.subcircuit_id===group2.subcircuit_id&&sourcePortConnectivityMap.areIdsConnected(sourceNet.source_net_id,sourcePortId)),sourceNetForLabel=connKeyToSourceNet.get(connKey)??(sourcePortConnKey?connKeyToSourceNet.get(sourcePortConnKey):void 0)??sourceNetInCurrentSubcircuit,connectedSourcePortIdsForKey=Array.from(schematicPortIdsInScope).map(portId=>schPortIdToSourcePortId.get(portId)).filter(sourcePortId2=>sourcePortId2?db22.source_port.get(sourcePortId2)?.subcircuit_connectivity_map_key===connKey:!1),{text:text4}=resolveNetLabelForPortMissingTrace({group:group2,sourcePortId,connectedSourcePortIdsForKey,sourcePortIdsInSchematicScope,schematicSheetId:opts.schematicSheetId,connKey,sourceNet:sourceNetForLabel});if(text4){let sourceConnectivityNetId=getSourceConnectivityNetId(st22);userNetIdToConnKey.has(sourceConnectivityNetId)||userNetIdToConnKey.set(sourceConnectivityNetId,connKey),crossesSchematicSectionOnSameSheet?addPortToCrossSectionInlineNetConnection({sourceConnectivityNetId,schematicPortId,text:text4,sourceTraceId:st22.source_trace_id,connKey}):setCrossScopeSourceTraceId({schematicPortId,netId:sourceConnectivityNetId,sourceTraceId:st22.source_trace_id})&&boundaryTraceNetConnections.push({netId:sourceConnectivityNetId,netLabelText:text4,schematicPortIds:[schematicPortId],netLabelWidth:Number(getSchematicNetLabelTextWidth2({text:text4}).toFixed(2)),connKey})}}}else if(connected.length>=2){for(let schematicPortId of connected){let sourceTraceIds=sourceTraceIdsByPortOnlyLabelSchematicPortId.get(schematicPortId)??new Set;sourceTraceIds.add(st22.source_trace_id),sourceTraceIdsByPortOnlyLabelSchematicPortId.set(schematicPortId,sourceTraceIds)}let traceLabel=st22.name??st22.display_name,userNetId=traceLabel??st22.source_trace_id;st22.subcircuit_connectivity_map_key&&userNetIdToConnKey.set(userNetId,st22.subcircuit_connectivity_map_key);let maxMspDist=group2._parsedProps.schMaxTraceDistance??DEFAULT_MAX_MSP_PAIR_DISTANCE2,portsForConnection=connected.map(schematicPortId=>componentPortBySchematicPortId.get(schematicPortId)).filter(port=>!!port),renderedNetLabelText=st22.subcircuit_connectivity_map_key?resolveCanonicalNetLabelText({subcircuitConnectivityMapKey:st22.subcircuit_connectivity_map_key}).name:getNetNameFromPorts(portsForConnection).name||traceLabel,shouldRenderNetLabels=connected.slice(1).some((b23,index2)=>{let a23=connected[index2],portA=db22.schematic_port.get(a23),portB=db22.schematic_port.get(b23);return!portA||!portB?!1:Math.sqrt((portA.center.x-portB.center.x)**2+(portA.center.y-portB.center.y)**2)>maxMspDist}),netLabelWidth=renderedNetLabelText&&shouldRenderNetLabels?Number(getSchematicNetLabelTextWidth2({text:renderedNetLabelText}).toFixed(2)):void 0,crossSectionNetLabelText=renderedNetLabelText;for(let i23=0;i23<connected.length-1;i23++){let a23=connected[i23],b23=connected[i23+1],pairKey=[a23,b23].sort().join("::");if(!connectedPairKeys.has(pairKey)){if(connectedPairKeys.add(pairKey),crossSectionNetLabelText&&areSchematicPortsInDifferentSectionsOnSameSheet(a23,b23)){let sourceConnectivityNetId=getSourceConnectivityNetId(st22);st22.subcircuit_connectivity_map_key&&userNetIdToConnKey.set(sourceConnectivityNetId,st22.subcircuit_connectivity_map_key),addPortToCrossSectionInlineNetConnection({sourceConnectivityNetId,schematicPortId:a23,text:crossSectionNetLabelText,sourceTraceId:st22.source_trace_id,connKey:st22.subcircuit_connectivity_map_key,preferInScopeTraceMetadata:!0}),addPortToCrossSectionInlineNetConnection({sourceConnectivityNetId,schematicPortId:b23,text:crossSectionNetLabelText,sourceTraceId:st22.source_trace_id,connKey:st22.subcircuit_connectivity_map_key,preferInScopeTraceMetadata:!0});continue}sourceTraceIdByPinPairKey.set(pairKey,st22.source_trace_id),directConnections.push({schematicPortIds:[a23,b23],netId:userNetId,netLabelWidth,connKey:st22.subcircuit_connectivity_map_key})}}}}let netConnections=[...boundaryTraceNetConnections],connKeyToSchematicPortIds=new Map;for(let[schId,srcPortId]of schPortIdToSourcePortId){if(schematicPortIdsWithExternallyRoutedRepresentations.has(schId))continue;let sp22=db22.source_port.get(srcPortId);if(!sp22?.subcircuit_connectivity_map_key)continue;let connKey=sp22.subcircuit_connectivity_map_key;connKeyToSchematicPortIds.has(connKey)||connKeyToSchematicPortIds.set(connKey,[]);let routedSchematicPortId=resolveRoutedSchematicPortId(schId),netSchematicPortIds=connKeyToSchematicPortIds.get(connKey);netSchematicPortIds.includes(routedSchematicPortId)||netSchematicPortIds.push(routedSchematicPortId)}for(let[connKey,schematicPortIds]of connKeyToSchematicPortIds){let sourceNet=connKeyToSourceNet.get(connKey);if(sourceNet&&schematicPortIds.length>=1){let userNetId=String(sourceNet.name||sourceNet.source_net_id||connKey);userNetIdToConnKey.set(userNetId,connKey);let netLabelTextWidth=Number(getSchematicNetLabelTextWidth2({text:String(userNetId)}).toFixed(2)),netLabelWidth=netLabelTextWidth,netLabelHeight;(sourceNet.is_ground||sourceNet.is_power)&&(netLabelWidth=SCHEMATIC_RAIL_NET_LABEL_HEIGHT,netLabelHeight=netLabelTextWidth),netConnections.push({netId:userNetId,schematicPortIds,isGround:sourceNet.is_ground,netLabelWidth,netLabelHeight,connKey})}}applyInlineNetLabelEligibility({directConnections,netConnections,connKeyToSchematicPortIds,connKeyToSourceNet,connKeysWithExplicitPortNetTraces,schematicPortIdsWithExplicitNetLabels,schematicPortIdsWithInlineNetLabels,areSchematicPortsOnDifferentComponents:schematicPortIds=>{let componentIds=schematicPortIds.map(schematicPortId=>db22.schematic_port.get(schematicPortId)?.schematic_component_id);return componentIds.every(componentId=>!!componentId)&&componentIds[0]!==componentIds[1]},resolveCanonicalNetLabelText});let availableNetLabelOrientations=(()=>{let netToAllowedOrientations={},presentNetIds=new Set(netConnections.map(nc3=>nc3.netId));for(let net of db22.source_net.list().filter(n23=>!n23.subcircuit_id||allowedSubcircuitIds.has(n23.subcircuit_id)))net.name&&presentNetIds.has(net.name)&&(net.is_ground?netToAllowedOrientations[net.name]=["y-"]:net.is_power?netToAllowedOrientations[net.name]=["y+"]:netToAllowedOrientations[net.name]=["x-","x+"]);for(let{netId}of boundaryTraceNetConnections)netToAllowedOrientations[netId]??(netToAllowedOrientations[netId]=["x-","x+"]);return netToAllowedOrientations})(),inputProblem={chips,directConnections:directConnections.map(({schematicPortIds,connKey,...connection})=>({...connection,pinIds:schematicPortIds})),netConnections:netConnections.map(({schematicPortIds,connKey,isSameSheetCrossSectionConnection,isPowerOrGroundConnection,...connection})=>({...connection,pinIds:schematicPortIds})),textBoxes,availableNetLabelOrientations,maxMspPairDistance:group2._parsedProps.schMaxTraceDistance??DEFAULT_MAX_MSP_PAIR_DISTANCE2},sourceTraceIdByPortOnlyLabelSchematicPortId=new Map(Array.from(sourceTraceIdsByPortOnlyLabelSchematicPortId).flatMap(([schematicPortId,sourceTraceIds])=>sourceTraceIds.size!==1?[]:[[schematicPortId,sourceTraceIds.values().next().value]]));return{inputProblem,routedSchematicPortIdBySchematicPortId,connKeyToSourceNet,userNetIdToConnKey,crossScopeSourceTraceIdBySchematicPortIdAndNetId,sourceTraceIdByPortOnlyLabelSchematicPortId,connKeysWithExplicitPortNetTraces,schematicPortIdsInScope,schematicPortIdsWithExternallyRoutedRepresentations,schPortIdToSourcePortId,netLabelsInScope,sourceTraceIdByPinPairKey}}var getSchematicPortIdsWithAssignedNetLabels=(netLabels,routedSchematicPortIdBySchematicPortId)=>{let schematicPortIdsWithNetLabels=new Set;for(let netLabel of netLabels){let{inline,schX,schY}=netLabel._parsedProps;if(inline||schX===void 0&&schY===void 0)continue;let netLabelPorts=netLabel._getConnectedPorts();for(let port of netLabelPorts)port.schematic_port_id&&schematicPortIdsWithNetLabels.add(routedSchematicPortIdBySchematicPortId.get(asSchematicPortId(port.schematic_port_id))??asSchematicPortId(port.schematic_port_id))}return schematicPortIdsWithNetLabels},getSchematicPortIdsWithRoutedTraces=({solver})=>{let solvedTraces=solver.traceCleanupSolver?.getOutput().traces??solver.traceLabelOverlapAvoidanceSolver?.getOutput().traces??solver.schematicTraceLinesSolver?.solvedTracePaths??[],schematicPortIdsWithRoutedTraces=new Set;for(let solvedTrace of solvedTraces){let points=solvedTrace?.tracePath;if(!Array.isArray(points)||points.length<2)continue;let pinIds=Array.isArray(solvedTrace.pins)?solvedTrace.pins.map(pin=>pin.pinId):solvedTrace.pinIds;for(let pinId of pinIds){let schPortId=asSchematicPortId(pinId);schPortId&&schematicPortIdsWithRoutedTraces.add(schPortId)}}return schematicPortIdsWithRoutedTraces},NEAR_EXISTING_NET_LABEL_DISTANCE=.5,SAME_ANCHOR_POSITION_DISTANCE=.1,doesSchematicNetLabelRepresentCurrentSourceConnection=args=>{let{nl:nl3,connKey,sourceNet,text:text4}=args;return sourceNet?.source_net_id&&nl3.source_net_id?nl3.source_net_id===sourceNet.source_net_id:nl3.source_net_id?nl3.source_net_id===connKey:nl3.text===text4},insertNetLabelsForPortsMissingTrace=({schematicPortIdsInScope,schematicPortIdsWithExternallyRoutedRepresentations,group:group2,schPortIdToSourcePortId,connKeyToSourceNet})=>{let{db:db22}=group2.root,sourcePortIdsInSchematicScope=new Set(Array.from(schematicPortIdsInScope).map(schematicPortId=>schPortIdToSourcePortId.get(schematicPortId)).filter(sourcePortId=>sourcePortId!==void 0));for(let schematicPortId of schematicPortIdsInScope){if(schematicPortIdsWithExternallyRoutedRepresentations.has(schematicPortId))continue;let schPort=db22.schematic_port.get(schematicPortId);if(!schPort||schPort.is_connected)continue;let srcPortId=schPortIdToSourcePortId.get(schematicPortId);if(!srcPortId)continue;let sourcePort=db22.source_port.get(srcPortId);if(group2._parsedProps.showAsSchematicBox&&sourcePort?.subcircuit_id===group2.subcircuit_id&&!sourcePort.source_component_id&&getDirectConnectionOutsideSchematicScopeSourcePortId({db:db22,sourcePortId:srcPortId,sourcePortIdsInSchematicScope,schematicSheetId:schPort.schematic_sheet_id}))continue;let connKey=sourcePort?.subcircuit_connectivity_map_key;if(!connKey)continue;let sourceNet=connKeyToSourceNet.get(connKey),schComponent=schPort.schematic_component_id?db22.schematic_component.get(schPort.schematic_component_id):void 0,portSchematicSheetId=schComponent?.schematic_sheet_id??group2._resolveSchematicSheetId(),connectedSourcePortIdsForKey=Array.from(schematicPortIdsInScope).map(portId=>schPortIdToSourcePortId.get(portId)).filter(sourcePortId=>sourcePortId?db22.source_port.get(sourcePortId)?.subcircuit_connectivity_map_key===connKey:!1),{text:text4,wasAssignedDisplayLabel,directConnectionOutsideSchematicScopeSourcePortId}=resolveNetLabelForPortMissingTrace({group:group2,sourcePortId:srcPortId,connectedSourcePortIdsForKey,sourcePortIdsInSchematicScope,schematicSheetId:schPort.schematic_sheet_id,connKey,sourceNet}),shouldPreserveDirectConnectionEndpointLabels=directConnectionOutsideSchematicScopeSourcePortId?db22.schematic_port.list({source_port_id:directConnectionOutsideSchematicScopeSourcePortId}).some(port=>!port.is_connected):!1,isCollapsedBoxPort=schComponent?.is_box_with_pins&&sourcePort&&!sourcePort.source_component_id,hasExternalTrace=db22.source_trace.list().some(trace=>trace.connected_source_port_ids.includes(srcPortId)&&trace.subcircuit_id!==sourcePort?.subcircuit_id);if(isCollapsedBoxPort&&!hasExternalTrace&&!!!(sourceNet||wasAssignedDisplayLabel))continue;let connectedPortCountForKey=Array.from(schematicPortIdsInScope).filter(portId=>{let sourcePortId=schPortIdToSourcePortId.get(portId);return sourcePortId?db22.source_port.get(sourcePortId)?.subcircuit_connectivity_map_key===connKey:!1}).length,isGndNet=sourceNet?.is_ground??!1,isPowerNet=!isGndNet&&(sourceNet?.is_power??!1),side;isGndNet?side="top":isPowerNet?side="bottom":side=getEnteringEdgeFromDirection(schPort.facing_direction||"right")||"right";let center2=computeSchematicNetLabelCenter({anchor_position:schPort.center,anchor_side:side,text:text4}),existingNetLabelForCurrentSourceConnection=db22.schematic_net_label.list().find(nl3=>nl3.schematic_sheet_id!==portSchematicSheetId?!1:doesSchematicNetLabelRepresentCurrentSourceConnection({nl:nl3,connKey,sourceNet,text:text4}));if(existingNetLabelForCurrentSourceConnection&&connectedPortCountForKey<=1&&!shouldPreserveDirectConnectionEndpointLabels){db22.schematic_net_label.update(existingNetLabelForCurrentSourceConnection.schematic_net_label_id,{text:text4,anchor_position:schPort.center,center:center2,anchor_side:side});continue}if(existingNetLabelForCurrentSourceConnection){let dx22=existingNetLabelForCurrentSourceConnection.anchor_position.x-schPort.center.x,dy22=existingNetLabelForCurrentSourceConnection.anchor_position.y-schPort.center.y;if(dx22*dx22+dy22*dy22<NEAR_EXISTING_NET_LABEL_DISTANCE*NEAR_EXISTING_NET_LABEL_DISTANCE){if(isGndNet){let anchor_side=existingNetLabelForCurrentSourceConnection.anchor_side??side;db22.schematic_net_label.update(existingNetLabelForCurrentSourceConnection.schematic_net_label_id,{text:text4,anchor_position:schPort.center,center:computeSchematicNetLabelCenter({anchor_position:schPort.center,anchor_side,text:text4}),anchor_side})}else if(!isPowerNet&&existingNetLabelForCurrentSourceConnection.text===text4){let anchor_side=existingNetLabelForCurrentSourceConnection.anchor_side??side;db22.schematic_net_label.update(existingNetLabelForCurrentSourceConnection.schematic_net_label_id,{text:text4,anchor_position:schPort.center,center:computeSchematicNetLabelCenter({anchor_position:schPort.center,anchor_side,text:text4}),anchor_side})}continue}if(db22.schematic_net_label.list().some(nl3=>{if(nl3.schematic_sheet_id!==portSchematicSheetId)return!1;let dx32=nl3.anchor_position.x-schPort.center.x,dy32=nl3.anchor_position.y-schPort.center.y;return dx32*dx32+dy32*dy32>=SAME_ANCHOR_POSITION_DISTANCE*SAME_ANCHOR_POSITION_DISTANCE?!1:doesSchematicNetLabelRepresentCurrentSourceConnection({nl:nl3,connKey,sourceNet,text:text4})}))continue}if(!sourceNet&&!shouldPreserveDirectConnectionEndpointLabels)for(let nl3 of db22.schematic_net_label.list()){if(nl3.source_net_id!==connKey||nl3.schematic_sheet_id!==portSchematicSheetId)continue;connectedSourcePortIdsForKey.some(sourcePortId=>{let schPortId=Array.from(schPortIdToSourcePortId.entries()).find(([,id3])=>id3===sourcePortId)?.[0],connectedSchPort;if(schPortId&&(connectedSchPort=db22.schematic_port.get(schPortId)),!connectedSchPort?.center||!nl3.anchor_position)return!1;let dx22=nl3.anchor_position.x-connectedSchPort.center.x,dy22=nl3.anchor_position.y-connectedSchPort.center.y;return dx22*dx22+dy22*dy22<SAME_ANCHOR_POSITION_DISTANCE*SAME_ANCHOR_POSITION_DISTANCE})||db22.schematic_net_label.delete(nl3.schematic_net_label_id)}let netLabel={text:text4,source_net_id:sourceNet?.source_net_id??connKey,anchor_position:schPort.center,center:center2,anchor_side:side,schematic_sheet_id:portSchematicSheetId};db22.schematic_net_label.insert(netLabel)}},debug11=(0,import_debug16.default)("Group_doInitialSchematicTraceRender"),renderSchematicTracesForSheet=({group:group2,schematicSheetId,netLabels})=>{let{inputProblem,routedSchematicPortIdBySchematicPortId,connKeyToSourceNet,schematicPortIdsInScope,schematicPortIdsWithExternallyRoutedRepresentations,schPortIdToSourcePortId,userNetIdToConnKey,crossScopeSourceTraceIdBySchematicPortIdAndNetId,sourceTraceIdByPortOnlyLabelSchematicPortId,connKeysWithExplicitPortNetTraces,netLabelsInScope,sourceTraceIdByPinPairKey}=createSchematicTraceSolverInputProblem(group2,{schematicSheetId,netLabels});if(inputProblem.chips.length===0)return;let schematicPortIdsWithPreExistingNetLabels=getSchematicPortIdsWithAssignedNetLabels(netLabelsInScope,routedSchematicPortIdBySchematicPortId);if(!(inputProblem.directConnections.length>0||inputProblem.netConnections.length>0)){insertNetLabelsForPortsMissingTrace({group:group2,schematicPortIdsInScope,schematicPortIdsWithExternallyRoutedRepresentations,schPortIdToSourcePortId,connKeyToSourceNet});return}debug11.enabled&&group2.root?.emit("debug:logOutput",{type:"debug:logOutput",name:"group-trace-render-input-problem",content:JSON.stringify(inputProblem,null,2)});let solver=new SchematicTracePipelineSolver(inputProblem),solverConstructorArgs=solver.getConstructorParams();group2.root?.emit("solver:started",{type:"solver:started",solverName:"SchematicTracePipelineSolver",solverParams:solverConstructorArgs[0],solverConstructorArgs,componentName:group2.getString()}),solver.solve();let schematicPortIdsWithRoutedTraces=getSchematicPortIdsWithRoutedTraces({solver});applyTracesFromSolverOutput({group:group2,solver,userNetIdToConnKey,schematicPortIdsWithPreExistingNetLabels,schematicSheetId}),applyNetLabelPlacements({group:group2,routedSchematicPortIdBySchematicPortId,solver,connKeyToSourceNet,userNetIdToConnKey,crossScopeSourceTraceIdBySchematicPortIdAndNetId,sourceTraceIdByPortOnlyLabelSchematicPortId,connKeysWithExplicitPortNetTraces,schematicPortIdsWithPreExistingNetLabels,schematicPortIdsWithRoutedTraces,netLabels:netLabelsInScope}),applyInlineNetLabelPlacements({group:group2,solver,userNetIdToConnKey,sourceTraceIdByPinPairKey,crossScopeSourceTraceIdBySchematicPortIdAndNetId});let{db:db22}=group2.root;for(let[schematicPortId,routedSchematicPortId]of routedSchematicPortIdBySchematicPortId)db22.schematic_port.get(routedSchematicPortId)?.is_connected&&db22.schematic_port.update(schematicPortId,{is_connected:!0});insertNetLabelsForPortsMissingTrace({group:group2,schematicPortIdsInScope,schematicPortIdsWithExternallyRoutedRepresentations,schPortIdToSourcePortId,connKeyToSourceNet})},Group_doInitialSchematicTraceRender=group2=>{if(!group2.root?._featureMspSchematicTraceRouting||!group2.isSubcircuit||group2.root?.schematicDisabled)return;let netLabels=new Set,board=group2._getBoard(),schematicScope=group2;for(;schematicScope;){if(schematicScope instanceof Group)for(let netLabel of schematicScope.selectAll("netlabel"))netLabels.add(netLabel);if(schematicScope===board)break;schematicScope=schematicScope.parent}let netLabelComponents=[...netLabels],schematicGroupIds=new Set([group2,...group2.getDescendants().filter(component=>component instanceof Group)].map(schematicGroup=>schematicGroup.schematic_group_id).filter(schematicGroupId=>!!schematicGroupId)),schematicSheetIds=new Set(group2.root.db.schematic_component.list().filter(schematicComponent=>schematicGroupIds.has(schematicComponent.schematic_group_id)).map(schematicComponent=>schematicComponent.schematic_sheet_id).filter(schematicSheetId=>!!schematicSheetId));if(schematicSheetIds.size===0){renderSchematicTracesForSheet({group:group2,netLabels:netLabelComponents});return}for(let schematicSheetId of schematicSheetIds)renderSchematicTracesForSheet({group:group2,schematicSheetId,netLabels:netLabelComponents})};function getTransientVoltageGraphNamesFromSpiceNetlist(spiceNetlist){let graphNames=[];for(let printStatement of spiceNetlist.printStatements){let match2=printStatement.match(/^\.PRINT\s+TRAN\s+(.+)$/i);if(match2)for(let voltageExpression of match2[1].match(/V\(([^)]+)\)/g)??[]){let nodeList=voltageExpression.slice(2,-1);graphNames.push(nodeList.replace(",","-"))}}return graphNames}var SIMULATION_COLOR_PALETTE=["rgb(0, 150, 0)","rgb(0, 0, 220)","rgb(220, 0, 0)","rgb(0, 160, 160)","rgb(180, 0, 180)","rgb(170, 140, 0)","rgb(220, 120, 0)","rgb(128, 128, 128)","rgb(100, 0, 180)","rgb(140, 70, 0)","rgb(220, 80, 120)","rgb(0, 120, 220)","rgb(0, 120, 120)","rgb(120, 0, 0)","rgb(0, 0, 132)","rgb(80, 80, 80)"],idToColorMap=new Map,colorIndex=0;function getSimulationColorForId(id3){if(idToColorMap.has(id3))return idToColorMap.get(id3);let color32=SIMULATION_COLOR_PALETTE[colorIndex];return colorIndex=(colorIndex+1)%SIMULATION_COLOR_PALETTE.length,idToColorMap.set(id3,color32),color32}function resetSimulationColorState(){idToColorMap.clear(),colorIndex=0}var getSpiceyEngine=()=>({async simulate(spiceString){let simulation_experiment_id="spice-experiment-1",{circuit:parsedCircuit,tran}=simulate(spiceString);return{simulationResultCircuitJson:spiceyTranToVGraphs(tran,parsedCircuit,simulation_experiment_id)}}}),isCurrentGraph2=element2=>element2.type==="simulation_transient_current_graph",isSimulationCurrentResult=circuitElement=>circuitElement.type==="simulation_dc_operating_point_current"||circuitElement.type==="simulation_dc_sweep_current_graph"||circuitElement.type==="simulation_ac_sweep_current_graph",isSimulationVoltageResult=circuitElement=>circuitElement.type==="simulation_dc_operating_point_voltage"||circuitElement.type==="simulation_dc_sweep_voltage_graph"||circuitElement.type==="simulation_ac_sweep_voltage_graph",isVoltageGraph=element2=>element2.type==="simulation_transient_voltage_graph",isSimulationAnalysisResult2=circuitElement=>isVoltageGraph(circuitElement)||isCurrentGraph2(circuitElement)||isSimulationVoltageResult(circuitElement)||isSimulationCurrentResult(circuitElement),attachSweepCoordinateToSimulationResult=({simulationResult,simulationParameterSweepCoordinate})=>{if(!simulationParameterSweepCoordinate||!isSimulationAnalysisResult2(simulationResult))return simulationResult;let simulationResultWithSweepCoordinate={...simulationResult},simulationResultIdKey=`${simulationResultWithSweepCoordinate.type}_id`;return Reflect.deleteProperty(simulationResultWithSweepCoordinate,simulationResultIdKey),simulationResultWithSweepCoordinate.simulation_parameter_sweep_coordinate=simulationParameterSweepCoordinate,simulationResultWithSweepCoordinate},getSourceComponentOrThrow=({circuitJson,sourceComponentId,isMatchingSourceComponent})=>{let sourceComponent=circuitJson.find(circuitElement=>isMatchingSourceComponent(circuitElement)&&circuitElement.source_component_id===sourceComponentId);if(!sourceComponent)throw new Error(`Parameter sweep target ${sourceComponentId} was not found`);return sourceComponent},applyParameterSweepCoordinate=({circuitJson,parameterSweep,simulationParameterSweepCoordinate})=>{let sweptCircuitJson=structuredClone(circuitJson),parameterValue=simulationParameterSweepCoordinate.parameter_value;if(parameterSweep.parameter_type==="resistance"){let resistor=getSourceComponentOrThrow({circuitJson:sweptCircuitJson,sourceComponentId:parameterSweep.resistor_source_component_id,isMatchingSourceComponent:circuitElement=>circuitElement.type==="source_component"&&circuitElement.ftype==="simple_resistor"});return resistor.resistance=parameterValue,sweptCircuitJson}if(parameterSweep.parameter_type==="capacitance"){let capacitor=getSourceComponentOrThrow({circuitJson:sweptCircuitJson,sourceComponentId:parameterSweep.capacitor_source_component_id,isMatchingSourceComponent:circuitElement=>circuitElement.type==="source_component"&&circuitElement.ftype==="simple_capacitor"});return capacitor.capacitance=parameterValue,sweptCircuitJson}if(parameterSweep.parameter_type==="inductance"){let inductor=getSourceComponentOrThrow({circuitJson:sweptCircuitJson,sourceComponentId:parameterSweep.inductor_source_component_id,isMatchingSourceComponent:circuitElement=>circuitElement.type==="source_component"&&circuitElement.ftype==="simple_inductor"});return inductor.inductance=parameterValue,sweptCircuitJson}if(parameterSweep.parameter_type==="voltage"){let groundNet=sweptCircuitJson.find(circuitElement=>circuitElement.type==="source_net"&&circuitElement.name.toUpperCase()==="GND");if(!groundNet||groundNet.type!=="source_net")throw new Error("A voltage parameter sweep requires a GND net");let sweepVoltageSource={type:"simulation_voltage_source",simulation_voltage_source_id:`simulation_voltage_source_${simulationParameterSweepCoordinate.simulation_parameter_sweep_id}_${simulationParameterSweepCoordinate.sweep_index}`,is_dc_source:!0,positive_source_net_id:parameterSweep.source_net_id,negative_source_net_id:groundNet.source_net_id,voltage:parameterValue};return sweptCircuitJson.push(sweepVoltageSource),sweptCircuitJson}if(parameterSweep.parameter_type==="current"){let currentSourcePortIds=new Set(sweptCircuitJson.filter(circuitElement=>circuitElement.type==="source_port"&&circuitElement.source_component_id===parameterSweep.current_source_component_id).map(sourcePort=>sourcePort.source_port_id)),currentSource=sweptCircuitJson.find(circuitElement=>circuitElement.type==="simulation_current_source"&&(circuitElement.is_dc_source?!!(circuitElement.positive_source_port_id&&currentSourcePortIds.has(circuitElement.positive_source_port_id)):!!(circuitElement.terminal1_source_port_id&&currentSourcePortIds.has(circuitElement.terminal1_source_port_id))));if(!currentSource)throw new Error(`Current sweep target ${parameterSweep.current_source_component_id} has no simulation source`);return currentSource.current=parameterValue,sweptCircuitJson}throw new Error("Parameter sweep target is incomplete")},createSimulationRun=({circuitJson,simulationParameterSweepCoordinate})=>{let spiceNetlist=circuitJsonToSpice(circuitJson);return{spiceNetlist,spiceString:spiceNetlist.toSpiceString(),simulationParameterSweepCoordinate}},createSimulationRuns=({circuitJson,simulationExperimentId})=>{let parameterSweep=circuitJson.find(circuitElement=>circuitElement.type==="simulation_parameter_sweep"&&circuitElement.simulation_experiment_id===simulationExperimentId);return parameterSweep?parameterSweep.parameter_values.map((parameterValue,sweepIndex)=>{let simulationParameterSweepCoordinate={simulation_parameter_sweep_id:parameterSweep.simulation_parameter_sweep_id,sweep_index:sweepIndex,parameter_value:parameterValue,parameter_unit:parameterSweep.parameter_unit};return createSimulationRun({circuitJson:applyParameterSweepCoordinate({circuitJson,parameterSweep,simulationParameterSweepCoordinate}),simulationParameterSweepCoordinate})}):[createSimulationRun({circuitJson})]},SI_PREFIX_MULTIPLIERS={p:1e-12,n:1e-9,u:1e-6,\u00B5:1e-6,m:.001,"":1,k:1e3,K:1e3,M:1e6,G:1e9},parseSimulationGraphValue=value=>{if(value===void 0)return;if(typeof value=="number")return value;let match2=value.trim().match(/^([+-]?(?:\d+(?:\.\d*)?|\.\d+))\s*([pnumµkKMG]?)/);if(!match2)return;let numericValue=Number(match2[1]);if(Number.isFinite(numericValue))return numericValue*(SI_PREFIX_MULTIPLIERS[match2[2]??""]??1)},getVoltageProbeGraphDisplayOverrides=probe=>{let{graphDisplayName,graphCenter,graphVerticalOffset,graphVoltagePerDiv}=probe._parsedProps;return{displayName:graphDisplayName,color:probe.color??void 0,center:graphCenter,verticalOffset:parseSimulationGraphValue(graphVerticalOffset),valuePerDiv:parseSimulationGraphValue(graphVoltagePerDiv)}},getAmmeterGraphDisplayOverrides=ammeter=>{let{color:color32,graphDisplayName,graphCenter,graphVerticalOffset,graphCurrentPerDiv}=ammeter._parsedProps;return{displayName:graphDisplayName,color:color32,center:graphCenter,verticalOffset:parseSimulationGraphValue(graphVerticalOffset),valuePerDiv:parseSimulationGraphValue(graphCurrentPerDiv)}},getFiniteBounds=values2=>{let min4=Number.POSITIVE_INFINITY,max5=Number.NEGATIVE_INFINITY;for(let value of values2)Number.isFinite(value)&&(min4=Math.min(min4,value),max5=Math.max(max5,value));return min4===Number.POSITIVE_INFINITY||max5===Number.NEGATIVE_INFINITY?null:{min:min4,max:max5}},getGraphLevels2=graph=>graph.type==="simulation_transient_current_graph"?graph.current_levels:graph.voltage_levels,DISPLAY_SECTION_HEIGHT_DIVS=2,DISPLAY_SECTION_DATA_FILL=.8,getAutoDisplayScale=({graph,index:index2,graphCount})=>{let bounds=getFiniteBounds(getGraphLevels2(graph));if(!bounds)return null;let center2=(bounds.min+bounds.max)/2,span=bounds.max-bounds.min,valuePerDiv=span>0?span/(DISPLAY_SECTION_HEIGHT_DIVS*DISPLAY_SECTION_DATA_FILL):Math.max(Math.abs(center2)/10,Number.EPSILON);return{display_center_value:center2,display_center_offset_divs:((graphCount-1)/2-index2)*DISPLAY_SECTION_HEIGHT_DIVS,value_per_div:valuePerDiv}},isDefinedString=value=>value!==void 0,getTraceByVoltageProbeId=traces=>{let traceByVoltageProbeId=new Map;for(let trace of traces)trace.simulation_voltage_probe_id&&traceByVoltageProbeId.set(trace.simulation_voltage_probe_id,trace);return traceByVoltageProbeId},getTraceByCurrentProbeId=traces=>{let traceByCurrentProbeId=new Map;for(let trace of traces)trace.simulation_current_probe_id&&traceByCurrentProbeId.set(trace.simulation_current_probe_id,trace);return traceByCurrentProbeId},insertIndependentAxisScopeTraces=({db:db22,graphs,graphDisplayOverridesByProbeId})=>{if(graphs.length===0)return;let existingScopeTraces=db22.simulation_oscilloscope_trace.list(),traceByVoltageProbeId=getTraceByVoltageProbeId(existingScopeTraces),traceByCurrentProbeId=getTraceByCurrentProbeId(existingScopeTraces),graphIdsWithTrace=new Set(existingScopeTraces.flatMap(trace=>[trace.simulation_transient_voltage_graph_id,trace.simulation_transient_current_graph_id]).filter(isDefinedString));for(let[index2,{type,graph}]of graphs.entries()){let scale52=getAutoDisplayScale({graph,index:index2,graphCount:graphs.length});if(!scale52)continue;let graphId=type==="voltage"?graph.simulation_transient_voltage_graph_id:graph.simulation_transient_current_graph_id;if(graphIdsWithTrace.has(graphId))continue;let sourceProbeId=graph.source_probe_id??void 0,probeTrace=sourceProbeId===void 0?void 0:type==="voltage"?traceByVoltageProbeId.get(sourceProbeId):traceByCurrentProbeId.get(sourceProbeId),overrides=sourceProbeId===void 0?void 0:graphDisplayOverridesByProbeId?.get(sourceProbeId),valuePerDiv=overrides?.valuePerDiv??scale52.value_per_div,displayCenter=overrides?.center??scale52.display_center_value,displayCenterOffsetDivs=overrides?.verticalOffset!==void 0&&valuePerDiv!==0?overrides.verticalOffset/valuePerDiv:probeTrace?.display_center_offset_divs??scale52.display_center_offset_divs;db22.simulation_oscilloscope_trace.insert({...type==="voltage"?{simulation_transient_voltage_graph_id:graph.simulation_transient_voltage_graph_id,volts_per_div:valuePerDiv}:{simulation_transient_current_graph_id:graph.simulation_transient_current_graph_id,amps_per_div:valuePerDiv},display_name:overrides?.displayName??probeTrace?.display_name,color:overrides?.color??probeTrace?.color??graph.color,display_center_value:displayCenter,display_center_offset_divs:displayCenterOffsetDivs})}},isCircuitElementInput=element2=>!!(element2&&typeof element2=="object"&&"type"in element2),debug12=(0,import_debug20.default)("tscircuit:core:Group_doInitialSimulationSpiceEngineRender"),getCircuitJsonForAnalogSimulation=({circuitJson,simulationExperimentId,voltageProbes,ammeters})=>{let voltageProbeIds=new Set(voltageProbes.map(voltageProbe=>voltageProbe.simulation_voltage_probe_id).filter(simulationVoltageProbeId=>!!simulationVoltageProbeId)),currentProbeIds=new Set(ammeters.map(ammeter=>ammeter.simulation_current_probe_id).filter(simulationCurrentProbeId=>!!simulationCurrentProbeId));return circuitJson.filter(element2=>{if(element2.type==="simulation_experiment")return element2.simulation_experiment_id===simulationExperimentId;if(element2.type==="simulation_voltage_probe")return voltageProbeIds.has(element2.simulation_voltage_probe_id);if(element2.type==="simulation_current_probe")return currentProbeIds.has(element2.simulation_current_probe_id);if(element2.type==="simulation_parameter_sweep")return element2.simulation_experiment_id===simulationExperimentId;if(element2.type==="simulation_oscilloscope_trace"){if(element2.simulation_voltage_probe_id)return voltageProbeIds.has(element2.simulation_voltage_probe_id);if(element2.simulation_current_probe_id)return currentProbeIds.has(element2.simulation_current_probe_id)}return!(element2.type==="simulation_transient_voltage_graph"||element2.type==="simulation_transient_current_graph"||element2.type==="simulation_dc_operating_point_voltage"||element2.type==="simulation_dc_operating_point_current"||element2.type==="simulation_dc_sweep_voltage_graph"||element2.type==="simulation_dc_sweep_current_graph"||element2.type==="simulation_ac_sweep_voltage_graph"||element2.type==="simulation_ac_sweep_current_graph"||element2.type==="simulation_unknown_experiment_error")})};function Group_doInitialSimulationSpiceEngineRender(group2){if(group2.getInheritedProperty("analogSimulationDisabled")||!group2.isSubcircuit)return;let{root}=group2;if(!root)return;let analogSimulations=[...group2.selectAll("analogsimulation"),...group2.selectAll("analogtransientsimulation"),...group2.selectAll("analogdcoperatingpointsimulation"),...group2.selectAll("analogdcsweepsimulation"),...group2.selectAll("analogacsweepsimulation")];if(analogSimulations.length===0)return;resetSimulationColorState();let spiceEngineMap={...root.platform?.spiceEngineMap};spiceEngineMap.spicey||(spiceEngineMap.spicey=getSpiceyEngine());for(let analogSimulation of analogSimulations){let simulationExperimentId=analogSimulation.simulation_experiment_id;if(!simulationExperimentId){debug12("No simulation experiment id found, skipping simulation");continue}let simulationExperiment=root.db.simulation_experiment.get(simulationExperimentId);if(!simulationExperiment){debug12("No simulation experiment found, skipping simulation");continue}if(simulationExperiment.spice_engine==="pcb_spice"&&(!spiceEngineMap.pcb_spice||isExternalIbisExperiment(root.db,simulationExperimentId))){debug12("Skipping external pcb_spice experiment during rendering");continue}let simulationScope=analogSimulation.getGroup()??group2,voltageProbes=simulationScope.selectAll("voltageprobe"),ammeters=simulationScope.selectAll("ammeter"),circuitJson=getCircuitJsonForAnalogSimulation({circuitJson:root.db.toArray(),simulationExperimentId,voltageProbes,ammeters}),simulationRuns;try{simulationRuns=createSimulationRuns({circuitJson,simulationExperimentId}),debug12(`Generated ${simulationRuns.length} SPICE run(s):
1047
1047
  ${simulationRuns.map(simulationRun=>simulationRun.spiceString).join(`
1048
- `)}`)}catch(error2){debug12(`Failed to convert circuit JSON to SPICE: ${error2}`),root.db.simulation_unknown_experiment_error.insert({simulation_experiment_id:simulationExperimentId,error_type:"simulation_unknown_experiment_error",message:error2 instanceof Error?error2.message:String(error2)});continue}let voltageProbeByGraphName=new Map,voltageProbeById=new Map,graphDisplayOverridesByProbeId=new Map;for(let probe of voltageProbes)probe.finalProbeName&&voltageProbeByGraphName.set(probe.finalProbeName,probe),probe.simulation_voltage_probe_id&&(voltageProbeById.set(probe.simulation_voltage_probe_id,probe),graphDisplayOverridesByProbeId.set(probe.simulation_voltage_probe_id,getVoltageProbeGraphDisplayOverrides(probe)));for(let ammeter of ammeters)ammeter.simulation_current_probe_id&&graphDisplayOverridesByProbeId.set(ammeter.simulation_current_probe_id,getAmmeterGraphDisplayOverrides(ammeter));let scopedCurrentProbeIds=new Set(ammeters.map(ammeter=>ammeter.simulation_current_probe_id).filter(simulationCurrentProbeId=>!!simulationCurrentProbeId)),currentProbeById=new Map,currentProbeByName=new Map;for(let probe of root.db.simulation_current_probe.list().filter(probe2=>scopedCurrentProbeIds.has(probe2.simulation_current_probe_id)))currentProbeById.set(probe.simulation_current_probe_id,probe),probe.name!==void 0&&currentProbeByName.set(probe.name,probe);let orderedSimulationProbes=root.db.simulation_voltage_probe.list().filter(probe=>voltageProbeById.has(probe.simulation_voltage_probe_id)),firstSpiceNetlist=simulationRuns[0]?.spiceNetlist,graphNamesFromNetlist=firstSpiceNetlist?getTransientVoltageGraphNamesFromSpiceNetlist(firstSpiceNetlist):[];if(graphNamesFromNetlist.length===orderedSimulationProbes.length)for(let[simulationProbeIndex,simulationProbe]of orderedSimulationProbes.entries()){let probe=voltageProbeById.get(simulationProbe.simulation_voltage_probe_id),graphName=graphNamesFromNetlist[simulationProbeIndex];probe&&graphName&&voltageProbeByGraphName.set(graphName,probe)}else debug12(`Skipping probe-to-graph order mapping because counts differ: probes=${orderedSimulationProbes.length} graphNames=${graphNamesFromNetlist.length}`);let engineName=analogSimulation.getSpiceEngineName()??"spicey",spiceEngine3=spiceEngineMap[engineName];if(!spiceEngine3)throw new Error(`SPICE engine "${engineName}" not found in platform config. Available engines: ${JSON.stringify(Object.keys(spiceEngineMap).filter(spiceEngineName=>spiceEngineName!=="spicey"))}`);let effectId=`spice-simulation-${engineName}-${simulationExperimentId}`;debug12(`Queueing simulation for spice engine: ${engineName} (id: ${effectId})`),group2._queueAsyncEffect(effectId,async()=>{try{let insertedVoltageGraphs=[],insertedCurrentGraphs=[];for(let simulationRun of simulationRuns){debug12(`Running simulation with engine: ${engineName}`);let simulationResult=await spiceEngine3.simulate(simulationRun.spiceString);debug12(`Simulation completed, received ${simulationResult.simulationResultCircuitJson.length} elements`);for(let simulationResultCircuitElement of simulationResult.simulationResultCircuitJson){if(!isCircuitElementInput(simulationResultCircuitElement)){debug12("Skipping invalid simulation result element");continue}let simulationResultWithSweepCoordinate=attachSweepCoordinateToSimulationResult({simulationResult:simulationResultCircuitElement,simulationParameterSweepCoordinate:simulationRun.simulationParameterSweepCoordinate});if(isVoltageGraph(simulationResultWithSweepCoordinate)){simulationResultWithSweepCoordinate.simulation_experiment_id=simulationExperiment.simulation_experiment_id;let probeMatch=simulationResultWithSweepCoordinate.name?voltageProbeByGraphName.get(simulationResultWithSweepCoordinate.name):void 0;probeMatch&&(simulationResultWithSweepCoordinate.color=probeMatch.color??void 0,simulationResultWithSweepCoordinate.source_probe_id=probeMatch.simulation_voltage_probe_id??void 0)}else if(isSimulationVoltageResult(simulationResultWithSweepCoordinate)){simulationResultWithSweepCoordinate.simulation_experiment_id=simulationExperiment.simulation_experiment_id;let probeMatch=voltageProbeById.get(simulationResultWithSweepCoordinate.simulation_voltage_probe_id)??(simulationResultWithSweepCoordinate.name?voltageProbeByGraphName.get(simulationResultWithSweepCoordinate.name):void 0);probeMatch?.simulation_voltage_probe_id&&(simulationResultWithSweepCoordinate.color=probeMatch.color??void 0,simulationResultWithSweepCoordinate.simulation_voltage_probe_id=probeMatch.simulation_voltage_probe_id)}if(isCurrentGraph2(simulationResultWithSweepCoordinate)){simulationResultWithSweepCoordinate.simulation_experiment_id=simulationExperiment.simulation_experiment_id;let probeMatch=(simulationResultWithSweepCoordinate.source_probe_id?currentProbeById.get(simulationResultWithSweepCoordinate.source_probe_id):void 0)??(simulationResultWithSweepCoordinate.name?currentProbeByName.get(simulationResultWithSweepCoordinate.name):void 0);probeMatch&&(simulationResultWithSweepCoordinate.color=probeMatch.color,simulationResultWithSweepCoordinate.source_probe_id=probeMatch.simulation_current_probe_id)}else if(isSimulationCurrentResult(simulationResultWithSweepCoordinate)){simulationResultWithSweepCoordinate.simulation_experiment_id=simulationExperiment.simulation_experiment_id;let probeMatch=currentProbeById.get(simulationResultWithSweepCoordinate.simulation_current_probe_id)??(simulationResultWithSweepCoordinate.name?currentProbeByName.get(simulationResultWithSweepCoordinate.name):void 0);probeMatch&&(simulationResultWithSweepCoordinate.color=probeMatch.color,simulationResultWithSweepCoordinate.simulation_current_probe_id=probeMatch.simulation_current_probe_id)}let insertedSimulationResult=root.db.insert(simulationResultWithSweepCoordinate);isVoltageGraph(insertedSimulationResult)&&insertedVoltageGraphs.push({type:"voltage",graph:insertedSimulationResult}),isCurrentGraph2(insertedSimulationResult)&&insertedCurrentGraphs.push({type:"current",graph:insertedSimulationResult}),debug12(`Inserted ${simulationResultWithSweepCoordinate.type} into database`)}}analogSimulation.usesIndependentGraphAxes()&&insertIndependentAxisScopeTraces({db:root.db,graphs:[...insertedVoltageGraphs,...insertedCurrentGraphs],graphDisplayOverridesByProbeId}),group2._markDirty("SimulationSpiceEngineRender")}catch(error2){debug12(`Simulation failed for engine ${engineName}: ${error2}`),root.db.simulation_unknown_experiment_error.insert({simulation_experiment_id:simulationExperimentId,error_type:"simulation_unknown_experiment_error",message:error2 instanceof Error?error2.message:String(error2)})}})}}function isExternalIbisExperiment(db22,simulationExperimentId){let belongsToExperiment=record=>record.simulation_experiment_id===simulationExperimentId;return db22.simulation_ibis_pin_state.list().some(belongsToExperiment)||db22.simulation_digital_stimulus.list().some(belongsToExperiment)||db22.simulation_eye_diagram.list().some(belongsToExperiment)}function Group_doInitialSourceAddConnectivityMapKey(group2){if(!group2.isSubcircuit)return;let{db:db22}=group2.root,traces=group2.selectAll("trace"),vias=group2.selectAll("via"),nets=group2.selectAll("net"),connMap=new ConnectivityMap({});connMap.addConnections(traces.map(t48=>{let source_trace23=db22.source_trace.get(t48.source_trace_id);return source_trace23?[source_trace23.source_trace_id,...source_trace23.connected_source_port_ids,...source_trace23.connected_source_net_ids]:null}).filter(c23=>c23!==null));let sourceNets=db22.source_net.list().filter(net=>net.subcircuit_id===group2.subcircuit_id);for(let sourceNet of sourceNets)connMap.addConnections([[sourceNet.source_net_id]]);let{name:subcircuitName}=group2._parsedProps;for(let trace of traces){if(!trace.source_trace_id)continue;let connNetId=connMap.getNetConnectedToId(trace.source_trace_id);connNetId&&(trace.subcircuit_connectivity_map_key=`${subcircuitName??`unnamedsubcircuit${group2.subcircuit_id??group2.source_group_id??group2._renderId}`}_${connNetId}`,db22.source_trace.update(trace.source_trace_id,{subcircuit_connectivity_map_key:trace.subcircuit_connectivity_map_key}))}let allSourcePortIds=new Set;for(let trace of traces){if(!trace.source_trace_id)continue;let source_trace23=db22.source_trace.get(trace.source_trace_id);if(source_trace23)for(let id3 of source_trace23.connected_source_port_ids)allSourcePortIds.add(id3)}for(let portId of allSourcePortIds){let connNetId=connMap.getNetConnectedToId(portId);if(!connNetId)continue;let connectivityMapKey=`${subcircuitName??`unnamedsubcircuit${group2.subcircuit_id??group2.source_group_id??group2._renderId}`}_${connNetId}`;db22.source_port.update(portId,{subcircuit_connectivity_map_key:connectivityMapKey})}let allSourceNetIds=new Set;for(let trace of traces){if(!trace.source_trace_id)continue;let source_trace23=db22.source_trace.get(trace.source_trace_id);if(source_trace23)for(let source_net_id of source_trace23.connected_source_net_ids)allSourceNetIds.add(source_net_id)}for(let sourceNet of sourceNets)allSourceNetIds.add(sourceNet.source_net_id);for(let netId of allSourceNetIds){let connNetId=connMap.getNetConnectedToId(netId);if(!connNetId)continue;let connectivityMapKey=`${subcircuitName??`unnamedsubcircuit${group2.subcircuit_id??group2.source_group_id??group2._renderId}`}_${connNetId}`;db22.source_net.update(netId,{subcircuit_connectivity_map_key:connectivityMapKey});let netInstance=nets.find(n23=>n23.source_net_id===netId);netInstance&&(netInstance.subcircuit_connectivity_map_key=connectivityMapKey)}for(let via of vias){let connectedNetOrTrace=via._getConnectedNetOrTrace();connectedNetOrTrace&&connectedNetOrTrace.subcircuit_connectivity_map_key&&(via.subcircuit_connectivity_map_key=connectedNetOrTrace.subcircuit_connectivity_map_key)}}var Group_doInitialStandaloneSubcircuitPcbDesignRuleChecks=group2=>{let isRootSubcircuit=group2.root?.firstChild===group2;if(!group2.isSubcircuit||!isRootSubcircuit||group2._getBoard())return;let routingDisabled=group2.root?.pcbRoutingDisabled||group2.getInheritedProperty("routingDisabled"),drcChecksDisabled=group2.root?.platform?.drcChecksDisabled??group2.getInheritedProperty("drcChecksDisabled"),routingDrcChecksDisabled=group2.root?.platform?.routingDrcChecksDisabled??group2.getInheritedProperty("routingDrcChecksDisabled");if(group2.root?.pcbDisabled||routingDisabled||drcChecksDisabled||routingDrcChecksDisabled||group2._hasIncompleteAsyncEffectsInSubtreeForPhase("PcbTraceRender")||group2._hasTracesToRoute()&&!group2._areChildSubcircuitsRouted()||group2._standaloneSubcircuitDrcChecksComplete||group2._standaloneSubcircuitDrcChecksInProgress)return;let{db:db22}=group2.root,subcircuitCircuitJson=db22.subtree({subcircuit_id:group2.subcircuit_id}).toArray(),panelComponent=getOwningPanel(group2),panel=panelComponent?.pcb_panel_id?db22.pcb_panel.get(panelComponent.pcb_panel_id):void 0,routingCircuitJson=panel?subcircuitCircuitJson.filter(element2=>element2.type!=="pcb_board"):subcircuitCircuitJson;panel&&routingCircuitJson.push({type:"pcb_board",pcb_board_id:panel.pcb_panel_id,center:panel.center,width:panel.width,height:panel.height,thickness:panel.thickness,num_layers:2,material:"fr4"}),group2._standaloneSubcircuitDrcChecksInProgress=!0,group2._queueAsyncEffect("standalone-subcircuit:routing-drc-checks",async()=>{try{let results=await runAllRoutingChecks(routingCircuitJson);db22.insertAll(dedupePcbDrcErrors(results)),group2._standaloneSubcircuitDrcChecksComplete=!0}finally{group2._standaloneSubcircuitDrcChecksInProgress=!1}})},addPourNetMap=(target,pourNetMap)=>{for(let[layer,netOrNets]of Object.entries(pourNetMap)){if(!netOrNets)continue;let nets=Array.isArray(netOrNets)?netOrNets:[netOrNets],layerNets=target.get(layer)??new Set;for(let net of nets)layerNets.add(net);target.set(layer,layerNets)}},toFanoutPourNetMap=netsByLayer=>Object.fromEntries(Array.from(netsByLayer,([layer,nets])=>[layer,nets.size===1?Array.from(nets)[0]:Array.from(nets)])),Group_getFanoutPourNetMap=(group2,routingPhasePlans)=>{let explicitMaps=routingPhasePlans.map(plan=>plan.fanoutPourNetMap).filter(map=>map!==void 0),netsByLayer=new Map;if(explicitMaps.length>0){for(let explicitMap of explicitMaps)addPourNetMap(netsByLayer,explicitMap);return toFanoutPourNetMap(netsByLayer)}let scope=group2;for(;scope;){if(scope.isSubcircuit){let subcircuit=scope,copperPours=subcircuit.selectAll("copperpour");for(let copperPour of copperPours){if(copperPour.getSubcircuit()!==subcircuit)continue;let{layer,connectsTo}=copperPour._parsedProps;addPourNetMap(netsByLayer,{[layer]:connectsTo})}}scope=scope.parent}return netsByLayer.size>0?toFanoutPourNetMap(netsByLayer):void 0},baseBreakoutPointProps=pcbLayoutProps.omit({pcbRotation:!0,layer:!0}),BaseBreakoutPoint=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"pcb_breakout_point_id",null);__publicField(this,"matchedPort",null);__publicField(this,"matchedNet",null);__publicField(this,"matchedSourceTraceId",null);__publicField(this,"isPcbPrimitive",!0)}_getSourceTraceIdForPort(port){let{db:db22}=this.root;return db22.source_trace.list().find(st22=>st22.connected_source_port_ids.includes(port.source_port_id))?.source_trace_id}_getSourceNetIdForPort(port){let{db:db22}=this.root;return db22.source_trace.list().find(st22=>st22.connected_source_port_ids.includes(port.source_port_id))?.connected_source_net_ids[0]}_renderPcbBreakoutPoint({layer}={}){if(this.pcb_breakout_point_id||this.root?.pcbDisabled)return;let{db:db22}=this.root,position22=this._getGlobalPcbPositionBeforeLayout(),group2=this.parent?.getGroup(),subcircuit=this.getSubcircuit();if(!group2||!group2.pcb_group_id)return;let pcb_breakout_point23=db22.pcb_breakout_point.insert({pcb_group_id:group2.pcb_group_id,subcircuit_id:subcircuit?.subcircuit_id??void 0,source_port_id:this.matchedPort?.source_port_id??void 0,source_trace_id:this.matchedPort?this.matchedSourceTraceId??this._getSourceTraceIdForPort(this.matchedPort):void 0,source_net_id:this.matchedNet?this.matchedNet.source_net_id:this.matchedPort?this._getSourceNetIdForPort(this.matchedPort):void 0,layer,x:position22.x,y:position22.y});this.pcb_breakout_point_id=pcb_breakout_point23.pcb_breakout_point_id}_getPcbCircuitJsonBounds(){let position22=this._getGlobalPcbPositionBeforeLayout();return{center:{x:position22.x,y:position22.y},bounds:{left:position22.x,top:position22.y,right:position22.x,bottom:position22.y},width:0,height:0}}_setPositionFromLayout(newCenter){let{db:db22}=this.root;if(!this.pcb_breakout_point_id)return;let updatedProperties={x:newCenter.x,y:newCenter.y};this.matchedSourceTraceId&&(updatedProperties.source_trace_id=this.matchedSourceTraceId),db22.pcb_breakout_point.update(this.pcb_breakout_point_id,updatedProperties)}_moveCircuitJsonElements({deltaX,deltaY}){if(this.root?.pcbDisabled)return;let{db:db22}=this.root;if(!this.pcb_breakout_point_id)return;let point12=db22.pcb_breakout_point.get(this.pcb_breakout_point_id);point12&&db22.pcb_breakout_point.update(this.pcb_breakout_point_id,{x:point12.x+deltaX,y:point12.y+deltaY})}getPcbSize(){return{width:0,height:0}}},BreakoutPoint=class extends BaseBreakoutPoint{get config(){return{componentName:"BreakoutPoint",zodProps:breakoutPointProps}}_matchConnection(){if(this.matchedPort)return;let{connection}=this._parsedProps,subcircuit=this.getSubcircuit();subcircuit&&(this.matchedPort=subcircuit.selectOne(connection,{type:"port"}),this.matchedPort||(this.matchedNet=subcircuit.selectOne(connection,{type:"net"})),!this.matchedPort&&!this.matchedNet&&this.renderError(`Could not find connection target "${connection}"`))}doInitialPcbPrimitiveRender(){this._matchConnection(),this._renderPcbBreakoutPoint()}},SavedFanoutPoint=class extends BreakoutPoint{constructor(){super(...arguments);__publicField(this,"exitLayer","top")}doInitialPcbPrimitiveRender(){this._matchConnection(),this._renderPcbBreakoutPoint({layer:this.exitLayer})}};function getSavedFanoutTraces(breakout,input2){let{db:db22}=breakout.root,boardLayers=getViaBoardLayers(input2.layerCount),coveredConnections=new Set,exits=breakout.children.filter(child=>child instanceof SavedFanoutPoint),traces=(breakout._parsedProps.pcbTracePaths??[]).map((path,pathIndex)=>{for(let point12 of path.route)if((point12.route_type==="wire"?[point12.layer]:[point12.from_layer,point12.to_layer]).some(layer=>!boardLayers.includes(layer)))throw new Error(`Saved fanout path "${path.connection}" uses a layer unavailable on this board`);let exit=exits[pathIndex],port=exit.matchedPort,connection=input2.connections.find(connection2=>connection2.pointsToConnect.some(point12=>point12.pcb_port_id===port.pcb_port_id));if(!connection)throw new Error(`No fanout connection for saved path "${path.connection}"`);let pcbExit=db22.pcb_breakout_point.get(exit.pcb_breakout_point_id),localExit=path.route.at(-1),transform22=compose3(exit._computePcbGlobalTransformBeforeLayout(),translate8(-localExit.x,-localExit.y)),originalExit=applyToPoint3(transform22,localExit),route2=resolveSavedTraceRouteWidths(path.route).map(point12=>{let position22=applyToPoint3(transform22,point12);return{...point12,x:position22.x+pcbExit.x-originalExit.x,y:position22.y+pcbExit.y-originalExit.y}}),first=route2[0],firstLayer=first.route_type==="wire"?first.layer:first.from_layer,portPosition=port._getGlobalPcbPositionAfterLayout();if(Math.hypot(first.x-portPosition.x,first.y-portPosition.y)>1e-4||!port.getAvailablePcbLayers().includes(firstLayer))throw new Error(`Saved fanout path "${path.connection}" must start at its PCB port on an available layer`);if(first.route_type==="via"&&!input2.allowViaInPad)throw new Error(`Saved fanout path "${path.connection}" starts with a via at a pad; enable allowViaInPad`);let last=route2.at(-1),lastLayer=last.route_type==="wire"?last.layer:last.to_layer,endpoints=[{...first,layer:firstLayer},{...last,layer:lastLayer}];if(connection.pointsToConnect.some(point12=>!endpoints.some(endpoint=>Math.hypot(point12.x-endpoint.x,point12.y-endpoint.y)<1e-4&&point12.layer===endpoint.layer)))throw new Error(`Saved fanout path "${path.connection}" does not cover its connection endpoints`);let startContactWidths=getSavedTraceViaContactWidths(route2,0,input2.minTraceWidth),endContactWidths=getSavedTraceViaContactWidths(route2,route2.length-1,input2.minTraceWidth);return first.route_type==="via"&&(route2.splice(1,0,{route_type:"wire",x:first.x,y:first.y,layer:first.to_layer,width:startContactWidths.toWidth}),route2.unshift({route_type:"wire",x:first.x,y:first.y,layer:first.from_layer,width:startContactWidths.fromWidth})),last.route_type==="via"&&(route2.splice(route2.length-1,0,{route_type:"wire",x:last.x,y:last.y,layer:last.from_layer,width:endContactWidths.fromWidth}),route2.push({route_type:"wire",x:last.x,y:last.y,layer:last.to_layer,width:endContactWidths.toWidth})),last.route_type==="via"&&route2.push({route_type:"wire",x:last.x,y:last.y,layer:last.to_layer,width:endContactWidths.toWidth}),coveredConnections.add(connection),{type:"pcb_trace",pcb_trace_id:`saved_fanout_${breakout.pcb_group_id}_${pathIndex}`,connection_name:connection.name,source_trace_id:connection.source_trace_id,connectsTo:[connection.source_trace_id,...connection.pointsToConnect.map(point12=>point12.pointId)].filter(id3=>!!id3),route:route2}}),missing=input2.connections.filter(connection=>!coveredConnections.has(connection));if(missing.length)throw new Error(`pcbTracePaths must cover every fanout connection; missing: ${missing.map(connection=>connection.name).join(", ")}`);return traces}function getPhaseSortValue(routingPhaseIndex){return routingPhaseIndex===null?Number.POSITIVE_INFINITY:routingPhaseIndex}function compareRoutingPhasePlans(a23,b23){return getPhaseSortValue(a23.routingPhaseIndex)-getPhaseSortValue(b23.routingPhaseIndex)}function getOrCreateRoutingPhasePlan(plansByPhaseIndex,routingPhaseIndex){let plan=plansByPhaseIndex.get(routingPhaseIndex);return plan||(plan={routingPhaseIndex,nets:[],traces:[]},plansByPhaseIndex.set(routingPhaseIndex,plan)),plan}function getNetRoutingPhaseIndex(net){return net.props.routingPhaseIndex??null}function getTraceRoutingPhaseIndex(trace,buses=[]){let busRoutingPhaseIndexes=new Set;for(let bus of buses){if(bus._parsedProps.routingPhaseIndex===void 0)continue;bus._parsedProps.connections.some(connection=>connection===trace.name||traceHasEndpointMatchingConnectionSelector(trace,convertPortSelectorToEndpointKey(connection)))&&busRoutingPhaseIndexes.add(bus._parsedProps.routingPhaseIndex)}if(busRoutingPhaseIndexes.size>1)throw new Error(`Trace "${trace.name}" belongs to buses with different routing phases`);let busRoutingPhaseIndex=busRoutingPhaseIndexes.values().next().value;if(busRoutingPhaseIndex!==void 0)return busRoutingPhaseIndex;let traceRoutingPhaseIndex=trace.props.routingPhaseIndex;if(traceRoutingPhaseIndex!==void 0)return traceRoutingPhaseIndex;let routingPhaseIndex=null,connectedNets=trace._findConnectedNets().nets;for(let net of connectedNets){let netRoutingPhaseIndex=getNetRoutingPhaseIndex(net);typeof netRoutingPhaseIndex=="number"&&(routingPhaseIndex===null||netRoutingPhaseIndex<routingPhaseIndex)&&(routingPhaseIndex=netRoutingPhaseIndex)}return routingPhaseIndex}function convertPortSelectorToEndpointKey(selector2){return selector2.trim().replace(/\s*>\s*/g,".").replace(/\s+/g,".").replace(/^\./,"").replace(/\.\./g,".")}function getConnectionSelectorsFromAutoroutingPhaseProps(phaseProps){return phaseProps.connection===void 0&&phaseProps.connections===void 0?phaseProps.pcbTracePaths?.map(path=>path.connection)??[]:[...phaseProps.connection?[phaseProps.connection]:[],...phaseProps.connections??[]]}function traceHasEndpointMatchingConnectionSelector(trace,connectionSelector){let connectionSelectorEndpointKey=convertPortSelectorToEndpointKey(connectionSelector);if(trace.getTracePortPathSelectors().some(selector2=>convertPortSelectorToEndpointKey(selector2)===connectionSelectorEndpointKey))return!0;let port=trace.getSubcircuit().selectOne(connectionSelector,{type:"port"});return port!==null&&(trace._findConnectedPorts().ports?.includes(port)??!1)}function resolvePhaseConnectionTraces(group2,traces,phaseProps){let resolvedTraces=new Set,phaseName=phaseProps.name??"unnamed phase";for(let rawSelector of getConnectionSelectorsFromAutoroutingPhaseProps(phaseProps)){let selector2=rawSelector.trim(),explicitlySelectsTrace=selector2.startsWith("trace."),namedTraces=explicitlySelectsTrace?group2.selectAll(selector2).filter(trace=>traces.includes(trace)):traces.filter(trace=>trace.name===selector2),endpointTraces=explicitlySelectsTrace?[]:traces.filter(trace=>traceHasEndpointMatchingConnectionSelector(trace,selector2));if(namedTraces.length>1||namedTraces.length>0&&endpointTraces.length>0)throw new Error(`Autorouting phase "${phaseName}": connection "${rawSelector}" is ambiguous. Use a unique trace name qualified as "trace.DDR_D0" or a port such as ".U1 > .A1".`);let matches=namedTraces.length>0?namedTraces:endpointTraces;if(matches.length===0)throw new Error(`Autorouting phase "${phaseName}": connection "${rawSelector}" matched no trace or endpoint. Use a trace name such as "DDR_D0" or a port such as ".U1 > .A1".`);for(let trace of matches)resolvedTraces.add(trace)}return resolvedTraces}function getAutoroutersByPhaseIndex(group2){let autoroutingPhases=group2.selectAll("autoroutingphase"),autoroutersByPhaseIndex=new Map;for(let autoroutingPhase of autoroutingPhases){let{phaseIndex,autorouter}=autoroutingPhase._parsedProps;autorouter!==void 0&&autoroutersByPhaseIndex.set(phaseIndex??null,autorouter)}return autoroutersByPhaseIndex}function getAutoroutingPhasePropsByPhaseIndex(group2){let autoroutingPhases=group2.selectAll("autoroutingphase"),propsByPhaseIndex=new Map;for(let autoroutingPhase of autoroutingPhases){let props=autoroutingPhase._parsedProps;propsByPhaseIndex.set(props.phaseIndex??null,props)}return propsByPhaseIndex}function toParsedDistance(value){if(value!==void 0)return Number(value)}function getDrcTolerancesFromAutoroutingPhaseProps(phaseProps){let{minTraceWidth,minViaHoleEdgeToViaHoleEdgeClearance,minPlatedHoleDrillEdgeToDrillEdgeClearance,minTraceToPadEdgeClearance,minTraceToHoleEdgeClearance,minPadEdgeToPadEdgeClearance,minBoardEdgeClearance,minViaEdgeToPadEdgeClearance,minViaHoleDiameter,minViaPadDiameter}=phaseProps;if(!(minTraceWidth===void 0&&minViaHoleEdgeToViaHoleEdgeClearance===void 0&&minPlatedHoleDrillEdgeToDrillEdgeClearance===void 0&&minTraceToPadEdgeClearance===void 0&&minTraceToHoleEdgeClearance===void 0&&minPadEdgeToPadEdgeClearance===void 0&&minBoardEdgeClearance===void 0&&minViaEdgeToPadEdgeClearance===void 0&&minViaHoleDiameter===void 0&&minViaPadDiameter===void 0))return{minTraceWidth:toParsedDistance(minTraceWidth),minViaHoleEdgeToViaHoleEdgeClearance:toParsedDistance(minViaHoleEdgeToViaHoleEdgeClearance),minPlatedHoleDrillEdgeToDrillEdgeClearance:toParsedDistance(minPlatedHoleDrillEdgeToDrillEdgeClearance),minTraceToPadEdgeClearance:toParsedDistance(minTraceToPadEdgeClearance),minTraceToHoleEdgeClearance:toParsedDistance(minTraceToHoleEdgeClearance),minPadEdgeToPadEdgeClearance:toParsedDistance(minPadEdgeToPadEdgeClearance),minBoardEdgeClearance:toParsedDistance(minBoardEdgeClearance),minViaEdgeToPadEdgeClearance:toParsedDistance(minViaEdgeToPadEdgeClearance),minViaHoleDiameter:toParsedDistance(minViaHoleDiameter),minViaPadDiameter:toParsedDistance(minViaPadDiameter)}}function Group_getRoutingPhasePlans(group2){let traces=group2.selectAll("trace"),nets=group2.selectAll("net"),buses=group2.selectAll("bus"),breakouts=group2.selectAll("group").filter(candidate=>candidate.isRoutingDirective),breakoutByTrace=new Map,breakoutByNet=new Map;for(let trace of traces){let ancestor=trace.parent;for(;ancestor&&ancestor!==group2;){if(ancestor.isRoutingDirective){breakoutByTrace.set(trace,ancestor);break}ancestor=ancestor.parent}}for(let net of nets)net.parent?.isRoutingDirective&&breakouts.includes(net.parent)&&breakoutByNet.set(net,net.parent);let plansByPhaseIndex=new Map,autoroutersByPhaseIndex=getAutoroutersByPhaseIndex(group2),phasePropsByPhaseIndex=getAutoroutingPhasePropsByPhaseIndex(group2),selectedTracesByPhaseIndex=new Map(Array.from(phasePropsByPhaseIndex,([phaseIndex,phaseProps])=>[phaseIndex,resolvePhaseConnectionTraces(group2,traces,phaseProps)])),groupFanoutProps=group2._parsedProps,routeRemaining=group2.getInheritedProperty("routeRemaining")!==!1,defaultPhaseProps=phasePropsByPhaseIndex.get(null),includeUnassignedConnections=routeRemaining||defaultPhaseProps!==void 0&&!defaultPhaseProps.reroute&&getConnectionSelectorsFromAutoroutingPhaseProps(defaultPhaseProps).length===0,hasDirectRoutingTargets=traces.length>0||nets.length>0,hasReroutePhase=Array.from(phasePropsByPhaseIndex.values()).some(phaseProps=>phaseProps.reroute),hasConnectionTargetedPhase=Array.from(phasePropsByPhaseIndex.values()).some(phaseProps=>getConnectionSelectorsFromAutoroutingPhaseProps(phaseProps).length>0);if(!hasDirectRoutingTargets&&!hasReroutePhase&&!hasConnectionTargetedPhase&&breakouts.length===0)return[];for(let net of nets){if(breakoutByNet.has(net))continue;let routingPhaseIndex=getNetRoutingPhaseIndex(net);routingPhaseIndex===null&&!includeUnassignedConnections||getOrCreateRoutingPhasePlan(plansByPhaseIndex,routingPhaseIndex).nets.push(net)}for(let trace of traces){if(breakoutByTrace.has(trace))continue;let routingPhaseIndex=getTraceRoutingPhaseIndex(trace,buses);routingPhaseIndex===null&&!includeUnassignedConnections||getOrCreateRoutingPhasePlan(plansByPhaseIndex,routingPhaseIndex).traces.push(trace)}for(let[phaseIndex,phaseProps]of phasePropsByPhaseIndex){let connectionSelectors=getConnectionSelectorsFromAutoroutingPhaseProps(phaseProps);if(connectionSelectors.length>0){let plan=getOrCreateRoutingPhasePlan(plansByPhaseIndex,phaseIndex);plan.connectionSelectors=connectionSelectors;for(let trace of traces)if(!breakoutByTrace.has(trace)&&selectedTracesByPhaseIndex.get(phaseIndex).has(trace)){let connectedNets=trace._findConnectedPorts().ports?.length===1?nets.filter(net=>!breakoutByNet.has(net)&&trace.subcircuit_connectivity_map_key!==null&&net.subcircuit_connectivity_map_key===trace.subcircuit_connectivity_map_key):[];for(let net of connectedNets)plan.nets.includes(net)||plan.nets.push(net);if(!phaseProps.reroute)for(let existingPlan of plansByPhaseIndex.values())existingPlan!==plan&&(!phasePropsByPhaseIndex.get(existingPlan.routingPhaseIndex)?.reroute&&connectedNets.length>0&&(existingPlan.nets=existingPlan.nets.filter(net=>!connectedNets.includes(net))),existingPlan.traces=existingPlan.traces.filter(existingTrace=>existingTrace!==trace));if(plan.traces.includes(trace))continue;plan.traces.push(trace)}}(phaseProps.reroute||phaseProps.pcbTracePaths!==void 0)&&getOrCreateRoutingPhasePlan(plansByPhaseIndex,phaseIndex)}let plans=Array.from(plansByPhaseIndex.values()).sort(compareRoutingPhasePlans);for(let plan of plans){plan.autorouter=autoroutersByPhaseIndex.get(plan.routingPhaseIndex);let phaseProps=phasePropsByPhaseIndex.get(plan.routingPhaseIndex);plan.algorithmFn=phaseProps?.algorithmFn,plan.isImplicitRemainingPhase=plan.routingPhaseIndex===null&&phaseProps===void 0,plan.phaseName=phaseProps?.name,plan.reroute=phaseProps?.reroute,plan.region=phaseProps?.region,plan.connectionSelectors=phaseProps?getConnectionSelectorsFromAutoroutingPhaseProps(phaseProps):void 0,plan.busFanoutDirections=phaseProps?.busFanoutDirections??groupFanoutProps.busFanoutDirections,plan.fanoutBoundaryPadding=phaseProps?.fanoutBoundaryPadding??groupFanoutProps.fanoutBoundaryPadding;let fanoutRoutingLayers=phaseProps?.fanoutRoutingLayers??groupFanoutProps.fanoutRoutingLayers;plan.fanoutRoutingLayers=fanoutRoutingLayers?.map(layer=>typeof layer=="string"?layer:layer.name),plan.fanoutPourNetMap=phaseProps?.fanoutPourNetMap??groupFanoutProps.fanoutPourNetMap,plan.drcTolerances=phaseProps?getDrcTolerancesFromAutoroutingPhaseProps(phaseProps):void 0}for(let phase of group2.selectAll("autoroutingphase")){let plan=plansByPhaseIndex.get(phase._parsedProps.phaseIndex??null);if(!plan)continue;let props=phase._parsedProps;if(props.addTestPoints&&(plan.testPointOptions={layer:props.testPointLayer??"bottom",diameter:props.testPointDiameter??1,clearance:props.testPointClearance??.2,minProbeSpacing:props.testPointMinProbeSpacing??2.54,maxDetour:props.testPointMaxDetour??1}),plan.autoroutingPhase=phase,phase._parsedProps.pcbTracePaths===void 0)continue;let config=plan.autorouter!==void 0?getPresetAutoroutingConfig(plan.autorouter,group2.root?.platform):group2._getAutorouterConfig(),isFanout=["fanout","single_layer_fanout"].includes(config.preset??"");plan.getPrecomputedRoutingResult=input2=>getSavedAutoroutingPhaseTraces(phase,input2,isFanout)}let breakoutPlans=[];for(let breakout of breakouts){let breakoutProps22=breakout._parsedProps,shouldUseDefaultAutorouterForBreakoutPoints=breakout.children.some(child=>child instanceof BreakoutPoint)&&breakout.props.autorouter===void 0,breakoutTraces=traces.filter(trace=>breakoutByTrace.get(trace)===breakout),unroutedBreakoutTraces=breakoutTraces.filter(trace=>!trace.pcb_trace_id),pcbGroup=breakout.pcb_group_id?breakout.root?.db.pcb_group.get(breakout.pcb_group_id):null,outlineBounds=pcbGroup?.outline?getBoundsFromPoints3(pcbGroup.outline):null,routingWidth=pcbGroup?.width??(outlineBounds?outlineBounds.maxX-outlineBounds.minX:void 0),routingHeight=pcbGroup?.height??(outlineBounds?outlineBounds.maxY-outlineBounds.minY:void 0),routingBounds2=pcbGroup&&routingWidth&&routingHeight?{minX:pcbGroup.center.x-routingWidth/2,maxX:pcbGroup.center.x+routingWidth/2,minY:pcbGroup.center.y-routingHeight/2,maxY:pcbGroup.center.y+routingHeight/2}:void 0,rawBreakoutProps=breakout.props,hasExplicitGeometry=rawBreakoutProps.width!==void 0||rawBreakoutProps.height!==void 0||!!rawBreakoutProps.outline?.length,hasExplicitFanoutBoundaryPadding=rawBreakoutProps.fanoutBoundaryPadding!==void 0,breakoutPlan={routingPhaseIndex:null,routingPcbGroupId:breakout.pcb_group_id??void 0,fanoutRegionPcbGroupId:breakout.pcb_group_id??void 0,routingBounds:routingBounds2,fanoutBounds:hasExplicitGeometry?routingBounds2:hasExplicitFanoutBoundaryPadding?void 0:routingBounds2,autorouter:breakoutProps22.autorouter??"fanout",busFanoutDirections:breakoutProps22.busFanoutDirections,fanoutBoundaryPadding:breakoutProps22.fanoutBoundaryPadding,fanoutRoutingLayers:breakoutProps22.fanoutRoutingLayers?.map(layer=>typeof layer=="string"?layer:layer.name),fanoutPourNetMap:breakoutProps22.fanoutPourNetMap,nets:nets.filter(net=>breakoutByNet.get(net)===breakout),traces:breakoutTraces};if(breakout.isDogboneFanout&&breakoutProps22.pcbTracePaths===void 0){breakoutPlans.push({...breakoutPlan,routingBounds:void 0,fanoutBounds:routingBounds2});continue}if(breakout._parsedProps.pcbTracePaths!==void 0){breakoutPlans.push({...breakoutPlan,autorouter:{local:!0,groupMode:"subcircuit",allowViaInPad:(typeof breakoutProps22.autorouter=="object"?breakoutProps22.autorouter.allowViaInPad:void 0)??group2._getAutorouterConfig().allowViaInPad},getPrecomputedRoutingResult:input2=>({traces:getSavedFanoutTraces(breakout,input2)})});continue}if(!shouldUseDefaultAutorouterForBreakoutPoints){breakoutPlans.push(breakoutPlan);continue}if(breakoutPlans.push({...breakoutPlan,autorouter:"default",traces:[]}),unroutedBreakoutTraces.length>0){let automaticFanoutBusIds=new Set(buses.filter(bus=>unroutedBreakoutTraces.some(trace=>bus._parsedProps.connections.some(connection=>connection===trace.name||traceHasEndpointMatchingConnectionSelector(trace,convertPortSelectorToEndpointKey(connection))))).map(bus=>bus.name));for(let trace of unroutedBreakoutTraces)trace.name&&automaticFanoutBusIds.add(trace.name);let automaticBusFanoutDirections=breakoutProps22.busFanoutDirections?Object.fromEntries(Object.entries(breakoutProps22.busFanoutDirections).filter(([busId])=>automaticFanoutBusIds.has(busId))):void 0;breakoutPlans.push({...breakoutPlan,routingPcbGroupId:void 0,busFanoutDirections:automaticBusFanoutDirections,traces:unroutedBreakoutTraces})}}if(routeRemaining&&hasDirectRoutingTargets&&phasePropsByPhaseIndex.size===1&&defaultPhaseProps?.reroute&&plans.length===1&&plans[0]?.routingPhaseIndex===null){let reroutePlan=plans[0];return[...breakoutPlans,{routingPhaseIndex:null,isImplicitRemainingPhase:!0,nets:[...reroutePlan.nets],traces:[...reroutePlan.traces]},reroutePlan]}return[...breakoutPlans,...plans]}var RoutingPhasePreparationError=class extends Error{},package_default3={name:"@tscircuit/core",type:"module",version:"0.0.2366",types:"dist/index.d.ts",main:"dist/index.js",module:"dist/index.js",exports:{".":{import:"./dist/index.js",types:"./dist/index.d.ts"}},files:["dist"],repository:{type:"git",url:"https://github.com/tscircuit/core"},scripts:{"check:class-exports":"bun run scripts/check-class-exports.ts",build:"bun run scripts/build-test-point-rerouter-types.ts && tsup-node",format:"biome format . --write","measure-bundle":"howfat -r table .","pkg-pr-new-release":"bunx pkg-pr-new publish --comment=off --peerDeps","smoke-test:dist":"bun run scripts/smoke-tests/test-dist-assembly-bom.tsx && bun run scripts/smoke-tests/test-dist-simple-circuit.tsx && bun run scripts/smoke-tests/check-dist-bundled-schematic-solver.ts && bun run scripts/smoke-tests/test-dist-drawing-dimensions.tsx && bun run scripts/smoke-tests/check-dist-bundled-test-point-rerouter.ts && bun run scripts/smoke-tests/check-dist-collision-runtime.ts && bun run scripts/smoke-tests/test-dist-explosion-collisions.tsx && node scripts/smoke-tests/test-dist-node-explosion-collisions.mjs","build:benchmarking":"bun build --experimental-html ./benchmarking/website/index.html --outdir ./benchmarking-dist","build:benchmarking:watch":`chokidar "./{benchmarking,lib}/**/*.{ts,tsx}" -c 'bun build --experimental-html ./benchmarking/website/index.html --outdir ./benchmarking-dist'`,"start:benchmarking":'concurrently "bun run build:benchmarking:watch" "live-server ./benchmarking-dist"',"generate-test-plan":"bun run scripts/generate-test-plan.ts","benchmark:ddr":"bun scripts/benchmark-ddr/run.ts"},devDependencies:{"@tscircuit/cad-collision-checking":"https://jscdn.tscircuit.com/@tscircuit/cad-collision-checking/0.0.6.tgz","@tscircuit/graphics-debug-3d":"https://jscdn.tscircuit.com/@tscircuit/graphics-debug-3d/0.0.1.tgz","@biomejs/biome":"^1.8.3","@resvg/resvg-js":"^2.6.2","@tsci/tscircuit.ti":"github:tscircuit/ti#57e314be4b2b06bc546d4def7453e619604d1157","@tscircuit/alphabet":"0.0.25","@tscircuit/bga-fanout-solver":"github:tscircuit/bga-fanout-solver#247c835cb8d69b65e53891dcf869731079415b39","@tscircuit/bus-lanes-solver":"https://jscdn.tscircuit.com/@tscircuit/bus-lanes-solver/0.0.55.tgz","@tscircuit/cableprinter":"^0.0.6","@tscircuit/capacity-autorouter":"^0.0.1089","@tscircuit/checks":"^0.0.277","@tscircuit/circuit-json-util":"^0.0.131","@tscircuit/common":"^0.0.20","@tscircuit/copper-pour-solver":"^0.0.74","@tscircuit/create-fdm-enclosure":"0.0.6","@tscircuit/dogbone-solver":"https://jscdn.tscircuit.com/@tscircuit/dogbone-solver/0.0.4.tgz","@tscircuit/fanout-solver":"0.0.84","@tscircuit/flex-utils":"https://jscdn.tscircuit.com/@tscircuit/flex-utils/0.0.8.tgz","@tscircuit/footprinter":"^0.0.451","@tscircuit/image-utils":"^0.0.8","@tscircuit/implicit-copper-pour-solver":"github:tscircuit/implicit-copper-pour-solver#a5cbbda0cd65fd4707c5c1af25779837c25aba92","@tscircuit/infer-cable-insertion-point":"^0.0.5","@tscircuit/infgrid-ijump-astar":"^0.0.35","@tscircuit/jlcpcb-manufacturing-specs":"git+https://github.com/tscircuit/jlcpcb-manufacturing-specs#d2fcf9a557a196cf9f2824463d06cd86534b1c21","@tscircuit/krt-wasm":"^0.1.1","@tscircuit/log-soup":"^1.0.2","@tscircuit/matchpack":"^0.0.100","@tscircuit/math-utils":"0.0.39","@tscircuit/miniflex":"^0.0.4","@tscircuit/modelprinter":"^0.0.37","@tscircuit/ngspice-spice-engine":"^0.0.20","@tscircuit/props":"^0.0.728","@tscircuit/schematic-match-adapt":"^0.0.18","@tscircuit/schematic-trace-solver":"https://jscdn.tscircuit.com/@tscircuit/schematic-trace-solver/0.0.238.tgz","@tscircuit/solver-utils":"^0.0.16","@tscircuit/soup-util":"^0.0.41","@tscircuit/via-stitch-solver":"github:tscircuit/via-stitch-solver#64f2ac7781b795bdc0d74ba411988e60767fa653","@tscircuit/winding-breakout-point-solver":"github:tscircuit/winding-breakout-point-solver#202dbe9eb0088633b6fa094120dba6f2f41f8803","@types/bun":"^1.2.16","@types/debug":"^4.1.12","@types/react":"^19.1.8","@types/react-dom":"^19.1.6","@types/react-reconciler":"^0.28.9","bpc-graph":"^0.0.57","bun-match-svg":"0.0.16","calculate-elbow":"^0.0.12","chokidar-cli":"^3.0.0","circuit-json":"^0.0.548","circuit-json-to-bom-csv":"^0.0.28","circuit-json-to-bpc":"^0.0.13","circuit-json-to-connectivity-map":"^0.0.33","circuit-json-to-spice":"^0.0.45","circuit-to-svg":"^0.0.457",concurrently:"^9.1.2","connectivity-map":"^1.0.1",debug:"^4.3.6",flatbush:"^4.5.0","graphics-debug":"^0.0.99",howfat:"^0.3.8","kicad-to-circuit-json":"^0.0.149",kicadts:"^0.0.53","live-server":"^1.2.2",minicssgrid:"^0.0.9","pkg-pr-new":"^0.0.37",react:"^19.1.0","react-dom":"^19.1.0","schematic-symbols":"^0.0.251",spicets:"^0.0.4",spicey:"^0.0.14","stack-svgs":"^0.0.1","ts-expect":"^1.3.0",tsup:"^8.2.4","@tscircuit/circuit-json-to-drawing":"https://jscdn.tscircuit.com/@tscircuit/circuit-json-to-drawing/0.0.4.tgz","circuit-json-to-gltf":"^0.0.164","@tscircuit/jscad":"^0.0.6","@tscircuit/test-point-rerouter":"github:tscircuit/test-point-rerouter#b0ccfaca75a7e187c55ddb6f2071a1f2084e3167","@tscircuit/manifold-2d":"^0.0.8",typescript:"^5.9.3","@tscircuit/jscad-to-manifold":"https://jscdn.tscircuit.com/@tscircuit/jscad-to-manifold/0.0.1.tgz","circuit-json-to-3d-png":"^0.0.6","circuit-json-to-altium":"github:tscircuit/circuit-json-to-altium#1a50d0dd2c0737cf940d92c0315852dc0111dd87","circuit-json-to-fdm-component-box":"^0.0.2","circuit-json-to-footprinter":"^0.0.59","circuit-json-to-gerber":"^0.0.120","circuit-json-to-kicad":"0.0.272","circuit-json-to-readable-netlist":"^0.0.15","circuit-json-to-step":"^0.0.63","circuit-json-to-tscircuit":"^0.0.50","dsn-converter":"^0.0.90",easyeda:"^0.0.389","circuit-json-to-pnp-csv":"^0.0.20","@tscircuit/core-ddr-benchmark":"github:ShiboSoftwareDev/core-ddr-benchmark#7b05251f6e868954adead2275a26c95b163c4813"},peerDependencies:{"@tscircuit/capacity-autorouter":"*","@tscircuit/checks":"*","@tscircuit/circuit-json-util":"*","@tscircuit/create-fdm-enclosure":"*","@tscircuit/footprinter":"*","@tscircuit/infgrid-ijump-astar":"*","@tscircuit/math-utils":"*","@tscircuit/modelprinter":"*","@tscircuit/props":"*","@tscircuit/schematic-match-adapt":"*","circuit-json-to-bpc":"*","bpc-graph":"*","@tscircuit/matchpack":"*","circuit-json":"*","circuit-json-to-connectivity-map":"*","circuit-json-to-spice":"*","schematic-symbols":"*",spicets:"*",typescript:"^5.0.0","@tscircuit/cableprinter":"*","@tscircuit/manifold-2d":"*"},dependencies:{"@flatten-js/core":"^1.6.2","@lume/kiwi":"^0.4.3","calculate-cell-boundaries":"^0.0.25","calculate-packing":"^0.0.90","css-select":"5.1.0","format-si-unit":"^0.0.12","gl-matrix":"^3.4.4",nanoid:"^5.0.7","performance-now":"^2.1.0","react-reconciler":"^0.32.0","svg-path-commander":"^2.1.11","transformation-matrix":"^2.16.1",zod:"^3.25.67","jscad-planner":"^0.0.21","jscad-fiber":"^0.0.93",poppygl:"0.0.38","@jscad/modeling":"^2.13.0","@dagrejs/dagre":"^2.0.4"},overrides:{"graphics-debug":"$graphics-debug","@tscircuit/graphics-debug-3d":"https://jscdn.tscircuit.com/@tscircuit/graphics-debug-3d/0.0.1.tgz","@tscircuit/props":"^0.0.728","circuit-json":"^0.0.548","@tscircuit/cableprinter":"^0.0.6"},browser:{"@resvg/resvg-js":!1}},getFnv1aHash=value=>{let hash=2166136261;for(let i23=0;i23<value.length;i23++)hash^=value.charCodeAt(i23),hash=Math.imul(hash,16777619);return hash>>>0},getJsonHash=value=>{let serializedValue=JSON.stringify(value),hash1=getFnv1aHash(serializedValue),hash2=getFnv1aHash(`${serializedValue}${hash1}`);return`${hash1.toString(16).padStart(8,"0")}${hash2.toString(16).padStart(8,"0")}`},getLocalAutoroutingCacheKey=(simpleRouteJson,solverOptions)=>`routes:core@${package_default3.version}:solver:${getJsonHash(solverOptions)}:srj:${getJsonHash(simpleRouteJson)}`,getCachedLocalAutoroutingPhaseResult=async({cacheEngine,cacheKey})=>{if(!cacheEngine)return null;try{let cachedResult=await cacheEngine.getItem(cacheKey);if(!cachedResult)return null;let parsedResult=JSON.parse(cachedResult);return!parsedResult||!Array.isArray(parsedResult.traces)?null:parsedResult}catch{return null}},cacheLocalAutoroutingPhaseResult=async({cacheEngine,cacheKey,result})=>{if(cacheEngine)try{await cacheEngine.setItem(cacheKey,JSON.stringify(result))}catch{}},SRJ_POINT_POSITION_TOLERANCE_MM=1e-6,srjPointsHaveSamePointId=(first,second)=>first.pointId!==void 0&&second.pointId!==void 0&&first.pointId===second.pointId,srjPointsHaveSameBoardPositionAndLayer=(first,second)=>Math.abs(first.x-second.x)<=SRJ_POINT_POSITION_TOLERANCE_MM&&Math.abs(first.y-second.y)<=SRJ_POINT_POSITION_TOLERANCE_MM&&first.layer===second.layer,srjPointsReferToSameEndpoint=(first,second)=>first.pointId!==void 0&&second.pointId!==void 0?srjPointsHaveSamePointId(first,second):srjPointsHaveSameBoardPositionAndLayer(first,second),getPairedGlobalPoint=(simpleRouteJson,connection)=>{let globalConnection=simpleRouteJson.connections.find(candidate=>candidate.routingPcbGroupId!==connection.routingPcbGroupId&&candidate.source_trace_id===connection.source_trace_id&&candidate.pointsToConnect.some(globalPoint=>connection.pointsToConnect.some(localPoint=>srjPointsReferToSameEndpoint(globalPoint,localPoint))));if(!globalConnection)return;let pairedPoints=globalConnection.pointsToConnect.filter(globalPoint=>!connection.pointsToConnect.some(localPoint=>srjPointsReferToSameEndpoint(globalPoint,localPoint)));return pairedPoints.length===1?pairedPoints[0]:void 0},getPairedBreakoutExitTarget=(simpleRouteJson,connection)=>{if(!connection.routingPcbGroupId||!connection.source_trace_id)return;let pairedGlobalPoint=getPairedGlobalPoint(simpleRouteJson,connection);if(!(!pairedGlobalPoint||!simpleRouteJson.connections.some(candidate=>candidate.routingPcbGroupId!==void 0&&candidate.routingPcbGroupId!==connection.routingPcbGroupId&&candidate.source_trace_id===connection.source_trace_id&&candidate.pointsToConnect.some(candidatePoint=>srjPointsReferToSameEndpoint(candidatePoint,pairedGlobalPoint)))))return{x:pairedGlobalPoint.x,y:pairedGlobalPoint.y,layer:pairedGlobalPoint.layer}};function connectionIsInRoutingPhase(connection,phasePlan){if(connection.routingPcbGroupId)return connection.routingPcbGroupId===phasePlan.routingPcbGroupId;for(let trace of phasePlan.traces)if(trace.source_trace_id&&(connection.source_trace_id===trace.source_trace_id||connection.name===trace.source_trace_id||connection.rootConnectionName===trace.source_trace_id||connection.mergedConnectionNames?.includes(trace.source_trace_id)))return!0;for(let net of phasePlan.nets)if(net.source_net_id&&connection.name===net.source_net_id)return!0;return!1}function Group_hasPhasedAutorouting(routingPhasePlans){for(let plan of routingPhasePlans)if(plan.routingPcbGroupId||plan.routingPhaseIndex!==null)return!0;return!1}function Group_filterSimpleRouteJsonForPhase(simpleRouteJson,phasePlan){let connections=[];for(let connection of simpleRouteJson.connections)connectionIsInRoutingPhase(connection,phasePlan)&&connections.push(connection);let includedConnectionNames=new Set;for(let connection of connections)includedConnectionNames.add(connection.name);let differentialPairs=[];for(let differentialPair of simpleRouteJson.differentialPairs??[]){let positiveConnectionIncluded=includedConnectionNames.has(differentialPair.connectionNames[0]),negativeConnectionIncluded=includedConnectionNames.has(differentialPair.connectionNames[1]);if(positiveConnectionIncluded!==negativeConnectionIncluded)throw new Error(`Differential pair "${differentialPair.connectionNames.join("/")}" cannot be split across autorouting phases`);positiveConnectionIncluded&&differentialPairs.push(differentialPair)}let srjConnectionByName=new Map(simpleRouteJson.connections.map(connection=>[connection.name,connection])),buses=(simpleRouteJson.buses??[]).map(bus=>{let connectionNames=bus.connectionNames.filter(connectionName=>includedConnectionNames.has(connectionName)),cohortConnectionNames=bus.connectionNames.filter(connectionName=>srjConnectionByName.get(connectionName)?.routingPcbGroupId===phasePlan.routingPcbGroupId);if(bus.maxLengthSkew!==void 0&&connectionNames.length>0&&connectionNames.length!==cohortConnectionNames.length)throw new RoutingPhasePreparationError(`Length-matched bus "${bus.name||"unnamed bus"}" cannot be split across autorouting phases. Assign the complete bus to one routingPhaseIndex.`);let connectionExitTargets=Object.fromEntries(connectionNames.flatMap(connectionName=>{let connection=srjConnectionByName.get(connectionName);if(!connection)return[];let pairedTarget=getPairedBreakoutExitTarget(simpleRouteJson,connection);return pairedTarget?[[connectionName,pairedTarget]]:[]}));return{...bus,connectionNames,...Object.keys(connectionExitTargets).length>0?{connectionExitTargets}:{}}}).filter(bus=>bus.connectionNames.length>0),bounds=expandSrjBoundsToIncludeConnectionPoints({bounds:phasePlan.routingBounds??simpleRouteJson.bounds,connections});return{...simpleRouteJson,bounds,outline:getSrjOutlineForRoutingBounds(simpleRouteJson,bounds),connections,differentialPairs:differentialPairs.length>0?differentialPairs:void 0,buses:buses.length>0?buses:void 0}}function hasDrcTolerances(drcTolerances){return drcTolerances?Object.values(drcTolerances).some(value=>value!==void 0):!1}function applyMinTraceWidthToConnections(connections,minTraceWidth){return minTraceWidth===void 0?connections:connections.map(connection=>({...connection,nominalTraceWidth:Math.max(connection.nominalTraceWidth??minTraceWidth,minTraceWidth),width:Math.max(connection.width??minTraceWidth,minTraceWidth)}))}function Group_applyDrcTolerancesToSimpleRouteJson(simpleRouteJson,drcTolerances){if(!hasDrcTolerances(drcTolerances))return simpleRouteJson;let minTraceWidth=drcTolerances.minTraceWidth??simpleRouteJson.minTraceWidth,minViaHoleDiameter=drcTolerances.minViaHoleDiameter??simpleRouteJson.minViaHoleDiameter,minViaPadDiameter=drcTolerances.minViaPadDiameter??simpleRouteJson.minViaPadDiameter,minTraceToHoleEdgeClearance=drcTolerances.minTraceToHoleEdgeClearance??simpleRouteJson.minTraceToHoleEdgeClearance,minTraceToPadEdgeClearance=drcTolerances.minTraceToPadEdgeClearance??simpleRouteJson.minTraceToPadEdgeClearance,minViaEdgeToPadEdgeClearance=drcTolerances.minViaEdgeToPadEdgeClearance??simpleRouteJson.minViaEdgeToPadEdgeClearance,minViaHoleEdgeToViaHoleEdgeClearance=drcTolerances.minViaHoleEdgeToViaHoleEdgeClearance??simpleRouteJson.minViaHoleEdgeToViaHoleEdgeClearance,minPlatedHoleDrillEdgeToDrillEdgeClearance=drcTolerances.minPlatedHoleDrillEdgeToDrillEdgeClearance??simpleRouteJson.minPlatedHoleDrillEdgeToDrillEdgeClearance,minPadEdgeToPadEdgeClearance=drcTolerances.minPadEdgeToPadEdgeClearance??simpleRouteJson.minPadEdgeToPadEdgeClearance,minBoardEdgeClearance=drcTolerances.minBoardEdgeClearance??simpleRouteJson.minBoardEdgeClearance;return{...simpleRouteJson,connections:applyMinTraceWidthToConnections(simpleRouteJson.connections,drcTolerances.minTraceWidth),minTraceWidth,minViaDiameter:minViaPadDiameter,minViaHoleDiameter,minViaPadDiameter,min_via_hole_diameter:minViaHoleDiameter,min_via_pad_diameter:minViaPadDiameter,minTraceToPadEdgeClearance,minTraceToHoleEdgeClearance,minViaEdgeToPadEdgeClearance,minViaHoleEdgeToViaHoleEdgeClearance,minPlatedHoleDrillEdgeToDrillEdgeClearance,minPadEdgeToPadEdgeClearance,minBoardEdgeClearance}}var removeCompletedFanoutConnections=(simpleRouteJson,routingPcbGroupId)=>{let connections=simpleRouteJson.connections.filter(connection=>connection.routingPcbGroupId!==routingPcbGroupId),includedConnectionNames=new Set(connections.map(connection=>connection.name)),differentialPairs=[];for(let differentialPair of simpleRouteJson.differentialPairs??[]){let positiveConnectionIncluded=includedConnectionNames.has(differentialPair.connectionNames[0]),negativeConnectionIncluded=includedConnectionNames.has(differentialPair.connectionNames[1]);if(positiveConnectionIncluded!==negativeConnectionIncluded)throw new Error(`Differential pair "${differentialPair.connectionNames.join("/")}" cannot be split at a breakout boundary`);positiveConnectionIncluded&&differentialPairs.push(differentialPair)}let buses=(simpleRouteJson.buses??[]).map(bus=>({...bus,connectionNames:bus.connectionNames.filter(connectionName=>includedConnectionNames.has(connectionName))})).filter(bus=>bus.connectionNames.length>0);return{...simpleRouteJson,connections,differentialPairs:differentialPairs.length>0?differentialPairs:void 0,buses:buses.length>0?buses:void 0}},connectFanoutTracesToBreakoutPoints=(simpleRouteJson,breakoutPointIdByConnectionName)=>({...simpleRouteJson,traces:simpleRouteJson.traces?.map(trace=>{let breakoutPointId=breakoutPointIdByConnectionName.get(trace.connection_name??"");return breakoutPointId?{...trace,connectsTo:[...new Set([...trace.connectsTo??[],breakoutPointId])]}:trace})});function Group_syncFanoutExitsWithGlobalConnections({fanoutInputSimpleRouteJson,fanoutOutputSimpleRouteJson,baseSimpleRouteJson,routingPhasePlan}){let routingPcbGroupId=routingPhasePlan.routingPcbGroupId;if(!routingPcbGroupId)return{downstreamSimpleRouteJson:fanoutOutputSimpleRouteJson,baseSimpleRouteJson,synchronizedBreakoutPoints:[]};let outputConnectionByName=new Map(fanoutOutputSimpleRouteJson.connections.map(connection=>[connection.name,connection])),baseConnections=baseSimpleRouteJson.connections.map(connection=>({...connection,pointsToConnect:connection.pointsToConnect.map(point12=>({...point12}))})),synchronizedBreakoutPoints=[],breakoutPointIdByConnectionName=new Map;for(let inputConnection of fanoutInputSimpleRouteJson.connections){if(inputConnection.routingPcbGroupId!==routingPcbGroupId||!inputConnection.source_trace_id)continue;let outputConnection=outputConnectionByName.get(inputConnection.name);if(!outputConnection)continue;let globalPointMatches=baseConnections.filter(connection=>{if(connection.routingPcbGroupId===routingPcbGroupId)return!1;let sharesSourceTrace=connection.source_trace_id===inputConnection.source_trace_id,sharesPointId=connection.pointsToConnect.some(globalPoint=>inputConnection.pointsToConnect.some(inputPoint=>srjPointsHaveSamePointId(globalPoint,inputPoint)));return!sharesSourceTrace&&!sharesPointId?!1:connection.pointsToConnect.some(globalPoint=>inputConnection.pointsToConnect.some(inputPoint=>srjPointsReferToSameEndpoint(globalPoint,inputPoint)))}).flatMap(globalConnection=>globalConnection.pointsToConnect.flatMap((previousPoint,pointIndex)=>inputConnection.pointsToConnect.some(inputPoint=>srjPointsReferToSameEndpoint(previousPoint,inputPoint))?[{globalConnection,pointIndex,previousPoint}]:[])),changedPointIndex=outputConnection.pointsToConnect.findIndex((outputPoint,pointIndex)=>{let inputPoint=inputConnection.pointsToConnect[pointIndex];return inputPoint!==void 0&&!srjPointsHaveSameBoardPositionAndLayer(outputPoint,inputPoint)});if(changedPointIndex<0)continue;let fanoutExitPoint=outputConnection.pointsToConnect[changedPointIndex];globalPointMatches.length===0&&synchronizedBreakoutPoints.push({sourceTraceId:inputConnection.source_trace_id,routingPcbGroupId,previousPoint:inputConnection.pointsToConnect[changedPointIndex],fanoutExitPoint});for(let{globalConnection,pointIndex,previousPoint}of globalPointMatches){let{terminalVia:_previousTerminalVia,...previousPointWithoutLayerOverrides}=previousPoint,synchronizedGlobalPoint={...previousPointWithoutLayerOverrides,x:fanoutExitPoint.x,y:fanoutExitPoint.y,layer:fanoutExitPoint.layer,...fanoutExitPoint.terminalVia?{terminalVia:{...fanoutExitPoint.terminalVia}}:{}};globalConnection.pointsToConnect[pointIndex]=synchronizedGlobalPoint,previousPoint.pointId&&breakoutPointIdByConnectionName.set(inputConnection.name,previousPoint.pointId),synchronizedBreakoutPoints.push({sourceTraceId:inputConnection.source_trace_id,routingPcbGroupId,previousPoint,fanoutExitPoint})}}let newFanoutSourceKeepouts=fanoutOutputSimpleRouteJson.obstacles.filter(obstacle=>obstacle.isFanoutSourceKeepout===!0&&obstacle.componentId!==void 0),completedSourceComponentIds=new Set(newFanoutSourceKeepouts.flatMap(obstacle=>obstacle.componentId===void 0?[]:[obstacle.componentId])),retainedBaseObstacles=baseSimpleRouteJson.obstacles.filter(obstacle=>!obstacle.componentId||!completedSourceComponentIds.has(obstacle.componentId));return{downstreamSimpleRouteJson:removeCompletedFanoutConnections(connectFanoutTracesToBreakoutPoints(fanoutOutputSimpleRouteJson,breakoutPointIdByConnectionName),routingPcbGroupId),baseSimpleRouteJson:{...baseSimpleRouteJson,connections:baseConnections,obstacles:[...retainedBaseObstacles,...newFanoutSourceKeepouts]},synchronizedBreakoutPoints}}function getJumperPadInfos(db22){let padInfos=[],jumperSourceComponentIds=new Set(db22.source_component.list().filter(component=>component.name?.startsWith("__autoplaced_jumper")).map(component=>component.source_component_id));if(jumperSourceComponentIds.size===0)return padInfos;let jumperPcbComponentIds=new Set(db22.pcb_component.list().filter(component=>jumperSourceComponentIds.has(component.source_component_id)).map(component=>component.pcb_component_id)),jumperSmtpads=db22.pcb_smtpad.list().filter(pad2=>jumperPcbComponentIds.has(pad2.pcb_component_id));for(let smtpad2 of jumperSmtpads)if(smtpad2.shape!=="polygon"&&smtpad2.pcb_port_id){if(smtpad2.shape==="rect"||smtpad2.shape==="rotated_rect"){let halfWidth=smtpad2.width/2,halfHeight=smtpad2.height/2;padInfos.push({pcb_port_id:smtpad2.pcb_port_id,x:smtpad2.x,y:smtpad2.y,minX:smtpad2.x-halfWidth,maxX:smtpad2.x+halfWidth,minY:smtpad2.y-halfHeight,maxY:smtpad2.y+halfHeight})}else if(smtpad2.shape==="circle"){let radius=smtpad2.radius;padInfos.push({pcb_port_id:smtpad2.pcb_port_id,x:smtpad2.x,y:smtpad2.y,minX:smtpad2.x-radius,maxX:smtpad2.x+radius,minY:smtpad2.y-radius,maxY:smtpad2.y+radius})}}return padInfos}function findJumperPortAtPosition(padInfos,x23,y23,tolerance=.01){for(let pad2 of padInfos)if(Math.abs(pad2.x-x23)<tolerance&&Math.abs(pad2.y-y23)<tolerance)return pad2.pcb_port_id}function findJumperPortContainingPoint(padInfos,x23,y23){for(let pad2 of padInfos)if(x23>=pad2.minX&&x23<=pad2.maxX&&y23>=pad2.minY&&y23<=pad2.maxY)return pad2}function splitRouteAtJumperPads(route2,padInfos){if(route2.length===0||padInfos.length===0)return[route2];let segments2=[],currentSegment=[];for(let i23=0;i23<route2.length;i23++){let point12=route2[i23];if(currentSegment.push(point12),point12.route_type==="wire"&&i23>0&&i23<route2.length-1){let padInfo=findJumperPortContainingPoint(padInfos,point12.x,point12.y);if(padInfo){point12.end_pcb_port_id||(point12.end_pcb_port_id=padInfo.pcb_port_id),segments2.push(currentSegment);let newStartPoint={...point12};delete newStartPoint.end_pcb_port_id,newStartPoint.start_pcb_port_id||(newStartPoint.start_pcb_port_id=padInfo.pcb_port_id),currentSegment=[newStartPoint]}}}return currentSegment.length>0&&segments2.push(currentSegment),segments2}function addPortIdsToTracesAtJumperPads(segments2,padInfos){if(padInfos.length===0)return segments2;let result=[];for(let segment5 of segments2){let subSegments=splitRouteAtJumperPads(segment5,padInfos);for(let subSegment of subSegments)if(subSegment.length>0){let firstPoint=subSegment[0],lastPoint=subSegment[subSegment.length-1];if(firstPoint.route_type==="wire"&&!firstPoint.start_pcb_port_id){let portId=findJumperPortAtPosition(padInfos,firstPoint.x,firstPoint.y);portId&&(firstPoint.start_pcb_port_id=portId)}if(lastPoint.route_type==="wire"&&!lastPoint.end_pcb_port_id){let portId=findJumperPortAtPosition(padInfos,lastPoint.x,lastPoint.y);portId&&(lastPoint.end_pcb_port_id=portId)}result.push(subSegment)}}return result}var claimSrjAssignablePcbViasTraversedByRoute=({db:db22,pcbTrace,routeWithSrjMetadata})=>{for(let routePoint3 of routeWithSrjMetadata){if(routePoint3.route_type!=="through_pad")continue;let pcbViaId=routePoint3.circuitJsonMetadata?.pcb_via_id;if(!pcbViaId)continue;let assignablePcbVia=db22.pcb_via.get(pcbViaId);!assignablePcbVia?.net_is_assignable||assignablePcbVia.net_assigned&&assignablePcbVia.pcb_trace_id!==pcbTrace.pcb_trace_id||db22.pcb_via.update(assignablePcbVia.pcb_via_id,{pcb_trace_id:pcbTrace.pcb_trace_id,net_assigned:!0})}},getAxisGap=(firstMinimum,firstMaximum,secondMinimum,secondMaximum)=>Math.max(secondMinimum-firstMaximum,firstMinimum-secondMaximum),findFanoutPhaseSeparationConflict=regions=>{for(let firstIndex=0;firstIndex<regions.length;firstIndex++){let firstRegion=regions[firstIndex];for(let secondIndex=firstIndex+1;secondIndex<regions.length;secondIndex++){let secondRegion=regions[secondIndex];if(firstRegion.regionId&&firstRegion.regionId===secondRegion.regionId)continue;let horizontalGap=getAxisGap(firstRegion.bounds.minX,firstRegion.bounds.maxX,secondRegion.bounds.minX,secondRegion.bounds.maxX),verticalGap=getAxisGap(firstRegion.bounds.minY,firstRegion.bounds.maxY,secondRegion.bounds.minY,secondRegion.bounds.maxY),availableGap=Math.max(horizontalGap,verticalGap),requiredGap=firstRegion.boundaryKeepaway+secondRegion.boundaryKeepaway;if(availableGap+1e-6<requiredGap)return{firstRegion,secondRegion,availableGap,requiredGap}}}};function getAccumulatedPcbTracesWithStageOutputReplacements({accumulatedPcbTraces,stageOutputPcbTraces}){let replacedPcbTraceIds=new Set(stageOutputPcbTraces.flatMap(trace=>[trace.pcb_trace_id,...trace.__replaces_pcb_trace_id?[trace.__replaces_pcb_trace_id]:[]]));return[...accumulatedPcbTraces.filter(trace=>!replacedPcbTraceIds.has(trace.pcb_trace_id)),...stageOutputPcbTraces]}var POINT_EPSILON3=1e-6;function isPointOnWireSegment({point:point12,segmentStart,segmentEnd}){return point12.layer&&(segmentStart.layer!==point12.layer||segmentEnd.layer!==point12.layer)?!1:pointToSegmentDistance2(point12,segmentStart,segmentEnd)<=POINT_EPSILON3}function isPointInSmtPad({point:point12,pad:pad2,traceWidth=0}){if(pad2.shape==="rect"||pad2.shape==="rotated_rect"){let unrotatedPoint=pad2.shape==="rotated_rect"?applyToPoint3(rotateDEG3(-pad2.ccw_rotation,pad2.x,pad2.y),point12):point12;return Math.abs(unrotatedPoint.x-pad2.x)<=pad2.width/2+traceWidth/2&&Math.abs(unrotatedPoint.y-pad2.y)<=pad2.height/2+traceWidth/2}return pad2.shape==="circle"?distance7(point12,pad2)<=pad2.radius+traceWidth/2:!1}function isPointInPlatedHole({point:point12,hole,traceWidth=0}){return distance7(point12,hole)<=(hole.outer_diameter??hole.hole_diameter??0)/2+traceWidth/2}function getEndpointSourcePortIdsFromGeometry(db22,trace){let sourcePortIds=new Set,route2=trace.route,endpoints=[route2[0],route2[route2.length-1]].filter(point12=>!!point12&&point12.route_type==="wire"&&point12.x!==void 0&&point12.y!==void 0);for(let endpoint of endpoints){let exactEndpointSourcePortIds=new Set;for(let pcbPort of db22.pcb_port.list())pcbPort.source_port_id&&(endpoint.layer&&pcbPort.layers&&!pcbPort.layers.includes(endpoint.layer)||distance7(endpoint,pcbPort)<=.01&&exactEndpointSourcePortIds.add(pcbPort.source_port_id));if(exactEndpointSourcePortIds.size>0){for(let sourcePortId of exactEndpointSourcePortIds)sourcePortIds.add(sourcePortId);continue}for(let smtpad2 of db22.pcb_smtpad.list()){if(!smtpad2.pcb_port_id||endpoint.layer&&smtpad2.layer!==endpoint.layer||!isPointInSmtPad({point:endpoint,pad:smtpad2,traceWidth:endpoint.width}))continue;let sourcePortId=db22.pcb_port.get(smtpad2.pcb_port_id)?.source_port_id;sourcePortId&&sourcePortIds.add(sourcePortId)}for(let hole of db22.pcb_plated_hole.list()){if(!hole.pcb_port_id||!isPointInPlatedHole({point:endpoint,hole,traceWidth:endpoint.width}))continue;let sourcePortId=db22.pcb_port.get(hole.pcb_port_id)?.source_port_id;sourcePortId&&sourcePortIds.add(sourcePortId)}}return[...sourcePortIds]}function getWireRouteEndpoints(trace){let route2=trace.route.filter(point12=>point12.route_type==="wire"&&point12.x!==void 0&&point12.y!==void 0);return[route2[0],route2[route2.length-1]].filter(point12=>!!point12)}function getSourceIdsFromConnectedPcbTraces(db22,trace){let sourceIds=new Set,endpoints=getWireRouteEndpoints(trace);if(endpoints.length===0)return[];for(let existingTrace of db22.pcb_trace.list()){if(!existingTrace.source_trace_id||existingTrace.pcb_trace_id===trace.pcb_trace_id||!db22.source_trace.get(existingTrace.source_trace_id)&&!db22.source_net.get(existingTrace.source_trace_id))continue;let existingRoute=existingTrace.route.filter(point12=>point12.route_type==="wire");for(let i23=0;i23<existingRoute.length-1;i23++){let segmentStart=existingRoute[i23],segmentEnd=existingRoute[i23+1];if(!(!segmentStart||!segmentEnd))for(let endpoint of endpoints)isPointOnWireSegment({point:endpoint,segmentStart,segmentEnd})&&sourceIds.add(existingTrace.source_trace_id)}}return[...sourceIds]}function getSourcePortIdsFromRoutedTrace(db22,trace){let sourcePortIds=new Set;for(let point12 of trace.route)for(let pcbPortId of[point12.start_pcb_port_id,point12.end_pcb_port_id]){if(!pcbPortId)continue;let sourcePortId=db22.pcb_port.get(pcbPortId)?.source_port_id;sourcePortId&&sourcePortIds.add(sourcePortId)}return sourcePortIds.size>0?[...sourcePortIds]:getEndpointSourcePortIdsFromGeometry(db22,trace)}function buildSourceConnectivityMap(sourceTraces){let connMap=new ConnectivityMap({});return connMap.addConnections(sourceTraces.map(trace=>[trace.source_trace_id,...trace.connected_source_port_ids,...trace.connected_source_net_ids])),connMap}function getSourceTraceIdForRoutedTrace({db:db22,trace,subcircuit_id}){if(trace.source_trace_id&&db22.source_trace.get(trace.source_trace_id))return trace.source_trace_id;let routedSourceNet=trace.source_trace_id?db22.source_net.get(trace.source_trace_id):void 0,sourceTraces=db22.source_trace.list(),connMap=buildSourceConnectivityMap(sourceTraces),routedSourceNetConnectivityId=routedSourceNet?connMap.getNetConnectedToId(routedSourceNet.source_net_id):void 0,routedNetSourceTraces=routedSourceNetConnectivityId?sourceTraces.filter(sourceTrace=>connMap.getNetConnectedToId(sourceTrace.source_trace_id)===routedSourceNetConnectivityId):[],soleRoutedNetSourceTrace=routedNetSourceTraces.length===1?routedNetSourceTraces[0]:void 0,sourcePortIds=getSourcePortIdsFromRoutedTrace(db22,trace);if(sourcePortIds.length===0)return soleRoutedNetSourceTrace?.source_trace_id??routedSourceNet?.source_net_id??getSourceIdsFromConnectedPcbTraces(db22,trace)[0];let endpointNetIds=sourcePortIds.map(sourcePortId=>connMap.getNetConnectedToId(sourcePortId)).filter(netId=>!!netId),exactSourceTrace=sourcePortIds.length>=2?sourceTraces.find(sourceTrace=>sourcePortIds.every(sourcePortId=>sourceTrace.connected_source_port_ids.includes(sourcePortId))):void 0;if(exactSourceTrace)return exactSourceTrace.source_trace_id;if(soleRoutedNetSourceTrace)return soleRoutedNetSourceTrace.source_trace_id;if(routedSourceNet)return routedSourceNet.source_net_id;let sourceTracesInEndpointNets=sourceTraces.filter(sourceTrace=>{let sourceTraceNetId=connMap.getNetConnectedToId(sourceTrace.source_trace_id);return endpointNetIds.some(netId=>netId===sourceTraceNetId)}),connectedToEndpoint=sourceTracesInEndpointNets.filter(sourceTrace=>sourceTrace.connected_source_port_ids.some(sourcePortId=>sourcePortIds.includes(sourcePortId))),candidates=connectedToEndpoint.length>0?connectedToEndpoint:sourceTracesInEndpointNets;if(candidates.length!==0)return(candidates.find(sourceTrace=>sourceTrace.subcircuit_id===subcircuit_id)??candidates[0])?.source_trace_id}function groupPadsByInternalConnection(pads,orientation32){let groups=[];for(let pad2 of pads){let key=orientation32==="vertical"?pad2.center.y:pad2.center.x,foundGroup=!1;for(let group2 of groups){let groupKey=orientation32==="vertical"?group2[0].center.y:group2[0].center.x;if(Math.abs(key-groupKey)<.01){group2.push(pad2),foundGroup=!0;break}}foundGroup||groups.push([pad2])}return groups.filter(g23=>g23.length>=2)}function insertAutoplacedJumpers(params){let{db:db22,output_jumpers,subcircuit_id}=params;for(let jumperIndex=0;jumperIndex<output_jumpers.length;jumperIndex++){let jumper=output_jumpers[jumperIndex],sourceComponent=db22.source_component.insert({ftype:"simple_chip",name:`__autoplaced_jumper_${jumperIndex}`,supplier_part_numbers:{}}),rotation6=jumper.orientation==="horizontal"?0:90,firstPadLayer=jumper.pads[0]?.layer||jumper.pads[0]?.layers?.[0]||"top",pcbComponent=db22.pcb_component.insert({source_component_id:sourceComponent.source_component_id,center:jumper.center,rotation:rotation6,layer:firstPadLayer,width:jumper.width||0,height:jumper.height||0,obstructs_within_bounds:!1}),padData=[];for(let padIndex=0;padIndex<jumper.pads.length;padIndex++){let pad2=jumper.pads[padIndex],pinNumber2=padIndex+1,sourcePort=db22.source_port.insert({source_component_id:sourceComponent.source_component_id,name:`pin${pinNumber2}`,pin_number:pinNumber2}),padLayer=pad2.layer||pad2.layers?.[0]||"top",pcbPort=db22.pcb_port.insert({pcb_component_id:pcbComponent.pcb_component_id,source_port_id:sourcePort.source_port_id,x:pad2.center.x,y:pad2.center.y,layers:[padLayer]}),pcbSmtpad=db22.pcb_smtpad.insert({pcb_component_id:pcbComponent.pcb_component_id,pcb_port_id:pcbPort.pcb_port_id,shape:"rect",x:pad2.center.x,y:pad2.center.y,width:pad2.width,height:pad2.height,layer:padLayer});padData.push({pad:pad2,sourcePortId:sourcePort.source_port_id,pcbSmtpadId:pcbSmtpad.pcb_smtpad_id})}let internalGroups=groupPadsByInternalConnection(jumper.pads,jumper.orientation);for(let group2 of internalGroups){let sourcePortIds=[];for(let groupPad of group2){let padInfo=padData.find(p23=>Math.abs(p23.pad.center.x-groupPad.center.x)<.01&&Math.abs(p23.pad.center.y-groupPad.center.y)<.01);padInfo&&sourcePortIds.push(padInfo.sourcePortId)}sourcePortIds.length>=2&&db22.source_component_internal_connection.insert({source_component_id:sourceComponent.source_component_id,subcircuit_id:subcircuit_id??void 0,source_port_ids:sourcePortIds})}}}function convertPcbTraceToSimplifiedPcbTrace(trace){return{...trace,type:"pcb_trace",pcb_trace_id:trace.pcb_trace_id,connection_name:trace.connection_name??trace.source_trace_id??trace.pcb_trace_id,route:trace.route.map(point12=>({...point12}))}}function getRelevantSubcircuitIdsForReroute(group2){let relevantSubcircuitIds=new Set;if(!group2.subcircuit_id)return relevantSubcircuitIds;relevantSubcircuitIds.add(group2.subcircuit_id);let db22=group2.root?.db;if(!db22)return relevantSubcircuitIds;for(let subcircuitId of getDescendantSubcircuitIds2(db22,group2.subcircuit_id))relevantSubcircuitIds.add(subcircuitId);return relevantSubcircuitIds}function getExistingPcbTracesForReroute(group2){let db22=group2.root?.db;if(!db22)return[];let relevantSubcircuitIds=getRelevantSubcircuitIdsForReroute(group2);return db22.pcb_trace.list().filter(trace=>!trace.route||trace.route.length<2?!1:group2.subcircuit_id?!!(trace.subcircuit_id&&relevantSubcircuitIds.has(trace.subcircuit_id)):!0)}function getSourceTraceIdsFromRerouteName(value){return typeof value!="string"||value.length===0?[]:value.split("__").flatMap(connectionNamePart=>{if(connectionNamePart.length===0)return[];let sourceTraceIds=[connectionNamePart],rerouteSuffixIndex=connectionNamePart.indexOf("_reroute_");return rerouteSuffixIndex>0&&sourceTraceIds.push(connectionNamePart.slice(0,rerouteSuffixIndex)),sourceTraceIds})}function addPossibleReplacementSourceTraceId(sourceTraceIds,value){if(!(typeof value!="string"||value.length===0)){sourceTraceIds.add(value);for(let sourceTraceId of getSourceTraceIdsFromRerouteName(value))sourceTraceIds.add(sourceTraceId)}}function deleteExistingPcbTracesReplacedBy({group:group2,outputPcbTraces,pcbTraceIdsToReplace=[]}){let db22=group2.root?.db;if(!db22)return;let replacementPcbTraceIds=new Set(pcbTraceIdsToReplace),replacementSourceTraceIds=new Set;for(let trace of outputPcbTraces){if(trace.type!=="pcb_trace")continue;let replacementTrace=trace;replacementPcbTraceIds.add(replacementTrace.pcb_trace_id),addPossibleReplacementSourceTraceId(replacementSourceTraceIds,replacementTrace.source_trace_id),addPossibleReplacementSourceTraceId(replacementSourceTraceIds,replacementTrace.connection_name),addPossibleReplacementSourceTraceId(replacementSourceTraceIds,replacementTrace.rootConnectionName)}if(replacementPcbTraceIds.size===0&&replacementSourceTraceIds.size===0)return;let tracesToDelete=getExistingPcbTracesForReroute(group2).filter(trace=>replacementPcbTraceIds.has(trace.pcb_trace_id)||!!(trace.source_trace_id&&trace.subcircuit_id===group2.subcircuit_id&&replacementSourceTraceIds.has(trace.source_trace_id)));if(tracesToDelete.length===0)return;let deletedPcbTraceIds=new Set(tracesToDelete.map(trace=>trace.pcb_trace_id));for(let via of db22.pcb_via.list())via.pcb_trace_id&&deletedPcbTraceIds.has(via.pcb_trace_id)&&db22.pcb_via.delete(via.pcb_via_id);for(let trace of tracesToDelete)db22.pcb_trace.delete(trace.pcb_trace_id)}function getExistingSimplifiedPcbTracesForReroute(group2){return getExistingPcbTracesForReroute(group2).map(convertPcbTraceToSimplifiedPcbTrace)}function splitPcbTracesOnJumperSegments(route2){let jumperRoutes=route2.filter(p23=>p23.route_type==="jumper"),wireAndViaRoutes=route2.filter(p23=>p23.route_type!=="jumper");if(jumperRoutes.length===0)return null;let splitRanges=[];for(let jumperRoute of jumperRoutes){let jumperStart=jumperRoute.start,jumperEnd=jumperRoute.end,startIdx=-1,endIdx=-1,minStartDist=1/0,minEndDist=1/0;for(let i23=0;i23<wireAndViaRoutes.length;i23++){let p23=wireAndViaRoutes[i23];if(p23.route_type!=="wire")continue;let distToStart=Math.hypot(p23.x-jumperStart.x,p23.y-jumperStart.y),distToEnd=Math.hypot(p23.x-jumperEnd.x,p23.y-jumperEnd.y);distToStart<minStartDist&&(minStartDist=distToStart,startIdx=i23),distToEnd<minEndDist&&(minEndDist=distToEnd,endIdx=i23)}startIdx>endIdx&&([startIdx,endIdx]=[endIdx,startIdx]),startIdx>=0&&endIdx>=0&&startIdx!==endIdx&&splitRanges.push({startIdx,endIdx})}splitRanges.sort((a23,b23)=>a23.startIdx-b23.startIdx);let segments2=[],currentStart=0;for(let range4 of splitRanges)currentStart<range4.startIdx&&segments2.push(wireAndViaRoutes.slice(currentStart,range4.startIdx+1)),currentStart=range4.endIdx;return currentStart<wireAndViaRoutes.length&&segments2.push(wireAndViaRoutes.slice(currentStart)),segments2}function computeCenterFromAnchorPosition(anchorPosition,ctx){let{width:width10,height:height10,pcbAnchorAlignment}=ctx;if(!pcbAnchorAlignment)return anchorPosition;let alignment=pcbAnchorAlignment;if(typeof width10!="number"||typeof height10!="number")return anchorPosition;let ax22=anchorPosition.x,ay22=anchorPosition.y;switch(alignment){case"top_left":return{x:ax22+width10/2,y:ay22-height10/2};case"top_center":return{x:ax22,y:ay22-height10/2};case"top_right":return{x:ax22-width10/2,y:ay22-height10/2};case"center_left":return{x:ax22+width10/2,y:ay22};case"center_right":return{x:ax22-width10/2,y:ay22};case"bottom_left":return{x:ax22+width10/2,y:ay22+height10/2};case"bottom_center":return{x:ax22,y:ay22+height10/2};case"bottom_right":return{x:ax22-width10/2,y:ay22+height10/2};default:return anchorPosition}}var getDistanceToPoint=(routePoint3,targetPoint)=>{let position22=getRoutePointPosition(routePoint3);return Math.hypot(position22.x-targetPoint.x,position22.y-targetPoint.y)},platformAllowsLegacyAutorouters=group2=>{let platform=group2.root?.platform;return platform!==void 0&&"allowLegacyAutorouters"in platform&&platform.allowLegacyAutorouters===!0},getDisabledLegacyGroupAutorouterPreset=group2=>{if(platformAllowsLegacyAutorouters(group2))return null;let resolvedGroupAutorouter=group2._parsedProps.autorouter??group2.getInheritedProperty("autorouter");return getLegacyAutorouterPreset(resolvedGroupAutorouter)},getDisabledLegacyAutorouterPreset=group2=>{if(platformAllowsLegacyAutorouters(group2))return null;let legacyGroupAutorouterPreset=getDisabledLegacyGroupAutorouterPreset(group2);if(legacyGroupAutorouterPreset)return legacyGroupAutorouterPreset;let routingPhaseAutorouters=group2.selectAll("autoroutingphase").map(autoroutingPhase=>autoroutingPhase._parsedProps.autorouter);for(let autorouter of routingPhaseAutorouters){let legacyAutorouterPreset=getLegacyAutorouterPreset(autorouter);if(legacyAutorouterPreset)return legacyAutorouterPreset}return null},ensureRouteStartsAtSourceTraceStart=({db:db22,route:route2,routeThicknessMode,sourceTraceId})=>{if(!sourceTraceId||route2.length<2)return route2;let firstSourcePortId=db22.source_trace.get(sourceTraceId)?.connected_source_port_ids[0];if(!firstSourcePortId)return route2;let firstPcbPort=db22.pcb_port.list().find(port=>port.source_port_id===firstSourcePortId);if(!firstPcbPort)return route2;let firstPoint=route2[0],lastPoint=route2[route2.length-1];return getDistanceToPoint(lastPoint,firstPcbPort)<getDistanceToPoint(firstPoint,firstPcbPort)?reversePcbTraceRoute(route2,routeThicknessMode):route2},Group=class extends NormalComponent{constructor(){super(...arguments);__publicField(this,"pcb_group_id",null);__publicField(this,"schematic_group_id",null);__publicField(this,"subcircuit_id",null);__publicField(this,"_hasStartedAsyncAutorouting",!1);__publicField(this,"_pcbPlacementDrcErrorCount",null);__publicField(this,"_pcbPlacementDrcCheckError",null);__publicField(this,"_pcbPlacementDrcChecksPending",!1);__publicField(this,"_standaloneSubcircuitDrcChecksComplete",!1);__publicField(this,"_standaloneSubcircuitDrcChecksInProgress",!1);__publicField(this,"_isInflatedFromCircuitJson",!1);__publicField(this,"_isolatedCircuitJson",null);__publicField(this,"_normalComponentNameMap",null);__publicField(this,"_asyncAutoroutingResult",null);__publicField(this,"unnamedElementCounter",{})}get _isIsolatedSubcircuit(){return!!this.getInheritedProperty("_subcircuitCachingEnabled")}getNormalComponentNameMap(){if(this._normalComponentNameMap)return this._normalComponentNameMap;let nameMap=new Map,collectNamedComponents=component=>{if(component._isNormalComponent&&component.name){let componentsWithSameName=nameMap.get(component.name);componentsWithSameName?componentsWithSameName.push(component):nameMap.set(component.name,[component])}for(let child of component.children)child.isSubcircuit||collectNamedComponents(child)};for(let child of this.children)child.isSubcircuit||collectNamedComponents(child);return this._normalComponentNameMap=nameMap,nameMap}get config(){return{zodProps:groupProps,componentName:"Group"}}initPorts(opts={}){let schPinArrangement=this._getSchematicPortArrangement();this._parsedProps?.showAsSchematicBox&&!this._parsedProps.pinLabels&&schPinArrangement&&getPinsFromPortArrangement(schPinArrangement).some(pin=>typeof pin=="string")||super.initPorts(opts)}_getSchematicPortArrangementFromPortDirections(){if(!this._parsedProps?.showAsSchematicBox)return null;let sidePins={leftSide:[],rightSide:[],topSide:[],bottomSide:[]};for(let port of this.children){if(port.componentName!=="Port")continue;let direction4=port._parsedProps.direction;if(!direction4)continue;let pin=port._parsedProps.pinNumber??port._parsedProps.name??void 0;if(pin===void 0)continue;sidePins[direction4==="left"?"leftSide":direction4==="right"?"rightSide":direction4==="up"?"topSide":"bottomSide"].push(pin)}if(sidePins.leftSide.length===0&&sidePins.rightSide.length===0&&sidePins.topSide.length===0&&sidePins.bottomSide.length===0)return null;let arrangement={};return sidePins.leftSide.length>0&&(arrangement.leftSide={pins:sidePins.leftSide,direction:"top-to-bottom"}),sidePins.rightSide.length>0&&(arrangement.rightSide={pins:sidePins.rightSide,direction:"top-to-bottom"}),sidePins.topSide.length>0&&(arrangement.topSide={pins:sidePins.topSide,direction:"left-to-right"}),sidePins.bottomSide.length>0&&(arrangement.bottomSide={pins:sidePins.bottomSide,direction:"left-to-right"}),arrangement}_getSchematicPortArrangement(){return super._getSchematicPortArrangement()??this._getSchematicPortArrangementFromPortDirections()}_ensureSchematicBoxPortsFromConnections(){if(this._parsedProps?.showAsSchematicBox&&this._parsedProps?.connections)for(let[pinName,target]of Object.entries(this._parsedProps.connections)){if(this.children.find(child=>child.componentName==="Port"&&child.isMatchingAnyOf([pinName])))continue;let pinNumberMatch=pinName.match(/^pin(\d+)$/i)??pinName.match(/^(\d+)$/),pinNumber2=pinNumberMatch?Number(pinNumberMatch[1]):void 0;this.add(new Port({name:pinName,pinNumber:pinNumber2,connectsTo:target}))}}doInitialInitializePortsFromChildren(){super.doInitialInitializePortsFromChildren(),this._ensureSchematicBoxPortsFromConnections()}updateInitializePortsFromChildren(){super.updateInitializePortsFromChildren(),this._ensureSchematicBoxPortsFromConnections()}_getPrimaryPinCount(){let superPinCount=super._getPrimaryPinCount();if(!this._parsedProps?.showAsSchematicBox)return superPinCount;let directPortPinNumbers=this.children.filter(child=>child.componentName==="Port").map(port=>port._parsedProps.pinNumber).filter(pinNumber2=>pinNumber2!==void 0);return directPortPinNumbers.length===0?superPinCount:Math.max(superPinCount,...directPortPinNumbers)}_getPinLabelsFromPorts(){return this._parsedProps?.showAsSchematicBox?getGroupSchematicBoxPinLabels(this):super._getPinLabelsFromPorts()}doInitialSourceGroupRender(){let{db:db22}=this.root,hasExplicitName=typeof this._parsedProps.name=="string"&&this._parsedProps.name.length>0,source_group23=db22.source_group.insert({name:this.name,is_subcircuit:this.isSubcircuit,was_automatically_named:!hasExplicitName});this.source_group_id=source_group23.source_group_id,this.isSubcircuit&&(this.subcircuit_id=`subcircuit_${source_group23.source_group_id}`,db22.source_group.update(source_group23.source_group_id,{subcircuit_id:this.subcircuit_id}))}doInitialSourceRender(){let{db:db22}=this.root;for(let child of this.getDescendants())child.getGroup()?.source_group_id===this.source_group_id&&db22.source_component.update(child.source_component_id,{source_group_id:this.source_group_id});if(!this.isSubcircuit)return;let disabledLegacyAutorouterPreset=getDisabledLegacyAutorouterPreset(this);disabledLegacyAutorouterPreset&&db22.source_invalid_component_property_error.insert({source_component_id:this.source_component_id??"",property_name:"autorouter",error_type:"source_invalid_component_property_error",message:`The "${disabledLegacyAutorouterPreset}" autorouter is deprecated and is not enabled by this platform. Use the default autorouter and introduce <autoroutingphase /> or <fanout /> elements as needed.`})}doInitialSourceParentAttachment(){let{db:db22}=this.root,parentGroup=this.parent?.getGroup?.();if(parentGroup?.source_group_id&&db22.source_group.update(this.source_group_id,{parent_source_group_id:parentGroup.source_group_id}),!this.isSubcircuit||isAssemblyDeviceContainer(this.parent))return;let parent_subcircuit_id=this.parent?.getSubcircuit?.()?.subcircuit_id;parent_subcircuit_id&&db22.source_group.update(this.source_group_id,{parent_subcircuit_id})}doInitialPcbComponentRender(){if(this.root?.pcbDisabled)return;let{db:db22}=this.root,{_parsedProps:props}=this,groupProps22=props,hasOutline=groupProps22.outline&&groupProps22.outline.length>0,numericOutline=hasOutline?groupProps22.outline.map(point12=>({x:distance4.parse(point12.x),y:distance4.parse(point12.y)})):void 0,ctx=this.props,anchorPosition=this._getGlobalPcbPositionBeforeLayout(),center2=computeCenterFromAnchorPosition(anchorPosition,ctx),pcb_group32=db22.pcb_group.insert({is_subcircuit:this.isSubcircuit,subcircuit_id:this.subcircuit_id??this.getSubcircuit()?.subcircuit_id,name:this.name,anchor_position:anchorPosition,center:center2,...hasOutline?{outline:numericOutline}:{width:0,height:0},pcb_component_ids:[],source_group_id:this.source_group_id,autorouter_configuration:props.autorouter?{trace_clearance:props.autorouter.traceClearance}:void 0,anchor_alignment:props.pcbAnchorAlignment??"center"});this.pcb_group_id=pcb_group32.pcb_group_id;for(let child of this.children)db22.pcb_component.update(child.pcb_component_id,{pcb_group_id:pcb_group32.pcb_group_id})}doInitialPcbPrimitiveRender(){this.calculatePcbGroupBounds()}calculatePcbGroupBounds(pcbContentBounds){if(!this.pcb_group_id||this.root?.pcbDisabled)return;let{db:db22}=this.root,props=this._parsedProps,hasOutline=props.outline&&props.outline.length>0,hasExplicitPositioning=this._parsedProps.pcbX!==void 0||this._parsedProps.pcbY!==void 0;if(hasOutline){let numericOutline=props.outline.map(point12=>({x:distance4.parse(point12.x),y:distance4.parse(point12.y)})),outlineBounds=getBoundsFromPoints3(numericOutline);if(!outlineBounds)return;let centerX2=(outlineBounds.minX+outlineBounds.maxX)/2,centerY2=(outlineBounds.minY+outlineBounds.maxY)/2,center22=hasExplicitPositioning?db22.pcb_group.get(this.pcb_group_id)?.center??{x:centerX2,y:centerY2}:{x:centerX2,y:centerY2};db22.pcb_group.update(this.pcb_group_id,{center:center22});return}let contentBounds=pcbContentBounds;if(!contentBounds){let bounds=getBoundsOfPcbComponents(this.children);contentBounds={center:{x:(bounds.minX+bounds.maxX)/2,y:(bounds.minY+bounds.maxY)/2},width:bounds.width,height:bounds.height}}let{width:width10,height:height10}=contentBounds,{x:centerX,y:centerY}=contentBounds.center;if(this.isSubcircuit||this.isRoutingDirective){let{padLeft,padRight,padTop,padBottom}=this._resolvePcbPadding();width10+=padLeft+padRight,height10+=padTop+padBottom,centerX+=(padRight-padLeft)/2,centerY+=(padTop-padBottom)/2}let resolvedWidth=Number(props.width??width10),resolvedHeight=Number(props.height??height10),existingCenter=db22.pcb_group.get(this.pcb_group_id)?.center??{x:centerX,y:centerY},shouldUsePcbContentCenter=this.isSubcircuit||this.isRoutingDirective||pcbContentBounds!==void 0,center2=hasExplicitPositioning?shouldUsePcbContentCenter?{x:props.width===void 0?centerX:existingCenter.x,y:props.height===void 0?centerY:existingCenter.y}:existingCenter:{x:centerX,y:centerY};if(hasExplicitPositioning&&props.pcbAnchorAlignment){let anchorPosition=this._getGlobalPcbPositionBeforeLayout(),anchorAlignedCenter=computeCenterFromAnchorPosition(anchorPosition,{...this.props,width:resolvedWidth,height:resolvedHeight});(Math.abs(anchorAlignedCenter.x-center2.x)>1e-6||Math.abs(anchorAlignedCenter.y-center2.y)>1e-6)&&this._repositionOnPcb(anchorAlignedCenter),center2=anchorAlignedCenter}db22.pcb_group.update(this.pcb_group_id,{width:resolvedWidth,height:resolvedHeight,center:center2})}updatePcbPrimitiveRender(){this.calculatePcbGroupBounds()}getNextAvailableName(elm){var _a548,_b5;return(_a548=this.unnamedElementCounter)[_b5=elm.lowercaseComponentName]??(_a548[_b5]=1),`unnamed_${elm.lowercaseComponentName}${this.unnamedElementCounter[elm.lowercaseComponentName]++}`}_resolvePcbPadding(){let props=this._parsedProps,layout=props.pcbLayout,getPaddingValue=key=>{let layoutValue=layout?.[key],propsValue=props[key];if(typeof layoutValue=="number")return layoutValue;if(typeof propsValue=="number")return propsValue},generalPadding=getPaddingValue("padding")??0,paddingX=getPaddingValue("paddingX"),paddingY=getPaddingValue("paddingY"),padLeft=getPaddingValue("paddingLeft")??paddingX??generalPadding,padRight=getPaddingValue("paddingRight")??paddingX??generalPadding,padTop=getPaddingValue("paddingTop")??paddingY??generalPadding,padBottom=getPaddingValue("paddingBottom")??paddingY??generalPadding;return{padLeft,padRight,padTop,padBottom}}doInitialCreateTraceHintsFromProps(){let{_parsedProps:props}=this,{db:db22}=this.root,groupProps22=props;if(!this.isSubcircuit)return;let manualTraceHints=groupProps22.manualEdits?.manual_trace_hints;if(manualTraceHints)for(let manualTraceHint of manualTraceHints)this.add(new TraceHint({for:manualTraceHint.pcb_port_selector,offsets:manualTraceHint.offsets}))}doInitialSourceAddConnectivityMapKey(){Group_doInitialSourceAddConnectivityMapKey(this),Group_doInitialAssignSchematicSheetToConnectedComponents(this)}_areChildSubcircuitsRouted(){let subcircuitChildren=this._findDirectChildSubcircuits();for(let subcircuitChild of subcircuitChildren)if(!subcircuitChild._isInflatedFromCircuitJson&&subcircuitChild._hasTracesToRoute()&&subcircuitChild._shouldRouteAsync()&&!subcircuitChild._asyncAutoroutingResult)return!1;return!0}_findDirectChildSubcircuits(){let result=[],visit=children=>{for(let child of children)child.isSubcircuit&&child!==this?result.push(child):visit(child.children)};return visit(this.children),result}_shouldRouteAsync(){if(this._isLegacyAutorouterDisabled())return!1;let autorouter=this._getAutorouterConfig();return autorouter.groupMode==="sequential-trace"?!1:!!(autorouter.local&&autorouter.groupMode==="subcircuit"||!autorouter.local)}_getRoutingPhasePlans(){let plans=Group_getRoutingPhasePlans(this),testPointPhases=plans.filter(plan=>plan.testPointOptions);if(testPointPhases.length>1||testPointPhases.length===1&&plans.at(-1)!==testPointPhases[0])throw new Error("Use a single final autorouting phase for PCB test points");return plans}_hasTracesToRoute(){let debug132=(0,import_debug11.default)("tscircuit:core:_hasTracesToRoute"),routingPhasePlans=this._getRoutingPhasePlans(),traceCount=0,hasReroutePhaseWithExistingTraceInput=!1;for(let routingPhasePlan of routingPhasePlans){traceCount+=routingPhasePlan.traces.length;let phaseAutorouterConfig=routingPhasePlan.autorouter?getPresetAutoroutingConfig(routingPhasePlan.autorouter,this.root?.platform):void 0;hasReroutePhaseWithExistingTraceInput||(hasReroutePhaseWithExistingTraceInput=!!(routingPhasePlan.reroute&&(routingPhasePlan.region||phaseAutorouterConfig?.preset==="simplify")))}if(debug132(`[${this.getString()}] has ${traceCount} traces to route`),traceCount>0)return!0;if(hasReroutePhaseWithExistingTraceInput){let existingTraceCount=getExistingPcbTracesForReroute(this).length;return debug132(`[${this.getString()}] has ${existingTraceCount} existing pcb traces available for reroute`),existingTraceCount>0}return!1}async _runEffectMakeHttpAutoroutingRequest(){let{db:db22}=this.root,debug132=(0,import_debug11.default)("tscircuit:core:_runEffectMakeHttpAutoroutingRequest"),props=this._parsedProps,autorouterConfig3=this._getAutorouterConfig(),serverUrl=autorouterConfig3.serverUrl,serverMode=autorouterConfig3.serverMode,fetchWithDebug=(url3,options)=>(debug132("fetching",url3),options.headers&&(options.headers["Tscircuit-Core-Version"]=this.root?.getCoreVersion()),fetch(url3,options)),pcbAndSourceCircuitJson=this.root.db.toArray().filter(element2=>element2.type.startsWith("source_")||element2.type.startsWith("pcb_")),preferredTraceWidth=props.defaultTraceWidth??props.nominalTraceWidth,{simpleRouteJson}=getSimpleRouteJsonFromCircuitJson({pcb_panel_id:getOwningPanel(this)?.pcb_panel_id??void 0,db:db22,allowViaInPad:autorouterConfig3.allowViaInPad,minTraceWidth:Number(props.minTraceWidth??.15),nominalTraceWidth:preferredTraceWidth!=null?Number(preferredTraceWidth):void 0,subcircuit_id:this.subcircuit_id,subcircuitComponent:this}),unbrokenPlaneRouteJson=simpleRouteJson.obstacles.some(obstacle=>obstacle.isCopperPour)?simpleRouteJson:void 0;if(serverMode==="solve-endpoint"){let simplifiedInput=this.props.autorouter?.inputFormat==="simplified",{autorouting_result}=await fetchWithDebug(`${serverUrl}/autorouting/solve`,{method:"POST",body:JSON.stringify({input_circuit_json:simplifiedInput?void 0:pcbAndSourceCircuitJson,input_simple_route_json:simplifiedInput?simpleRouteJson:unbrokenPlaneRouteJson,subcircuit_id:this.subcircuit_id}),headers:{"Content-Type":"application/json"}}).then(r23=>r23.json());this._asyncAutoroutingResult=autorouting_result,this._markDirty("PcbTraceRender");return}let{autorouting_job}=await fetchWithDebug(`${serverUrl}/autorouting/jobs/create`,{method:"POST",body:JSON.stringify({input_circuit_json:pcbAndSourceCircuitJson,input_simple_route_json:unbrokenPlaneRouteJson,provider:"freerouting",autostart:!0,display_name:this.root?.name,subcircuit_id:this.subcircuit_id,server_cache_enabled:autorouterConfig3.serverCacheEnabled}),headers:{"Content-Type":"application/json"}}).then(r23=>r23.json());for(;;){let{autorouting_job:job}=await fetchWithDebug(`${serverUrl}/autorouting/jobs/get`,{method:"POST",body:JSON.stringify({autorouting_job_id:autorouting_job.autorouting_job_id}),headers:{"Content-Type":"application/json"}}).then(r23=>r23.json());if(job.is_finished){let{autorouting_job_output}=await fetchWithDebug(`${serverUrl}/autorouting/jobs/get_output`,{method:"POST",body:JSON.stringify({autorouting_job_id:autorouting_job.autorouting_job_id}),headers:{"Content-Type":"application/json"}}).then(r23=>r23.json());this._asyncAutoroutingResult={output_pcb_traces:autorouting_job_output.output_pcb_traces},this._markDirty("PcbTraceRender");break}if(job.has_error){let err2=new AutorouterError(`Autorouting job failed: ${JSON.stringify(job.error)}`);throw db22.pcb_autorouting_error.insert({pcb_error_id:autorouting_job.autorouting_job_id,error_type:"pcb_autorouting_error",message:err2.message}),err2}await new Promise(resolve10=>setTimeout(resolve10,100))}}async _runLocalAutorouting(){let{db:db22}=this.root,props=this._parsedProps,debug132=(0,import_debug11.default)("tscircuit:core:_runLocalAutorouting");debug132(`[${this.getString()}] starting local autorouting`);let autorouterConfig3=this._getAutorouterConfig(),isLaserPrefabPreset=this._isLaserPrefabAutorouter(autorouterConfig3),isAutoJumperPreset=this._isAutoJumperAutorouter(autorouterConfig3),isSingleLayerBoard=this._getSubcircuitLayerCount()===1,minTraceWidth=Number(props.minTraceWidth??.15),nominalTraceWidth=Number(props.defaultTraceWidth??props.nominalTraceWidth??minTraceWidth),routingPhasePlans=this._getRoutingPhasePlans(),hasPhasedAutorouting=this.getInheritedProperty("routeRemaining")===!1||Group_hasPhasedAutorouting(routingPhasePlans),shouldEmitRoutingPhaseDebugObjects=routingPhasePlans.length>1,routingPhaseDebugLabels=new Map;if(shouldEmitRoutingPhaseDebugObjects)for(let debugObject of db22.pcb_debug_object.list())debugObject.subcircuit_id===this.subcircuit_id&&(debugObject.label?.startsWith("Autorouting phase: ")||debugObject.label?.startsWith("autorouting phase "))&&db22.pcb_debug_object.delete(debugObject.pcb_debug_object_id);let emitRoutingPhaseDebugObject=(routingPhasePlan,bounds)=>{if(!shouldEmitRoutingPhaseDebugObjects)return;let phaseLabel=routingPhaseDebugLabels.get(routingPhasePlan),phaseName=routingPhasePlan.phaseName?.trim();db22.pcb_debug_object.insert({shape:"rect",center:{x:(bounds.minX+bounds.maxX)/2,y:(bounds.minY+bounds.maxY)/2},size:{width:bounds.maxX-bounds.minX,height:bounds.maxY-bounds.minY},label:`autorouting phase ${phaseLabel}${phaseName?` ${phaseName}`:""}`,subcircuit_id:this.subcircuit_id??void 0})},routingStages=routingPhasePlans.flatMap(routingPhasePlan=>{let resolvedPhaseAutorouterConfig=routingPhasePlan.autorouter?getPresetAutoroutingConfig(routingPhasePlan.autorouter,this.root?.platform):autorouterConfig3,preset=resolvedPhaseAutorouterConfig.preset,implicitPhaseLabel=routingPhasePlan.testPointOptions?"test points":routingPhasePlan.reroute?preset==="simplify"?"simplify":"reroute":routingPhasePlan.fanoutRegionPcbGroupId?routingPhasePlan.autorouter==="default"&&!routingPhasePlan.getPrecomputedRoutingResult?"breakout":"fanout":preset&&preset!=="default"?preset.replaceAll("_"," "):"default";routingPhaseDebugLabels.set(routingPhasePlan,routingPhasePlan.routingPhaseIndex?.toString()??implicitPhaseLabel);let phaseAutorouterConfig=routingPhasePlan.getPrecomputedRoutingResult?{...resolvedPhaseAutorouterConfig,allowViaInPad:(typeof routingPhasePlan.autorouter=="object"?routingPhasePlan.autorouter.allowViaInPad:void 0)??autorouterConfig3.allowViaInPad}:resolvedPhaseAutorouterConfig,stages=getLocalAutoroutingStages(routingPhasePlan.testPointOptions?{local:!0,groupMode:"subcircuit",preset:"default"}:routingPhasePlan.algorithmFn?{...phaseAutorouterConfig,algorithmFn:routingPhasePlan.algorithmFn}:phaseAutorouterConfig,this.root?.platform);return stages.map((stage,phaseStageIndex)=>({...stage,routingPhasePlan,phaseStageIndex,phaseStageCount:stages.length}))}),implicitPhaseLabelCounts=new Map;for(let plan of routingPhasePlans){if(plan.routingPhaseIndex!==null)continue;let label=routingPhaseDebugLabels.get(plan);implicitPhaseLabelCounts.set(label,(implicitPhaseLabelCounts.get(label)??0)+1)}let implicitPhaseLabelOrdinals=new Map;for(let plan of routingPhasePlans){if(plan.routingPhaseIndex!==null)continue;let label=routingPhaseDebugLabels.get(plan);if(implicitPhaseLabelCounts.get(label)<=1)continue;let ordinal=(implicitPhaseLabelOrdinals.get(label)??0)+1;implicitPhaseLabelOrdinals.set(label,ordinal),routingPhaseDebugLabels.set(plan,`${label} ${ordinal}`)}let fanoutPourNetMap=routingStages.some(({autorouterConfig:autorouterConfig22})=>["fanout","single_layer_fanout","dogbone"].includes(autorouterConfig22.preset??""))?Group_getFanoutPourNetMap(this,routingPhasePlans):void 0,{simpleRouteJson:baseSimpleRouteJson}=getSimpleRouteJsonFromCircuitJson({pcb_panel_id:getOwningPanel(this)?.pcb_panel_id??void 0,db:db22,minTraceWidth,nominalTraceWidth,subcircuit_id:this.subcircuit_id,subcircuitComponent:this,fanoutPourNetMap}),emitFanoutBoundsConflictWarning=routingPhasePlan=>{let fanoutRegionPcbGroupId=routingPhasePlan.fanoutRegionPcbGroupId;if(!fanoutRegionPcbGroupId)return;let pcbGroup=db22.pcb_group.get(fanoutRegionPcbGroupId),sourceComponentId=db22.pcb_component.list().find(component=>component.pcb_group_id===fanoutRegionPcbGroupId)?.source_component_id;if(!sourceComponentId)return;let message=`${pcbGroup?.name??"Breakout"} defines conflicting fanout bounds with explicit breakout geometry and fanoutBoundaryPadding. Explicit breakout geometry takes precedence, so fanoutBoundaryPadding is ignored.`;db22.source_property_ignored_warning.list().some(warning=>warning.source_component_id===sourceComponentId&&warning.property_name==="fanoutBoundaryPadding"&&warning.message===message)||db22.source_property_ignored_warning.insert({source_component_id:sourceComponentId,property_name:"fanoutBoundaryPadding",message,error_type:"source_property_ignored_warning",subcircuit_id:pcbGroup?.subcircuit_id})},fanoutConfigByPhasePlan=new Map;for(let routingStage of routingStages){let fanoutMode=routingStage.autorouterConfig.preset;(fanoutMode==="fanout"||fanoutMode==="single_layer_fanout")&&!fanoutConfigByPhasePlan.has(routingStage.routingPhasePlan)&&fanoutConfigByPhasePlan.set(routingStage.routingPhasePlan,routingStage.autorouterConfig)}let fanoutPhaseRegions=[];for(let[routingPhasePlan,phaseAutorouterConfig]of fanoutConfigByPhasePlan){let fanoutRegionPcbGroupId=routingPhasePlan.fanoutRegionPcbGroupId;if(!fanoutRegionPcbGroupId)continue;let phaseSimpleRouteJson=Group_filterSimpleRouteJsonForPhase(baseSimpleRouteJson,routingPhasePlan);if(phaseSimpleRouteJson.connections.length===0)continue;phaseSimpleRouteJson=Group_applyDrcTolerancesToSimpleRouteJson(phaseSimpleRouteJson,routingPhasePlan.drcTolerances);let breakoutPoints=db22.pcb_breakout_point.list().filter(point12=>point12.pcb_group_id===fanoutRegionPcbGroupId).map(point12=>({x:point12.x,y:point12.y})),fanoutMode=phaseAutorouterConfig.preset,fanoutBounds=FanoutAutorouter.resolveFanoutBounds(phaseSimpleRouteJson,{mode:fanoutMode,busFanoutDirections:routingPhasePlan.busFanoutDirections,fanoutBounds:routingPhasePlan.fanoutBounds,fanoutBoundaryPadding:routingPhasePlan.fanoutBoundaryPadding,fanoutRoutingLayers:routingPhasePlan.fanoutRoutingLayers,allowBlindAndBuriedVias:phaseSimpleRouteJson.allowBlindAndBuriedVias,breakoutPoints,onFanoutBoundsConflict:()=>emitFanoutBoundsConflictWarning(routingPhasePlan)});if(routingPhasePlan.fanoutBounds=fanoutBounds,!fanoutBounds)continue;let pcbGroup=db22.pcb_group.get(fanoutRegionPcbGroupId),maximumTraceWidth=Math.max(phaseSimpleRouteJson.minTraceWidth,...phaseSimpleRouteJson.connections.map(connection=>connection.nominalTraceWidth??connection.width??phaseSimpleRouteJson.minTraceWidth)),viaPadDiameter=phaseSimpleRouteJson.minViaPadDiameter??phaseSimpleRouteJson.min_via_pad_diameter??phaseSimpleRouteJson.minViaDiameter,traceToPadClearance=phaseSimpleRouteJson.minTraceToPadEdgeClearance??phaseSimpleRouteJson.defaultObstacleMargin??maximumTraceWidth;fanoutPhaseRegions.push({regionId:fanoutRegionPcbGroupId,name:pcbGroup?.name??routingPhasePlan.phaseName??fanoutRegionPcbGroupId,bounds:fanoutBounds,boundaryKeepaway:getFanoutBoundaryPointSpacing({traceWidth:maximumTraceWidth,traceToPadClearance,viaPadDiameter})/2})}let fanoutSeparationConflict=findFanoutPhaseSeparationConflict(fanoutPhaseRegions);if(fanoutSeparationConflict){let{firstRegion,secondRegion,availableGap,requiredGap}=fanoutSeparationConflict,separationDescription=availableGap<0?`overlap by ${Math.abs(availableGap).toFixed(3)}mm`:`are only ${availableGap.toFixed(3)}mm apart`,message=`Fanout regions "${firstRegion.name}" and "${secondRegion.name}" ${separationDescription}, but at least ${requiredGap.toFixed(3)}mm of separation is required for a via-safe routing channel. Move the components farther apart or reduce their facing fanout padding.`;throw db22.pcb_autorouting_error.insert({pcb_error_id:`pcb_autorouter_error_subcircuit_${this.subcircuit_id}`,error_type:"pcb_autorouting_error",message}),this.root?.emit("autorouting:error",{subcircuit_id:this.subcircuit_id,componentDisplayName:this.getString(),error:{message},simpleRouteJson:baseSimpleRouteJson}),new Error(message)}for(let{regionId,bounds}of fanoutPhaseRegions)db22.pcb_group.update(regionId,{center:{x:(bounds.minX+bounds.maxX)/2,y:(bounds.minY+bounds.maxY)/2},width:bounds.maxX-bounds.minX,height:bounds.maxY-bounds.minY});let outputTestPoints=[],routingError,outputTraces=[],outputJumpers=[],pcbTraceIdsToDelete=new Set,existingRerouteSeedTraces=getExistingSimplifiedPcbTracesForReroute(this),traceMatchesRoutingPhase=(trace,routingPhasePlan)=>{let connectionName=trace.connection_name??trace.pcb_trace_id,sourceTraceIds=new Set([connectionName,trace.pcb_trace_id,...getSourceTraceIdsFromRerouteName(connectionName),...getSourceTraceIdsFromRerouteName(trace.pcb_trace_id)]);return baseSimpleRouteJson.connections.some(connection=>connectionIsInRoutingPhase(connection,routingPhasePlan)?sourceTraceIds.has(connection.name)||(connection.source_trace_id?sourceTraceIds.has(connection.source_trace_id):!1)||(connection.rootConnectionName?sourceTraceIds.has(connection.rootConnectionName):!1)||connection.mergedConnectionNames?.some(name=>sourceTraceIds.has(name)):!1)},manualSourceTraceIds=new Set(this.getDescendants().filter(child=>child instanceof Trace&&!child.getSubcircuit()._isInflatedFromCircuitJson&&!!child._parsedProps.pcbPath?.length).map(trace=>trace.source_trace_id)),manualPcbTraceIds=new Set(db22.pcb_trace.list().filter(trace=>trace.source_trace_id&&manualSourceTraceIds.has(trace.source_trace_id)).map(trace=>trace.pcb_trace_id)),fixedTraceIds=new Set(manualPcbTraceIds),previousStageOutputSimpleRouteJson,skippedRemainingPhases=new Set;for(let[routingStageIndex,{routingPhasePlan,autorouterConfig:phaseAutorouterConfig,strategy:localAutorouterStrategy,usesPreviousStageOutput,phaseStageIndex,phaseStageCount}]of routingStages.entries()){if(skippedRemainingPhases.has(routingPhasePlan))continue;if(usesPreviousStageOutput||(previousStageOutputSimpleRouteJson=void 0),usesPreviousStageOutput&&previousStageOutputSimpleRouteJson===void 0)throw new Error("Autorouting follow-up stage is missing the preceding stage output");let simpleRouteJson=previousStageOutputSimpleRouteJson??baseSimpleRouteJson,isTestPointPhase=!!routingPhasePlan.testPointOptions,isTraceSimplificationPhase=!!(routingPhasePlan.reroute&&phaseAutorouterConfig.preset==="simplify"),preservesExistingTraceInput=isTraceSimplificationPhase||isTestPointPhase,isRegionReroutePhase=!!(routingPhasePlan.reroute&&routingPhasePlan.region&&!preservesExistingTraceInput),isConnectionReroutePhase=!!(routingPhasePlan.reroute&&!preservesExistingTraceInput&&!routingPhasePlan.region&&routingPhasePlan.traces.length>0),isReroutePhase=isRegionReroutePhase||isConnectionReroutePhase||preservesExistingTraceInput,rerouteOriginalSrj=isRegionReroutePhase?{...baseSimpleRouteJson,traces:[...existingRerouteSeedTraces,...outputTraces]}:null;if(!usesPreviousStageOutput&&preservesExistingTraceInput)simpleRouteJson={...Group_filterSimpleRouteJsonForPhase(baseSimpleRouteJson,routingPhasePlan),traces:getAccumulatedPcbTracesWithStageOutputReplacements({accumulatedPcbTraces:existingRerouteSeedTraces,stageOutputPcbTraces:outputTraces})};else if(!usesPreviousStageOutput&&isRegionReroutePhase&&rerouteOriginalSrj)simpleRouteJson=Jhe(rerouteOriginalSrj,{shape:"rect",...routingPhasePlan.region});else if(!usesPreviousStageOutput&&isConnectionReroutePhase){let phaseInput=Group_filterSimpleRouteJsonForPhase(baseSimpleRouteJson,routingPhasePlan);simpleRouteJson={...phaseInput,traces:[...phaseInput.traces??[],...outputTraces.filter(trace=>!traceMatchesRoutingPhase(trace,routingPhasePlan))]}}else if(!usesPreviousStageOutput&&hasPhasedAutorouting){let phaseInput=Group_filterSimpleRouteJsonForPhase(baseSimpleRouteJson,routingPhasePlan),activeCustomBreakoutRoutingGroupId=routingPhasePlan.routingPcbGroupId;if(activeCustomBreakoutRoutingGroupId){let activeGroupCopperPourObstacles=getSimpleRouteJsonFromCircuitJson({pcb_panel_id:getOwningPanel(this)?.pcb_panel_id??void 0,db:db22,minTraceWidth,nominalTraceWidth,subcircuit_id:this.subcircuit_id,subcircuitComponent:this,routingPcbGroupId:activeCustomBreakoutRoutingGroupId,fanoutPourNetMap}).simpleRouteJson.obstacles.filter(obstacle=>obstacle.isCopperPour),nonCopperPourObstacles=phaseInput.obstacles.filter(obstacle=>!obstacle.isCopperPour);phaseInput.obstacles=nonCopperPourObstacles.concat(activeGroupCopperPourObstacles)}simpleRouteJson={...phaseInput,traces:getAccumulatedPcbTracesWithStageOutputReplacements({accumulatedPcbTraces:phaseInput.traces??[],stageOutputPcbTraces:outputTraces})}}if(phaseAutorouterConfig.preset!=="bus_lanes"&&!isTestPointPhase){let preservesManualTraceGeometry=!phaseAutorouterConfig.algorithmFn&&(phaseAutorouterConfig.preset==="fanout"||phaseAutorouterConfig.preset==="single_layer_fanout");simpleRouteJson=withFixedTraces(simpleRouteJson,preservesManualTraceGeometry?new Set([...fixedTraceIds].filter(pcbTraceId=>!manualPcbTraceIds.has(pcbTraceId))):fixedTraceIds)}simpleRouteJson=Group_applyDrcTolerancesToSimpleRouteJson(simpleRouteJson,routingPhasePlan.drcTolerances),simpleRouteJson.allowViaInPad=phaseAutorouterConfig.allowViaInPad??simpleRouteJson.allowViaInPad;let getPrecomputedRoutingResult=usesPreviousStageOutput?void 0:routingPhasePlan.getPrecomputedRoutingResult,preflightRoutingCheckPolicy3=this.getInheritedProperty("preflightRoutingCheckPolicy")??"basic";if(routingPhasePlan.isImplicitRemainingPhase&&phaseStageIndex===0&&this.getInheritedProperty("routeRemaining")===void 0&&(preflightRoutingCheckPolicy3==="basic"||preflightRoutingCheckPolicy3==="conservative")&&simpleRouteJson.connections.length>50){skippedRemainingPhases.add(routingPhasePlan),db22.pcb_autorouting_error.insert({pcb_error_id:`pcb_autorouting_error_remaining_routes_${this.subcircuit_id}`,subcircuit_id:this.subcircuit_id??void 0,error_type:"pcb_autorouting_error",message:`Remaining routes left unrouted (over 50 traces remaining and preflightRoutingCheckPolicy="${preflightRoutingCheckPolicy3}"). Set <board routeRemaining={true} /> or create <autoroutingphase /> elements for specific connections in the order you'd like to route them. The autorouter may hang unless you create autorouting phases incrementally.`});continue}let simplificationHasNoTraceInput=!!(isTraceSimplificationPhase&&simpleRouteJson.traces?.length===0);if((hasPhasedAutorouting||isReroutePhase||usesPreviousStageOutput)&&(simpleRouteJson.connections.length===0&&!preservesExistingTraceInput&&!getPrecomputedRoutingResult||simplificationHasNoTraceInput)){phaseStageIndex===0&&emitRoutingPhaseDebugObject(routingPhasePlan,simpleRouteJson.bounds),previousStageOutputSimpleRouteJson=simpleRouteJson;continue}let phaseIsAutoJumperPreset=routingPhasePlan.autorouter!==void 0?this._isAutoJumperAutorouter(phaseAutorouterConfig):isAutoJumperPreset,phaseIsLaserPrefabPreset=routingPhasePlan.autorouter!==void 0?this._isLaserPrefabAutorouter(phaseAutorouterConfig):isLaserPrefabPreset;phaseIsAutoJumperPreset&&(simpleRouteJson.allowJumpers=!0,phaseAutorouterConfig.availableJumperTypes&&(simpleRouteJson.availableJumperTypes=phaseAutorouterConfig.availableJumperTypes));let fanoutMode=phaseAutorouterConfig.preset;if((fanoutMode==="fanout"||fanoutMode==="single_layer_fanout")&&!routingPhasePlan.fanoutRegionPcbGroupId&&!getPrecomputedRoutingResult&&(routingPhasePlan.fanoutBounds=FanoutAutorouter.resolveFanoutBounds(simpleRouteJson,{mode:fanoutMode,busFanoutDirections:routingPhasePlan.busFanoutDirections,fanoutBounds:routingPhasePlan.fanoutBounds,fanoutBoundaryPadding:routingPhasePlan.fanoutBoundaryPadding,fanoutRoutingLayers:routingPhasePlan.fanoutRoutingLayers,allowBlindAndBuriedVias:simpleRouteJson.allowBlindAndBuriedVias})),phaseStageIndex===0&&emitRoutingPhaseDebugObject(routingPhasePlan,routingPhasePlan.fanoutBounds??simpleRouteJson.bounds),debug132.enabled&&global.debugOutputArray?.push({name:`simpleroutejson-${this.props.name}.json`,obj:simpleRouteJson}),debug132.enabled){let graphicsObject=Vo2(simpleRouteJson);graphicsObject.title=`autorouting-${this.props.name}`,global.debugGraphics?.push(graphicsObject)}let autorouterVersion22=phaseAutorouterConfig.autorouterVersion??this.props.autorouterVersion,effortLevel=this.props.autorouterEffortLevel,effort=effortLevel?Number.parseInt(effortLevel.replace("x",""),10):void 0,commonAutorouterOptions={capacityDepth:phaseAutorouterConfig.capacityDepth,targetMinCapacity:phaseAutorouterConfig.targetMinCapacity,platformConfig:this.root?.platform,useAssignableSolver:phaseIsLaserPrefabPreset||isSingleLayerBoard,useAutoJumperSolver:phaseIsAutoJumperPreset,useLaserPrefabSolver:phaseIsLaserPrefabPreset,autorouterVersion:autorouterVersion22,effort},autorouterName=isTestPointPhase?"test_points":getPrecomputedRoutingResult?"precomputed":phaseAutorouterConfig.algorithmFn?"custom":localAutorouterStrategy.name,solverName=isTestPointPhase||getPrecomputedRoutingResult||phaseAutorouterConfig.algorithmFn?void 0:localAutorouterStrategy.getSolverName(commonAutorouterOptions),localAutoroutingCacheSolverOptions={autorouterName,solverName,capacityDepth:commonAutorouterOptions.capacityDepth,targetMinCapacity:commonAutorouterOptions.targetMinCapacity,useAssignableSolver:commonAutorouterOptions.useAssignableSolver,useAutoJumperSolver:commonAutorouterOptions.useAutoJumperSolver,useLaserPrefabSolver:commonAutorouterOptions.useLaserPrefabSolver,useTraceSimplificationSolver:phaseAutorouterConfig.preset==="simplify",autorouterVersion:commonAutorouterOptions.autorouterVersion,effort:commonAutorouterOptions.effort},cacheEngine=isTestPointPhase||getPrecomputedRoutingResult||phaseAutorouterConfig.algorithmFn||!localAutorouterStrategy.cacheable?void 0:this.root?.platform?.localCacheEngine,cacheKey=cacheEngine?getLocalAutoroutingCacheKey(simpleRouteJson,localAutoroutingCacheSolverOptions):void 0,cachedResult=cacheKey?await getCachedLocalAutoroutingPhaseResult({cacheEngine,cacheKey}):null,cacheDisabledReason=getPrecomputedRoutingResult?"precomputed":phaseAutorouterConfig.algorithmFn?"custom_algorithm":localAutorouterStrategy.cacheable?cacheEngine?void 0:"no_cache_engine":"strategy_not_cacheable",autoroutingMetadata={routingPhaseIndex:routingPhasePlan.routingPhaseIndex,_actualRoutingPhaseOrderIndex:routingStageIndex,phaseOrdinal:routingStageIndex+1,phaseCount:routingStages.length,connectionCount:simpleRouteJson.connections.length,obstacleCount:simpleRouteJson.obstacles.length,previousTraceCount:simpleRouteJson.traces?.length??0,isReroutePhase,autorouterName,autorouterVersion:autorouterVersion22,solverName,effort,cacheStatus:cacheEngine?cachedResult?"hit":"miss":"disabled",cacheKey,cacheDisabledReason};this.root?.emit("autorouting:start",{type:"autorouting:start",subcircuit_id:this.subcircuit_id,componentDisplayName:this.getString(),...routingPhasePlan.phaseName!==void 0?{phaseName:routingPhasePlan.phaseName,phaseStageIndex,phaseStageCount}:{},...autoroutingMetadata,simpleRouteJson});let autorouter;try{let runAutorouter=async activeAutorouter=>{let routingPromise=new Promise((resolve10,reject)=>{activeAutorouter.on("complete",event=>{debug132(`[${this.getString()}] local autorouting complete`),resolve10(event.traces)}),activeAutorouter.on("error",event=>{debug132(`[${this.getString()}] local autorouting error: ${event.error.message}`),routingError=event.error,reject(event.error)})});return activeAutorouter.on("progress",event=>{this.root?.emit("autorouting:progress",{subcircuit_id:this.subcircuit_id,componentDisplayName:this.getString(),...routingPhasePlan.phaseName!==void 0?{phaseName:routingPhasePlan.phaseName,phaseStageIndex,phaseStageCount}:{},...autoroutingMetadata,...event,type:"autorouting:progress"})}),activeAutorouter.start(),await routingPromise},traces,precomputedOutputSimpleRouteJson;if(isTestPointPhase){let settings=routingPhasePlan.testPointOptions,selectedTraces=(simpleRouteJson.traces??[]).filter(trace=>traceMatchesRoutingPhase(trace,routingPhasePlan));if(selectedTraces.some(trace=>fixedTraceIds.has(trace.pcb_trace_id)))throw new Error("Test point phases cannot modify fixed PCB paths");if(selectedTraces.length===0)throw new Error("Test point phase has no selected routed traces");let probeInput={...simpleRouteJson,obstacles:[...simpleRouteJson.obstacles,...db22.pcb_component.list().filter(component=>!component.do_not_place).map(component=>({type:"rect",center:component.center,width:component.width,height:component.height,layers:[component.layer],ccwRotationDegrees:component.rotation,connectedTo:[]}))]},testPointAutorouter=new TestPointAutorouter(probeInput,{...settings,requests:selectedTraces.map((trace,index2)=>({name:`TP_AUTO_${routingStageIndex+1}_${index2+1}`,pcbTraceId:trace.pcb_trace_id,layer:settings.layer,diameter:settings.diameter}))});autorouter=testPointAutorouter,traces=await runAutorouter(testPointAutorouter);let result=testPointAutorouter.getOutputSimpleRouteJson();for(let point12 of testPointAutorouter.getTestPoints()){let trace=selectedTraces.find(trace2=>trace2.pcb_trace_id===point12.pcbTraceId),routedSourceId=getSourceTraceIdForRoutedTrace({db:db22,trace:{...trace,source_trace_id:trace.connection_name},subcircuit_id:this.subcircuit_id}),sourceTraceId=routedSourceId?db22.source_trace.get(routedSourceId)?.source_trace_id??db22.source_trace.list().find(sourceTrace=>sourceTrace.connected_source_net_ids.includes(routedSourceId))?.source_trace_id:void 0;if(!sourceTraceId)throw new Error(`Test point ${point12.name} has no source connection`);outputTestPoints.push({...point12,sourceTraceId})}traces=result.traces,precomputedOutputSimpleRouteJson=result,baseSimpleRouteJson={...baseSimpleRouteJson,obstacles:[...baseSimpleRouteJson.obstacles,...result.obstacles.slice(probeInput.obstacles.length)]};for(let trace of selectedTraces)fixedTraceIds.add(trace.pcb_trace_id)}else if(getPrecomputedRoutingResult){let result=getPrecomputedRoutingResult(simpleRouteJson);traces=result.traces,precomputedOutputSimpleRouteJson=result.outputSimpleRouteJson;for(let trace of traces)fixedTraceIds.add(trace.pcb_trace_id)}else if(cachedResult)debug132(`[${this.getString()}] using cached local autorouting result`),traces=cachedResult.traces;else{if(phaseAutorouterConfig.algorithmFn?autorouter=await phaseAutorouterConfig.algorithmFn(simpleRouteJson):autorouter=localAutorouterStrategy.create({simpleRouteJson,onSolverEnded:event=>this.root?.emit("solver:ended",{...event,type:"solver:ended",componentName:this.getString()}),commonAutorouterOptions,busFanoutDirections:routingPhasePlan.busFanoutDirections,fanoutBounds:routingPhasePlan.fanoutBounds,fanoutRoutingLayers:routingPhasePlan.fanoutRoutingLayers,allowBlindAndBuriedVias:simpleRouteJson.allowBlindAndBuriedVias,componentNamesById:getPcbComponentNamesById(db22),onSolverStarted:({solverName:solverName2,solverParams,solverConstructorArgs})=>this.root?.emit("solver:started",{type:"solver:started",solverName:solverName2,solverParams,solverConstructorArgs,componentName:this.getString()})}),!autorouter)throw new Error("Failed to create local autorouter");traces=await runAutorouter(autorouter)}let transformedSimpleRouteJson=precomputedOutputSimpleRouteJson??autorouter?.getOutputSimpleRouteJson?.();if(localAutorouterStrategy.preserveOutputTraces&&transformedSimpleRouteJson?.traces&&(transformedSimpleRouteJson={...transformedSimpleRouteJson,traces:getAccumulatedPcbTracesWithStageOutputReplacements({accumulatedPcbTraces:simpleRouteJson.traces??[],stageOutputPcbTraces:transformedSimpleRouteJson.traces})}),transformedSimpleRouteJson&&!usesPreviousStageOutput&&["fanout","single_layer_fanout","dogbone"].includes(phaseAutorouterConfig.preset??"")&&routingPhasePlan.routingPcbGroupId){let synchronizedFanout=Group_syncFanoutExitsWithGlobalConnections({fanoutInputSimpleRouteJson:simpleRouteJson,fanoutOutputSimpleRouteJson:transformedSimpleRouteJson,baseSimpleRouteJson,routingPhasePlan});baseSimpleRouteJson=synchronizedFanout.baseSimpleRouteJson,transformedSimpleRouteJson=synchronizedFanout.downstreamSimpleRouteJson;for(let synchronizedPoint of synchronizedFanout.synchronizedBreakoutPoints){let breakoutPoint=db22.pcb_breakout_point.list().find(point12=>point12.pcb_group_id===synchronizedPoint.routingPcbGroupId&&point12.source_trace_id===synchronizedPoint.sourceTraceId&&Math.abs(point12.x-synchronizedPoint.previousPoint.x)<=1e-6&&Math.abs(point12.y-synchronizedPoint.previousPoint.y)<=1e-6);breakoutPoint&&db22.pcb_breakout_point.update(breakoutPoint.pcb_breakout_point_id,{x:synchronizedPoint.fanoutExitPoint.x,y:synchronizedPoint.fanoutExitPoint.y,layer:synchronizedPoint.fanoutExitPoint.layer})}}if(localAutorouterStrategy.preserveOutputTraces)for(let trace of traces)fixedTraceIds.add(trace.pcb_trace_id);let stageOutputTraces=traces;transformedSimpleRouteJson?.traces?stageOutputTraces=transformedSimpleRouteJson.traces:usesPreviousStageOutput&&(stageOutputTraces=getAccumulatedPcbTracesWithStageOutputReplacements({accumulatedPcbTraces:simpleRouteJson.traces??[],stageOutputPcbTraces:traces}));let eventOutputPcbTraces=stageOutputTraces;!transformedSimpleRouteJson&&!usesPreviousStageOutput&&routingPhasePlan.routingPhaseIndex!==null&&(eventOutputPcbTraces=getAccumulatedPcbTracesWithStageOutputReplacements({accumulatedPcbTraces:simpleRouteJson.traces??[],stageOutputPcbTraces:traces}));let outputSimpleRouteJson={...transformedSimpleRouteJson??simpleRouteJson,traces:eventOutputPcbTraces};previousStageOutputSimpleRouteJson=transformedSimpleRouteJson?outputSimpleRouteJson:void 0;let computeCostSummary=cachedResult?cachedResult.computeCostSummary:autorouter?.getComputeCostSummary?.();!cachedResult&&cacheKey&&await cacheLocalAutoroutingPhaseResult({cacheEngine,cacheKey,result:{...simpleRouteJson,traces,...computeCostSummary!==void 0?{computeCostSummary}:{}}});let savedPhasePaths=getAutoroutingPhasePcbTracePaths({group:this.selectAll("group").find(group2=>group2.pcb_group_id===routingPhasePlan.fanoutRegionPcbGroupId)??routingPhasePlan.autoroutingPhase?.getGroup()??this,subcircuit:this,input:simpleRouteJson,traces,isFanout:["fanout","single_layer_fanout","dogbone"].includes(phaseAutorouterConfig.preset??"")});if(this.root?.emit("autorouting:end",{...savedPhasePaths,...computeCostSummary!==void 0?{computeCostSummary}:{},type:"autorouting:end",subcircuit_id:this.subcircuit_id,componentDisplayName:this.getString(),...routingPhasePlan.phaseName!==void 0?{phaseName:routingPhasePlan.phaseName,phaseStageIndex,phaseStageCount}:{},...autoroutingMetadata,simpleRouteJson:outputSimpleRouteJson}),autorouter?.getConnectedOffboardObstacles){let connectedOffboardObstacles=autorouter.getConnectedOffboardObstacles();createSourceTracesFromOffboardConnections({db:db22,connectedOffboardObstacles,simpleRouteJson,subcircuit_id:this.subcircuit_id})}let solver=autorouter?.solver;if(solver?.getOutputJumpers&&outputJumpers.push(...solver.getOutputJumpers()||[]),isRegionReroutePhase&&rerouteOriginalSrj){for(let trace of rerouteOriginalSrj.traces??[])trace.type==="pcb_trace"&&pcbTraceIdsToDelete.add(trace.pcb_trace_id);let reconnectedSrj=Qhe(rerouteOriginalSrj,{...simpleRouteJson,traces:[...simpleRouteJson.traces??[],...traces]});outputTraces.splice(0,outputTraces.length,...reconnectedSrj.traces??[])}else if(isConnectionReroutePhase){let retainedPcbTraces=outputTraces.filter(trace=>!traceMatchesRoutingPhase(trace,routingPhasePlan));outputTraces.splice(0,outputTraces.length,...getAccumulatedPcbTracesWithStageOutputReplacements({accumulatedPcbTraces:retainedPcbTraces,stageOutputPcbTraces:stageOutputTraces}))}else{if(preservesExistingTraceInput)for(let existingTrace of existingRerouteSeedTraces)!isTestPointPhase&&fixedTraceIds.has(existingTrace.pcb_trace_id)||pcbTraceIdsToDelete.add(existingTrace.pcb_trace_id);outputTraces.splice(0,outputTraces.length,...getAccumulatedPcbTracesWithStageOutputReplacements({accumulatedPcbTraces:outputTraces,stageOutputPcbTraces:stageOutputTraces}))}}catch(error2){let{db:db3}=this.root;db3.pcb_autorouting_error.insert({pcb_error_id:`pcb_autorouter_error_subcircuit_${this.subcircuit_id}`,error_type:"pcb_autorouting_error",message:error2 instanceof Error?error2.message:String(error2)});let computeCostSummary=autorouter?.getComputeCostSummary?.();if(this.root?.emit("autorouting:error",{...computeCostSummary!==void 0?{computeCostSummary}:{},type:"autorouting:error",subcircuit_id:this.subcircuit_id,componentDisplayName:this.getString(),...routingPhasePlan.phaseName!==void 0?{phaseName:routingPhasePlan.phaseName,phaseStageIndex,phaseStageCount}:{},...autoroutingMetadata,error:{message:error2 instanceof Error?error2.message:String(error2)},simpleRouteJson}),outputTraces.length===0||!routingError)throw error2;break}finally{autorouter?.stop()}}if(this._asyncAutoroutingResult={output_pcb_traces:outputTraces,output_jumpers:outputJumpers,output_test_points:outputTestPoints,pcb_trace_ids_to_be_replaced:[...pcbTraceIdsToDelete]},this._markDirty("PcbTraceRender"),routingError)throw routingError}_startAsyncAutorouting(){this._hasStartedAsyncAutorouting||(this._hasStartedAsyncAutorouting=!0,this._getAutorouterConfig().local?this._queueAsyncEffect("autorouting",async()=>{try{await this._runLocalAutorouting()}catch(error2){if(!(error2 instanceof RoutingPhasePreparationError))throw error2;let{db:db22}=this.root,pcbErrorId=`pcb_autorouter_error_subcircuit_${this.subcircuit_id}`;throw db22.pcb_autorouting_error.list().some(recordedError=>recordedError.pcb_error_id===pcbErrorId&&recordedError.message===error2.message)||(db22.pcb_autorouting_error.insert({pcb_error_id:pcbErrorId,error_type:"pcb_autorouting_error",message:error2.message,subcircuit_id:this.subcircuit_id??void 0}),this.root?.emit("autorouting:error",{type:"autorouting:error",subcircuit_id:this.subcircuit_id,componentDisplayName:this.getString(),error:{message:error2.message}})),error2}}):this._queueAsyncEffect("make-http-autorouting-request",async()=>this._runEffectMakeHttpAutoroutingRequest()))}doInitialPcbTraceRender(){let debug132=(0,import_debug11.default)("tscircuit:core:doInitialPcbTraceRender");if(!this.isSubcircuit||this.root?.pcbDisabled||this.root?.pcbRoutingDisabled||this.getInheritedProperty("routingDisabled")||this._isInflatedFromCircuitJson||this._isLegacyAutorouterDisabled()||this._shouldUseTraceByTraceRouting())return;if(!this._areChildSubcircuitsRouted()){debug132(`[${this.getString()}] child subcircuits are not routed, skipping async autorouting until subcircuits routed`);return}if(debug132(`[${this.getString()}] no child subcircuits to wait for, initiating async routing`),!this._hasTracesToRoute())return;let shouldSkipBecauseOfPlacementErrors=shouldSkipAutoroutingBecauseOfPlacementErrors({component:this,subcircuit:this}),shouldSkipBecauseOfTraceLengthViolations=shouldSkipAutoroutingBecauseOfTraceLengthViolations({component:this,subcircuit:this});shouldSkipBecauseOfPlacementErrors||shouldSkipBecauseOfTraceLengthViolations||this._startAsyncAutorouting()}doInitialSchematicTraceRender(){this._parsedProps.showAsSchematicBox||Group_doInitialSchematicTraceRender(this)}doInitialSchematicSheetRender(){Group_doInitialSchematicSheetRender(this)}updateSchematicSheetRender(){Group_updateSchematicSheetRender(this)}updatePcbTraceRender(){let debug132=(0,import_debug11.default)("tscircuit:core:updatePcbTraceRender");if(debug132(`[${this.getString()}] updating...`),!this.isSubcircuit||this.root?.pcbDisabled||this.root?.pcbRoutingDisabled||this.getInheritedProperty("routingDisabled")||this._isInflatedFromCircuitJson||this._isLegacyAutorouterDisabled())return;if(this._shouldRouteAsync()&&this._hasTracesToRoute()&&!this._hasStartedAsyncAutorouting){if(this._areChildSubcircuitsRouted()){let shouldSkipBecauseOfPlacementErrors=shouldSkipAutoroutingBecauseOfPlacementErrors({component:this,subcircuit:this}),shouldSkipBecauseOfTraceLengthViolations=shouldSkipAutoroutingBecauseOfTraceLengthViolations({component:this,subcircuit:this});if(shouldSkipBecauseOfPlacementErrors||shouldSkipBecauseOfTraceLengthViolations)return;debug132(`[${this.getString()}] child subcircuits are now routed, starting async autorouting`),this._startAsyncAutorouting()}return}if(!this._asyncAutoroutingResult||this._shouldUseTraceByTraceRouting())return;let{db:db22}=this.root;if(this._asyncAutoroutingResult.output_simple_route_json){debug132(`[${this.getString()}] updating PCB traces from simple route json (${this._asyncAutoroutingResult.output_simple_route_json.traces?.length} traces)`),this._updatePcbTraceRenderFromSimpleRouteJson();return}if(this._asyncAutoroutingResult.output_pcb_traces){debug132(`[${this.getString()}] updating PCB traces from ${this._asyncAutoroutingResult.output_pcb_traces.length} traces`),this._updatePcbTraceRenderFromPcbTraces();return}}_updatePcbTraceRenderFromSimpleRouteJson(){let{db:db22}=this.root,{traces:routedTraces}=this._asyncAutoroutingResult.output_simple_route_json;if(routedTraces)for(let routedTrace of routedTraces){let cjRoute=routedTrace.route.map(point12=>point12.route_type!=="through_obstacle"?point12:{route_type:"through_pad",start:point12.start,end:point12.end,start_layer:point12.from_layer,end_layer:point12.to_layer,width:point12.width,circuitJsonMetadata:point12.circuitJsonMetadata}),pcb_trace23=db22.pcb_trace.insert({subcircuit_id:this.subcircuit_id,route:getCircuitJsonPcbTraceRoute(cjRoute)});claimSrjAssignablePcbViasTraversedByRoute({db:db22,pcbTrace:pcb_trace23,routeWithSrjMetadata:cjRoute})}}_updatePcbTraceRenderFromPcbTraces(){let{output_pcb_traces,output_jumpers,pcb_trace_ids_to_be_replaced}=this._asyncAutoroutingResult;if(!output_pcb_traces)return;let{db:db22}=this.root,testPoints=this._asyncAutoroutingResult.output_test_points;testPoints?.length&&(materializeRoutedTestPoints(db22,testPoints,this.subcircuit_id),this._asyncAutoroutingResult.output_test_points=[]);let pcbStyle3=this.getInheritedMergedProperty("pcbStyle"),{holeDiameter,padDiameter}=getViaDiameterDefaults(pcbStyle3),boardComponent=this._getBoard(),board=boardComponent?.pcb_board_id?db22.pcb_board.get(boardComponent.pcb_board_id):db22.pcb_board.list()[0],routedViaHoleDiameter=board?.min_via_hole_diameter??holeDiameter,routedViaPadDiameter=board?.min_via_pad_diameter??padDiameter;output_jumpers&&output_jumpers.length>0&&insertAutoplacedJumpers({db:db22,output_jumpers,subcircuit_id:this.subcircuit_id}),deleteExistingPcbTracesReplacedBy({group:this,outputPcbTraces:output_pcb_traces,pcbTraceIdsToReplace:pcb_trace_ids_to_be_replaced});let materializedPcbVias=db22.pcb_via.list(),jumperPadInfos=getJumperPadInfos(db22);for(let pcb_trace23 of output_pcb_traces){if(pcb_trace23.type!=="pcb_trace")continue;pcb_trace23.subcircuit_id??(pcb_trace23.subcircuit_id=this.subcircuit_id);let cjRoute=pcb_trace23.route.map(point12=>point12.route_type!=="through_obstacle"?point12:{route_type:"through_pad",start:point12.start,end:point12.end,start_layer:point12.from_layer,end_layer:point12.to_layer,width:point12.width,circuitJsonMetadata:point12.circuitJsonMetadata}),routeSourceTraceId=getSourceTraceIdForRoutedTrace({db:db22,trace:{...pcb_trace23,route:cjRoute},subcircuit_id:this.subcircuit_id});cjRoute=ensureRouteStartsAtSourceTraceStart({db:db22,route:cjRoute,routeThicknessMode:pcb_trace23.route_thickness_mode,sourceTraceId:routeSourceTraceId}),pcb_trace23.route=cjRoute;let segments2=splitPcbTracesOnJumperSegments(cjRoute);segments2===null&&(segments2=[cjRoute]);let processedSegments=addPortIdsToTracesAtJumperPads(segments2,jumperPadInfos);for(let segment5 of processedSegments)if(segment5.length>0){let circuitJsonSegment=getCircuitJsonPcbTraceRoute(segment5),sourceTraceId=getSourceTraceIdForRoutedTrace({db:db22,trace:{...pcb_trace23,route:circuitJsonSegment},subcircuit_id:this.subcircuit_id}),insertedPcbTrace=db22.pcb_trace.insert({...pcb_trace23,pcb_panel_id:getOwningPanel(this)?.pcb_panel_id??void 0,source_trace_id:sourceTraceId,route:circuitJsonSegment});claimSrjAssignablePcbViasTraversedByRoute({db:db22,pcbTrace:insertedPcbTrace,routeWithSrjMetadata:segment5})}}for(let pcb_trace23 of output_pcb_traces)if(pcb_trace23.type!=="pcb_via"&&pcb_trace23.type==="pcb_trace"){let sourceTraceId=getSourceTraceIdForRoutedTrace({db:db22,trace:pcb_trace23,subcircuit_id:this.subcircuit_id}),{connection_name:inputConnectionName}=pcb_trace23,subcircuitConnectivityMapKey;if(sourceTraceId&&(subcircuitConnectivityMapKey=db22.source_trace.get(sourceTraceId)?.subcircuit_connectivity_map_key),!subcircuitConnectivityMapKey&&inputConnectionName){let sourceNet=db22.source_net.get(inputConnectionName);sourceNet&&(subcircuitConnectivityMapKey=sourceNet.subcircuit_connectivity_map_key)}for(let point12 of pcb_trace23.route)if(point12.route_type==="via"){let routedViaPoint=point12,fromLayer=point12.from_layer,toLayer=point12.to_layer,pcbVia={pcb_trace_id:pcb_trace23.pcb_trace_id,x:point12.x,y:point12.y,hole_diameter:routedViaPoint.via_hole_diameter??routedViaPoint.hole_diameter??routedViaHoleDiameter,outer_diameter:routedViaPoint.via_diameter??routedViaPoint.outer_diameter??routedViaPadDiameter,layers:getAutoroutedViaLayers({fromLayer,toLayer,layerCount:this._getSubcircuitLayerCount(),allowBlindAndBuriedVias:board?.allow_blind_and_buried_vias??!1,physicalLayers:routedViaPoint.layers}),from_layer:fromLayer,to_layer:toLayer,subcircuit_id:this.subcircuit_id,pcb_group_id:this.pcb_group_id??void 0,pcb_panel_id:getOwningPanel(this)?.pcb_panel_id??void 0,subcircuit_connectivity_map_key:subcircuitConnectivityMapKey};if(materializedPcbVias.some(materializedPcbVia=>pcbViasSharePhysicalHole(materializedPcbVia,pcbVia)))continue;materializedPcbVias.push(db22.pcb_via.insert(pcbVia))}}}doInitialSchematicComponentRender(){if(this.root?.schematicDisabled)return;let{db:db22}=this.root,{_parsedProps:props}=this,schematic_group23=db22.schematic_group.insert({is_subcircuit:this.isSubcircuit,subcircuit_id:this.getSubcircuit().subcircuit_id??void 0,name:this.name,center:this._getGlobalSchematicPositionBeforeLayout(),width:0,height:0,schematic_component_ids:[],source_group_id:this.source_group_id,show_as_schematic_box:props.showAsSchematicBox??!1});this.schematic_group_id=schematic_group23.schematic_group_id,props.showAsSchematicBox&&Group_doInitialSchematicBoxComponentRender(this);for(let child of this.getDescendants())child.getGroup()?.source_group_id===this.source_group_id&&(child._parsedProps?.showAsSchematicBox||child.schematic_component_id&&db22.schematic_component.update(child.schematic_component_id,{schematic_group_id:schematic_group23.schematic_group_id}))}_getSchematicLayoutMode(){let props=this._parsedProps,schAutoLayoutEnabled=props.schAutoLayoutEnabled??!1;if(props.schLayout?.layoutMode==="none"||props.schLayout?.layoutMode==="relative")return"relative";if(props.schLayout?.matchAdapt)return"match-adapt";if(props.schLayout?.flex)return"flex";if(props.schLayout?.grid)return"grid";if(props.schMatchAdapt)return"match-adapt";if(props.schFlex)return"flex";if(props.schGrid)return"grid";if(props.matchAdapt)return"match-adapt";if(props.flex)return"flex";if(props.grid)return"grid";if(props.relative||props.schRelative)return"relative";let anyLayoutChildHasSchCoords=this.children.some(child=>{let cProps=child._parsedProps;return(child.source_component_id!==null||child.source_group_id!==null)&&(cProps?.schX!==void 0||cProps?.schY!==void 0)}),hasManualEdits=(props.manualEdits?.schematic_placements?.length??0)>0;return schAutoLayoutEnabled&&!hasManualEdits||!anyLayoutChildHasSchCoords&&!hasManualEdits?"match-adapt":"relative"}doInitialSchematicLayout(){if(this._parsedProps.showAsSchematicBox){this._insertSchematicBorder();return}if(this.children.some(c23=>c23.source_component_id!==null&&c23._parsedProps?.schSectionName!==void 0)){this._doInitialSchematicLayoutSections(),this._insertSchematicBorder();return}let schematicLayoutMode=this._getSchematicLayoutMode();schematicLayoutMode==="match-adapt"&&this._doInitialSchematicLayoutMatchpack(),schematicLayoutMode==="grid"&&this._doInitialSchematicLayoutGrid(),schematicLayoutMode==="flex"&&this._doInitialSchematicLayoutFlex(),this._insertSchematicBorder()}_doInitialSchematicLayoutSections(){Group_doInitialSchematicLayoutSections(this)}_doInitialSchematicLayoutMatchAdapt(){Group_doInitialSchematicLayoutMatchAdapt(this)}_doInitialSchematicLayoutMatchpack(){Group_doInitialSchematicLayoutMatchPack(this)}_doInitialSchematicLayoutGrid(){Group_doInitialSchematicLayoutGrid(this)}_doInitialSchematicLayoutFlex(){Group_doInitialSchematicLayoutFlex(this)}_getPcbLayoutMode(){let props=this._parsedProps,rawProps=this.props;if(this._isInflatedFromCircuitJson||props.pcbRelative)return"none";if(props.pcbLayout?.matchAdapt)return"match-adapt";if(props.pcbLayout?.flex)return"flex";if(props.pcbLayout?.grid)return"grid";if(props.pcbLayout?.pack)return"pack";if(props.pcbFlex)return"flex";if(props.pcbGrid)return"grid";if(props.pcbPack||props.pack)return"pack";if(props.matchAdapt)return"match-adapt";if(props.flex)return"flex";if(props.grid)return"grid";let groupHasCoords=props.pcbX!==void 0||props.pcbY!==void 0||props.pcbLeftEdgeX!==void 0||props.pcbRightEdgeX!==void 0||props.pcbTopEdgeY!==void 0||props.pcbBottomEdgeY!==void 0||rawProps.pcbLeftEdgeX!==void 0||rawProps.pcbRightEdgeX!==void 0||rawProps.pcbTopEdgeY!==void 0||rawProps.pcbBottomEdgeY!==void 0,hasManualEdits=(props.manualEdits?.pcb_placements?.length??0)>0,unpositionedDirectChildrenCount=this.children.reduce((count,child)=>{if(!child.pcb_component_id&&!child.pcb_group_id)return count;let childProps=child._parsedProps,rawChildProps=child.props,hasCoords=childProps?.pcbX!==void 0||childProps?.pcbY!==void 0||childProps?.pcbLeftEdgeX!==void 0||childProps?.pcbRightEdgeX!==void 0||childProps?.pcbTopEdgeY!==void 0||childProps?.pcbBottomEdgeY!==void 0||rawChildProps?.pcbLeftEdgeX!==void 0||rawChildProps?.pcbRightEdgeX!==void 0||rawChildProps?.pcbTopEdgeY!==void 0||rawChildProps?.pcbBottomEdgeY!==void 0;return count+(hasCoords?0:1)},0);return!hasManualEdits&&unpositionedDirectChildrenCount>1?"pack":"none"}doInitialPcbLayout(){if(this.root?.pcbDisabled)return;if(this.pcb_group_id){let{db:db22}=this.root,props=this._parsedProps;if(props.pcbX!==void 0||props.pcbY!==void 0){let parentGroup=this.parent?.getGroup?.(),pcbParentGroupId=parentGroup?.pcb_group_id?db22.pcb_group.get(parentGroup.pcb_group_id)?.pcb_group_id:void 0,positionedRelativeToBoardId=pcbParentGroupId?void 0:this._getBoard()?.pcb_board_id??void 0;db22.pcb_group.update(this.pcb_group_id,{position_mode:"relative_to_group_anchor",positioned_relative_to_pcb_group_id:pcbParentGroupId,positioned_relative_to_pcb_board_id:positionedRelativeToBoardId,display_offset_x:formatPcbDisplayOffset(props.pcbX),display_offset_y:formatPcbDisplayOffset(props.pcbY)})}}let pcbLayoutMode=this._getPcbLayoutMode();pcbLayoutMode==="grid"?this._doInitialPcbLayoutGrid():pcbLayoutMode==="pack"?this._doInitialPcbLayoutPack():pcbLayoutMode==="flex"&&this._doInitialPcbLayoutFlex()}_doInitialPcbLayoutGrid(){Group_doInitialPcbLayoutGrid(this)}_doInitialPcbLayoutPack(){Group_doInitialPcbLayoutPack(this)}_doInitialPcbLayoutFlex(){Group_doInitialPcbLayoutFlex(this)}_insertSchematicBorder(){if(this.root?.schematicDisabled)return;let{db:db22}=this.root,props=this._parsedProps;if(!props.border)return;let width10=typeof props.schWidth=="number"?props.schWidth:void 0,height10=typeof props.schHeight=="number"?props.schHeight:void 0,paddingGeneral=typeof props.schPadding=="number"?props.schPadding:0,paddingLeft=typeof props.schPaddingLeft=="number"?props.schPaddingLeft:paddingGeneral,paddingRight=typeof props.schPaddingRight=="number"?props.schPaddingRight:paddingGeneral,paddingTop=typeof props.schPaddingTop=="number"?props.schPaddingTop:paddingGeneral,paddingBottom=typeof props.schPaddingBottom=="number"?props.schPaddingBottom:paddingGeneral,schematicGroup=this.schematic_group_id?db22.schematic_group.get(this.schematic_group_id):null;if(schematicGroup&&(width10===void 0&&typeof schematicGroup.width=="number"&&(width10=schematicGroup.width),height10===void 0&&typeof schematicGroup.height=="number"&&(height10=schematicGroup.height)),width10===void 0||height10===void 0)return;let center2=schematicGroup?.center??this._getGlobalSchematicPositionBeforeLayout(),left=center2.x-width10/2-paddingLeft,bottom=center2.y-height10/2-paddingBottom,finalWidth=width10+paddingLeft+paddingRight,finalHeight=height10+paddingTop+paddingBottom;db22.schematic_box.insert({width:finalWidth,height:finalHeight,x:left,y:bottom,is_dashed:props.border?.dashed??!1})}_determineSideFromPosition(port,component){if(!port.center||!component.center)return"left";let dx22=port.center.x-component.center.x,dy22=port.center.y-component.center.y;return Math.abs(dx22)>Math.abs(dy22)?dx22>0?"right":"left":dy22>0?"bottom":"top"}_calculateSchematicBounds(boxes){if(boxes.length===0)return{minX:0,maxX:0,minY:0,maxY:0};let minX=1/0,maxX=-1/0,minY=1/0,maxY=-1/0;for(let box32 of boxes)minX=Math.min(minX,box32.centerX),maxX=Math.max(maxX,box32.centerX),minY=Math.min(minY,box32.centerY),maxY=Math.max(maxY,box32.centerY);let padding=2;return{minX:minX-padding,maxX:maxX+padding,minY:minY-padding,maxY:maxY+padding}}_getAutorouterConfig(){let autorouter=this._parsedProps.autorouter||this.getInheritedProperty("autorouter");return getPresetAutoroutingConfig(autorouter,this.root?.platform)}_isLegacyAutorouterDisabled(){return getDisabledLegacyAutorouterPreset(this)!==null}_isLaserPrefabAutorouter(autorouterConfig3=this._getAutorouterConfig()){let autorouterProp3=this.props.autorouter,normalize13=value=>value?.replace(/-/g,"_")??value;return autorouterConfig3.preset==="laser_prefab"?!0:typeof autorouterProp3=="string"?normalize13(autorouterProp3)==="laser_prefab":typeof autorouterProp3=="object"&&autorouterProp3?normalize13(autorouterProp3.preset)==="laser_prefab":!1}_isAutoJumperAutorouter(autorouterConfig3=this._getAutorouterConfig()){let autorouterProp3=this.props.autorouter,normalize13=value=>value?.replace(/-/g,"_")??value;return autorouterConfig3.preset==="auto_jumper"?!0:typeof autorouterProp3=="string"?normalize13(autorouterProp3)==="auto_jumper":typeof autorouterProp3=="object"&&autorouterProp3?normalize13(autorouterProp3.preset)==="auto_jumper":!1}_getSubcircuitLayerCount(){let layers=this.getInheritedProperty("layers");return typeof layers=="number"?layers:2}_shouldUseTraceByTraceRouting(){return getDisabledLegacyGroupAutorouterPreset(this)?!1:this._getAutorouterConfig().groupMode==="sequential-trace"}doInitialPcbDesignRuleChecks(){if(this.root?.pcbDisabled||this._isLegacyAutorouterDisabled()||this.root?.pcbRoutingDisabled||this.getInheritedProperty("routingDisabled"))return;let{db:db22}=this.root;if(this.isSubcircuit){let immediateChildrenByName=new Map;for(let child of this.children)if(!child.isSubcircuit&&child._parsedProps.name){let components=immediateChildrenByName.get(child._parsedProps.name)||[];components.push(child),immediateChildrenByName.set(child._parsedProps.name,components)}for(let[name,components]of immediateChildrenByName.entries()){if(components.length<=1)continue;let sameNamedTraces=components.filter(child=>child instanceof Trace),duplicateNameIsOnlyTraces=sameNamedTraces.length===components.length,mutuallyConnectedTraceKeys=sameNamedTraces.map(trace=>trace.subcircuit_connectivity_map_key),sameNamedTracesAreMutuallyConnected=duplicateNameIsOnlyTraces&&mutuallyConnectedTraceKeys.every(Boolean)&&new Set(mutuallyConnectedTraceKeys).size===1;if(!duplicateNameIsOnlyTraces||!sameNamedTracesAreMutuallyConnected){let displaySubcircuitName=this.name||"unnamed",message=duplicateNameIsOnlyTraces?`Trace "${name}" in subcircuit "${displaySubcircuitName}" shares a name with another trace, but the traces are not mutually connected. Same-named traces must have the same subcircuit connectivity map key.`:`Multiple immediate children found with name "${name}" in subcircuit "${displaySubcircuitName}". Names must be unique.`;db22.pcb_trace_error.insert({error_type:"pcb_trace_error",message,source_trace_id:"",pcb_trace_id:"",pcb_component_ids:components.map(c23=>c23.pcb_component_id).filter(Boolean),pcb_port_ids:[]})}}}Group_doInitialStandaloneSubcircuitPcbDesignRuleChecks(this)}doInitialSchematicLabelNetsWithConflictingNames(){this.root?.schematicDisabled||this.getTopLevelRenderable()===this&&assignSchematicNetLabelSuperscripts(this.root.db)}updateSchematicLabelNetsWithConflictingNames(){this.doInitialSchematicLabelNetsWithConflictingNames()}doInitialSchematicReplaceNetLabelsWithSymbols(){if(this.root?.schematicDisabled||!this.isSubcircuit)return;let{db:db22}=this.root,subtree=db22;for(let nl3 of subtree.schematic_net_label.list()){let net=subtree.source_net.get(nl3.source_net_id),text4=nl3.text||net?.name||"",isGroundNet=net?.is_ground||GROUND_NET_REGEX.test(text4),isPowerNet=net?.is_power||POWER_NET_REGEX.test(text4);if(nl3.anchor_side==="top"&&isGroundNet){subtree.schematic_net_label.update(nl3.schematic_net_label_id,{symbol_name:"rail_down"});continue}nl3.anchor_side==="bottom"&&isPowerNet&&subtree.schematic_net_label.update(nl3.schematic_net_label_id,{symbol_name:"rail_up"})}}doInitialSimulationSpiceEngineRender(){Group_doInitialSimulationSpiceEngineRender(this)}doInitialPcbComponentAnchorAlignment(){Group_doInitialPcbComponentAnchorAlignment(this)}updatePcbComponentAnchorAlignment(){this.doInitialPcbComponentAnchorAlignment()}doInitialPcbCalcPlacementResolution(){Group_doInitialPcbCalcPlacementResolution(this)}updatePcbCalcPlacementResolution(){this.doInitialPcbCalcPlacementResolution()}_getMinimumFlexContainerSize(){return super._getMinimumFlexContainerSize()}_repositionOnPcb(position22){return super._repositionOnPcb(position22)}};function inflateSourceGroup(sourceGroup,inflatorContext){let{injectionDb,subcircuit,groupsMap}=inflatorContext,pcbGroup=injectionDb.pcb_group.getWhere({source_group_id:sourceGroup.source_group_id}),groupProps22={name:sourceGroup.name??`inflated_group_${sourceGroup.source_group_id}`};if(pcbGroup?.position_mode==="relative_to_group_anchor"&&pcbGroup.anchor_position){let baseAnchor={x:0,y:0};if(sourceGroup.parent_source_group_id){let parentPcbGroup=injectionDb.pcb_group.getWhere({source_group_id:sourceGroup.parent_source_group_id});parentPcbGroup?.anchor_position&&(baseAnchor=parentPcbGroup.anchor_position)}groupProps22.pcbX=pcbGroup.anchor_position.x-baseAnchor.x,groupProps22.pcbY=pcbGroup.anchor_position.y-baseAnchor.y}pcbGroup?.anchor_alignment&&(groupProps22.pcbAnchorAlignment=pcbGroup.anchor_alignment);let group2=new Group(groupProps22);return group2._isInflatedFromCircuitJson=!0,group2.source_group_id=sourceGroup.source_group_id,groupsMap&&groupsMap.set(sourceGroup.source_group_id,group2),sourceGroup.parent_source_group_id&&groupsMap?.has(sourceGroup.parent_source_group_id)?groupsMap.get(sourceGroup.parent_source_group_id).add(group2):subcircuit.add(group2),group2}var Inductor2=class extends NormalComponent{constructor(){super(...arguments);__publicField(this,"_adjustSilkscreenTextAutomatically",!0)}get config(){return{componentName:"Inductor",schematicSymbolName:this.props.symbolName??"inductor",zodProps:inductorProps,sourceFtype:FTYPE.simple_inductor}}_getSchematicSymbolDisplayValue(){return`${formatSiUnit(this._parsedProps.inductance)}H`}initPorts(){super.initPorts({additionalAliases:{pin1:["anode","pos","left"],pin2:["cathode","neg","right"]}})}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({name:this.name,ftype:FTYPE.simple_inductor,inductance:this.props.inductance,max_current_rating:props.maxCurrentRating===void 0?void 0:parseAndConvertSiUnit(props.maxCurrentRating,"A").value,display_inductance:this._getSchematicSymbolDisplayValue(),supplier_part_numbers:props.supplierPartNumbers,manufacturer_part_number:resolveManufacturerPartNumber(props),are_pins_interchangeable:!0,display_name:props.displayName});this.source_component_id=source_component.source_component_id}};function inflateSourceInductor(sourceElm,inflatorContext){let{injectionDb,subcircuit,groupsMap}=inflatorContext,pcbElm=injectionDb.pcb_component.getWhere({source_component_id:sourceElm.source_component_id}),cadElm=injectionDb.cad_component.getWhere({source_component_id:sourceElm.source_component_id}),{pcbX,pcbY}=getInflatedPcbPlacement({pcbComponent:pcbElm,sourceGroupId:sourceElm.source_group_id,inflatorContext}),inductor=new Inductor2({name:sourceElm.name,inductance:sourceElm.inductance,layer:pcbElm?.layer,pcbX,pcbY,pcbRotation:pcbElm?.rotation,doNotPlace:pcbElm?.do_not_place,obstructsWithinBounds:pcbElm?.obstructs_within_bounds});if(pcbElm){let footprint=inflateFootprintComponent(pcbElm,{...inflatorContext,normalComponent:inductor});footprint&&inductor.add(footprint)}sourceElm.source_group_id&&groupsMap?.has(sourceElm.source_group_id)?groupsMap.get(sourceElm.source_group_id).add(inductor):subcircuit.add(inductor)}var Led=class extends NormalComponent{resolveFootprint(){let footprint=super.resolveFootprint();return isFootprinterString(footprint)?resolveDiodeFootprint(footprint,{name:this.name??"Led",pinLabels:this._resolvePinLabels()}).footprint:footprint}get config(){let symbolMap={laser:"laser_diode"},variantSymbol=this.props.laser?"laser":null,baseSymbolName=variantSymbol?symbolMap[variantSymbol]:this.props.symbolName??"led",compactSize=this.props.schSize==="sm"||this.props.schSize==="xs"?this.props.schSize:void 0,compactSymbolName=compactSize&&baseSymbolName==="led"?`led_${compactSize}`:void 0;return{schematicSymbolName:compactSymbolName&&`${compactSymbolName}_right`in cc?compactSymbolName:baseSymbolName,componentName:"Led",zodProps:ledProps,sourceFtype:"simple_led"}}initPorts(){super.initPorts(getDiodePortOptions(this))}_getSchematicSymbolDisplayValue(){return this._parsedProps.schDisplayValue||this._parsedProps.color||void 0}getFootprinterString(){let baseFootprint=super.getFootprinterString();return baseFootprint&&this.props.color?`${baseFootprint}_color(${this.props.color})`:baseFootprint}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({ftype:"simple_led",name:this.name,wave_length:props.wavelength,color:props.color,symbol_display_value:this._getSchematicSymbolDisplayValue(),manufacturer_part_number:resolveManufacturerPartNumber(props),supplier_part_numbers:props.supplierPartNumbers,are_pins_interchangeable:!1,display_name:props.displayName});this.source_component_id=source_component.source_component_id}get pos(){return this.portMap.pos}get anode(){return this.portMap.anode}get neg(){return this.portMap.neg}get cathode(){return this.portMap.cathode}};function inflateSourceLed(sourceElm,inflatorContext){let{injectionDb,subcircuit,groupsMap}=inflatorContext,pcbElm=injectionDb.pcb_component.getWhere({source_component_id:sourceElm.source_component_id}),cadElm=injectionDb.cad_component.getWhere({source_component_id:sourceElm.source_component_id}),{pcbX,pcbY}=getInflatedPcbPlacement({pcbComponent:pcbElm,sourceGroupId:sourceElm.source_group_id,inflatorContext}),led2=new Led({name:sourceElm.name,color:sourceElm.color,wavelength:sourceElm.wavelength??sourceElm.wave_length,layer:pcbElm?.layer,pcbX,pcbY,pcbRotation:pcbElm?.rotation,doNotPlace:pcbElm?.do_not_place,obstructsWithinBounds:pcbElm?.obstructs_within_bounds});if(pcbElm){let footprint=inflateFootprintComponent(pcbElm,{...inflatorContext,normalComponent:led2});footprint&&led2.add(footprint)}sourceElm.source_group_id&&groupsMap?.has(sourceElm.source_group_id)?groupsMap.get(sourceElm.source_group_id).add(led2):subcircuit.add(led2)}var possibleOrientations=[{gate:"left",drain:"top",source:"bottom"},{gate:"left",drain:"bottom",source:"top"},{gate:"right",drain:"top",source:"bottom"},{gate:"right",drain:"bottom",source:"top"},{gate:"top",drain:"left",source:"right"},{gate:"top",drain:"right",source:"left"},{gate:"bottom",drain:"left",source:"right"},{gate:"bottom",drain:"right",source:"left"}],getBaselineOrientation=rotation6=>{let normalizedRotation=(rotation6%360+360)%360;if(normalizedRotation%90!==0)throw new Error(`Schematic rotation ${rotation6} is not supported for Mosfet`);return[{gate:"left",drain:"top",source:"bottom"},{gate:"top",drain:"right",source:"left"},{gate:"right",drain:"bottom",source:"top"},{gate:"bottom",drain:"left",source:"right"}][normalizedRotation/90]},getRequestedOrientation=props=>{let requestedSides={drain:props.symbolDrainSide,source:props.symbolSourceSide,gate:props.symbolGateSide},baseline=getBaselineOrientation(Number(props.schRotation??0)),matchingOrientations=possibleOrientations.filter(orientation32=>Object.keys(requestedSides).every(portName=>requestedSides[portName]===void 0||requestedSides[portName]===orientation32[portName]));if(matchingOrientations.length===0){let requestedDescription=Object.entries(requestedSides).filter(([,side])=>side!==void 0).map(([portName,side])=>`${portName}=${side}`).join(", ");throw new Error(`Invalid MOSFET symbol port side combination (${requestedDescription}). The gate must be perpendicular to the drain and source, and the drain and source must be opposite.`)}return matchingOrientations.sort((a23,b23)=>{let score=orientation32=>Object.keys(baseline).filter(portName=>orientation32[portName]!==baseline[portName]).length;return score(a23)-score(b23)})[0]},getMosfetSchematicSymbolName=props=>{let mosfetMode=props.mosfetMode==="depletion"?"d":"e",baseSymbolName=`${props.channelType}_channel_${mosfetMode}_mosfet_transistor`;if(!(props.symbolDrainSide!==void 0||props.symbolSourceSide!==void 0||props.symbolGateSide!==void 0))return baseSymbolName;let{gate,drain}=getRequestedOrientation(props);return`${baseSymbolName}_gate_${gate}_drain_${drain}`},Mosfet2=class extends NormalComponent{get config(){return{componentName:"Mosfet",schematicSymbolName:this.props.symbolName??getMosfetSchematicSymbolName(this.props),zodProps:mosfetProps,shouldRenderAsSchematicBox:!1}}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({ftype:"simple_mosfet",name:this.name,manufacturer_part_number:resolveManufacturerPartNumber(props),supplier_part_numbers:props.supplierPartNumbers,mosfet_mode:props.mosfetMode,channel_type:props.channelType,display_name:props.displayName});this.source_component_id=source_component.source_component_id}};function inflateSourceMosfet(sourceElm,inflatorContext){let{injectionDb,subcircuit,groupsMap}=inflatorContext,pcbElm=injectionDb.pcb_component.getWhere({source_component_id:sourceElm.source_component_id}),{pcbX,pcbY}=getInflatedPcbPlacement({pcbComponent:pcbElm,sourceGroupId:sourceElm.source_group_id,inflatorContext}),mosfet=new Mosfet2({name:sourceElm.name,channelType:sourceElm.channel_type,mosfetMode:sourceElm.mosfet_mode,manufacturerPartNumber:sourceElm.manufacturer_part_number,supplierPartNumbers:sourceElm.supplier_part_numbers??void 0,displayName:sourceElm.display_name,layer:pcbElm?.layer,pcbX,pcbY,pcbRotation:pcbElm?.rotation,doNotPlace:pcbElm?.do_not_place,obstructsWithinBounds:pcbElm?.obstructs_within_bounds});if(pcbElm){let footprint=inflateFootprintComponent(pcbElm,{...inflatorContext,normalComponent:mosfet});footprint&&mosfet.add(footprint)}sourceElm.source_group_id&&groupsMap?.has(sourceElm.source_group_id)?groupsMap.get(sourceElm.source_group_id).add(mosfet):subcircuit.add(mosfet)}function inflateSourcePort(sourcePort,inflatorContext){let{injectionDb,subcircuit}=inflatorContext;if(sourcePort.source_component_id!==null)return;let pcbPortFromInjection=injectionDb.pcb_port.getWhere({source_port_id:sourcePort.source_port_id}),port=new Port({name:sourcePort.name,pinNumber:sourcePort.pin_number});subcircuit.add(port),port.source_port_id=sourcePort.source_port_id;let root=subcircuit.root;if(root&&pcbPortFromInjection){let{db:db22}=root,pcb_port23=db22.pcb_port.insert({pcb_component_id:void 0,layers:pcbPortFromInjection.layers,subcircuit_id:subcircuit.subcircuit_id??void 0,pcb_group_id:subcircuit.getGroup()?.pcb_group_id??void 0,x:pcbPortFromInjection.x,y:pcbPortFromInjection.y,source_port_id:sourcePort.source_port_id,is_board_pinout:!1});port.pcb_port_id=pcb_port23.pcb_port_id}}var PushButton2=class extends NormalComponent{get config(){return{componentName:"PushButton",schematicSymbolName:this.props.symbolName??"push_button_normally_open_momentary",zodProps:pushButtonProps,sourceFtype:FTYPE.simple_push_button}}get defaultInternallyConnectedPinNames(){return[]}initPorts(){super.initPorts({pinCount:2,ignoreSymbolPorts:!0});let symbol=cc[this._getSchematicSymbolNameOrThrow()],symPort1=symbol.ports.find(p23=>p23.labels.includes("1")),symPort2=symbol.ports.find(p23=>p23.labels.includes("2")),ports=this.selectAll("port"),pin1Port=ports.find(port=>port.props.pinNumber===1);pin1Port.schematicSymbolPortDef=symPort1;let firstTerminalPorts=new Set(pin1Port._getPortsInternallyConnectedToThisPort()),secondTerminalPort=ports.filter(port=>port!==pin1Port&&!firstTerminalPorts.has(port)).sort((a23,b23)=>(a23.props.pinNumber??0)-(b23.props.pinNumber??0))[0];secondTerminalPort&&(secondTerminalPort.schematicSymbolPortDef=symPort2)}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({name:this.name,ftype:FTYPE.simple_push_button,supplier_part_numbers:props.supplierPartNumbers,manufacturer_part_number:resolveManufacturerPartNumber(props),are_pins_interchangeable:!0,display_name:props.displayName});this.source_component_id=source_component.source_component_id}};function inflateSourcePushButton(sourceElm,inflatorContext){let{injectionDb,subcircuit,groupsMap}=inflatorContext,pcbElm=injectionDb.pcb_component.getWhere({source_component_id:sourceElm.source_component_id}),cadElm=injectionDb.cad_component.getWhere({source_component_id:sourceElm.source_component_id}),{pcbX,pcbY}=getInflatedPcbPlacement({pcbComponent:pcbElm,sourceGroupId:sourceElm.source_group_id,inflatorContext}),pushButton=new PushButton2({name:sourceElm.name,layer:pcbElm?.layer,pcbX,pcbY,pcbRotation:pcbElm?.rotation,doNotPlace:pcbElm?.do_not_place,obstructsWithinBounds:pcbElm?.obstructs_within_bounds});if(pcbElm){let footprint=inflateFootprintComponent(pcbElm,{...inflatorContext,normalComponent:pushButton});footprint&&pushButton.add(footprint)}sourceElm.source_group_id&&groupsMap?.has(sourceElm.source_group_id)?groupsMap.get(sourceElm.source_group_id).add(pushButton):subcircuit.add(pushButton)}var Resistor2=class extends NormalComponent{constructor(){super(...arguments);__publicField(this,"_adjustSilkscreenTextAutomatically",!0)}get config(){let baseSymbolName=this.props.symbolName??"boxresistor",compactSize=this.props.schSize==="sm"||this.props.schSize==="xs"?this.props.schSize:void 0,compactSymbolName=compactSize&&(baseSymbolName==="boxresistor"||baseSymbolName==="resistor")?`${baseSymbolName}_${compactSize}`:void 0;return{componentName:"Resistor",schematicSymbolName:compactSymbolName&&`${compactSymbolName}_right`in cc?compactSymbolName:baseSymbolName,zodProps:resistorProps,sourceFtype:"simple_resistor"}}initPorts(){super.initPorts({additionalAliases:{pin1:["anode","pos","left"],pin2:["cathode","neg","right"]}})}_getSchematicSymbolDisplayValue(){return`${formatSiUnit(this._parsedProps.resistance)}\u03A9`}doInitialCreateNetsFromProps(){this._createNetsFromProps([this.props.pullupFor,this.props.pullupTo,this.props.pulldownFor,this.props.pulldownTo,...this._getNetsFromConnectionsProp()])}doInitialCreateTracesFromProps(){this.props.pullupFor&&this.props.pullupTo&&(this.add(new Trace({from:`${this.getSubcircuitSelector()} > port.1`,to:this.props.pullupFor})),this.add(new Trace({from:`${this.getSubcircuitSelector()} > port.2`,to:this.props.pullupTo}))),this.props.pulldownFor&&this.props.pulldownTo&&(this.add(new Trace({from:`${this.getSubcircuitSelector()} > port.1`,to:this.props.pulldownFor})),this.add(new Trace({from:`${this.getSubcircuitSelector()} > port.2`,to:this.props.pulldownTo}))),this._createTracesFromConnectionsProp()}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({ftype:"simple_resistor",name:this.name,manufacturer_part_number:resolveManufacturerPartNumber(props),supplier_part_numbers:props.supplierPartNumbers,resistance:props.resistance,display_resistance:this._getSchematicSymbolDisplayValue(),are_pins_interchangeable:!0,display_name:props.displayName});this.source_component_id=source_component.source_component_id}};function inflateSourceResistor(sourceElm,inflatorContext){let{injectionDb,subcircuit,groupsMap}=inflatorContext,pcbElm=injectionDb.pcb_component.getWhere({source_component_id:sourceElm.source_component_id}),cadElm=injectionDb.cad_component.getWhere({source_component_id:sourceElm.source_component_id}),{pcbX,pcbY}=getInflatedPcbPlacement({pcbComponent:pcbElm,sourceGroupId:sourceElm.source_group_id,inflatorContext}),resistor=new Resistor2({name:sourceElm.name,resistance:sourceElm.resistance,layer:pcbElm?.layer,pcbX,pcbY,pcbRotation:pcbElm?.rotation,doNotPlace:pcbElm?.do_not_place,obstructsWithinBounds:pcbElm?.obstructs_within_bounds});if(pcbElm){let footprint=inflateFootprintComponent(pcbElm,{...inflatorContext,normalComponent:resistor});footprint&&resistor.add(footprint)}sourceElm.source_group_id&&groupsMap?.has(sourceElm.source_group_id)?groupsMap.get(sourceElm.source_group_id).add(resistor):subcircuit.add(resistor)}function hasSimProps(props){return props.simSwitchFrequency!==void 0||props.simCloseAt!==void 0||props.simOpenAt!==void 0||props.simStartClosed!==void 0||props.simStartOpen!==void 0}var Switch=class extends NormalComponent{_getSwitchType(){let props=this._parsedProps;return props?props.dpdt?"dpdt":props.spst?"spst":props.spdt?"spdt":props.dpst?"dpst":props.type??"spst":"spst"}get config(){let switchType=this._getSwitchType(),isNormallyClosed=this._parsedProps?.isNormallyClosed??!1,symbolMap={spst:isNormallyClosed?"spst_normally_closed_switch":"spst_switch",spdt:isNormallyClosed?"spdt_normally_closed_switch":"spdt_switch",dpst:isNormallyClosed?"dpst_normally_closed_switch":"dpst_switch",dpdt:isNormallyClosed?"dpdt_normally_closed_switch":"dpdt_switch"};return{componentName:"Switch",schematicSymbolName:this.props.symbolName??symbolMap[switchType],zodProps:switchProps,shouldRenderAsSchematicBox:!1}}doInitialSourceRender(){let{db:db22}=this.root,props=this._parsedProps??{},source_component=db22.source_component.insert({ftype:"simple_switch",name:this.name,manufacturer_part_number:resolveManufacturerPartNumber(props),supplier_part_numbers:props.supplierPartNumbers,are_pins_interchangeable:this._getSwitchType()==="spst",display_name:props?.displayName});this.source_component_id=source_component.source_component_id}doInitialSimulationRender(){let{_parsedProps:props}=this;if(!hasSimProps(props))return;let{db:db22}=this.root,simulationSwitch={type:"simulation_switch",source_component_id:this.source_component_id||""};props.simSwitchFrequency!==void 0&&(simulationSwitch.switching_frequency=frequency.parse(props.simSwitchFrequency)),props.simCloseAt!==void 0&&(simulationSwitch.closes_at=ms.parse(props.simCloseAt)),props.simOpenAt!==void 0&&(simulationSwitch.opens_at=ms.parse(props.simOpenAt)),props.simStartOpen!==void 0&&(simulationSwitch.starts_closed=!props.simStartOpen),props.simStartClosed!==void 0&&(simulationSwitch.starts_closed=props.simStartClosed),db22.simulation_switch.insert(simulationSwitch)}},getImportedSwitchProps=(sourceElm,inflatorContext)=>{let sourcePorts=inflatorContext.injectionDb.source_port.list().filter(port=>port.source_component_id===sourceElm.source_component_id),pinLabels={},highestPinNumber=0;for(let sourcePort of sourcePorts){let pinNumber2=sourcePort.pin_number;if(pinNumber2==null)continue;highestPinNumber=Math.max(highestPinNumber,pinNumber2);let labels=Array.from(new Set([sourcePort.name,...sourcePort.port_hints??[]].filter(label=>typeof label=="string"&&label.length>0)));labels.length>0&&(pinLabels[`pin${pinNumber2}`]=labels)}let type="spst";return highestPinNumber>=5?type="dpdt":highestPinNumber===4?type="dpst":highestPinNumber===3&&(type="spdt"),{type,pinLabels:Object.keys(pinLabels).length>0?pinLabels:void 0}};function inflateSourceSwitch(sourceElm,inflatorContext){let{injectionDb,subcircuit,groupsMap}=inflatorContext,pcbElm=injectionDb.pcb_component.getWhere({source_component_id:sourceElm.source_component_id}),{pcbX,pcbY}=getInflatedPcbPlacement({pcbComponent:pcbElm,sourceGroupId:sourceElm.source_group_id,inflatorContext}),importedSwitchProps=getImportedSwitchProps(sourceElm,inflatorContext),switchComponent=new Switch({name:sourceElm.name,displayName:sourceElm.display_name,...importedSwitchProps,layer:pcbElm?.layer,pcbX,pcbY,pcbRotation:pcbElm?.rotation,doNotPlace:pcbElm?.do_not_place,obstructsWithinBounds:pcbElm?.obstructs_within_bounds});if(pcbElm){let footprint=inflateFootprintComponent(pcbElm,{...inflatorContext,normalComponent:switchComponent});footprint&&switchComponent.add(footprint)}sourceElm.source_group_id&&groupsMap?.has(sourceElm.source_group_id)?groupsMap.get(sourceElm.source_group_id).add(switchComponent):subcircuit.add(switchComponent)}var TESTPOINT_DEFAULTS={HOLE_DIAMETER:.5,SMT_CIRCLE_DIAMETER:1.2,SMT_RECT_SIZE:2},TestPoint=class extends NormalComponent{get config(){return{componentName:"TestPoint",schematicSymbolName:this.props.symbolName??"testpoint",zodProps:testpointProps,sourceFtype:FTYPE.simple_test_point}}_getPropsWithDefaults(){let{padShape,holeDiameter,footprintVariant,padDiameter,width:width10,height:height10}=this._parsedProps;return!footprintVariant&&holeDiameter&&(footprintVariant="through_hole"),footprintVariant??(footprintVariant="through_hole"),padShape??(padShape="circle"),footprintVariant==="pad"?padShape==="circle"?padDiameter??(padDiameter=TESTPOINT_DEFAULTS.SMT_CIRCLE_DIAMETER):padShape==="rect"&&(width10??(width10=TESTPOINT_DEFAULTS.SMT_RECT_SIZE),height10??(height10=width10)):footprintVariant==="through_hole"&&(holeDiameter??(holeDiameter=TESTPOINT_DEFAULTS.HOLE_DIAMETER)),{padShape,holeDiameter,footprintVariant,padDiameter,width:width10,height:height10}}_getImpliedFootprintString(){let{padShape,holeDiameter,footprintVariant,padDiameter,width:width10,height:height10}=this._getPropsWithDefaults();if(footprintVariant==="through_hole")return`platedhole_d${holeDiameter}`;if(footprintVariant==="pad"){if(padShape==="circle")return`smtpad_circle_d${padDiameter}`;if(padShape==="rect")return`smtpad_rect_w${width10}_h${height10}`}throw new Error(`Footprint variant "${footprintVariant}" with pad shape "${padShape}" not implemented`)}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,{padShape,holeDiameter,footprintVariant,padDiameter,width:width10,height:height10}=this._getPropsWithDefaults(),source_component=db22.source_component.insert({ftype:FTYPE.simple_test_point,name:this.name,supplier_part_numbers:props.supplierPartNumbers,manufacturer_part_number:resolveManufacturerPartNumber(props),footprint_variant:footprintVariant,pad_shape:padShape,pad_diameter:padDiameter,hole_diameter:holeDiameter,width:width10,height:height10,are_pins_interchangeable:!0,display_name:props.displayName});this.source_component_id=source_component.source_component_id}};function inflateSourceTestPoint(sourceElm,inflatorContext){let{injectionDb,subcircuit,groupsMap}=inflatorContext,pcbElm=injectionDb.pcb_component.getWhere({source_component_id:sourceElm.source_component_id}),{pcbX,pcbY}=getInflatedPcbPlacement({pcbComponent:pcbElm,sourceGroupId:sourceElm.source_group_id,inflatorContext}),testPoint=new TestPoint({name:sourceElm.name,footprint:[],displayName:sourceElm.display_name,footprintVariant:sourceElm.footprint_variant,padShape:sourceElm.pad_shape,padDiameter:sourceElm.pad_diameter,holeDiameter:sourceElm.hole_diameter,width:sourceElm.width,height:sourceElm.height,supplierPartNumbers:sourceElm.supplier_part_numbers,manufacturerPartNumber:sourceElm.manufacturer_part_number,layer:pcbElm?.layer,pcbX,pcbY,pcbRotation:pcbElm?.rotation,doNotPlace:pcbElm?.do_not_place,obstructsWithinBounds:pcbElm?.obstructs_within_bounds});if(pcbElm){let footprint=inflateFootprintComponent(pcbElm,{...inflatorContext,normalComponent:testPoint});footprint&&testPoint.add(footprint)}let parentGroup=sourceElm.source_group_id?groupsMap?.get(sourceElm.source_group_id):void 0;parentGroup?parentGroup.add(testPoint):subcircuit.add(testPoint)}function pcbTraceRouteToPcbPath(route2){if(route2.length<=2)return[];let firstPoint=route2[0],lastPoint=route2[route2.length-1];return route2.slice(1,-1).filter(point12=>{let position22=getRoutePointPosition(point12),firstPosition=getRoutePointPosition(firstPoint),lastPosition=getRoutePointPosition(lastPoint),isSameAsFirst=position22.x===firstPosition.x&&position22.y===firstPosition.y,isSameAsLast=position22.x===lastPosition.x&&position22.y===lastPosition.y;return!isSameAsFirst&&!isSameAsLast}).map(point12=>{if(point12.route_type==="via")return{x:point12.x,y:point12.y,via:!0,fromLayer:point12.from_layer,toLayer:point12.to_layer};let position22=getRoutePointPosition(point12);return{x:position22.x,y:position22.y}})}var getSelectorPath=(component,inflatorContext)=>{let{injectionDb,subcircuit,groupsMap}=inflatorContext,path_parts=[],currentGroupId=component.source_group_id;for(;currentGroupId&&currentGroupId!==subcircuit.source_group_id;){let sourceGroup=injectionDb.source_group.get(currentGroupId),groupInstance=groupsMap?.get(currentGroupId);if(!sourceGroup||!groupInstance)break;let groupName=groupInstance.props.name??groupInstance.fallbackUnassignedName;path_parts.unshift(`.${groupName}`),currentGroupId=sourceGroup.parent_source_group_id}return path_parts.push(`.${component.name}`),path_parts.join(" > ")};function inflateSourceTrace(sourceTrace,inflatorContext){let{injectionDb,subcircuit}=inflatorContext,connectedSelectors=[];for(let sourcePortId of sourceTrace.connected_source_port_ids){let sourcePort=injectionDb.source_port.get(sourcePortId);if(!sourcePort)continue;let selector2;if(sourcePort.source_component_id){let sourceComponent=injectionDb.source_component.get(sourcePort.source_component_id);sourceComponent&&(selector2=`${getSelectorPath({name:sourceComponent.name,source_group_id:sourceComponent.source_group_id},inflatorContext)} > .${sourcePort.name}`)}else selector2=`.${sourcePort.name}`;selector2&&connectedSelectors.push(selector2)}for(let sourceNetId of sourceTrace.connected_source_net_ids){let sourceNet=injectionDb.source_net.get(sourceNetId);sourceNet&&connectedSelectors.push(`net.${sourceNet.name}`)}if(connectedSelectors.length<2)return;let pcbTraces=injectionDb.pcb_trace.list().filter(trace2=>trace2.source_trace_id===sourceTrace.source_trace_id),pcbTrace=pcbTraces[0],pcbPath3;pcbTrace&&(pcbPath3=pcbTraceRouteToPcbPath(pcbTrace.route));let traceWidth=sourceTrace.min_trace_thickness;if(!traceWidth&&pcbTrace?.route){let wirePoint=pcbTrace.route.find(pt22=>pt22.route_type==="wire");wirePoint&&wirePoint.route_type==="wire"&&(traceWidth=wirePoint.width)}let traceProps22={path:connectedSelectors};traceWidth!==void 0&&(traceProps22.thickness=traceWidth),pcbPath3&&pcbPath3.length>0?traceProps22.pcbPath=pcbPath3:!pcbTrace&&sourceTrace.connected_source_port_ids.length===2&&sourceTrace.connected_source_net_ids.length===0&&(traceProps22.pcbStraightLine=!0);let trace=new Trace(traceProps22);trace._inflatedPcbTraces=pcbTraces.length>0?pcbTraces:void 0,trace._inflatedPcbVias=pcbTrace?injectionDb.pcb_via.list().filter(via=>pcbTraces.some(trace2=>via.pcb_trace_id===trace2.pcb_trace_id)):void 0,subcircuit.add(trace)}var SHORT_ALIASES={collector:["c"],base:["b"],emitter:["e"]},Transistor=class extends NormalComponent{get config(){let baseSymbolName=this.props.type==="npn"?"npn_bipolar_transistor":"pnp_bipolar_transistor";return{componentName:"Transistor",schematicSymbolName:this.props.symbolName??baseSymbolName,zodProps:transistorProps,sourceFtype:"simple_transistor",shouldRenderAsSchematicBox:!1}}initPorts(){let additionalAliases={},pinLabels=this._resolvePinLabels(),portLabels=pinLabels?Object.entries(pinLabels).map(([pin,labels])=>[pin,...Array.isArray(labels)?labels:[labels]]):this.getSchematicSymbol()?.ports.map(port=>port.labels)??[];for(let labels of portLabels){let pinNumber2=getPinNumberFromLabels(labels);pinNumber2&&(additionalAliases[`pin${pinNumber2}`]=labels.flatMap(label=>SHORT_ALIASES[label]??[]))}super.initPorts({pinCount:3,additionalAliases})}get collector(){return this.portMap.collector}get base(){return this.portMap.base}get emitter(){return this.portMap.emitter}doInitialCreateNetsFromProps(){this._createNetsFromProps([...this._getNetsFromConnectionsProp()])}doInitialCreateTracesFromProps(){this._createTracesFromConnectionsProp()}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({ftype:"simple_transistor",name:this.name,manufacturer_part_number:resolveManufacturerPartNumber(props),supplier_part_numbers:props.supplierPartNumbers,transistor_type:props.type,display_name:props.displayName});this.source_component_id=source_component.source_component_id}};function inflateSourceTransistor(sourceElm,inflatorContext){let{injectionDb,subcircuit,groupsMap}=inflatorContext,pcbElm=injectionDb.pcb_component.getWhere({source_component_id:sourceElm.source_component_id}),cadElm=injectionDb.cad_component.getWhere({source_component_id:sourceElm.source_component_id}),{pcbX,pcbY}=getInflatedPcbPlacement({pcbComponent:pcbElm,sourceGroupId:sourceElm.source_group_id,inflatorContext}),transistor=new Transistor({name:sourceElm.name,type:sourceElm.transistor_type,layer:pcbElm?.layer,pcbX,pcbY,pcbRotation:pcbElm?.rotation,doNotPlace:pcbElm?.do_not_place,obstructsWithinBounds:pcbElm?.obstructs_within_bounds});if(pcbElm){let footprint=inflateFootprintComponent(pcbElm,{...inflatorContext,normalComponent:transistor});footprint&&transistor.add(footprint)}sourceElm.source_group_id&&groupsMap?.has(sourceElm.source_group_id)?groupsMap.get(sourceElm.source_group_id).add(transistor):subcircuit.add(transistor)}function inflateStandalonePcbPrimitives(inflatorContext){let{injectionDb,subcircuit,groupsMap}=inflatorContext,standalonePrimitiveTypes=["pcb_silkscreen_rect","pcb_silkscreen_circle","pcb_silkscreen_line","pcb_silkscreen_path","pcb_silkscreen_text","pcb_fabrication_note_text","pcb_fabrication_note_path","pcb_fabrication_note_rect","pcb_note_text","pcb_note_rect","pcb_note_path","pcb_note_line","pcb_via","pcb_hole","pcb_plated_hole","pcb_cutout","pcb_soldermask_opening","pcb_solder_paste"],standalonePrimitives=injectionDb.toArray().filter(elm=>{if(!standalonePrimitiveTypes.includes(elm.type))return!1;if(elm.type==="pcb_via"){if(!elm.pcb_trace_id)return!0;let pcbTrace=injectionDb.pcb_trace.get(elm.pcb_trace_id),sourceTraceId=pcbTrace?.source_trace_id;return!(sourceTraceId&&injectionDb.source_trace.get(sourceTraceId)&&pcbTrace?.route.some(point12=>point12.route_type==="via"&&Math.abs(point12.x-elm.x)<1e-4&&Math.abs(point12.y-elm.y)<1e-4))}return elm.type==="pcb_cutout"?!0:elm.type==="pcb_solder_paste"?elm.pcb_component_id===void 0&&!elm.pcb_smtpad_id:elm.type==="pcb_soldermask_opening"?elm.pcb_component_id===void 0:"pcb_component_id"in elm&&(elm.pcb_component_id===null||elm.pcb_component_id===void 0)});if(standalonePrimitives.length===0)return;let components=createComponentsFromCircuitJson({componentName:"",componentRotation:"0deg"},standalonePrimitives);for(let component of components)subcircuit.add(component)}var inflateCircuitJson=(target,circuitJson,children)=>{if(!circuitJson)return;let injectionDb=cju_default(circuitJson);if(circuitJson&&children?.length>0)throw new Error("Component cannot have both circuitJson and children");let inflationCtx={injectionDb,subcircuit:target,groupsMap:new Map},sourceGroups=injectionDb.source_group.list(),renderedGroupIds=new Set,groupsToRender=[...sourceGroups];for(;groupsToRender.length>0;){let groupIndex=groupsToRender.findIndex(g23=>!g23.parent_source_group_id||renderedGroupIds.has(g23.parent_source_group_id));if(groupIndex===-1){let remainingIds=groupsToRender.map(g23=>g23.source_group_id).join(", ");throw new Error(`Cannot inflate source_groups: cyclic dependency or missing parent detected. Remaining groups: ${remainingIds}`)}let groupToRender=groupsToRender[groupIndex];inflateSourceGroup(groupToRender,inflationCtx),renderedGroupIds.add(groupToRender.source_group_id),groupsToRender.splice(groupIndex,1)}let pcbBoards=injectionDb.pcb_board.list();for(let pcbBoard of pcbBoards)inflatePcbBoard(pcbBoard,inflationCtx);let sourceComponents=injectionDb.source_component.list();for(let sourceComponent of sourceComponents)switch(sourceComponent.ftype){case"simple_resistor":inflateSourceResistor(sourceComponent,inflationCtx);break;case"simple_fuse":inflateSourceFuse(sourceComponent,inflationCtx);break;case"simple_capacitor":inflateSourceCapacitor(sourceComponent,inflationCtx);break;case"simple_inductor":inflateSourceInductor(sourceComponent,inflationCtx);break;case"simple_diode":inflateSourceDiode(sourceComponent,inflationCtx);break;case"simple_fiducial":inflateSourceFiducial(sourceComponent,inflationCtx);break;case"simple_led":inflateSourceLed(sourceComponent,inflationCtx);break;case"simple_chip":inflateSourceChip(sourceComponent,inflationCtx);break;case"simple_connector":inflateSourceConnector(sourceComponent,inflationCtx);break;case"simple_transistor":inflateSourceTransistor(sourceComponent,inflationCtx);break;case"simple_mosfet":inflateSourceMosfet(sourceComponent,inflationCtx);break;case"simple_push_button":inflateSourcePushButton(sourceComponent,inflationCtx);break;case"simple_switch":inflateSourceSwitch(sourceComponent,inflationCtx);break;case"simple_test_point":inflateSourceTestPoint(sourceComponent,inflationCtx);break;default:throw new Error(`No inflator implemented for source component ftype: "${sourceComponent.ftype}"`)}let sourcePorts=injectionDb.source_port.list();for(let sourcePort of sourcePorts)inflateSourcePort(sourcePort,inflationCtx);let sourceTraces=injectionDb.source_trace.list();for(let sourceTrace of sourceTraces)inflateSourceTrace(sourceTrace,inflationCtx);inflateStandalonePcbPrimitives(inflationCtx),inflateSimulation(inflationCtx)},resolveBoardMotorMount=board=>{if(boardMountsToPrintedPart(board)){resolvePrintedPartMounts(board);return}let{mountedTo,mountRotation,mountRotationAnchor,mountOrientation}=board._parsedProps;if(!mountedTo){if(mountRotation||mountRotationAnchor||mountOrientation)throw new Error(`board "${board.name}" mounting alignment requires mountedTo`);return}let target=resolveAssemblyMountTarget(board,mountedTo,getComponentsInAssemblyScope(board).filter(isAssemblyMountPart)),motorName=target.part.name;if(target.part.componentName!=="AssemblyMotor"||target.face.name!=="backface")throw new Error(`board "${board.name}" mountedTo "${mountedTo}" must name a motor backface, e.g. "NEMA17.backface"`);let motor=target.part;if(motor._parsedProps.mountedTo){resolvePrintedPartMounts(board);return}let direction4=motor._parsedProps.shaftFacingDirection;if(direction4!=="z+"&&direction4!=="z-")throw new Error(`board "${board.name}" cannot mount to motor "${motorName}" facing ${direction4}: rotated PCB boards are not yet supported; use shaftFacingDirection="z+" or "z-"`);if(mountRotationAnchor&&!mountRotation)throw new Error(`board "${board.name}" mountRotationAnchor requires mountRotation`);if(motor.props.shaftFacingDirection&&mountOrientation&&mountOrientation!==(direction4==="z+"?"top_layer_toward_mount_face":"bottom_layer_toward_mount_face"))throw new Error(`board "${board.name}" mountOrientation "${mountOrientation}" conflicts with motor "${motorName}" shaftFacingDirection "${direction4}"`);return motor},resolveMotorMountedBoard=motor=>{let boards=getComponentsInAssemblyScope(motor).filter(board=>board.componentName==="Board").filter(board=>resolveBoardMotorMount(board)===motor);if(boards.length>1)throw new Error(`assembly.motor "${motor.name}" has multiple mounted boards; only one board may determine its placement`);return boards[0]};function createCircuitJsonDatabase(){if(typeof cju_indexed_default!="function")return cju_default([]);let indexed=cju_indexed_default([],{indexConfig:{byId:!0,byType:!0}});return typeof indexed.insert!="function"||typeof indexed.insertAll!="function"||typeof indexed.subtree!="function"?cju_default([]):indexed}var IsolatedCircuit=class{constructor({platform,projectUrl,cachedSubcircuits,pendingSubcircuitRenders}={}){__publicField(this,"firstChild",null);__publicField(this,"children");__publicField(this,"db");__publicField(this,"root",null);__publicField(this,"isRootCircuit",!1);__publicField(this,"cachedSubcircuits");__publicField(this,"pendingSubcircuitRenders");__publicField(this,"_schematicDisabledOverride");__publicField(this,"pcbDisabled",!1);__publicField(this,"pcbRoutingDisabled",!1);__publicField(this,"_featureMspSchematicTraceRouting",!0);__publicField(this,"_featurePcbViaStitching",!0);__publicField(this,"name");__publicField(this,"platform");__publicField(this,"projectUrl");__publicField(this,"_hasRenderedAtleastOnce",!1);__publicField(this,"_asyncEffectIdsByPhase",new Map);__publicField(this,"_asyncEffectPhaseById",new Map);__publicField(this,"_hasUnrenderedUpdatesFromAsyncEffects",!1);__publicField(this,"_runningAsyncEffectsById",new Map);__publicField(this,"_hasRenderLifecycleListeners",!1);__publicField(this,"_eventListeners",{});this.children=[],this.db=createCircuitJsonDatabase(),this.platform=platform,this.projectUrl=projectUrl,this.pcbDisabled=platform?.pcbDisabled??!1,this.pcbRoutingDisabled=platform?.routingDisabled??!1,this.cachedSubcircuits=cachedSubcircuits,this.pendingSubcircuitRenders=pendingSubcircuitRenders,this.root=this}get schematicDisabled(){return this._schematicDisabledOverride!==void 0?this._schematicDisabledOverride:this.platform?.schematicDisabled!==void 0?this.platform.schematicDisabled:this._getBoard()?._parsedProps?.schematicDisabled??!1}set schematicDisabled(value){this._schematicDisabledOverride=value}add(componentOrElm){let component;(0,import_react10.isValidElement)(componentOrElm)?component=createInstanceFromReactElement(componentOrElm):component=componentOrElm,this.children.push(component)}setPlatform(platform){this.platform={...this.platform,...platform},platform.pcbDisabled!==void 0&&(this.pcbDisabled=platform.pcbDisabled),platform.routingDisabled!==void 0&&(this.pcbRoutingDisabled=platform.routingDisabled)}_getBoard(){let findBoard=components=>{for(let child of components){if(child.componentName==="Board")return child;if(isAssemblyDeviceContainer(child)){let nested=findBoard(child.children);if(nested)return nested}}};return findBoard(this.children)}_guessRootComponent(){if(this.firstChild)return;if(this.children.length===0)throw new Error("Not able to guess root component: IsolatedCircuit has no children (use circuit.add(...))");let panels=this.children.filter(child=>child.lowercaseComponentName==="panel");if(panels.length>1)throw new Error("Only one <panel> is allowed per circuit");if(panels.length===1){if(this.children.length!==1)throw new Error("<panel> must be the root element of the circuit");this.firstChild=panels[0];return}if(this.children.length===1&&(this.children[0].isGroup||isAssemblyDeviceContainer(this.children[0]))){this.firstChild=this.children[0];return}let group2=new Group({subcircuit:!0});group2.parent=this,group2.addAll(this.children),this.children=[group2],this.firstChild=group2}render(){this.firstChild||this._guessRootComponent();let{firstChild,db:db22}=this;if(!firstChild)throw new Error("IsolatedCircuit has no root component");firstChild.parent=this,firstChild.runRenderCycle(),this._hasUnrenderedUpdatesFromAsyncEffects=!1,this._hasRenderedAtleastOnce=!0}async renderUntilSettled(){for(this.db.source_project_metadata.list()?.[0]||this.db.source_project_metadata.insert({software_used_string:`@tscircuit/core@${this.getCoreVersion()}`,...this.projectUrl?{project_url:this.projectUrl}:{}}),this.render();!this.isDoneRendering();)await new Promise(resolve10=>{let resume=()=>{clearTimeout(timer),this.removeListener("asyncEffect:end",resume),resolve10()},timer=setTimeout(resume,100);this.on("asyncEffect:end",resume),this._hasUnrenderedUpdatesFromAsyncEffects&&resume()}),(this._hasUnrenderedUpdatesFromAsyncEffects||this._asyncEffectPhaseById.size===0)&&this.render();this.emit("renderComplete")}isDoneRendering(){return this._hasRenderedAtleastOnce&&!this._hasIncompleteAsyncEffects()}_hasIncompleteAsyncEffects(){return this._asyncEffectPhaseById.size>0||this._hasUnrenderedUpdatesFromAsyncEffects?!0:this.children.some(child=>child._hasIncompleteAsyncEffects())}_hasIncompleteAsyncEffectsForPhase(phase){return(this._asyncEffectIdsByPhase.get(phase)?.size??0)>0}getRunningAsyncEffects(){return Array.from(this._runningAsyncEffectsById.values())}getCircuitJson(){return this._hasRenderedAtleastOnce||this.render(),this.db.toArray()}toJson(){return this.getCircuitJson()}async getSvg(options){let circuitToSvg=await Promise.resolve().then(()=>(init_dist14(),dist_exports2)).catch(e211=>{throw new Error(`To use circuit.getSvg, you must install the "circuit-to-svg" package.
1048
+ `)}`)}catch(error2){debug12(`Failed to convert circuit JSON to SPICE: ${error2}`),root.db.simulation_unknown_experiment_error.insert({simulation_experiment_id:simulationExperimentId,error_type:"simulation_unknown_experiment_error",message:error2 instanceof Error?error2.message:String(error2)});continue}let voltageProbeByGraphName=new Map,voltageProbeById=new Map,graphDisplayOverridesByProbeId=new Map;for(let probe of voltageProbes)probe.finalProbeName&&voltageProbeByGraphName.set(probe.finalProbeName,probe),probe.simulation_voltage_probe_id&&(voltageProbeById.set(probe.simulation_voltage_probe_id,probe),graphDisplayOverridesByProbeId.set(probe.simulation_voltage_probe_id,getVoltageProbeGraphDisplayOverrides(probe)));for(let ammeter of ammeters)ammeter.simulation_current_probe_id&&graphDisplayOverridesByProbeId.set(ammeter.simulation_current_probe_id,getAmmeterGraphDisplayOverrides(ammeter));let scopedCurrentProbeIds=new Set(ammeters.map(ammeter=>ammeter.simulation_current_probe_id).filter(simulationCurrentProbeId=>!!simulationCurrentProbeId)),currentProbeById=new Map,currentProbeByName=new Map;for(let probe of root.db.simulation_current_probe.list().filter(probe2=>scopedCurrentProbeIds.has(probe2.simulation_current_probe_id)))currentProbeById.set(probe.simulation_current_probe_id,probe),probe.name!==void 0&&currentProbeByName.set(probe.name,probe);let orderedSimulationProbes=root.db.simulation_voltage_probe.list().filter(probe=>voltageProbeById.has(probe.simulation_voltage_probe_id)),firstSpiceNetlist=simulationRuns[0]?.spiceNetlist,graphNamesFromNetlist=firstSpiceNetlist?getTransientVoltageGraphNamesFromSpiceNetlist(firstSpiceNetlist):[];if(graphNamesFromNetlist.length===orderedSimulationProbes.length)for(let[simulationProbeIndex,simulationProbe]of orderedSimulationProbes.entries()){let probe=voltageProbeById.get(simulationProbe.simulation_voltage_probe_id),graphName=graphNamesFromNetlist[simulationProbeIndex];probe&&graphName&&voltageProbeByGraphName.set(graphName,probe)}else debug12(`Skipping probe-to-graph order mapping because counts differ: probes=${orderedSimulationProbes.length} graphNames=${graphNamesFromNetlist.length}`);let engineName=analogSimulation.getSpiceEngineName()??"spicey",spiceEngine3=spiceEngineMap[engineName];if(!spiceEngine3)throw new Error(`SPICE engine "${engineName}" not found in platform config. Available engines: ${JSON.stringify(Object.keys(spiceEngineMap).filter(spiceEngineName=>spiceEngineName!=="spicey"))}`);let effectId=`spice-simulation-${engineName}-${simulationExperimentId}`;debug12(`Queueing simulation for spice engine: ${engineName} (id: ${effectId})`),group2._queueAsyncEffect(effectId,async()=>{try{let insertedVoltageGraphs=[],insertedCurrentGraphs=[];for(let simulationRun of simulationRuns){debug12(`Running simulation with engine: ${engineName}`);let simulationResult=await spiceEngine3.simulate(simulationRun.spiceString);debug12(`Simulation completed, received ${simulationResult.simulationResultCircuitJson.length} elements`);for(let simulationResultCircuitElement of simulationResult.simulationResultCircuitJson){if(!isCircuitElementInput(simulationResultCircuitElement)){debug12("Skipping invalid simulation result element");continue}let simulationResultWithSweepCoordinate=attachSweepCoordinateToSimulationResult({simulationResult:simulationResultCircuitElement,simulationParameterSweepCoordinate:simulationRun.simulationParameterSweepCoordinate});if(isVoltageGraph(simulationResultWithSweepCoordinate)){simulationResultWithSweepCoordinate.simulation_experiment_id=simulationExperiment.simulation_experiment_id;let probeMatch=simulationResultWithSweepCoordinate.name?voltageProbeByGraphName.get(simulationResultWithSweepCoordinate.name):void 0;probeMatch&&(simulationResultWithSweepCoordinate.color=probeMatch.color??void 0,simulationResultWithSweepCoordinate.source_probe_id=probeMatch.simulation_voltage_probe_id??void 0)}else if(isSimulationVoltageResult(simulationResultWithSweepCoordinate)){simulationResultWithSweepCoordinate.simulation_experiment_id=simulationExperiment.simulation_experiment_id;let probeMatch=voltageProbeById.get(simulationResultWithSweepCoordinate.simulation_voltage_probe_id)??(simulationResultWithSweepCoordinate.name?voltageProbeByGraphName.get(simulationResultWithSweepCoordinate.name):void 0);probeMatch?.simulation_voltage_probe_id&&(simulationResultWithSweepCoordinate.color=probeMatch.color??void 0,simulationResultWithSweepCoordinate.simulation_voltage_probe_id=probeMatch.simulation_voltage_probe_id)}if(isCurrentGraph2(simulationResultWithSweepCoordinate)){simulationResultWithSweepCoordinate.simulation_experiment_id=simulationExperiment.simulation_experiment_id;let probeMatch=(simulationResultWithSweepCoordinate.source_probe_id?currentProbeById.get(simulationResultWithSweepCoordinate.source_probe_id):void 0)??(simulationResultWithSweepCoordinate.name?currentProbeByName.get(simulationResultWithSweepCoordinate.name):void 0);probeMatch&&(simulationResultWithSweepCoordinate.color=probeMatch.color,simulationResultWithSweepCoordinate.source_probe_id=probeMatch.simulation_current_probe_id)}else if(isSimulationCurrentResult(simulationResultWithSweepCoordinate)){simulationResultWithSweepCoordinate.simulation_experiment_id=simulationExperiment.simulation_experiment_id;let probeMatch=currentProbeById.get(simulationResultWithSweepCoordinate.simulation_current_probe_id)??(simulationResultWithSweepCoordinate.name?currentProbeByName.get(simulationResultWithSweepCoordinate.name):void 0);probeMatch&&(simulationResultWithSweepCoordinate.color=probeMatch.color,simulationResultWithSweepCoordinate.simulation_current_probe_id=probeMatch.simulation_current_probe_id)}let insertedSimulationResult=root.db.insert(simulationResultWithSweepCoordinate);isVoltageGraph(insertedSimulationResult)&&insertedVoltageGraphs.push({type:"voltage",graph:insertedSimulationResult}),isCurrentGraph2(insertedSimulationResult)&&insertedCurrentGraphs.push({type:"current",graph:insertedSimulationResult}),debug12(`Inserted ${simulationResultWithSweepCoordinate.type} into database`)}}analogSimulation.usesIndependentGraphAxes()&&insertIndependentAxisScopeTraces({db:root.db,graphs:[...insertedVoltageGraphs,...insertedCurrentGraphs],graphDisplayOverridesByProbeId}),group2._markDirty("SimulationSpiceEngineRender")}catch(error2){debug12(`Simulation failed for engine ${engineName}: ${error2}`),root.db.simulation_unknown_experiment_error.insert({simulation_experiment_id:simulationExperimentId,error_type:"simulation_unknown_experiment_error",message:error2 instanceof Error?error2.message:String(error2)})}})}}function isExternalIbisExperiment(db22,simulationExperimentId){let belongsToExperiment=record=>record.simulation_experiment_id===simulationExperimentId;return db22.simulation_ibis_pin_state.list().some(belongsToExperiment)||db22.simulation_digital_stimulus.list().some(belongsToExperiment)||db22.simulation_eye_diagram.list().some(belongsToExperiment)}function Group_doInitialSourceAddConnectivityMapKey(group2){if(!group2.isSubcircuit)return;let{db:db22}=group2.root,traces=group2.selectAll("trace"),vias=group2.selectAll("via"),nets=group2.selectAll("net"),connMap=new ConnectivityMap({});connMap.addConnections(traces.map(t48=>{let source_trace23=db22.source_trace.get(t48.source_trace_id);return source_trace23?[source_trace23.source_trace_id,...source_trace23.connected_source_port_ids,...source_trace23.connected_source_net_ids]:null}).filter(c23=>c23!==null));let sourceNets=db22.source_net.list().filter(net=>net.subcircuit_id===group2.subcircuit_id);for(let sourceNet of sourceNets)connMap.addConnections([[sourceNet.source_net_id]]);let{name:subcircuitName}=group2._parsedProps;for(let trace of traces){if(!trace.source_trace_id)continue;let connNetId=connMap.getNetConnectedToId(trace.source_trace_id);connNetId&&(trace.subcircuit_connectivity_map_key=`${subcircuitName??`unnamedsubcircuit${group2.subcircuit_id??group2.source_group_id??group2._renderId}`}_${connNetId}`,db22.source_trace.update(trace.source_trace_id,{subcircuit_connectivity_map_key:trace.subcircuit_connectivity_map_key}))}let allSourcePortIds=new Set;for(let trace of traces){if(!trace.source_trace_id)continue;let source_trace23=db22.source_trace.get(trace.source_trace_id);if(source_trace23)for(let id3 of source_trace23.connected_source_port_ids)allSourcePortIds.add(id3)}for(let portId of allSourcePortIds){let connNetId=connMap.getNetConnectedToId(portId);if(!connNetId)continue;let connectivityMapKey=`${subcircuitName??`unnamedsubcircuit${group2.subcircuit_id??group2.source_group_id??group2._renderId}`}_${connNetId}`;db22.source_port.update(portId,{subcircuit_connectivity_map_key:connectivityMapKey})}let allSourceNetIds=new Set;for(let trace of traces){if(!trace.source_trace_id)continue;let source_trace23=db22.source_trace.get(trace.source_trace_id);if(source_trace23)for(let source_net_id of source_trace23.connected_source_net_ids)allSourceNetIds.add(source_net_id)}for(let sourceNet of sourceNets)allSourceNetIds.add(sourceNet.source_net_id);for(let netId of allSourceNetIds){let connNetId=connMap.getNetConnectedToId(netId);if(!connNetId)continue;let connectivityMapKey=`${subcircuitName??`unnamedsubcircuit${group2.subcircuit_id??group2.source_group_id??group2._renderId}`}_${connNetId}`;db22.source_net.update(netId,{subcircuit_connectivity_map_key:connectivityMapKey});let netInstance=nets.find(n23=>n23.source_net_id===netId);netInstance&&(netInstance.subcircuit_connectivity_map_key=connectivityMapKey)}for(let via of vias){let connectedNetOrTrace=via._getConnectedNetOrTrace();connectedNetOrTrace&&connectedNetOrTrace.subcircuit_connectivity_map_key&&(via.subcircuit_connectivity_map_key=connectedNetOrTrace.subcircuit_connectivity_map_key)}}var Group_doInitialStandaloneSubcircuitPcbDesignRuleChecks=group2=>{let isRootSubcircuit=group2.root?.firstChild===group2;if(!group2.isSubcircuit||!isRootSubcircuit||group2._getBoard())return;let routingDisabled=group2.root?.pcbRoutingDisabled||group2.getInheritedProperty("routingDisabled"),drcChecksDisabled=group2.root?.platform?.drcChecksDisabled??group2.getInheritedProperty("drcChecksDisabled"),routingDrcChecksDisabled=group2.root?.platform?.routingDrcChecksDisabled??group2.getInheritedProperty("routingDrcChecksDisabled");if(group2.root?.pcbDisabled||routingDisabled||drcChecksDisabled||routingDrcChecksDisabled||group2._hasIncompleteAsyncEffectsInSubtreeForPhase("PcbTraceRender")||group2._hasTracesToRoute()&&!group2._areChildSubcircuitsRouted()||group2._standaloneSubcircuitDrcChecksComplete||group2._standaloneSubcircuitDrcChecksInProgress)return;let{db:db22}=group2.root,subcircuitCircuitJson=db22.subtree({subcircuit_id:group2.subcircuit_id}).toArray(),panelComponent=getOwningPanel(group2),panel=panelComponent?.pcb_panel_id?db22.pcb_panel.get(panelComponent.pcb_panel_id):void 0,routingCircuitJson=panel?subcircuitCircuitJson.filter(element2=>element2.type!=="pcb_board"):subcircuitCircuitJson;panel&&routingCircuitJson.push({type:"pcb_board",pcb_board_id:panel.pcb_panel_id,center:panel.center,width:panel.width,height:panel.height,thickness:panel.thickness,num_layers:2,material:"fr4"}),group2._standaloneSubcircuitDrcChecksInProgress=!0,group2._queueAsyncEffect("standalone-subcircuit:routing-drc-checks",async()=>{try{let results=await runAllRoutingChecks(routingCircuitJson);db22.insertAll(dedupePcbDrcErrors(results)),group2._standaloneSubcircuitDrcChecksComplete=!0}finally{group2._standaloneSubcircuitDrcChecksInProgress=!1}})},addPourNetMap=(target,pourNetMap)=>{for(let[layer,netOrNets]of Object.entries(pourNetMap)){if(!netOrNets)continue;let nets=Array.isArray(netOrNets)?netOrNets:[netOrNets],layerNets=target.get(layer)??new Set;for(let net of nets)layerNets.add(net);target.set(layer,layerNets)}},toFanoutPourNetMap=netsByLayer=>Object.fromEntries(Array.from(netsByLayer,([layer,nets])=>[layer,nets.size===1?Array.from(nets)[0]:Array.from(nets)])),Group_getFanoutPourNetMap=(group2,routingPhasePlans)=>{let explicitMaps=routingPhasePlans.map(plan=>plan.fanoutPourNetMap).filter(map=>map!==void 0),netsByLayer=new Map;if(explicitMaps.length>0){for(let explicitMap of explicitMaps)addPourNetMap(netsByLayer,explicitMap);return toFanoutPourNetMap(netsByLayer)}let scope=group2;for(;scope;){if(scope.isSubcircuit){let subcircuit=scope,copperPours=subcircuit.selectAll("copperpour");for(let copperPour of copperPours){if(copperPour.getSubcircuit()!==subcircuit)continue;let{layer,connectsTo}=copperPour._parsedProps;addPourNetMap(netsByLayer,{[layer]:connectsTo})}}scope=scope.parent}return netsByLayer.size>0?toFanoutPourNetMap(netsByLayer):void 0},baseBreakoutPointProps=pcbLayoutProps.omit({pcbRotation:!0,layer:!0}),BaseBreakoutPoint=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"pcb_breakout_point_id",null);__publicField(this,"matchedPort",null);__publicField(this,"matchedNet",null);__publicField(this,"matchedSourceTraceId",null);__publicField(this,"isPcbPrimitive",!0)}_getSourceTraceIdForPort(port){let{db:db22}=this.root;return db22.source_trace.list().find(st22=>st22.connected_source_port_ids.includes(port.source_port_id))?.source_trace_id}_getSourceNetIdForPort(port){let{db:db22}=this.root;return db22.source_trace.list().find(st22=>st22.connected_source_port_ids.includes(port.source_port_id))?.connected_source_net_ids[0]}_renderPcbBreakoutPoint({layer}={}){if(this.pcb_breakout_point_id||this.root?.pcbDisabled)return;let{db:db22}=this.root,position22=this._getGlobalPcbPositionBeforeLayout(),group2=this.parent?.getGroup(),subcircuit=this.getSubcircuit();if(!group2||!group2.pcb_group_id)return;let pcb_breakout_point23=db22.pcb_breakout_point.insert({pcb_group_id:group2.pcb_group_id,subcircuit_id:subcircuit?.subcircuit_id??void 0,source_port_id:this.matchedPort?.source_port_id??void 0,source_trace_id:this.matchedPort?this.matchedSourceTraceId??this._getSourceTraceIdForPort(this.matchedPort):void 0,source_net_id:this.matchedNet?this.matchedNet.source_net_id:this.matchedPort?this._getSourceNetIdForPort(this.matchedPort):void 0,layer,x:position22.x,y:position22.y});this.pcb_breakout_point_id=pcb_breakout_point23.pcb_breakout_point_id}_getPcbCircuitJsonBounds(){let position22=this._getGlobalPcbPositionBeforeLayout();return{center:{x:position22.x,y:position22.y},bounds:{left:position22.x,top:position22.y,right:position22.x,bottom:position22.y},width:0,height:0}}_setPositionFromLayout(newCenter){let{db:db22}=this.root;if(!this.pcb_breakout_point_id)return;let updatedProperties={x:newCenter.x,y:newCenter.y};this.matchedSourceTraceId&&(updatedProperties.source_trace_id=this.matchedSourceTraceId),db22.pcb_breakout_point.update(this.pcb_breakout_point_id,updatedProperties)}_moveCircuitJsonElements({deltaX,deltaY}){if(this.root?.pcbDisabled)return;let{db:db22}=this.root;if(!this.pcb_breakout_point_id)return;let point12=db22.pcb_breakout_point.get(this.pcb_breakout_point_id);point12&&db22.pcb_breakout_point.update(this.pcb_breakout_point_id,{x:point12.x+deltaX,y:point12.y+deltaY})}getPcbSize(){return{width:0,height:0}}},BreakoutPoint=class extends BaseBreakoutPoint{get config(){return{componentName:"BreakoutPoint",zodProps:breakoutPointProps}}_matchConnection(){if(this.matchedPort)return;let{connection}=this._parsedProps,subcircuit=this.getSubcircuit();subcircuit&&(this.matchedPort=subcircuit.selectOne(connection,{type:"port"}),this.matchedPort||(this.matchedNet=subcircuit.selectOne(connection,{type:"net"})),!this.matchedPort&&!this.matchedNet&&this.renderError(`Could not find connection target "${connection}"`))}doInitialPcbPrimitiveRender(){this._matchConnection(),this._renderPcbBreakoutPoint()}},SavedFanoutPoint=class extends BreakoutPoint{constructor(){super(...arguments);__publicField(this,"exitLayer","top")}doInitialPcbPrimitiveRender(){this._matchConnection(),this._renderPcbBreakoutPoint({layer:this.exitLayer})}};function getSavedFanoutTraces(breakout,input2){let{db:db22}=breakout.root,boardLayers=getViaBoardLayers(input2.layerCount),coveredConnections=new Set,exits=breakout.children.filter(child=>child instanceof SavedFanoutPoint),traces=(breakout._parsedProps.pcbTracePaths??[]).map((path,pathIndex)=>{for(let point12 of path.route)if((point12.route_type==="wire"?[point12.layer]:[point12.from_layer,point12.to_layer]).some(layer=>!boardLayers.includes(layer)))throw new Error(`Saved fanout path "${path.connection}" uses a layer unavailable on this board`);let exit=exits[pathIndex],port=exit.matchedPort,connection=input2.connections.find(connection2=>connection2.pointsToConnect.some(point12=>point12.pcb_port_id===port.pcb_port_id));if(!connection)throw new Error(`No fanout connection for saved path "${path.connection}"`);let pcbExit=db22.pcb_breakout_point.get(exit.pcb_breakout_point_id),localExit=path.route.at(-1),transform22=compose3(exit._computePcbGlobalTransformBeforeLayout(),translate8(-localExit.x,-localExit.y)),originalExit=applyToPoint3(transform22,localExit),route2=resolveSavedTraceRouteWidths(path.route).map(point12=>{let position22=applyToPoint3(transform22,point12);return{...point12,x:position22.x+pcbExit.x-originalExit.x,y:position22.y+pcbExit.y-originalExit.y}}),first=route2[0],firstLayer=first.route_type==="wire"?first.layer:first.from_layer,portPosition=port._getGlobalPcbPositionAfterLayout();if(Math.hypot(first.x-portPosition.x,first.y-portPosition.y)>1e-4||!port.getAvailablePcbLayers().includes(firstLayer))throw new Error(`Saved fanout path "${path.connection}" must start at its PCB port on an available layer`);if(first.route_type==="via"&&!input2.allowViaInPad)throw new Error(`Saved fanout path "${path.connection}" starts with a via at a pad; enable allowViaInPad`);let last=route2.at(-1),lastLayer=last.route_type==="wire"?last.layer:last.to_layer,endpoints=[{...first,layer:firstLayer},{...last,layer:lastLayer}];if(connection.pointsToConnect.some(point12=>!endpoints.some(endpoint=>Math.hypot(point12.x-endpoint.x,point12.y-endpoint.y)<1e-4&&point12.layer===endpoint.layer)))throw new Error(`Saved fanout path "${path.connection}" does not cover its connection endpoints`);let startContactWidths=getSavedTraceViaContactWidths(route2,0,input2.minTraceWidth),endContactWidths=getSavedTraceViaContactWidths(route2,route2.length-1,input2.minTraceWidth);return first.route_type==="via"&&(route2.splice(1,0,{route_type:"wire",x:first.x,y:first.y,layer:first.to_layer,width:startContactWidths.toWidth}),route2.unshift({route_type:"wire",x:first.x,y:first.y,layer:first.from_layer,width:startContactWidths.fromWidth})),last.route_type==="via"&&(route2.splice(route2.length-1,0,{route_type:"wire",x:last.x,y:last.y,layer:last.from_layer,width:endContactWidths.fromWidth}),route2.push({route_type:"wire",x:last.x,y:last.y,layer:last.to_layer,width:endContactWidths.toWidth})),last.route_type==="via"&&route2.push({route_type:"wire",x:last.x,y:last.y,layer:last.to_layer,width:endContactWidths.toWidth}),coveredConnections.add(connection),{type:"pcb_trace",pcb_trace_id:`saved_fanout_${breakout.pcb_group_id}_${pathIndex}`,connection_name:connection.name,source_trace_id:connection.source_trace_id,connectsTo:[connection.source_trace_id,...connection.pointsToConnect.map(point12=>point12.pointId)].filter(id3=>!!id3),route:route2}}),missing=input2.connections.filter(connection=>!coveredConnections.has(connection));if(missing.length)throw new Error(`pcbTracePaths must cover every fanout connection; missing: ${missing.map(connection=>connection.name).join(", ")}`);return traces}function getPhaseSortValue(routingPhaseIndex){return routingPhaseIndex===null?Number.POSITIVE_INFINITY:routingPhaseIndex}function compareRoutingPhasePlans(a23,b23){return getPhaseSortValue(a23.routingPhaseIndex)-getPhaseSortValue(b23.routingPhaseIndex)}function getOrCreateRoutingPhasePlan(plansByPhaseIndex,routingPhaseIndex){let plan=plansByPhaseIndex.get(routingPhaseIndex);return plan||(plan={routingPhaseIndex,nets:[],traces:[]},plansByPhaseIndex.set(routingPhaseIndex,plan)),plan}function getNetRoutingPhaseIndex(net){return net.props.routingPhaseIndex??null}function getTraceRoutingPhaseIndex(trace,buses=[]){let busRoutingPhaseIndexes=new Set;for(let bus of buses){if(bus._parsedProps.routingPhaseIndex===void 0)continue;bus._parsedProps.connections.some(connection=>connection===trace.name||traceHasEndpointMatchingConnectionSelector(trace,convertPortSelectorToEndpointKey(connection)))&&busRoutingPhaseIndexes.add(bus._parsedProps.routingPhaseIndex)}if(busRoutingPhaseIndexes.size>1)throw new Error(`Trace "${trace.name}" belongs to buses with different routing phases`);let busRoutingPhaseIndex=busRoutingPhaseIndexes.values().next().value;if(busRoutingPhaseIndex!==void 0)return busRoutingPhaseIndex;let traceRoutingPhaseIndex=trace.props.routingPhaseIndex;if(traceRoutingPhaseIndex!==void 0)return traceRoutingPhaseIndex;let routingPhaseIndex=null,connectedNets=trace._findConnectedNets().nets;for(let net of connectedNets){let netRoutingPhaseIndex=getNetRoutingPhaseIndex(net);typeof netRoutingPhaseIndex=="number"&&(routingPhaseIndex===null||netRoutingPhaseIndex<routingPhaseIndex)&&(routingPhaseIndex=netRoutingPhaseIndex)}return routingPhaseIndex}function convertPortSelectorToEndpointKey(selector2){return selector2.trim().replace(/\s*>\s*/g,".").replace(/\s+/g,".").replace(/^\./,"").replace(/\.\./g,".")}function getConnectionSelectorsFromAutoroutingPhaseProps(phaseProps){return phaseProps.connection===void 0&&phaseProps.connections===void 0?phaseProps.pcbTracePaths?.map(path=>path.connection)??[]:[...phaseProps.connection?[phaseProps.connection]:[],...phaseProps.connections??[]]}function traceHasEndpointMatchingConnectionSelector(trace,connectionSelector){let connectionSelectorEndpointKey=convertPortSelectorToEndpointKey(connectionSelector);if(trace.getTracePortPathSelectors().some(selector2=>convertPortSelectorToEndpointKey(selector2)===connectionSelectorEndpointKey))return!0;let port=trace.getSubcircuit().selectOne(connectionSelector,{type:"port"});return port!==null&&(trace._findConnectedPorts().ports?.includes(port)??!1)}function resolvePhaseConnectionTraces(group2,traces,phaseProps){let resolvedTraces=new Set,phaseName=phaseProps.name??"unnamed phase";for(let rawSelector of getConnectionSelectorsFromAutoroutingPhaseProps(phaseProps)){let selector2=rawSelector.trim(),explicitlySelectsTrace=selector2.startsWith("trace."),namedTraces=explicitlySelectsTrace?group2.selectAll(selector2).filter(trace=>traces.includes(trace)):traces.filter(trace=>trace.name===selector2),endpointTraces=explicitlySelectsTrace?[]:traces.filter(trace=>traceHasEndpointMatchingConnectionSelector(trace,selector2));if(namedTraces.length>1||namedTraces.length>0&&endpointTraces.length>0)throw new Error(`Autorouting phase "${phaseName}": connection "${rawSelector}" is ambiguous. Use a unique trace name qualified as "trace.DDR_D0" or a port such as ".U1 > .A1".`);let matches=namedTraces.length>0?namedTraces:endpointTraces;if(matches.length===0)throw new Error(`Autorouting phase "${phaseName}": connection "${rawSelector}" matched no trace or endpoint. Use a trace name such as "DDR_D0" or a port such as ".U1 > .A1".`);for(let trace of matches)resolvedTraces.add(trace)}return resolvedTraces}function getAutoroutersByPhaseIndex(group2){let autoroutingPhases=group2.selectAll("autoroutingphase"),autoroutersByPhaseIndex=new Map;for(let autoroutingPhase of autoroutingPhases){let{phaseIndex,autorouter}=autoroutingPhase._parsedProps;autorouter!==void 0&&autoroutersByPhaseIndex.set(phaseIndex??null,autorouter)}return autoroutersByPhaseIndex}function getAutoroutingPhasePropsByPhaseIndex(group2){let autoroutingPhases=group2.selectAll("autoroutingphase"),propsByPhaseIndex=new Map;for(let autoroutingPhase of autoroutingPhases){let props=autoroutingPhase._parsedProps;propsByPhaseIndex.set(props.phaseIndex??null,props)}return propsByPhaseIndex}function toParsedDistance(value){if(value!==void 0)return Number(value)}function getDrcTolerancesFromAutoroutingPhaseProps(phaseProps){let{minTraceWidth,minViaHoleEdgeToViaHoleEdgeClearance,minPlatedHoleDrillEdgeToDrillEdgeClearance,minTraceToPadEdgeClearance,minTraceToHoleEdgeClearance,minPadEdgeToPadEdgeClearance,minBoardEdgeClearance,minViaEdgeToPadEdgeClearance,minViaHoleDiameter,minViaPadDiameter}=phaseProps;if(!(minTraceWidth===void 0&&minViaHoleEdgeToViaHoleEdgeClearance===void 0&&minPlatedHoleDrillEdgeToDrillEdgeClearance===void 0&&minTraceToPadEdgeClearance===void 0&&minTraceToHoleEdgeClearance===void 0&&minPadEdgeToPadEdgeClearance===void 0&&minBoardEdgeClearance===void 0&&minViaEdgeToPadEdgeClearance===void 0&&minViaHoleDiameter===void 0&&minViaPadDiameter===void 0))return{minTraceWidth:toParsedDistance(minTraceWidth),minViaHoleEdgeToViaHoleEdgeClearance:toParsedDistance(minViaHoleEdgeToViaHoleEdgeClearance),minPlatedHoleDrillEdgeToDrillEdgeClearance:toParsedDistance(minPlatedHoleDrillEdgeToDrillEdgeClearance),minTraceToPadEdgeClearance:toParsedDistance(minTraceToPadEdgeClearance),minTraceToHoleEdgeClearance:toParsedDistance(minTraceToHoleEdgeClearance),minPadEdgeToPadEdgeClearance:toParsedDistance(minPadEdgeToPadEdgeClearance),minBoardEdgeClearance:toParsedDistance(minBoardEdgeClearance),minViaEdgeToPadEdgeClearance:toParsedDistance(minViaEdgeToPadEdgeClearance),minViaHoleDiameter:toParsedDistance(minViaHoleDiameter),minViaPadDiameter:toParsedDistance(minViaPadDiameter)}}function Group_getRoutingPhasePlans(group2){let traces=group2.selectAll("trace"),nets=group2.selectAll("net"),buses=group2.selectAll("bus"),breakouts=group2.selectAll("group").filter(candidate=>candidate.isRoutingDirective),breakoutByTrace=new Map,breakoutByNet=new Map;for(let trace of traces){let ancestor=trace.parent;for(;ancestor&&ancestor!==group2;){if(ancestor.isRoutingDirective){breakoutByTrace.set(trace,ancestor);break}ancestor=ancestor.parent}}for(let net of nets)net.parent?.isRoutingDirective&&breakouts.includes(net.parent)&&breakoutByNet.set(net,net.parent);let plansByPhaseIndex=new Map,autoroutersByPhaseIndex=getAutoroutersByPhaseIndex(group2),phasePropsByPhaseIndex=getAutoroutingPhasePropsByPhaseIndex(group2),selectedTracesByPhaseIndex=new Map(Array.from(phasePropsByPhaseIndex,([phaseIndex,phaseProps])=>[phaseIndex,resolvePhaseConnectionTraces(group2,traces,phaseProps)])),groupFanoutProps=group2._parsedProps,routeRemaining=group2.getInheritedProperty("routeRemaining")!==!1,defaultPhaseProps=phasePropsByPhaseIndex.get(null),includeUnassignedConnections=routeRemaining||defaultPhaseProps!==void 0&&!defaultPhaseProps.reroute&&getConnectionSelectorsFromAutoroutingPhaseProps(defaultPhaseProps).length===0,hasDirectRoutingTargets=traces.length>0||nets.length>0,hasReroutePhase=Array.from(phasePropsByPhaseIndex.values()).some(phaseProps=>phaseProps.reroute),hasConnectionTargetedPhase=Array.from(phasePropsByPhaseIndex.values()).some(phaseProps=>getConnectionSelectorsFromAutoroutingPhaseProps(phaseProps).length>0);if(!hasDirectRoutingTargets&&!hasReroutePhase&&!hasConnectionTargetedPhase&&breakouts.length===0)return[];for(let net of nets){if(breakoutByNet.has(net))continue;let routingPhaseIndex=getNetRoutingPhaseIndex(net);routingPhaseIndex===null&&!includeUnassignedConnections||getOrCreateRoutingPhasePlan(plansByPhaseIndex,routingPhaseIndex).nets.push(net)}for(let trace of traces){if(breakoutByTrace.has(trace))continue;let routingPhaseIndex=getTraceRoutingPhaseIndex(trace,buses);routingPhaseIndex===null&&!includeUnassignedConnections||getOrCreateRoutingPhasePlan(plansByPhaseIndex,routingPhaseIndex).traces.push(trace)}for(let[phaseIndex,phaseProps]of phasePropsByPhaseIndex){let connectionSelectors=getConnectionSelectorsFromAutoroutingPhaseProps(phaseProps);if(connectionSelectors.length>0){let plan=getOrCreateRoutingPhasePlan(plansByPhaseIndex,phaseIndex);plan.connectionSelectors=connectionSelectors;for(let trace of traces)if(!breakoutByTrace.has(trace)&&selectedTracesByPhaseIndex.get(phaseIndex).has(trace)){let connectedNets=trace._findConnectedPorts().ports?.length===1?nets.filter(net=>!breakoutByNet.has(net)&&trace.subcircuit_connectivity_map_key!==null&&net.subcircuit_connectivity_map_key===trace.subcircuit_connectivity_map_key):[];for(let net of connectedNets)plan.nets.includes(net)||plan.nets.push(net);if(!phaseProps.reroute)for(let existingPlan of plansByPhaseIndex.values())existingPlan!==plan&&(!phasePropsByPhaseIndex.get(existingPlan.routingPhaseIndex)?.reroute&&connectedNets.length>0&&(existingPlan.nets=existingPlan.nets.filter(net=>!connectedNets.includes(net))),existingPlan.traces=existingPlan.traces.filter(existingTrace=>existingTrace!==trace));if(plan.traces.includes(trace))continue;plan.traces.push(trace)}}(phaseProps.reroute||phaseProps.pcbTracePaths!==void 0)&&getOrCreateRoutingPhasePlan(plansByPhaseIndex,phaseIndex)}let plans=Array.from(plansByPhaseIndex.values()).sort(compareRoutingPhasePlans);for(let plan of plans){plan.autorouter=autoroutersByPhaseIndex.get(plan.routingPhaseIndex);let phaseProps=phasePropsByPhaseIndex.get(plan.routingPhaseIndex);plan.algorithmFn=phaseProps?.algorithmFn,plan.isImplicitRemainingPhase=plan.routingPhaseIndex===null&&phaseProps===void 0,plan.phaseName=phaseProps?.name,plan.reroute=phaseProps?.reroute,plan.region=phaseProps?.region,plan.connectionSelectors=phaseProps?getConnectionSelectorsFromAutoroutingPhaseProps(phaseProps):void 0,plan.busFanoutDirections=phaseProps?.busFanoutDirections??groupFanoutProps.busFanoutDirections,plan.fanoutBoundaryPadding=phaseProps?.fanoutBoundaryPadding??groupFanoutProps.fanoutBoundaryPadding;let fanoutRoutingLayers=phaseProps?.fanoutRoutingLayers??groupFanoutProps.fanoutRoutingLayers;plan.fanoutRoutingLayers=fanoutRoutingLayers?.map(layer=>typeof layer=="string"?layer:layer.name),plan.fanoutPourNetMap=phaseProps?.fanoutPourNetMap??groupFanoutProps.fanoutPourNetMap,plan.drcTolerances=phaseProps?getDrcTolerancesFromAutoroutingPhaseProps(phaseProps):void 0}for(let phase of group2.selectAll("autoroutingphase")){let plan=plansByPhaseIndex.get(phase._parsedProps.phaseIndex??null);if(!plan)continue;let props=phase._parsedProps;if(props.addTestPoints&&(plan.testPointOptions={layer:props.testPointLayer??"bottom",diameter:props.testPointDiameter??1,clearance:props.testPointClearance??.2,minProbeSpacing:props.testPointMinProbeSpacing??2.54,maxDetour:props.testPointMaxDetour??1}),plan.autoroutingPhase=phase,phase._parsedProps.pcbTracePaths===void 0)continue;let config=plan.autorouter!==void 0?getPresetAutoroutingConfig(plan.autorouter,group2.root?.platform):group2._getAutorouterConfig(),isFanout=["fanout","single_layer_fanout"].includes(config.preset??"");plan.getPrecomputedRoutingResult=input2=>getSavedAutoroutingPhaseTraces(phase,input2,isFanout)}let breakoutPlans=[];for(let breakout of breakouts){let breakoutProps22=breakout._parsedProps,shouldUseDefaultAutorouterForBreakoutPoints=breakout.children.some(child=>child instanceof BreakoutPoint)&&breakout.props.autorouter===void 0,breakoutTraces=traces.filter(trace=>breakoutByTrace.get(trace)===breakout),unroutedBreakoutTraces=breakoutTraces.filter(trace=>!trace.pcb_trace_id),pcbGroup=breakout.pcb_group_id?breakout.root?.db.pcb_group.get(breakout.pcb_group_id):null,outlineBounds=pcbGroup?.outline?getBoundsFromPoints3(pcbGroup.outline):null,routingWidth=pcbGroup?.width??(outlineBounds?outlineBounds.maxX-outlineBounds.minX:void 0),routingHeight=pcbGroup?.height??(outlineBounds?outlineBounds.maxY-outlineBounds.minY:void 0),routingBounds2=pcbGroup&&routingWidth&&routingHeight?{minX:pcbGroup.center.x-routingWidth/2,maxX:pcbGroup.center.x+routingWidth/2,minY:pcbGroup.center.y-routingHeight/2,maxY:pcbGroup.center.y+routingHeight/2}:void 0,rawBreakoutProps=breakout.props,hasExplicitGeometry=rawBreakoutProps.width!==void 0||rawBreakoutProps.height!==void 0||!!rawBreakoutProps.outline?.length,hasExplicitFanoutBoundaryPadding=rawBreakoutProps.fanoutBoundaryPadding!==void 0,breakoutPlan={routingPhaseIndex:null,routingPcbGroupId:breakout.pcb_group_id??void 0,fanoutRegionPcbGroupId:breakout.pcb_group_id??void 0,routingBounds:routingBounds2,fanoutBounds:hasExplicitGeometry?routingBounds2:hasExplicitFanoutBoundaryPadding?void 0:routingBounds2,autorouter:breakoutProps22.autorouter??"fanout",busFanoutDirections:breakoutProps22.busFanoutDirections,fanoutBoundaryPadding:breakoutProps22.fanoutBoundaryPadding,fanoutRoutingLayers:breakoutProps22.fanoutRoutingLayers?.map(layer=>typeof layer=="string"?layer:layer.name),fanoutPourNetMap:breakoutProps22.fanoutPourNetMap,nets:nets.filter(net=>breakoutByNet.get(net)===breakout),traces:breakoutTraces};if(breakout.isDogboneFanout&&breakoutProps22.pcbTracePaths===void 0){breakoutPlans.push({...breakoutPlan,routingBounds:void 0,fanoutBounds:routingBounds2});continue}if(breakout._parsedProps.pcbTracePaths!==void 0){breakoutPlans.push({...breakoutPlan,autorouter:{local:!0,groupMode:"subcircuit",allowViaInPad:(typeof breakoutProps22.autorouter=="object"?breakoutProps22.autorouter.allowViaInPad:void 0)??group2._getAutorouterConfig().allowViaInPad},getPrecomputedRoutingResult:input2=>({traces:getSavedFanoutTraces(breakout,input2)})});continue}if(!shouldUseDefaultAutorouterForBreakoutPoints){breakoutPlans.push(breakoutPlan);continue}if(breakoutPlans.push({...breakoutPlan,autorouter:"default",traces:[]}),unroutedBreakoutTraces.length>0){let automaticFanoutBusIds=new Set(buses.filter(bus=>unroutedBreakoutTraces.some(trace=>bus._parsedProps.connections.some(connection=>connection===trace.name||traceHasEndpointMatchingConnectionSelector(trace,convertPortSelectorToEndpointKey(connection))))).map(bus=>bus.name));for(let trace of unroutedBreakoutTraces)trace.name&&automaticFanoutBusIds.add(trace.name);let automaticBusFanoutDirections=breakoutProps22.busFanoutDirections?Object.fromEntries(Object.entries(breakoutProps22.busFanoutDirections).filter(([busId])=>automaticFanoutBusIds.has(busId))):void 0;breakoutPlans.push({...breakoutPlan,routingPcbGroupId:void 0,busFanoutDirections:automaticBusFanoutDirections,traces:unroutedBreakoutTraces})}}if(routeRemaining&&hasDirectRoutingTargets&&phasePropsByPhaseIndex.size===1&&defaultPhaseProps?.reroute&&plans.length===1&&plans[0]?.routingPhaseIndex===null){let reroutePlan=plans[0];return[...breakoutPlans,{routingPhaseIndex:null,isImplicitRemainingPhase:!0,nets:[...reroutePlan.nets],traces:[...reroutePlan.traces]},reroutePlan]}return[...breakoutPlans,...plans]}var RoutingPhasePreparationError=class extends Error{},package_default3={name:"@tscircuit/core",type:"module",version:"0.0.2367",types:"dist/index.d.ts",main:"dist/index.js",module:"dist/index.js",exports:{".":{import:"./dist/index.js",types:"./dist/index.d.ts"}},files:["dist"],repository:{type:"git",url:"https://github.com/tscircuit/core"},scripts:{"check:class-exports":"bun run scripts/check-class-exports.ts",build:"bun run scripts/build-test-point-rerouter-types.ts && tsup-node",format:"biome format . --write","measure-bundle":"howfat -r table .","pkg-pr-new-release":"bunx pkg-pr-new publish --comment=off --peerDeps","smoke-test:dist":"bun run scripts/smoke-tests/test-dist-assembly-bom.tsx && bun run scripts/smoke-tests/test-dist-simple-circuit.tsx && bun run scripts/smoke-tests/check-dist-bundled-schematic-solver.ts && bun run scripts/smoke-tests/test-dist-drawing-dimensions.tsx && bun run scripts/smoke-tests/check-dist-bundled-test-point-rerouter.ts && bun run scripts/smoke-tests/check-dist-collision-runtime.ts && bun run scripts/smoke-tests/test-dist-explosion-collisions.tsx && node scripts/smoke-tests/test-dist-node-explosion-collisions.mjs","build:benchmarking":"bun build --experimental-html ./benchmarking/website/index.html --outdir ./benchmarking-dist","build:benchmarking:watch":`chokidar "./{benchmarking,lib}/**/*.{ts,tsx}" -c 'bun build --experimental-html ./benchmarking/website/index.html --outdir ./benchmarking-dist'`,"start:benchmarking":'concurrently "bun run build:benchmarking:watch" "live-server ./benchmarking-dist"',"generate-test-plan":"bun run scripts/generate-test-plan.ts","benchmark:ddr":"bun scripts/benchmark-ddr/run.ts"},devDependencies:{"@tscircuit/cad-collision-checking":"https://jscdn.tscircuit.com/@tscircuit/cad-collision-checking/0.0.6.tgz","@tscircuit/graphics-debug-3d":"https://jscdn.tscircuit.com/@tscircuit/graphics-debug-3d/0.0.1.tgz","@biomejs/biome":"^1.8.3","@resvg/resvg-js":"^2.6.2","@tsci/tscircuit.ti":"github:tscircuit/ti#57e314be4b2b06bc546d4def7453e619604d1157","@tscircuit/alphabet":"0.0.25","@tscircuit/bga-fanout-solver":"github:tscircuit/bga-fanout-solver#247c835cb8d69b65e53891dcf869731079415b39","@tscircuit/bus-lanes-solver":"https://jscdn.tscircuit.com/@tscircuit/bus-lanes-solver/0.0.55.tgz","@tscircuit/cableprinter":"^0.0.6","@tscircuit/capacity-autorouter":"^0.0.1089","@tscircuit/checks":"^0.0.277","@tscircuit/circuit-json-util":"^0.0.131","@tscircuit/common":"^0.0.20","@tscircuit/copper-pour-solver":"^0.0.74","@tscircuit/create-fdm-enclosure":"0.0.6","@tscircuit/dogbone-solver":"https://jscdn.tscircuit.com/@tscircuit/dogbone-solver/0.0.4.tgz","@tscircuit/fanout-solver":"0.0.84","@tscircuit/flex-utils":"https://jscdn.tscircuit.com/@tscircuit/flex-utils/0.0.8.tgz","@tscircuit/footprinter":"^0.0.451","@tscircuit/image-utils":"^0.0.8","@tscircuit/implicit-copper-pour-solver":"github:tscircuit/implicit-copper-pour-solver#a5cbbda0cd65fd4707c5c1af25779837c25aba92","@tscircuit/infer-cable-insertion-point":"^0.0.5","@tscircuit/infgrid-ijump-astar":"^0.0.35","@tscircuit/jlcpcb-manufacturing-specs":"git+https://github.com/tscircuit/jlcpcb-manufacturing-specs#d2fcf9a557a196cf9f2824463d06cd86534b1c21","@tscircuit/krt-wasm":"^0.1.1","@tscircuit/log-soup":"^1.0.2","@tscircuit/matchpack":"^0.0.100","@tscircuit/math-utils":"0.0.39","@tscircuit/miniflex":"^0.0.4","@tscircuit/modelprinter":"^0.0.37","@tscircuit/ngspice-spice-engine":"^0.0.20","@tscircuit/props":"^0.0.728","@tscircuit/schematic-match-adapt":"^0.0.18","@tscircuit/schematic-trace-solver":"https://jscdn.tscircuit.com/@tscircuit/schematic-trace-solver/0.0.238.tgz","@tscircuit/solver-utils":"^0.0.16","@tscircuit/soup-util":"^0.0.41","@tscircuit/via-stitch-solver":"github:tscircuit/via-stitch-solver#64f2ac7781b795bdc0d74ba411988e60767fa653","@tscircuit/winding-breakout-point-solver":"github:tscircuit/winding-breakout-point-solver#202dbe9eb0088633b6fa094120dba6f2f41f8803","@types/bun":"^1.2.16","@types/debug":"^4.1.12","@types/react":"^19.1.8","@types/react-dom":"^19.1.6","@types/react-reconciler":"^0.28.9","bpc-graph":"^0.0.57","bun-match-svg":"0.0.16","calculate-elbow":"^0.0.12","chokidar-cli":"^3.0.0","circuit-json":"^0.0.548","circuit-json-to-bom-csv":"^0.0.28","circuit-json-to-bpc":"^0.0.13","circuit-json-to-connectivity-map":"^0.0.33","circuit-json-to-spice":"^0.0.45","circuit-to-svg":"^0.0.457",concurrently:"^9.1.2","connectivity-map":"^1.0.1",debug:"^4.3.6",flatbush:"^4.5.0","graphics-debug":"^0.0.99",howfat:"^0.3.8","kicad-to-circuit-json":"^0.0.149",kicadts:"^0.0.53","live-server":"^1.2.2",minicssgrid:"^0.0.9","pkg-pr-new":"^0.0.37",react:"^19.1.0","react-dom":"^19.1.0","schematic-symbols":"^0.0.251",spicets:"^0.0.4",spicey:"^0.0.14","stack-svgs":"^0.0.1","ts-expect":"^1.3.0",tsup:"^8.2.4","@tscircuit/circuit-json-to-drawing":"https://jscdn.tscircuit.com/@tscircuit/circuit-json-to-drawing/0.0.4.tgz","circuit-json-to-gltf":"^0.0.164","@tscircuit/jscad":"^0.0.6","@tscircuit/test-point-rerouter":"github:tscircuit/test-point-rerouter#b0ccfaca75a7e187c55ddb6f2071a1f2084e3167","@tscircuit/manifold-2d":"^0.0.8",typescript:"^5.9.3","@tscircuit/jscad-to-manifold":"https://jscdn.tscircuit.com/@tscircuit/jscad-to-manifold/0.0.1.tgz","circuit-json-to-3d-png":"^0.0.6","circuit-json-to-altium":"github:tscircuit/circuit-json-to-altium#1a50d0dd2c0737cf940d92c0315852dc0111dd87","circuit-json-to-fdm-component-box":"^0.0.2","circuit-json-to-footprinter":"^0.0.59","circuit-json-to-gerber":"^0.0.120","circuit-json-to-kicad":"0.0.272","circuit-json-to-readable-netlist":"^0.0.15","circuit-json-to-step":"^0.0.63","circuit-json-to-tscircuit":"^0.0.50","dsn-converter":"^0.0.90",easyeda:"^0.0.389","circuit-json-to-pnp-csv":"^0.0.20","@tscircuit/core-ddr-benchmark":"github:ShiboSoftwareDev/core-ddr-benchmark#7b05251f6e868954adead2275a26c95b163c4813"},peerDependencies:{"@tscircuit/capacity-autorouter":"*","@tscircuit/checks":"*","@tscircuit/circuit-json-util":"*","@tscircuit/create-fdm-enclosure":"*","@tscircuit/footprinter":"*","@tscircuit/infgrid-ijump-astar":"*","@tscircuit/math-utils":"*","@tscircuit/modelprinter":"*","@tscircuit/props":"*","@tscircuit/schematic-match-adapt":"*","circuit-json-to-bpc":"*","bpc-graph":"*","@tscircuit/matchpack":"*","circuit-json":"*","circuit-json-to-connectivity-map":"*","circuit-json-to-spice":"*","schematic-symbols":"*",spicets:"*",typescript:"^5.0.0","@tscircuit/cableprinter":"*","@tscircuit/manifold-2d":"*"},dependencies:{"@flatten-js/core":"^1.6.2","@lume/kiwi":"^0.4.3","calculate-cell-boundaries":"^0.0.25","calculate-packing":"^0.0.90","css-select":"5.1.0","format-si-unit":"^0.0.12","gl-matrix":"^3.4.4",nanoid:"^5.0.7","performance-now":"^2.1.0","react-reconciler":"^0.32.0","svg-path-commander":"^2.1.11","transformation-matrix":"^2.16.1",zod:"^3.25.67","jscad-planner":"^0.0.21","jscad-fiber":"^0.0.93",poppygl:"0.0.38","@jscad/modeling":"^2.13.0","@dagrejs/dagre":"^2.0.4"},overrides:{"graphics-debug":"$graphics-debug","@tscircuit/graphics-debug-3d":"https://jscdn.tscircuit.com/@tscircuit/graphics-debug-3d/0.0.1.tgz","@tscircuit/props":"^0.0.728","circuit-json":"^0.0.548","@tscircuit/cableprinter":"^0.0.6"},browser:{"@resvg/resvg-js":!1}},getFnv1aHash=value=>{let hash=2166136261;for(let i23=0;i23<value.length;i23++)hash^=value.charCodeAt(i23),hash=Math.imul(hash,16777619);return hash>>>0},getJsonHash=value=>{let serializedValue=JSON.stringify(value),hash1=getFnv1aHash(serializedValue),hash2=getFnv1aHash(`${serializedValue}${hash1}`);return`${hash1.toString(16).padStart(8,"0")}${hash2.toString(16).padStart(8,"0")}`},getLocalAutoroutingCacheKey=(simpleRouteJson,solverOptions)=>`routes:core@${package_default3.version}:solver:${getJsonHash(solverOptions)}:srj:${getJsonHash(simpleRouteJson)}`,getCachedLocalAutoroutingPhaseResult=async({cacheEngine,cacheKey})=>{if(!cacheEngine)return null;try{let cachedResult=await cacheEngine.getItem(cacheKey);if(!cachedResult)return null;let parsedResult=JSON.parse(cachedResult);return!parsedResult||!Array.isArray(parsedResult.traces)?null:parsedResult}catch{return null}},cacheLocalAutoroutingPhaseResult=async({cacheEngine,cacheKey,result})=>{if(cacheEngine)try{await cacheEngine.setItem(cacheKey,JSON.stringify(result))}catch{}},SRJ_POINT_POSITION_TOLERANCE_MM=1e-6,srjPointsHaveSamePointId=(first,second)=>first.pointId!==void 0&&second.pointId!==void 0&&first.pointId===second.pointId,srjPointsHaveSameBoardPositionAndLayer=(first,second)=>Math.abs(first.x-second.x)<=SRJ_POINT_POSITION_TOLERANCE_MM&&Math.abs(first.y-second.y)<=SRJ_POINT_POSITION_TOLERANCE_MM&&first.layer===second.layer,srjPointsReferToSameEndpoint=(first,second)=>first.pointId!==void 0&&second.pointId!==void 0?srjPointsHaveSamePointId(first,second):srjPointsHaveSameBoardPositionAndLayer(first,second),getPairedGlobalPoint=(simpleRouteJson,connection)=>{let globalConnection=simpleRouteJson.connections.find(candidate=>candidate.routingPcbGroupId!==connection.routingPcbGroupId&&candidate.source_trace_id===connection.source_trace_id&&candidate.pointsToConnect.some(globalPoint=>connection.pointsToConnect.some(localPoint=>srjPointsReferToSameEndpoint(globalPoint,localPoint))));if(!globalConnection)return;let pairedPoints=globalConnection.pointsToConnect.filter(globalPoint=>!connection.pointsToConnect.some(localPoint=>srjPointsReferToSameEndpoint(globalPoint,localPoint)));return pairedPoints.length===1?pairedPoints[0]:void 0},getPairedBreakoutExitTarget=(simpleRouteJson,connection)=>{if(!connection.routingPcbGroupId||!connection.source_trace_id)return;let pairedGlobalPoint=getPairedGlobalPoint(simpleRouteJson,connection);if(!(!pairedGlobalPoint||!simpleRouteJson.connections.some(candidate=>candidate.routingPcbGroupId!==void 0&&candidate.routingPcbGroupId!==connection.routingPcbGroupId&&candidate.source_trace_id===connection.source_trace_id&&candidate.pointsToConnect.some(candidatePoint=>srjPointsReferToSameEndpoint(candidatePoint,pairedGlobalPoint)))))return{x:pairedGlobalPoint.x,y:pairedGlobalPoint.y,layer:pairedGlobalPoint.layer}};function connectionIsInRoutingPhase(connection,phasePlan){if(connection.routingPcbGroupId)return connection.routingPcbGroupId===phasePlan.routingPcbGroupId;for(let trace of phasePlan.traces)if(trace.source_trace_id&&(connection.source_trace_id===trace.source_trace_id||connection.name===trace.source_trace_id||connection.rootConnectionName===trace.source_trace_id||connection.mergedConnectionNames?.includes(trace.source_trace_id)))return!0;for(let net of phasePlan.nets)if(net.source_net_id&&connection.name===net.source_net_id)return!0;return!1}function Group_hasPhasedAutorouting(routingPhasePlans){for(let plan of routingPhasePlans)if(plan.routingPcbGroupId||plan.routingPhaseIndex!==null)return!0;return!1}function Group_filterSimpleRouteJsonForPhase(simpleRouteJson,phasePlan){let connections=[];for(let connection of simpleRouteJson.connections)connectionIsInRoutingPhase(connection,phasePlan)&&connections.push(connection);let includedConnectionNames=new Set;for(let connection of connections)includedConnectionNames.add(connection.name);let differentialPairs=[];for(let differentialPair of simpleRouteJson.differentialPairs??[]){let positiveConnectionIncluded=includedConnectionNames.has(differentialPair.connectionNames[0]),negativeConnectionIncluded=includedConnectionNames.has(differentialPair.connectionNames[1]);if(positiveConnectionIncluded!==negativeConnectionIncluded)throw new Error(`Differential pair "${differentialPair.connectionNames.join("/")}" cannot be split across autorouting phases`);positiveConnectionIncluded&&differentialPairs.push(differentialPair)}let srjConnectionByName=new Map(simpleRouteJson.connections.map(connection=>[connection.name,connection])),buses=(simpleRouteJson.buses??[]).map(bus=>{let connectionNames=bus.connectionNames.filter(connectionName=>includedConnectionNames.has(connectionName)),cohortConnectionNames=bus.connectionNames.filter(connectionName=>srjConnectionByName.get(connectionName)?.routingPcbGroupId===phasePlan.routingPcbGroupId);if(bus.maxLengthSkew!==void 0&&connectionNames.length>0&&connectionNames.length!==cohortConnectionNames.length)throw new RoutingPhasePreparationError(`Length-matched bus "${bus.name||"unnamed bus"}" cannot be split across autorouting phases. Assign the complete bus to one routingPhaseIndex.`);let connectionExitTargets=Object.fromEntries(connectionNames.flatMap(connectionName=>{let connection=srjConnectionByName.get(connectionName);if(!connection)return[];let pairedTarget=getPairedBreakoutExitTarget(simpleRouteJson,connection);return pairedTarget?[[connectionName,pairedTarget]]:[]}));return{...bus,connectionNames,...Object.keys(connectionExitTargets).length>0?{connectionExitTargets}:{}}}).filter(bus=>bus.connectionNames.length>0),bounds=expandSrjBoundsToIncludeConnectionPoints({bounds:phasePlan.routingBounds??simpleRouteJson.bounds,connections});return{...simpleRouteJson,bounds,outline:getSrjOutlineForRoutingBounds(simpleRouteJson,bounds),connections,differentialPairs:differentialPairs.length>0?differentialPairs:void 0,buses:buses.length>0?buses:void 0}}function hasDrcTolerances(drcTolerances){return drcTolerances?Object.values(drcTolerances).some(value=>value!==void 0):!1}function applyMinTraceWidthToConnections(connections,minTraceWidth){return minTraceWidth===void 0?connections:connections.map(connection=>({...connection,nominalTraceWidth:Math.max(connection.nominalTraceWidth??minTraceWidth,minTraceWidth),width:Math.max(connection.width??minTraceWidth,minTraceWidth)}))}function Group_applyDrcTolerancesToSimpleRouteJson(simpleRouteJson,drcTolerances){if(!hasDrcTolerances(drcTolerances))return simpleRouteJson;let minTraceWidth=drcTolerances.minTraceWidth??simpleRouteJson.minTraceWidth,minViaHoleDiameter=drcTolerances.minViaHoleDiameter??simpleRouteJson.minViaHoleDiameter,minViaPadDiameter=drcTolerances.minViaPadDiameter??simpleRouteJson.minViaPadDiameter,minTraceToHoleEdgeClearance=drcTolerances.minTraceToHoleEdgeClearance??simpleRouteJson.minTraceToHoleEdgeClearance,minTraceToPadEdgeClearance=drcTolerances.minTraceToPadEdgeClearance??simpleRouteJson.minTraceToPadEdgeClearance,minViaEdgeToPadEdgeClearance=drcTolerances.minViaEdgeToPadEdgeClearance??simpleRouteJson.minViaEdgeToPadEdgeClearance,minViaHoleEdgeToViaHoleEdgeClearance=drcTolerances.minViaHoleEdgeToViaHoleEdgeClearance??simpleRouteJson.minViaHoleEdgeToViaHoleEdgeClearance,minPlatedHoleDrillEdgeToDrillEdgeClearance=drcTolerances.minPlatedHoleDrillEdgeToDrillEdgeClearance??simpleRouteJson.minPlatedHoleDrillEdgeToDrillEdgeClearance,minPadEdgeToPadEdgeClearance=drcTolerances.minPadEdgeToPadEdgeClearance??simpleRouteJson.minPadEdgeToPadEdgeClearance,minBoardEdgeClearance=drcTolerances.minBoardEdgeClearance??simpleRouteJson.minBoardEdgeClearance;return{...simpleRouteJson,connections:applyMinTraceWidthToConnections(simpleRouteJson.connections,drcTolerances.minTraceWidth),minTraceWidth,minViaDiameter:minViaPadDiameter,minViaHoleDiameter,minViaPadDiameter,min_via_hole_diameter:minViaHoleDiameter,min_via_pad_diameter:minViaPadDiameter,minTraceToPadEdgeClearance,minTraceToHoleEdgeClearance,minViaEdgeToPadEdgeClearance,minViaHoleEdgeToViaHoleEdgeClearance,minPlatedHoleDrillEdgeToDrillEdgeClearance,minPadEdgeToPadEdgeClearance,minBoardEdgeClearance}}var removeCompletedFanoutConnections=(simpleRouteJson,routingPcbGroupId)=>{let connections=simpleRouteJson.connections.filter(connection=>connection.routingPcbGroupId!==routingPcbGroupId),includedConnectionNames=new Set(connections.map(connection=>connection.name)),differentialPairs=[];for(let differentialPair of simpleRouteJson.differentialPairs??[]){let positiveConnectionIncluded=includedConnectionNames.has(differentialPair.connectionNames[0]),negativeConnectionIncluded=includedConnectionNames.has(differentialPair.connectionNames[1]);if(positiveConnectionIncluded!==negativeConnectionIncluded)throw new Error(`Differential pair "${differentialPair.connectionNames.join("/")}" cannot be split at a breakout boundary`);positiveConnectionIncluded&&differentialPairs.push(differentialPair)}let buses=(simpleRouteJson.buses??[]).map(bus=>({...bus,connectionNames:bus.connectionNames.filter(connectionName=>includedConnectionNames.has(connectionName))})).filter(bus=>bus.connectionNames.length>0);return{...simpleRouteJson,connections,differentialPairs:differentialPairs.length>0?differentialPairs:void 0,buses:buses.length>0?buses:void 0}},connectFanoutTracesToBreakoutPoints=(simpleRouteJson,breakoutPointIdByConnectionName)=>({...simpleRouteJson,traces:simpleRouteJson.traces?.map(trace=>{let breakoutPointId=breakoutPointIdByConnectionName.get(trace.connection_name??"");return breakoutPointId?{...trace,connectsTo:[...new Set([...trace.connectsTo??[],breakoutPointId])]}:trace})});function Group_syncFanoutExitsWithGlobalConnections({fanoutInputSimpleRouteJson,fanoutOutputSimpleRouteJson,baseSimpleRouteJson,routingPhasePlan}){let routingPcbGroupId=routingPhasePlan.routingPcbGroupId;if(!routingPcbGroupId)return{downstreamSimpleRouteJson:fanoutOutputSimpleRouteJson,baseSimpleRouteJson,synchronizedBreakoutPoints:[]};let outputConnectionByName=new Map(fanoutOutputSimpleRouteJson.connections.map(connection=>[connection.name,connection])),baseConnections=baseSimpleRouteJson.connections.map(connection=>({...connection,pointsToConnect:connection.pointsToConnect.map(point12=>({...point12}))})),synchronizedBreakoutPoints=[],breakoutPointIdByConnectionName=new Map;for(let inputConnection of fanoutInputSimpleRouteJson.connections){if(inputConnection.routingPcbGroupId!==routingPcbGroupId||!inputConnection.source_trace_id)continue;let outputConnection=outputConnectionByName.get(inputConnection.name);if(!outputConnection)continue;let globalPointMatches=baseConnections.filter(connection=>{if(connection.routingPcbGroupId===routingPcbGroupId)return!1;let sharesSourceTrace=connection.source_trace_id===inputConnection.source_trace_id,sharesPointId=connection.pointsToConnect.some(globalPoint=>inputConnection.pointsToConnect.some(inputPoint=>srjPointsHaveSamePointId(globalPoint,inputPoint)));return!sharesSourceTrace&&!sharesPointId?!1:connection.pointsToConnect.some(globalPoint=>inputConnection.pointsToConnect.some(inputPoint=>srjPointsReferToSameEndpoint(globalPoint,inputPoint)))}).flatMap(globalConnection=>globalConnection.pointsToConnect.flatMap((previousPoint,pointIndex)=>inputConnection.pointsToConnect.some(inputPoint=>srjPointsReferToSameEndpoint(previousPoint,inputPoint))?[{globalConnection,pointIndex,previousPoint}]:[])),changedPointIndex=outputConnection.pointsToConnect.findIndex((outputPoint,pointIndex)=>{let inputPoint=inputConnection.pointsToConnect[pointIndex];return inputPoint!==void 0&&!srjPointsHaveSameBoardPositionAndLayer(outputPoint,inputPoint)});if(changedPointIndex<0)continue;let fanoutExitPoint=outputConnection.pointsToConnect[changedPointIndex];globalPointMatches.length===0&&synchronizedBreakoutPoints.push({sourceTraceId:inputConnection.source_trace_id,routingPcbGroupId,previousPoint:inputConnection.pointsToConnect[changedPointIndex],fanoutExitPoint});for(let{globalConnection,pointIndex,previousPoint}of globalPointMatches){let{terminalVia:_previousTerminalVia,...previousPointWithoutLayerOverrides}=previousPoint,synchronizedGlobalPoint={...previousPointWithoutLayerOverrides,x:fanoutExitPoint.x,y:fanoutExitPoint.y,layer:fanoutExitPoint.layer,...fanoutExitPoint.terminalVia?{terminalVia:{...fanoutExitPoint.terminalVia}}:{}};globalConnection.pointsToConnect[pointIndex]=synchronizedGlobalPoint,previousPoint.pointId&&breakoutPointIdByConnectionName.set(inputConnection.name,previousPoint.pointId),synchronizedBreakoutPoints.push({sourceTraceId:inputConnection.source_trace_id,routingPcbGroupId,previousPoint,fanoutExitPoint})}}let newFanoutSourceKeepouts=fanoutOutputSimpleRouteJson.obstacles.filter(obstacle=>obstacle.isFanoutSourceKeepout===!0&&obstacle.componentId!==void 0),completedSourceComponentIds=new Set(newFanoutSourceKeepouts.flatMap(obstacle=>obstacle.componentId===void 0?[]:[obstacle.componentId])),retainedBaseObstacles=baseSimpleRouteJson.obstacles.filter(obstacle=>!obstacle.componentId||!completedSourceComponentIds.has(obstacle.componentId));return{downstreamSimpleRouteJson:removeCompletedFanoutConnections(connectFanoutTracesToBreakoutPoints(fanoutOutputSimpleRouteJson,breakoutPointIdByConnectionName),routingPcbGroupId),baseSimpleRouteJson:{...baseSimpleRouteJson,connections:baseConnections,obstacles:[...retainedBaseObstacles,...newFanoutSourceKeepouts]},synchronizedBreakoutPoints}}function getJumperPadInfos(db22){let padInfos=[],jumperSourceComponentIds=new Set(db22.source_component.list().filter(component=>component.name?.startsWith("__autoplaced_jumper")).map(component=>component.source_component_id));if(jumperSourceComponentIds.size===0)return padInfos;let jumperPcbComponentIds=new Set(db22.pcb_component.list().filter(component=>jumperSourceComponentIds.has(component.source_component_id)).map(component=>component.pcb_component_id)),jumperSmtpads=db22.pcb_smtpad.list().filter(pad2=>jumperPcbComponentIds.has(pad2.pcb_component_id));for(let smtpad2 of jumperSmtpads)if(smtpad2.shape!=="polygon"&&smtpad2.pcb_port_id){if(smtpad2.shape==="rect"||smtpad2.shape==="rotated_rect"){let halfWidth=smtpad2.width/2,halfHeight=smtpad2.height/2;padInfos.push({pcb_port_id:smtpad2.pcb_port_id,x:smtpad2.x,y:smtpad2.y,minX:smtpad2.x-halfWidth,maxX:smtpad2.x+halfWidth,minY:smtpad2.y-halfHeight,maxY:smtpad2.y+halfHeight})}else if(smtpad2.shape==="circle"){let radius=smtpad2.radius;padInfos.push({pcb_port_id:smtpad2.pcb_port_id,x:smtpad2.x,y:smtpad2.y,minX:smtpad2.x-radius,maxX:smtpad2.x+radius,minY:smtpad2.y-radius,maxY:smtpad2.y+radius})}}return padInfos}function findJumperPortAtPosition(padInfos,x23,y23,tolerance=.01){for(let pad2 of padInfos)if(Math.abs(pad2.x-x23)<tolerance&&Math.abs(pad2.y-y23)<tolerance)return pad2.pcb_port_id}function findJumperPortContainingPoint(padInfos,x23,y23){for(let pad2 of padInfos)if(x23>=pad2.minX&&x23<=pad2.maxX&&y23>=pad2.minY&&y23<=pad2.maxY)return pad2}function splitRouteAtJumperPads(route2,padInfos){if(route2.length===0||padInfos.length===0)return[route2];let segments2=[],currentSegment=[];for(let i23=0;i23<route2.length;i23++){let point12=route2[i23];if(currentSegment.push(point12),point12.route_type==="wire"&&i23>0&&i23<route2.length-1){let padInfo=findJumperPortContainingPoint(padInfos,point12.x,point12.y);if(padInfo){point12.end_pcb_port_id||(point12.end_pcb_port_id=padInfo.pcb_port_id),segments2.push(currentSegment);let newStartPoint={...point12};delete newStartPoint.end_pcb_port_id,newStartPoint.start_pcb_port_id||(newStartPoint.start_pcb_port_id=padInfo.pcb_port_id),currentSegment=[newStartPoint]}}}return currentSegment.length>0&&segments2.push(currentSegment),segments2}function addPortIdsToTracesAtJumperPads(segments2,padInfos){if(padInfos.length===0)return segments2;let result=[];for(let segment5 of segments2){let subSegments=splitRouteAtJumperPads(segment5,padInfos);for(let subSegment of subSegments)if(subSegment.length>0){let firstPoint=subSegment[0],lastPoint=subSegment[subSegment.length-1];if(firstPoint.route_type==="wire"&&!firstPoint.start_pcb_port_id){let portId=findJumperPortAtPosition(padInfos,firstPoint.x,firstPoint.y);portId&&(firstPoint.start_pcb_port_id=portId)}if(lastPoint.route_type==="wire"&&!lastPoint.end_pcb_port_id){let portId=findJumperPortAtPosition(padInfos,lastPoint.x,lastPoint.y);portId&&(lastPoint.end_pcb_port_id=portId)}result.push(subSegment)}}return result}var claimSrjAssignablePcbViasTraversedByRoute=({db:db22,pcbTrace,routeWithSrjMetadata})=>{for(let routePoint3 of routeWithSrjMetadata){if(routePoint3.route_type!=="through_pad")continue;let pcbViaId=routePoint3.circuitJsonMetadata?.pcb_via_id;if(!pcbViaId)continue;let assignablePcbVia=db22.pcb_via.get(pcbViaId);!assignablePcbVia?.net_is_assignable||assignablePcbVia.net_assigned&&assignablePcbVia.pcb_trace_id!==pcbTrace.pcb_trace_id||db22.pcb_via.update(assignablePcbVia.pcb_via_id,{pcb_trace_id:pcbTrace.pcb_trace_id,net_assigned:!0})}},getAxisGap=(firstMinimum,firstMaximum,secondMinimum,secondMaximum)=>Math.max(secondMinimum-firstMaximum,firstMinimum-secondMaximum),findFanoutPhaseSeparationConflict=regions=>{for(let firstIndex=0;firstIndex<regions.length;firstIndex++){let firstRegion=regions[firstIndex];for(let secondIndex=firstIndex+1;secondIndex<regions.length;secondIndex++){let secondRegion=regions[secondIndex];if(firstRegion.regionId&&firstRegion.regionId===secondRegion.regionId)continue;let horizontalGap=getAxisGap(firstRegion.bounds.minX,firstRegion.bounds.maxX,secondRegion.bounds.minX,secondRegion.bounds.maxX),verticalGap=getAxisGap(firstRegion.bounds.minY,firstRegion.bounds.maxY,secondRegion.bounds.minY,secondRegion.bounds.maxY),availableGap=Math.max(horizontalGap,verticalGap),requiredGap=firstRegion.boundaryKeepaway+secondRegion.boundaryKeepaway;if(availableGap+1e-6<requiredGap)return{firstRegion,secondRegion,availableGap,requiredGap}}}};function getAccumulatedPcbTracesWithStageOutputReplacements({accumulatedPcbTraces,stageOutputPcbTraces}){let replacedPcbTraceIds=new Set(stageOutputPcbTraces.flatMap(trace=>[trace.pcb_trace_id,...trace.__replaces_pcb_trace_id?[trace.__replaces_pcb_trace_id]:[]]));return[...accumulatedPcbTraces.filter(trace=>!replacedPcbTraceIds.has(trace.pcb_trace_id)),...stageOutputPcbTraces]}var POINT_EPSILON3=1e-6;function isPointOnWireSegment({point:point12,segmentStart,segmentEnd}){return point12.layer&&(segmentStart.layer!==point12.layer||segmentEnd.layer!==point12.layer)?!1:pointToSegmentDistance2(point12,segmentStart,segmentEnd)<=POINT_EPSILON3}function isPointInSmtPad({point:point12,pad:pad2,traceWidth=0}){if(pad2.shape==="rect"||pad2.shape==="rotated_rect"){let unrotatedPoint=pad2.shape==="rotated_rect"?applyToPoint3(rotateDEG3(-pad2.ccw_rotation,pad2.x,pad2.y),point12):point12;return Math.abs(unrotatedPoint.x-pad2.x)<=pad2.width/2+traceWidth/2&&Math.abs(unrotatedPoint.y-pad2.y)<=pad2.height/2+traceWidth/2}return pad2.shape==="circle"?distance7(point12,pad2)<=pad2.radius+traceWidth/2:!1}function isPointInPlatedHole({point:point12,hole,traceWidth=0}){return distance7(point12,hole)<=(hole.outer_diameter??hole.hole_diameter??0)/2+traceWidth/2}function getEndpointSourcePortIdsFromGeometry(db22,trace){let sourcePortIds=new Set,route2=trace.route,endpoints=[route2[0],route2[route2.length-1]].filter(point12=>!!point12&&point12.route_type==="wire"&&point12.x!==void 0&&point12.y!==void 0);for(let endpoint of endpoints){let exactEndpointSourcePortIds=new Set;for(let pcbPort of db22.pcb_port.list())pcbPort.source_port_id&&(endpoint.layer&&pcbPort.layers&&!pcbPort.layers.includes(endpoint.layer)||distance7(endpoint,pcbPort)<=.01&&exactEndpointSourcePortIds.add(pcbPort.source_port_id));if(exactEndpointSourcePortIds.size>0){for(let sourcePortId of exactEndpointSourcePortIds)sourcePortIds.add(sourcePortId);continue}for(let smtpad2 of db22.pcb_smtpad.list()){if(!smtpad2.pcb_port_id||endpoint.layer&&smtpad2.layer!==endpoint.layer||!isPointInSmtPad({point:endpoint,pad:smtpad2,traceWidth:endpoint.width}))continue;let sourcePortId=db22.pcb_port.get(smtpad2.pcb_port_id)?.source_port_id;sourcePortId&&sourcePortIds.add(sourcePortId)}for(let hole of db22.pcb_plated_hole.list()){if(!hole.pcb_port_id||!isPointInPlatedHole({point:endpoint,hole,traceWidth:endpoint.width}))continue;let sourcePortId=db22.pcb_port.get(hole.pcb_port_id)?.source_port_id;sourcePortId&&sourcePortIds.add(sourcePortId)}}return[...sourcePortIds]}function getWireRouteEndpoints(trace){let route2=trace.route.filter(point12=>point12.route_type==="wire"&&point12.x!==void 0&&point12.y!==void 0);return[route2[0],route2[route2.length-1]].filter(point12=>!!point12)}function getSourceIdsFromConnectedPcbTraces(db22,trace){let sourceIds=new Set,endpoints=getWireRouteEndpoints(trace);if(endpoints.length===0)return[];for(let existingTrace of db22.pcb_trace.list()){if(!existingTrace.source_trace_id||existingTrace.pcb_trace_id===trace.pcb_trace_id||!db22.source_trace.get(existingTrace.source_trace_id)&&!db22.source_net.get(existingTrace.source_trace_id))continue;let existingRoute=existingTrace.route.filter(point12=>point12.route_type==="wire");for(let i23=0;i23<existingRoute.length-1;i23++){let segmentStart=existingRoute[i23],segmentEnd=existingRoute[i23+1];if(!(!segmentStart||!segmentEnd))for(let endpoint of endpoints)isPointOnWireSegment({point:endpoint,segmentStart,segmentEnd})&&sourceIds.add(existingTrace.source_trace_id)}}return[...sourceIds]}function getSourcePortIdsFromRoutedTrace(db22,trace){let sourcePortIds=new Set;for(let point12 of trace.route)for(let pcbPortId of[point12.start_pcb_port_id,point12.end_pcb_port_id]){if(!pcbPortId)continue;let sourcePortId=db22.pcb_port.get(pcbPortId)?.source_port_id;sourcePortId&&sourcePortIds.add(sourcePortId)}return sourcePortIds.size>0?[...sourcePortIds]:getEndpointSourcePortIdsFromGeometry(db22,trace)}function buildSourceConnectivityMap(sourceTraces){let connMap=new ConnectivityMap({});return connMap.addConnections(sourceTraces.map(trace=>[trace.source_trace_id,...trace.connected_source_port_ids,...trace.connected_source_net_ids])),connMap}function getSourceTraceIdForRoutedTrace({db:db22,trace,subcircuit_id}){if(trace.source_trace_id&&db22.source_trace.get(trace.source_trace_id))return trace.source_trace_id;let routedSourceNet=trace.source_trace_id?db22.source_net.get(trace.source_trace_id):void 0,sourceTraces=db22.source_trace.list(),connMap=buildSourceConnectivityMap(sourceTraces),routedSourceNetConnectivityId=routedSourceNet?connMap.getNetConnectedToId(routedSourceNet.source_net_id):void 0,routedNetSourceTraces=routedSourceNetConnectivityId?sourceTraces.filter(sourceTrace=>connMap.getNetConnectedToId(sourceTrace.source_trace_id)===routedSourceNetConnectivityId):[],soleRoutedNetSourceTrace=routedNetSourceTraces.length===1?routedNetSourceTraces[0]:void 0,sourcePortIds=getSourcePortIdsFromRoutedTrace(db22,trace);if(sourcePortIds.length===0)return soleRoutedNetSourceTrace?.source_trace_id??routedSourceNet?.source_net_id??getSourceIdsFromConnectedPcbTraces(db22,trace)[0];let endpointNetIds=sourcePortIds.map(sourcePortId=>connMap.getNetConnectedToId(sourcePortId)).filter(netId=>!!netId),exactSourceTrace=sourcePortIds.length>=2?sourceTraces.find(sourceTrace=>sourcePortIds.every(sourcePortId=>sourceTrace.connected_source_port_ids.includes(sourcePortId))):void 0;if(exactSourceTrace)return exactSourceTrace.source_trace_id;if(soleRoutedNetSourceTrace)return soleRoutedNetSourceTrace.source_trace_id;if(routedSourceNet)return routedSourceNet.source_net_id;let sourceTracesInEndpointNets=sourceTraces.filter(sourceTrace=>{let sourceTraceNetId=connMap.getNetConnectedToId(sourceTrace.source_trace_id);return endpointNetIds.some(netId=>netId===sourceTraceNetId)}),connectedToEndpoint=sourceTracesInEndpointNets.filter(sourceTrace=>sourceTrace.connected_source_port_ids.some(sourcePortId=>sourcePortIds.includes(sourcePortId))),candidates=connectedToEndpoint.length>0?connectedToEndpoint:sourceTracesInEndpointNets;if(candidates.length!==0)return(candidates.find(sourceTrace=>sourceTrace.subcircuit_id===subcircuit_id)??candidates[0])?.source_trace_id}function groupPadsByInternalConnection(pads,orientation32){let groups=[];for(let pad2 of pads){let key=orientation32==="vertical"?pad2.center.y:pad2.center.x,foundGroup=!1;for(let group2 of groups){let groupKey=orientation32==="vertical"?group2[0].center.y:group2[0].center.x;if(Math.abs(key-groupKey)<.01){group2.push(pad2),foundGroup=!0;break}}foundGroup||groups.push([pad2])}return groups.filter(g23=>g23.length>=2)}function insertAutoplacedJumpers(params){let{db:db22,output_jumpers,subcircuit_id}=params;for(let jumperIndex=0;jumperIndex<output_jumpers.length;jumperIndex++){let jumper=output_jumpers[jumperIndex],sourceComponent=db22.source_component.insert({ftype:"simple_chip",name:`__autoplaced_jumper_${jumperIndex}`,supplier_part_numbers:{}}),rotation6=jumper.orientation==="horizontal"?0:90,firstPadLayer=jumper.pads[0]?.layer||jumper.pads[0]?.layers?.[0]||"top",pcbComponent=db22.pcb_component.insert({source_component_id:sourceComponent.source_component_id,center:jumper.center,rotation:rotation6,layer:firstPadLayer,width:jumper.width||0,height:jumper.height||0,obstructs_within_bounds:!1}),padData=[];for(let padIndex=0;padIndex<jumper.pads.length;padIndex++){let pad2=jumper.pads[padIndex],pinNumber2=padIndex+1,sourcePort=db22.source_port.insert({source_component_id:sourceComponent.source_component_id,name:`pin${pinNumber2}`,pin_number:pinNumber2}),padLayer=pad2.layer||pad2.layers?.[0]||"top",pcbPort=db22.pcb_port.insert({pcb_component_id:pcbComponent.pcb_component_id,source_port_id:sourcePort.source_port_id,x:pad2.center.x,y:pad2.center.y,layers:[padLayer]}),pcbSmtpad=db22.pcb_smtpad.insert({pcb_component_id:pcbComponent.pcb_component_id,pcb_port_id:pcbPort.pcb_port_id,shape:"rect",x:pad2.center.x,y:pad2.center.y,width:pad2.width,height:pad2.height,layer:padLayer});padData.push({pad:pad2,sourcePortId:sourcePort.source_port_id,pcbSmtpadId:pcbSmtpad.pcb_smtpad_id})}let internalGroups=groupPadsByInternalConnection(jumper.pads,jumper.orientation);for(let group2 of internalGroups){let sourcePortIds=[];for(let groupPad of group2){let padInfo=padData.find(p23=>Math.abs(p23.pad.center.x-groupPad.center.x)<.01&&Math.abs(p23.pad.center.y-groupPad.center.y)<.01);padInfo&&sourcePortIds.push(padInfo.sourcePortId)}sourcePortIds.length>=2&&db22.source_component_internal_connection.insert({source_component_id:sourceComponent.source_component_id,subcircuit_id:subcircuit_id??void 0,source_port_ids:sourcePortIds})}}}function convertPcbTraceToSimplifiedPcbTrace(trace){return{...trace,type:"pcb_trace",pcb_trace_id:trace.pcb_trace_id,connection_name:trace.connection_name??trace.source_trace_id??trace.pcb_trace_id,route:trace.route.map(point12=>({...point12}))}}function getRelevantSubcircuitIdsForReroute(group2){let relevantSubcircuitIds=new Set;if(!group2.subcircuit_id)return relevantSubcircuitIds;relevantSubcircuitIds.add(group2.subcircuit_id);let db22=group2.root?.db;if(!db22)return relevantSubcircuitIds;for(let subcircuitId of getDescendantSubcircuitIds2(db22,group2.subcircuit_id))relevantSubcircuitIds.add(subcircuitId);return relevantSubcircuitIds}function getExistingPcbTracesForReroute(group2){let db22=group2.root?.db;if(!db22)return[];let relevantSubcircuitIds=getRelevantSubcircuitIdsForReroute(group2);return db22.pcb_trace.list().filter(trace=>!trace.route||trace.route.length<2?!1:group2.subcircuit_id?!!(trace.subcircuit_id&&relevantSubcircuitIds.has(trace.subcircuit_id)):!0)}function getSourceTraceIdsFromRerouteName(value){return typeof value!="string"||value.length===0?[]:value.split("__").flatMap(connectionNamePart=>{if(connectionNamePart.length===0)return[];let sourceTraceIds=[connectionNamePart],rerouteSuffixIndex=connectionNamePart.indexOf("_reroute_");return rerouteSuffixIndex>0&&sourceTraceIds.push(connectionNamePart.slice(0,rerouteSuffixIndex)),sourceTraceIds})}function addPossibleReplacementSourceTraceId(sourceTraceIds,value){if(!(typeof value!="string"||value.length===0)){sourceTraceIds.add(value);for(let sourceTraceId of getSourceTraceIdsFromRerouteName(value))sourceTraceIds.add(sourceTraceId)}}function deleteExistingPcbTracesReplacedBy({group:group2,outputPcbTraces,pcbTraceIdsToReplace=[]}){let db22=group2.root?.db;if(!db22)return;let replacementPcbTraceIds=new Set(pcbTraceIdsToReplace),replacementSourceTraceIds=new Set;for(let trace of outputPcbTraces){if(trace.type!=="pcb_trace")continue;let replacementTrace=trace;replacementPcbTraceIds.add(replacementTrace.pcb_trace_id),addPossibleReplacementSourceTraceId(replacementSourceTraceIds,replacementTrace.source_trace_id),addPossibleReplacementSourceTraceId(replacementSourceTraceIds,replacementTrace.connection_name),addPossibleReplacementSourceTraceId(replacementSourceTraceIds,replacementTrace.rootConnectionName)}if(replacementPcbTraceIds.size===0&&replacementSourceTraceIds.size===0)return;let tracesToDelete=getExistingPcbTracesForReroute(group2).filter(trace=>replacementPcbTraceIds.has(trace.pcb_trace_id)||!!(trace.source_trace_id&&trace.subcircuit_id===group2.subcircuit_id&&replacementSourceTraceIds.has(trace.source_trace_id)));if(tracesToDelete.length===0)return;let deletedPcbTraceIds=new Set(tracesToDelete.map(trace=>trace.pcb_trace_id));for(let via of db22.pcb_via.list())via.pcb_trace_id&&deletedPcbTraceIds.has(via.pcb_trace_id)&&db22.pcb_via.delete(via.pcb_via_id);for(let trace of tracesToDelete)db22.pcb_trace.delete(trace.pcb_trace_id)}function getExistingSimplifiedPcbTracesForReroute(group2){return getExistingPcbTracesForReroute(group2).map(convertPcbTraceToSimplifiedPcbTrace)}function splitPcbTracesOnJumperSegments(route2){let jumperRoutes=route2.filter(p23=>p23.route_type==="jumper"),wireAndViaRoutes=route2.filter(p23=>p23.route_type!=="jumper");if(jumperRoutes.length===0)return null;let splitRanges=[];for(let jumperRoute of jumperRoutes){let jumperStart=jumperRoute.start,jumperEnd=jumperRoute.end,startIdx=-1,endIdx=-1,minStartDist=1/0,minEndDist=1/0;for(let i23=0;i23<wireAndViaRoutes.length;i23++){let p23=wireAndViaRoutes[i23];if(p23.route_type!=="wire")continue;let distToStart=Math.hypot(p23.x-jumperStart.x,p23.y-jumperStart.y),distToEnd=Math.hypot(p23.x-jumperEnd.x,p23.y-jumperEnd.y);distToStart<minStartDist&&(minStartDist=distToStart,startIdx=i23),distToEnd<minEndDist&&(minEndDist=distToEnd,endIdx=i23)}startIdx>endIdx&&([startIdx,endIdx]=[endIdx,startIdx]),startIdx>=0&&endIdx>=0&&startIdx!==endIdx&&splitRanges.push({startIdx,endIdx})}splitRanges.sort((a23,b23)=>a23.startIdx-b23.startIdx);let segments2=[],currentStart=0;for(let range4 of splitRanges)currentStart<range4.startIdx&&segments2.push(wireAndViaRoutes.slice(currentStart,range4.startIdx+1)),currentStart=range4.endIdx;return currentStart<wireAndViaRoutes.length&&segments2.push(wireAndViaRoutes.slice(currentStart)),segments2}function computeCenterFromAnchorPosition(anchorPosition,ctx){let{width:width10,height:height10,pcbAnchorAlignment}=ctx;if(!pcbAnchorAlignment)return anchorPosition;let alignment=pcbAnchorAlignment;if(typeof width10!="number"||typeof height10!="number")return anchorPosition;let ax22=anchorPosition.x,ay22=anchorPosition.y;switch(alignment){case"top_left":return{x:ax22+width10/2,y:ay22-height10/2};case"top_center":return{x:ax22,y:ay22-height10/2};case"top_right":return{x:ax22-width10/2,y:ay22-height10/2};case"center_left":return{x:ax22+width10/2,y:ay22};case"center_right":return{x:ax22-width10/2,y:ay22};case"bottom_left":return{x:ax22+width10/2,y:ay22+height10/2};case"bottom_center":return{x:ax22,y:ay22+height10/2};case"bottom_right":return{x:ax22-width10/2,y:ay22+height10/2};default:return anchorPosition}}var getDistanceToPoint=(routePoint3,targetPoint)=>{let position22=getRoutePointPosition(routePoint3);return Math.hypot(position22.x-targetPoint.x,position22.y-targetPoint.y)},platformAllowsLegacyAutorouters=group2=>{let platform=group2.root?.platform;return platform!==void 0&&"allowLegacyAutorouters"in platform&&platform.allowLegacyAutorouters===!0},getDisabledLegacyGroupAutorouterPreset=group2=>{if(platformAllowsLegacyAutorouters(group2))return null;let resolvedGroupAutorouter=group2._parsedProps.autorouter??group2.getInheritedProperty("autorouter");return getLegacyAutorouterPreset(resolvedGroupAutorouter)},getDisabledLegacyAutorouterPreset=group2=>{if(platformAllowsLegacyAutorouters(group2))return null;let legacyGroupAutorouterPreset=getDisabledLegacyGroupAutorouterPreset(group2);if(legacyGroupAutorouterPreset)return legacyGroupAutorouterPreset;let routingPhaseAutorouters=group2.selectAll("autoroutingphase").map(autoroutingPhase=>autoroutingPhase._parsedProps.autorouter);for(let autorouter of routingPhaseAutorouters){let legacyAutorouterPreset=getLegacyAutorouterPreset(autorouter);if(legacyAutorouterPreset)return legacyAutorouterPreset}return null},ensureRouteStartsAtSourceTraceStart=({db:db22,route:route2,routeThicknessMode,sourceTraceId})=>{if(!sourceTraceId||route2.length<2)return route2;let firstSourcePortId=db22.source_trace.get(sourceTraceId)?.connected_source_port_ids[0];if(!firstSourcePortId)return route2;let firstPcbPort=db22.pcb_port.list().find(port=>port.source_port_id===firstSourcePortId);if(!firstPcbPort)return route2;let firstPoint=route2[0],lastPoint=route2[route2.length-1];return getDistanceToPoint(lastPoint,firstPcbPort)<getDistanceToPoint(firstPoint,firstPcbPort)?reversePcbTraceRoute(route2,routeThicknessMode):route2},Group=class extends NormalComponent{constructor(){super(...arguments);__publicField(this,"pcb_group_id",null);__publicField(this,"schematic_group_id",null);__publicField(this,"subcircuit_id",null);__publicField(this,"_hasStartedAsyncAutorouting",!1);__publicField(this,"_pcbPlacementDrcErrorCount",null);__publicField(this,"_pcbPlacementDrcCheckError",null);__publicField(this,"_pcbPlacementDrcChecksPending",!1);__publicField(this,"_standaloneSubcircuitDrcChecksComplete",!1);__publicField(this,"_standaloneSubcircuitDrcChecksInProgress",!1);__publicField(this,"_isInflatedFromCircuitJson",!1);__publicField(this,"_isolatedCircuitJson",null);__publicField(this,"_normalComponentNameMap",null);__publicField(this,"_asyncAutoroutingResult",null);__publicField(this,"unnamedElementCounter",{})}get _isIsolatedSubcircuit(){return!!this.getInheritedProperty("_subcircuitCachingEnabled")}getNormalComponentNameMap(){if(this._normalComponentNameMap)return this._normalComponentNameMap;let nameMap=new Map,collectNamedComponents=component=>{if(component._isNormalComponent&&component.name){let componentsWithSameName=nameMap.get(component.name);componentsWithSameName?componentsWithSameName.push(component):nameMap.set(component.name,[component])}for(let child of component.children)child.isSubcircuit||collectNamedComponents(child)};for(let child of this.children)child.isSubcircuit||collectNamedComponents(child);return this._normalComponentNameMap=nameMap,nameMap}get config(){return{zodProps:groupProps,componentName:"Group"}}initPorts(opts={}){let schPinArrangement=this._getSchematicPortArrangement();this._parsedProps?.showAsSchematicBox&&!this._parsedProps.pinLabels&&schPinArrangement&&getPinsFromPortArrangement(schPinArrangement).some(pin=>typeof pin=="string")||super.initPorts(opts)}_getSchematicPortArrangementFromPortDirections(){if(!this._parsedProps?.showAsSchematicBox)return null;let sidePins={leftSide:[],rightSide:[],topSide:[],bottomSide:[]};for(let port of this.children){if(port.componentName!=="Port")continue;let direction4=port._parsedProps.direction;if(!direction4)continue;let pin=port._parsedProps.pinNumber??port._parsedProps.name??void 0;if(pin===void 0)continue;sidePins[direction4==="left"?"leftSide":direction4==="right"?"rightSide":direction4==="up"?"topSide":"bottomSide"].push(pin)}if(sidePins.leftSide.length===0&&sidePins.rightSide.length===0&&sidePins.topSide.length===0&&sidePins.bottomSide.length===0)return null;let arrangement={};return sidePins.leftSide.length>0&&(arrangement.leftSide={pins:sidePins.leftSide,direction:"top-to-bottom"}),sidePins.rightSide.length>0&&(arrangement.rightSide={pins:sidePins.rightSide,direction:"top-to-bottom"}),sidePins.topSide.length>0&&(arrangement.topSide={pins:sidePins.topSide,direction:"left-to-right"}),sidePins.bottomSide.length>0&&(arrangement.bottomSide={pins:sidePins.bottomSide,direction:"left-to-right"}),arrangement}_getSchematicPortArrangement(){return super._getSchematicPortArrangement()??this._getSchematicPortArrangementFromPortDirections()}_ensureSchematicBoxPortsFromConnections(){if(this._parsedProps?.showAsSchematicBox&&this._parsedProps?.connections)for(let[pinName,target]of Object.entries(this._parsedProps.connections)){if(this.children.find(child=>child.componentName==="Port"&&child.isMatchingAnyOf([pinName])))continue;let pinNumberMatch=pinName.match(/^pin(\d+)$/i)??pinName.match(/^(\d+)$/),pinNumber2=pinNumberMatch?Number(pinNumberMatch[1]):void 0;this.add(new Port({name:pinName,pinNumber:pinNumber2,connectsTo:target}))}}doInitialInitializePortsFromChildren(){super.doInitialInitializePortsFromChildren(),this._ensureSchematicBoxPortsFromConnections()}updateInitializePortsFromChildren(){super.updateInitializePortsFromChildren(),this._ensureSchematicBoxPortsFromConnections()}_getPrimaryPinCount(){let superPinCount=super._getPrimaryPinCount();if(!this._parsedProps?.showAsSchematicBox)return superPinCount;let directPortPinNumbers=this.children.filter(child=>child.componentName==="Port").map(port=>port._parsedProps.pinNumber).filter(pinNumber2=>pinNumber2!==void 0);return directPortPinNumbers.length===0?superPinCount:Math.max(superPinCount,...directPortPinNumbers)}_getPinLabelsFromPorts(){return this._parsedProps?.showAsSchematicBox?getGroupSchematicBoxPinLabels(this):super._getPinLabelsFromPorts()}doInitialSourceGroupRender(){let{db:db22}=this.root,hasExplicitName=typeof this._parsedProps.name=="string"&&this._parsedProps.name.length>0,source_group23=db22.source_group.insert({name:this.name,is_subcircuit:this.isSubcircuit,was_automatically_named:!hasExplicitName});this.source_group_id=source_group23.source_group_id,this.isSubcircuit&&(this.subcircuit_id=`subcircuit_${source_group23.source_group_id}`,db22.source_group.update(source_group23.source_group_id,{subcircuit_id:this.subcircuit_id}))}doInitialSourceRender(){let{db:db22}=this.root;for(let child of this.getDescendants())child.getGroup()?.source_group_id===this.source_group_id&&db22.source_component.update(child.source_component_id,{source_group_id:this.source_group_id});if(!this.isSubcircuit)return;let disabledLegacyAutorouterPreset=getDisabledLegacyAutorouterPreset(this);disabledLegacyAutorouterPreset&&db22.source_invalid_component_property_error.insert({source_component_id:this.source_component_id??"",property_name:"autorouter",error_type:"source_invalid_component_property_error",message:`The "${disabledLegacyAutorouterPreset}" autorouter is deprecated and is not enabled by this platform. Use the default autorouter and introduce <autoroutingphase /> or <fanout /> elements as needed.`})}doInitialSourceParentAttachment(){let{db:db22}=this.root,parentGroup=this.parent?.getGroup?.();if(parentGroup?.source_group_id&&db22.source_group.update(this.source_group_id,{parent_source_group_id:parentGroup.source_group_id}),!this.isSubcircuit||isAssemblyDeviceContainer(this.parent))return;let parent_subcircuit_id=this.parent?.getSubcircuit?.()?.subcircuit_id;parent_subcircuit_id&&db22.source_group.update(this.source_group_id,{parent_subcircuit_id})}doInitialPcbComponentRender(){if(this.root?.pcbDisabled)return;let{db:db22}=this.root,{_parsedProps:props}=this,groupProps22=props,hasOutline=groupProps22.outline&&groupProps22.outline.length>0,numericOutline=hasOutline?groupProps22.outline.map(point12=>({x:distance4.parse(point12.x),y:distance4.parse(point12.y)})):void 0,ctx=this.props,anchorPosition=this._getGlobalPcbPositionBeforeLayout(),center2=computeCenterFromAnchorPosition(anchorPosition,ctx),pcb_group32=db22.pcb_group.insert({is_subcircuit:this.isSubcircuit,subcircuit_id:this.subcircuit_id??this.getSubcircuit()?.subcircuit_id,name:this.name,anchor_position:anchorPosition,center:center2,...hasOutline?{outline:numericOutline}:{width:0,height:0},pcb_component_ids:[],source_group_id:this.source_group_id,autorouter_configuration:props.autorouter?{trace_clearance:props.autorouter.traceClearance}:void 0,anchor_alignment:props.pcbAnchorAlignment??"center"});this.pcb_group_id=pcb_group32.pcb_group_id;for(let child of this.children)db22.pcb_component.update(child.pcb_component_id,{pcb_group_id:pcb_group32.pcb_group_id})}doInitialPcbPrimitiveRender(){this.calculatePcbGroupBounds()}calculatePcbGroupBounds(pcbContentBounds){if(!this.pcb_group_id||this.root?.pcbDisabled)return;let{db:db22}=this.root,props=this._parsedProps,hasOutline=props.outline&&props.outline.length>0,hasExplicitPositioning=this._parsedProps.pcbX!==void 0||this._parsedProps.pcbY!==void 0;if(hasOutline){let numericOutline=props.outline.map(point12=>({x:distance4.parse(point12.x),y:distance4.parse(point12.y)})),outlineBounds=getBoundsFromPoints3(numericOutline);if(!outlineBounds)return;let centerX2=(outlineBounds.minX+outlineBounds.maxX)/2,centerY2=(outlineBounds.minY+outlineBounds.maxY)/2,center22=hasExplicitPositioning?db22.pcb_group.get(this.pcb_group_id)?.center??{x:centerX2,y:centerY2}:{x:centerX2,y:centerY2};db22.pcb_group.update(this.pcb_group_id,{center:center22});return}let contentBounds=pcbContentBounds;if(!contentBounds){let bounds=getBoundsOfPcbComponents(this.children);contentBounds={center:{x:(bounds.minX+bounds.maxX)/2,y:(bounds.minY+bounds.maxY)/2},width:bounds.width,height:bounds.height}}let{width:width10,height:height10}=contentBounds,{x:centerX,y:centerY}=contentBounds.center;if(this.isSubcircuit||this.isRoutingDirective){let{padLeft,padRight,padTop,padBottom}=this._resolvePcbPadding();width10+=padLeft+padRight,height10+=padTop+padBottom,centerX+=(padRight-padLeft)/2,centerY+=(padTop-padBottom)/2}let resolvedWidth=Number(props.width??width10),resolvedHeight=Number(props.height??height10),existingCenter=db22.pcb_group.get(this.pcb_group_id)?.center??{x:centerX,y:centerY},shouldUsePcbContentCenter=this.isSubcircuit||this.isRoutingDirective||pcbContentBounds!==void 0,center2=hasExplicitPositioning?shouldUsePcbContentCenter?{x:props.width===void 0?centerX:existingCenter.x,y:props.height===void 0?centerY:existingCenter.y}:existingCenter:{x:centerX,y:centerY};if(hasExplicitPositioning&&props.pcbAnchorAlignment){let anchorPosition=this._getGlobalPcbPositionBeforeLayout(),anchorAlignedCenter=computeCenterFromAnchorPosition(anchorPosition,{...this.props,width:resolvedWidth,height:resolvedHeight});(Math.abs(anchorAlignedCenter.x-center2.x)>1e-6||Math.abs(anchorAlignedCenter.y-center2.y)>1e-6)&&this._repositionOnPcb(anchorAlignedCenter),center2=anchorAlignedCenter}db22.pcb_group.update(this.pcb_group_id,{width:resolvedWidth,height:resolvedHeight,center:center2})}updatePcbPrimitiveRender(){this.calculatePcbGroupBounds()}getNextAvailableName(elm){var _a548,_b5;return(_a548=this.unnamedElementCounter)[_b5=elm.lowercaseComponentName]??(_a548[_b5]=1),`unnamed_${elm.lowercaseComponentName}${this.unnamedElementCounter[elm.lowercaseComponentName]++}`}_resolvePcbPadding(){let props=this._parsedProps,layout=props.pcbLayout,getPaddingValue=key=>{let layoutValue=layout?.[key],propsValue=props[key];if(typeof layoutValue=="number")return layoutValue;if(typeof propsValue=="number")return propsValue},generalPadding=getPaddingValue("padding")??0,paddingX=getPaddingValue("paddingX"),paddingY=getPaddingValue("paddingY"),padLeft=getPaddingValue("paddingLeft")??paddingX??generalPadding,padRight=getPaddingValue("paddingRight")??paddingX??generalPadding,padTop=getPaddingValue("paddingTop")??paddingY??generalPadding,padBottom=getPaddingValue("paddingBottom")??paddingY??generalPadding;return{padLeft,padRight,padTop,padBottom}}doInitialCreateTraceHintsFromProps(){let{_parsedProps:props}=this,{db:db22}=this.root,groupProps22=props;if(!this.isSubcircuit)return;let manualTraceHints=groupProps22.manualEdits?.manual_trace_hints;if(manualTraceHints)for(let manualTraceHint of manualTraceHints)this.add(new TraceHint({for:manualTraceHint.pcb_port_selector,offsets:manualTraceHint.offsets}))}doInitialSourceAddConnectivityMapKey(){Group_doInitialSourceAddConnectivityMapKey(this),Group_doInitialAssignSchematicSheetToConnectedComponents(this)}_areChildSubcircuitsRouted(){let subcircuitChildren=this._findDirectChildSubcircuits();for(let subcircuitChild of subcircuitChildren)if(!subcircuitChild._isInflatedFromCircuitJson&&subcircuitChild._hasTracesToRoute()&&subcircuitChild._shouldRouteAsync()&&!subcircuitChild._asyncAutoroutingResult)return!1;return!0}_findDirectChildSubcircuits(){let result=[],visit=children=>{for(let child of children)child.isSubcircuit&&child!==this?result.push(child):visit(child.children)};return visit(this.children),result}_shouldRouteAsync(){if(this._isLegacyAutorouterDisabled())return!1;let autorouter=this._getAutorouterConfig();return autorouter.groupMode==="sequential-trace"?!1:!!(autorouter.local&&autorouter.groupMode==="subcircuit"||!autorouter.local)}_getRoutingPhasePlans(){let plans=Group_getRoutingPhasePlans(this),testPointPhases=plans.filter(plan=>plan.testPointOptions);if(testPointPhases.length>1||testPointPhases.length===1&&plans.at(-1)!==testPointPhases[0])throw new Error("Use a single final autorouting phase for PCB test points");return plans}_hasTracesToRoute(){let debug132=(0,import_debug11.default)("tscircuit:core:_hasTracesToRoute"),routingPhasePlans=this._getRoutingPhasePlans(),traceCount=0,hasReroutePhaseWithExistingTraceInput=!1;for(let routingPhasePlan of routingPhasePlans){traceCount+=routingPhasePlan.traces.length;let phaseAutorouterConfig=routingPhasePlan.autorouter?getPresetAutoroutingConfig(routingPhasePlan.autorouter,this.root?.platform):void 0;hasReroutePhaseWithExistingTraceInput||(hasReroutePhaseWithExistingTraceInput=!!(routingPhasePlan.reroute&&(routingPhasePlan.region||phaseAutorouterConfig?.preset==="simplify")))}if(debug132(`[${this.getString()}] has ${traceCount} traces to route`),traceCount>0)return!0;if(hasReroutePhaseWithExistingTraceInput){let existingTraceCount=getExistingPcbTracesForReroute(this).length;return debug132(`[${this.getString()}] has ${existingTraceCount} existing pcb traces available for reroute`),existingTraceCount>0}return!1}async _runEffectMakeHttpAutoroutingRequest(){let{db:db22}=this.root,debug132=(0,import_debug11.default)("tscircuit:core:_runEffectMakeHttpAutoroutingRequest"),props=this._parsedProps,autorouterConfig3=this._getAutorouterConfig(),serverUrl=autorouterConfig3.serverUrl,serverMode=autorouterConfig3.serverMode,fetchWithDebug=(url3,options)=>(debug132("fetching",url3),options.headers&&(options.headers["Tscircuit-Core-Version"]=this.root?.getCoreVersion()),fetch(url3,options)),pcbAndSourceCircuitJson=this.root.db.toArray().filter(element2=>element2.type.startsWith("source_")||element2.type.startsWith("pcb_")),preferredTraceWidth=props.defaultTraceWidth??props.nominalTraceWidth,{simpleRouteJson}=getSimpleRouteJsonFromCircuitJson({pcb_panel_id:getOwningPanel(this)?.pcb_panel_id??void 0,db:db22,allowViaInPad:autorouterConfig3.allowViaInPad,minTraceWidth:Number(props.minTraceWidth??.15),nominalTraceWidth:preferredTraceWidth!=null?Number(preferredTraceWidth):void 0,subcircuit_id:this.subcircuit_id,subcircuitComponent:this}),unbrokenPlaneRouteJson=simpleRouteJson.obstacles.some(obstacle=>obstacle.isCopperPour)?simpleRouteJson:void 0;if(serverMode==="solve-endpoint"){let simplifiedInput=this.props.autorouter?.inputFormat==="simplified",{autorouting_result}=await fetchWithDebug(`${serverUrl}/autorouting/solve`,{method:"POST",body:JSON.stringify({input_circuit_json:simplifiedInput?void 0:pcbAndSourceCircuitJson,input_simple_route_json:simplifiedInput?simpleRouteJson:unbrokenPlaneRouteJson,subcircuit_id:this.subcircuit_id}),headers:{"Content-Type":"application/json"}}).then(r23=>r23.json());this._asyncAutoroutingResult=autorouting_result,this._markDirty("PcbTraceRender");return}let{autorouting_job}=await fetchWithDebug(`${serverUrl}/autorouting/jobs/create`,{method:"POST",body:JSON.stringify({input_circuit_json:pcbAndSourceCircuitJson,input_simple_route_json:unbrokenPlaneRouteJson,provider:"freerouting",autostart:!0,display_name:this.root?.name,subcircuit_id:this.subcircuit_id,server_cache_enabled:autorouterConfig3.serverCacheEnabled}),headers:{"Content-Type":"application/json"}}).then(r23=>r23.json());for(;;){let{autorouting_job:job}=await fetchWithDebug(`${serverUrl}/autorouting/jobs/get`,{method:"POST",body:JSON.stringify({autorouting_job_id:autorouting_job.autorouting_job_id}),headers:{"Content-Type":"application/json"}}).then(r23=>r23.json());if(job.is_finished){let{autorouting_job_output}=await fetchWithDebug(`${serverUrl}/autorouting/jobs/get_output`,{method:"POST",body:JSON.stringify({autorouting_job_id:autorouting_job.autorouting_job_id}),headers:{"Content-Type":"application/json"}}).then(r23=>r23.json());this._asyncAutoroutingResult={output_pcb_traces:autorouting_job_output.output_pcb_traces},this._markDirty("PcbTraceRender");break}if(job.has_error){let err2=new AutorouterError(`Autorouting job failed: ${JSON.stringify(job.error)}`);throw db22.pcb_autorouting_error.insert({pcb_error_id:autorouting_job.autorouting_job_id,error_type:"pcb_autorouting_error",message:err2.message}),err2}await new Promise(resolve10=>setTimeout(resolve10,100))}}async _runLocalAutorouting(){let{db:db22}=this.root,props=this._parsedProps,debug132=(0,import_debug11.default)("tscircuit:core:_runLocalAutorouting");debug132(`[${this.getString()}] starting local autorouting`);let autorouterConfig3=this._getAutorouterConfig(),isLaserPrefabPreset=this._isLaserPrefabAutorouter(autorouterConfig3),isAutoJumperPreset=this._isAutoJumperAutorouter(autorouterConfig3),isSingleLayerBoard=this._getSubcircuitLayerCount()===1,minTraceWidth=Number(props.minTraceWidth??.15),nominalTraceWidth=Number(props.defaultTraceWidth??props.nominalTraceWidth??minTraceWidth),routingPhasePlans=this._getRoutingPhasePlans(),hasPhasedAutorouting=this.getInheritedProperty("routeRemaining")===!1||Group_hasPhasedAutorouting(routingPhasePlans),shouldEmitRoutingPhaseDebugObjects=routingPhasePlans.length>1,routingPhaseDebugLabels=new Map;if(shouldEmitRoutingPhaseDebugObjects)for(let debugObject of db22.pcb_debug_object.list())debugObject.subcircuit_id===this.subcircuit_id&&(debugObject.label?.startsWith("Autorouting phase: ")||debugObject.label?.startsWith("autorouting phase "))&&db22.pcb_debug_object.delete(debugObject.pcb_debug_object_id);let emitRoutingPhaseDebugObject=(routingPhasePlan,bounds)=>{if(!shouldEmitRoutingPhaseDebugObjects)return;let phaseLabel=routingPhaseDebugLabels.get(routingPhasePlan),phaseName=routingPhasePlan.phaseName?.trim();db22.pcb_debug_object.insert({shape:"rect",center:{x:(bounds.minX+bounds.maxX)/2,y:(bounds.minY+bounds.maxY)/2},size:{width:bounds.maxX-bounds.minX,height:bounds.maxY-bounds.minY},label:`autorouting phase ${phaseLabel}${phaseName?` ${phaseName}`:""}`,subcircuit_id:this.subcircuit_id??void 0})},routingStages=routingPhasePlans.flatMap(routingPhasePlan=>{let resolvedPhaseAutorouterConfig=routingPhasePlan.autorouter?getPresetAutoroutingConfig(routingPhasePlan.autorouter,this.root?.platform):autorouterConfig3,preset=resolvedPhaseAutorouterConfig.preset,implicitPhaseLabel=routingPhasePlan.testPointOptions?"test points":routingPhasePlan.reroute?preset==="simplify"?"simplify":"reroute":routingPhasePlan.fanoutRegionPcbGroupId?routingPhasePlan.autorouter==="default"&&!routingPhasePlan.getPrecomputedRoutingResult?"breakout":"fanout":preset&&preset!=="default"?preset.replaceAll("_"," "):"default";routingPhaseDebugLabels.set(routingPhasePlan,routingPhasePlan.routingPhaseIndex?.toString()??implicitPhaseLabel);let phaseAutorouterConfig=routingPhasePlan.getPrecomputedRoutingResult?{...resolvedPhaseAutorouterConfig,allowViaInPad:(typeof routingPhasePlan.autorouter=="object"?routingPhasePlan.autorouter.allowViaInPad:void 0)??autorouterConfig3.allowViaInPad}:resolvedPhaseAutorouterConfig,stages=getLocalAutoroutingStages(routingPhasePlan.testPointOptions?{local:!0,groupMode:"subcircuit",preset:"default"}:routingPhasePlan.algorithmFn?{...phaseAutorouterConfig,algorithmFn:routingPhasePlan.algorithmFn}:phaseAutorouterConfig,this.root?.platform);return stages.map((stage,phaseStageIndex)=>({...stage,routingPhasePlan,phaseStageIndex,phaseStageCount:stages.length}))}),implicitPhaseLabelCounts=new Map;for(let plan of routingPhasePlans){if(plan.routingPhaseIndex!==null)continue;let label=routingPhaseDebugLabels.get(plan);implicitPhaseLabelCounts.set(label,(implicitPhaseLabelCounts.get(label)??0)+1)}let implicitPhaseLabelOrdinals=new Map;for(let plan of routingPhasePlans){if(plan.routingPhaseIndex!==null)continue;let label=routingPhaseDebugLabels.get(plan);if(implicitPhaseLabelCounts.get(label)<=1)continue;let ordinal=(implicitPhaseLabelOrdinals.get(label)??0)+1;implicitPhaseLabelOrdinals.set(label,ordinal),routingPhaseDebugLabels.set(plan,`${label} ${ordinal}`)}let fanoutPourNetMap=routingStages.some(({autorouterConfig:autorouterConfig22})=>["fanout","single_layer_fanout","dogbone"].includes(autorouterConfig22.preset??""))?Group_getFanoutPourNetMap(this,routingPhasePlans):void 0,{simpleRouteJson:baseSimpleRouteJson}=getSimpleRouteJsonFromCircuitJson({pcb_panel_id:getOwningPanel(this)?.pcb_panel_id??void 0,db:db22,minTraceWidth,nominalTraceWidth,subcircuit_id:this.subcircuit_id,subcircuitComponent:this,fanoutPourNetMap}),emitFanoutBoundsConflictWarning=routingPhasePlan=>{let fanoutRegionPcbGroupId=routingPhasePlan.fanoutRegionPcbGroupId;if(!fanoutRegionPcbGroupId)return;let pcbGroup=db22.pcb_group.get(fanoutRegionPcbGroupId),sourceComponentId=db22.pcb_component.list().find(component=>component.pcb_group_id===fanoutRegionPcbGroupId)?.source_component_id;if(!sourceComponentId)return;let message=`${pcbGroup?.name??"Breakout"} defines conflicting fanout bounds with explicit breakout geometry and fanoutBoundaryPadding. Explicit breakout geometry takes precedence, so fanoutBoundaryPadding is ignored.`;db22.source_property_ignored_warning.list().some(warning=>warning.source_component_id===sourceComponentId&&warning.property_name==="fanoutBoundaryPadding"&&warning.message===message)||db22.source_property_ignored_warning.insert({source_component_id:sourceComponentId,property_name:"fanoutBoundaryPadding",message,error_type:"source_property_ignored_warning",subcircuit_id:pcbGroup?.subcircuit_id})},fanoutConfigByPhasePlan=new Map;for(let routingStage of routingStages){let fanoutMode=routingStage.autorouterConfig.preset;(fanoutMode==="fanout"||fanoutMode==="single_layer_fanout")&&!fanoutConfigByPhasePlan.has(routingStage.routingPhasePlan)&&fanoutConfigByPhasePlan.set(routingStage.routingPhasePlan,routingStage.autorouterConfig)}let fanoutPhaseRegions=[];for(let[routingPhasePlan,phaseAutorouterConfig]of fanoutConfigByPhasePlan){let fanoutRegionPcbGroupId=routingPhasePlan.fanoutRegionPcbGroupId;if(!fanoutRegionPcbGroupId)continue;let phaseSimpleRouteJson=Group_filterSimpleRouteJsonForPhase(baseSimpleRouteJson,routingPhasePlan);if(phaseSimpleRouteJson.connections.length===0)continue;phaseSimpleRouteJson=Group_applyDrcTolerancesToSimpleRouteJson(phaseSimpleRouteJson,routingPhasePlan.drcTolerances);let breakoutPoints=db22.pcb_breakout_point.list().filter(point12=>point12.pcb_group_id===fanoutRegionPcbGroupId).map(point12=>({x:point12.x,y:point12.y})),fanoutMode=phaseAutorouterConfig.preset,fanoutBounds=FanoutAutorouter.resolveFanoutBounds(phaseSimpleRouteJson,{mode:fanoutMode,busFanoutDirections:routingPhasePlan.busFanoutDirections,fanoutBounds:routingPhasePlan.fanoutBounds,fanoutBoundaryPadding:routingPhasePlan.fanoutBoundaryPadding,fanoutRoutingLayers:routingPhasePlan.fanoutRoutingLayers,allowBlindAndBuriedVias:phaseSimpleRouteJson.allowBlindAndBuriedVias,breakoutPoints,onFanoutBoundsConflict:()=>emitFanoutBoundsConflictWarning(routingPhasePlan)});if(routingPhasePlan.fanoutBounds=fanoutBounds,!fanoutBounds)continue;let pcbGroup=db22.pcb_group.get(fanoutRegionPcbGroupId),maximumTraceWidth=Math.max(phaseSimpleRouteJson.minTraceWidth,...phaseSimpleRouteJson.connections.map(connection=>connection.nominalTraceWidth??connection.width??phaseSimpleRouteJson.minTraceWidth)),viaPadDiameter=phaseSimpleRouteJson.minViaPadDiameter??phaseSimpleRouteJson.min_via_pad_diameter??phaseSimpleRouteJson.minViaDiameter,traceToPadClearance=phaseSimpleRouteJson.minTraceToPadEdgeClearance??phaseSimpleRouteJson.defaultObstacleMargin??maximumTraceWidth;fanoutPhaseRegions.push({regionId:fanoutRegionPcbGroupId,name:pcbGroup?.name??routingPhasePlan.phaseName??fanoutRegionPcbGroupId,bounds:fanoutBounds,boundaryKeepaway:getFanoutBoundaryPointSpacing({traceWidth:maximumTraceWidth,traceToPadClearance,viaPadDiameter})/2})}let fanoutSeparationConflict=findFanoutPhaseSeparationConflict(fanoutPhaseRegions);if(fanoutSeparationConflict){let{firstRegion,secondRegion,availableGap,requiredGap}=fanoutSeparationConflict,separationDescription=availableGap<0?`overlap by ${Math.abs(availableGap).toFixed(3)}mm`:`are only ${availableGap.toFixed(3)}mm apart`,message=`Fanout regions "${firstRegion.name}" and "${secondRegion.name}" ${separationDescription}, but at least ${requiredGap.toFixed(3)}mm of separation is required for a via-safe routing channel. Move the components farther apart or reduce their facing fanout padding.`;throw db22.pcb_autorouting_error.insert({pcb_error_id:`pcb_autorouter_error_subcircuit_${this.subcircuit_id}`,error_type:"pcb_autorouting_error",message}),this.root?.emit("autorouting:error",{subcircuit_id:this.subcircuit_id,componentDisplayName:this.getString(),error:{message},simpleRouteJson:baseSimpleRouteJson}),new Error(message)}for(let{regionId,bounds}of fanoutPhaseRegions)db22.pcb_group.update(regionId,{center:{x:(bounds.minX+bounds.maxX)/2,y:(bounds.minY+bounds.maxY)/2},width:bounds.maxX-bounds.minX,height:bounds.maxY-bounds.minY});let outputTestPoints=[],routingError,outputTraces=[],outputJumpers=[],pcbTraceIdsToDelete=new Set,existingRerouteSeedTraces=getExistingSimplifiedPcbTracesForReroute(this),traceMatchesRoutingPhase=(trace,routingPhasePlan)=>{let connectionName=trace.connection_name??trace.pcb_trace_id,sourceTraceIds=new Set([connectionName,trace.pcb_trace_id,...getSourceTraceIdsFromRerouteName(connectionName),...getSourceTraceIdsFromRerouteName(trace.pcb_trace_id)]);return baseSimpleRouteJson.connections.some(connection=>connectionIsInRoutingPhase(connection,routingPhasePlan)?sourceTraceIds.has(connection.name)||(connection.source_trace_id?sourceTraceIds.has(connection.source_trace_id):!1)||(connection.rootConnectionName?sourceTraceIds.has(connection.rootConnectionName):!1)||connection.mergedConnectionNames?.some(name=>sourceTraceIds.has(name)):!1)},manualSourceTraceIds=new Set(this.getDescendants().filter(child=>child instanceof Trace&&!child.getSubcircuit()._isInflatedFromCircuitJson&&!!child._parsedProps.pcbPath?.length).map(trace=>trace.source_trace_id)),manualPcbTraceIds=new Set(db22.pcb_trace.list().filter(trace=>trace.source_trace_id&&manualSourceTraceIds.has(trace.source_trace_id)).map(trace=>trace.pcb_trace_id)),fixedTraceIds=new Set(manualPcbTraceIds),previousStageOutputSimpleRouteJson,skippedRemainingPhases=new Set;for(let[routingStageIndex,{routingPhasePlan,autorouterConfig:phaseAutorouterConfig,strategy:localAutorouterStrategy,usesPreviousStageOutput,phaseStageIndex,phaseStageCount}]of routingStages.entries()){if(skippedRemainingPhases.has(routingPhasePlan))continue;if(usesPreviousStageOutput||(previousStageOutputSimpleRouteJson=void 0),usesPreviousStageOutput&&previousStageOutputSimpleRouteJson===void 0)throw new Error("Autorouting follow-up stage is missing the preceding stage output");let simpleRouteJson=previousStageOutputSimpleRouteJson??baseSimpleRouteJson,isTestPointPhase=!!routingPhasePlan.testPointOptions,isTraceSimplificationPhase=!!(routingPhasePlan.reroute&&phaseAutorouterConfig.preset==="simplify"),preservesExistingTraceInput=isTraceSimplificationPhase||isTestPointPhase,isRegionReroutePhase=!!(routingPhasePlan.reroute&&routingPhasePlan.region&&!preservesExistingTraceInput),isConnectionReroutePhase=!!(routingPhasePlan.reroute&&!preservesExistingTraceInput&&!routingPhasePlan.region&&routingPhasePlan.traces.length>0),isReroutePhase=isRegionReroutePhase||isConnectionReroutePhase||preservesExistingTraceInput,rerouteOriginalSrj=isRegionReroutePhase?{...baseSimpleRouteJson,traces:[...existingRerouteSeedTraces,...outputTraces]}:null;if(!usesPreviousStageOutput&&preservesExistingTraceInput)simpleRouteJson={...Group_filterSimpleRouteJsonForPhase(baseSimpleRouteJson,routingPhasePlan),traces:getAccumulatedPcbTracesWithStageOutputReplacements({accumulatedPcbTraces:existingRerouteSeedTraces,stageOutputPcbTraces:outputTraces})};else if(!usesPreviousStageOutput&&isRegionReroutePhase&&rerouteOriginalSrj)simpleRouteJson=Jhe(rerouteOriginalSrj,{shape:"rect",...routingPhasePlan.region});else if(!usesPreviousStageOutput&&isConnectionReroutePhase){let phaseInput=Group_filterSimpleRouteJsonForPhase(baseSimpleRouteJson,routingPhasePlan);simpleRouteJson={...phaseInput,traces:[...phaseInput.traces??[],...outputTraces.filter(trace=>!traceMatchesRoutingPhase(trace,routingPhasePlan))]}}else if(!usesPreviousStageOutput&&hasPhasedAutorouting){let phaseInput=Group_filterSimpleRouteJsonForPhase(baseSimpleRouteJson,routingPhasePlan),activeCustomBreakoutRoutingGroupId=routingPhasePlan.routingPcbGroupId;if(activeCustomBreakoutRoutingGroupId){let activeGroupCopperPourObstacles=getSimpleRouteJsonFromCircuitJson({pcb_panel_id:getOwningPanel(this)?.pcb_panel_id??void 0,db:db22,minTraceWidth,nominalTraceWidth,subcircuit_id:this.subcircuit_id,subcircuitComponent:this,routingPcbGroupId:activeCustomBreakoutRoutingGroupId,fanoutPourNetMap}).simpleRouteJson.obstacles.filter(obstacle=>obstacle.isCopperPour),nonCopperPourObstacles=phaseInput.obstacles.filter(obstacle=>!obstacle.isCopperPour);phaseInput.obstacles=nonCopperPourObstacles.concat(activeGroupCopperPourObstacles)}simpleRouteJson={...phaseInput,traces:getAccumulatedPcbTracesWithStageOutputReplacements({accumulatedPcbTraces:phaseInput.traces??[],stageOutputPcbTraces:outputTraces})}}if(phaseAutorouterConfig.preset!=="bus_lanes"&&!isTestPointPhase){let preservesManualTraceGeometry=!phaseAutorouterConfig.algorithmFn&&(phaseAutorouterConfig.preset==="fanout"||phaseAutorouterConfig.preset==="single_layer_fanout");simpleRouteJson=withFixedTraces(simpleRouteJson,preservesManualTraceGeometry?new Set([...fixedTraceIds].filter(pcbTraceId=>!manualPcbTraceIds.has(pcbTraceId))):fixedTraceIds)}simpleRouteJson=Group_applyDrcTolerancesToSimpleRouteJson(simpleRouteJson,routingPhasePlan.drcTolerances),simpleRouteJson.allowViaInPad=phaseAutorouterConfig.allowViaInPad??simpleRouteJson.allowViaInPad;let getPrecomputedRoutingResult=usesPreviousStageOutput?void 0:routingPhasePlan.getPrecomputedRoutingResult,preflightRoutingCheckPolicy3=this.getInheritedProperty("preflightRoutingCheckPolicy")??"basic";if(routingPhasePlan.isImplicitRemainingPhase&&phaseStageIndex===0&&this.getInheritedProperty("routeRemaining")===void 0&&(preflightRoutingCheckPolicy3==="basic"||preflightRoutingCheckPolicy3==="conservative")&&simpleRouteJson.connections.length>50){skippedRemainingPhases.add(routingPhasePlan),db22.pcb_autorouting_error.insert({pcb_error_id:`pcb_autorouting_error_remaining_routes_${this.subcircuit_id}`,subcircuit_id:this.subcircuit_id??void 0,error_type:"pcb_autorouting_error",message:`Remaining routes left unrouted (over 50 traces remaining and preflightRoutingCheckPolicy="${preflightRoutingCheckPolicy3}"). Set <board routeRemaining={true} /> or create <autoroutingphase /> elements for specific connections in the order you'd like to route them. The autorouter may hang unless you create autorouting phases incrementally.`});continue}let simplificationHasNoTraceInput=!!(isTraceSimplificationPhase&&simpleRouteJson.traces?.length===0);if((hasPhasedAutorouting||isReroutePhase||usesPreviousStageOutput)&&(simpleRouteJson.connections.length===0&&!preservesExistingTraceInput&&!getPrecomputedRoutingResult||simplificationHasNoTraceInput)){phaseStageIndex===0&&emitRoutingPhaseDebugObject(routingPhasePlan,simpleRouteJson.bounds),previousStageOutputSimpleRouteJson=simpleRouteJson;continue}let phaseIsAutoJumperPreset=routingPhasePlan.autorouter!==void 0?this._isAutoJumperAutorouter(phaseAutorouterConfig):isAutoJumperPreset,phaseIsLaserPrefabPreset=routingPhasePlan.autorouter!==void 0?this._isLaserPrefabAutorouter(phaseAutorouterConfig):isLaserPrefabPreset;phaseIsAutoJumperPreset&&(simpleRouteJson.allowJumpers=!0,phaseAutorouterConfig.availableJumperTypes&&(simpleRouteJson.availableJumperTypes=phaseAutorouterConfig.availableJumperTypes));let fanoutMode=phaseAutorouterConfig.preset;if((fanoutMode==="fanout"||fanoutMode==="single_layer_fanout")&&!routingPhasePlan.fanoutRegionPcbGroupId&&!getPrecomputedRoutingResult&&(routingPhasePlan.fanoutBounds=FanoutAutorouter.resolveFanoutBounds(simpleRouteJson,{mode:fanoutMode,busFanoutDirections:routingPhasePlan.busFanoutDirections,fanoutBounds:routingPhasePlan.fanoutBounds,fanoutBoundaryPadding:routingPhasePlan.fanoutBoundaryPadding,fanoutRoutingLayers:routingPhasePlan.fanoutRoutingLayers,allowBlindAndBuriedVias:simpleRouteJson.allowBlindAndBuriedVias})),phaseStageIndex===0&&emitRoutingPhaseDebugObject(routingPhasePlan,routingPhasePlan.fanoutBounds??simpleRouteJson.bounds),debug132.enabled&&global.debugOutputArray?.push({name:`simpleroutejson-${this.props.name}.json`,obj:simpleRouteJson}),debug132.enabled){let graphicsObject=Vo2(simpleRouteJson);graphicsObject.title=`autorouting-${this.props.name}`,global.debugGraphics?.push(graphicsObject)}let autorouterVersion22=phaseAutorouterConfig.autorouterVersion??this.props.autorouterVersion,effortLevel=this.props.autorouterEffortLevel,effort=effortLevel?Number.parseInt(effortLevel.replace("x",""),10):void 0,commonAutorouterOptions={capacityDepth:phaseAutorouterConfig.capacityDepth,targetMinCapacity:phaseAutorouterConfig.targetMinCapacity,platformConfig:this.root?.platform,useAssignableSolver:phaseIsLaserPrefabPreset||isSingleLayerBoard,useAutoJumperSolver:phaseIsAutoJumperPreset,useLaserPrefabSolver:phaseIsLaserPrefabPreset,autorouterVersion:autorouterVersion22,effort},autorouterName=isTestPointPhase?"test_points":getPrecomputedRoutingResult?"precomputed":phaseAutorouterConfig.algorithmFn?"custom":localAutorouterStrategy.name,solverName=isTestPointPhase||getPrecomputedRoutingResult||phaseAutorouterConfig.algorithmFn?void 0:localAutorouterStrategy.getSolverName(commonAutorouterOptions),localAutoroutingCacheSolverOptions={autorouterName,solverName,capacityDepth:commonAutorouterOptions.capacityDepth,targetMinCapacity:commonAutorouterOptions.targetMinCapacity,useAssignableSolver:commonAutorouterOptions.useAssignableSolver,useAutoJumperSolver:commonAutorouterOptions.useAutoJumperSolver,useLaserPrefabSolver:commonAutorouterOptions.useLaserPrefabSolver,useTraceSimplificationSolver:phaseAutorouterConfig.preset==="simplify",autorouterVersion:commonAutorouterOptions.autorouterVersion,effort:commonAutorouterOptions.effort},cacheEngine=isTestPointPhase||getPrecomputedRoutingResult||phaseAutorouterConfig.algorithmFn||!localAutorouterStrategy.cacheable?void 0:this.root?.platform?.localCacheEngine,cacheKey=cacheEngine?getLocalAutoroutingCacheKey(simpleRouteJson,localAutoroutingCacheSolverOptions):void 0,cachedResult=cacheKey?await getCachedLocalAutoroutingPhaseResult({cacheEngine,cacheKey}):null,cacheDisabledReason=getPrecomputedRoutingResult?"precomputed":phaseAutorouterConfig.algorithmFn?"custom_algorithm":localAutorouterStrategy.cacheable?cacheEngine?void 0:"no_cache_engine":"strategy_not_cacheable",autoroutingMetadata={routingPhaseIndex:routingPhasePlan.routingPhaseIndex,_actualRoutingPhaseOrderIndex:routingStageIndex,phaseOrdinal:routingStageIndex+1,phaseCount:routingStages.length,connectionCount:simpleRouteJson.connections.length,obstacleCount:simpleRouteJson.obstacles.length,previousTraceCount:simpleRouteJson.traces?.length??0,isReroutePhase,autorouterName,autorouterVersion:autorouterVersion22,solverName,effort,cacheStatus:cacheEngine?cachedResult?"hit":"miss":"disabled",cacheKey,cacheDisabledReason};this.root?.emit("autorouting:start",{type:"autorouting:start",subcircuit_id:this.subcircuit_id,componentDisplayName:this.getString(),...routingPhasePlan.phaseName!==void 0?{phaseName:routingPhasePlan.phaseName,phaseStageIndex,phaseStageCount}:{},...autoroutingMetadata,simpleRouteJson});let autorouter;try{let runAutorouter=async activeAutorouter=>{let routingPromise=new Promise((resolve10,reject)=>{activeAutorouter.on("complete",event=>{debug132(`[${this.getString()}] local autorouting complete`),resolve10(event.traces)}),activeAutorouter.on("error",event=>{debug132(`[${this.getString()}] local autorouting error: ${event.error.message}`),routingError=event.error,reject(event.error)})});return activeAutorouter.on("progress",event=>{this.root?.emit("autorouting:progress",{subcircuit_id:this.subcircuit_id,componentDisplayName:this.getString(),...routingPhasePlan.phaseName!==void 0?{phaseName:routingPhasePlan.phaseName,phaseStageIndex,phaseStageCount}:{},...autoroutingMetadata,...event,type:"autorouting:progress"})}),activeAutorouter.start(),await routingPromise},traces,precomputedOutputSimpleRouteJson;if(isTestPointPhase){let settings=routingPhasePlan.testPointOptions,selectedTraces=(simpleRouteJson.traces??[]).filter(trace=>traceMatchesRoutingPhase(trace,routingPhasePlan));if(selectedTraces.some(trace=>fixedTraceIds.has(trace.pcb_trace_id)))throw new Error("Test point phases cannot modify fixed PCB paths");if(selectedTraces.length===0)throw new Error("Test point phase has no selected routed traces");let probeInput={...simpleRouteJson,obstacles:[...simpleRouteJson.obstacles,...db22.pcb_component.list().filter(component=>!component.do_not_place).map(component=>({type:"rect",center:component.center,width:component.width,height:component.height,layers:[component.layer],ccwRotationDegrees:component.rotation,connectedTo:[]}))]},testPointAutorouter=new TestPointAutorouter(probeInput,{...settings,requests:selectedTraces.map((trace,index2)=>({name:`TP_AUTO_${routingStageIndex+1}_${index2+1}`,pcbTraceId:trace.pcb_trace_id,layer:settings.layer,diameter:settings.diameter}))});autorouter=testPointAutorouter,traces=await runAutorouter(testPointAutorouter);let result=testPointAutorouter.getOutputSimpleRouteJson();for(let point12 of testPointAutorouter.getTestPoints()){let trace=selectedTraces.find(trace2=>trace2.pcb_trace_id===point12.pcbTraceId),routedSourceId=getSourceTraceIdForRoutedTrace({db:db22,trace:{...trace,source_trace_id:trace.connection_name},subcircuit_id:this.subcircuit_id}),sourceTraceId=routedSourceId?db22.source_trace.get(routedSourceId)?.source_trace_id??db22.source_trace.list().find(sourceTrace=>sourceTrace.connected_source_net_ids.includes(routedSourceId))?.source_trace_id:void 0;if(!sourceTraceId)throw new Error(`Test point ${point12.name} has no source connection`);outputTestPoints.push({...point12,sourceTraceId})}traces=result.traces,precomputedOutputSimpleRouteJson=result,baseSimpleRouteJson={...baseSimpleRouteJson,obstacles:[...baseSimpleRouteJson.obstacles,...result.obstacles.slice(probeInput.obstacles.length)]};for(let trace of selectedTraces)fixedTraceIds.add(trace.pcb_trace_id)}else if(getPrecomputedRoutingResult){let result=getPrecomputedRoutingResult(simpleRouteJson);traces=result.traces,precomputedOutputSimpleRouteJson=result.outputSimpleRouteJson;for(let trace of traces)fixedTraceIds.add(trace.pcb_trace_id)}else if(cachedResult)debug132(`[${this.getString()}] using cached local autorouting result`),traces=cachedResult.traces;else{if(phaseAutorouterConfig.algorithmFn?autorouter=await phaseAutorouterConfig.algorithmFn(simpleRouteJson):autorouter=localAutorouterStrategy.create({simpleRouteJson,onSolverEnded:event=>this.root?.emit("solver:ended",{...event,type:"solver:ended",componentName:this.getString()}),commonAutorouterOptions,busFanoutDirections:routingPhasePlan.busFanoutDirections,fanoutBounds:routingPhasePlan.fanoutBounds,fanoutRoutingLayers:routingPhasePlan.fanoutRoutingLayers,allowBlindAndBuriedVias:simpleRouteJson.allowBlindAndBuriedVias,componentNamesById:getPcbComponentNamesById(db22),onSolverStarted:({solverName:solverName2,solverParams,solverConstructorArgs})=>this.root?.emit("solver:started",{type:"solver:started",solverName:solverName2,solverParams,solverConstructorArgs,componentName:this.getString()})}),!autorouter)throw new Error("Failed to create local autorouter");traces=await runAutorouter(autorouter)}let transformedSimpleRouteJson=precomputedOutputSimpleRouteJson??autorouter?.getOutputSimpleRouteJson?.();if(localAutorouterStrategy.preserveOutputTraces&&transformedSimpleRouteJson?.traces&&(transformedSimpleRouteJson={...transformedSimpleRouteJson,traces:getAccumulatedPcbTracesWithStageOutputReplacements({accumulatedPcbTraces:simpleRouteJson.traces??[],stageOutputPcbTraces:transformedSimpleRouteJson.traces})}),transformedSimpleRouteJson&&!usesPreviousStageOutput&&["fanout","single_layer_fanout","dogbone"].includes(phaseAutorouterConfig.preset??"")&&routingPhasePlan.routingPcbGroupId){let synchronizedFanout=Group_syncFanoutExitsWithGlobalConnections({fanoutInputSimpleRouteJson:simpleRouteJson,fanoutOutputSimpleRouteJson:transformedSimpleRouteJson,baseSimpleRouteJson,routingPhasePlan});baseSimpleRouteJson=synchronizedFanout.baseSimpleRouteJson,transformedSimpleRouteJson=synchronizedFanout.downstreamSimpleRouteJson;for(let synchronizedPoint of synchronizedFanout.synchronizedBreakoutPoints){let breakoutPoint=db22.pcb_breakout_point.list().find(point12=>point12.pcb_group_id===synchronizedPoint.routingPcbGroupId&&point12.source_trace_id===synchronizedPoint.sourceTraceId&&Math.abs(point12.x-synchronizedPoint.previousPoint.x)<=1e-6&&Math.abs(point12.y-synchronizedPoint.previousPoint.y)<=1e-6);breakoutPoint&&db22.pcb_breakout_point.update(breakoutPoint.pcb_breakout_point_id,{x:synchronizedPoint.fanoutExitPoint.x,y:synchronizedPoint.fanoutExitPoint.y,layer:synchronizedPoint.fanoutExitPoint.layer})}}if(localAutorouterStrategy.preserveOutputTraces)for(let trace of traces)fixedTraceIds.add(trace.pcb_trace_id);let stageOutputTraces=traces;transformedSimpleRouteJson?.traces?stageOutputTraces=transformedSimpleRouteJson.traces:usesPreviousStageOutput&&(stageOutputTraces=getAccumulatedPcbTracesWithStageOutputReplacements({accumulatedPcbTraces:simpleRouteJson.traces??[],stageOutputPcbTraces:traces}));let eventOutputPcbTraces=stageOutputTraces;!transformedSimpleRouteJson&&!usesPreviousStageOutput&&routingPhasePlan.routingPhaseIndex!==null&&(eventOutputPcbTraces=getAccumulatedPcbTracesWithStageOutputReplacements({accumulatedPcbTraces:simpleRouteJson.traces??[],stageOutputPcbTraces:traces}));let outputSimpleRouteJson={...transformedSimpleRouteJson??simpleRouteJson,traces:eventOutputPcbTraces};previousStageOutputSimpleRouteJson=transformedSimpleRouteJson?outputSimpleRouteJson:void 0;let computeCostSummary=cachedResult?cachedResult.computeCostSummary:autorouter?.getComputeCostSummary?.();!cachedResult&&cacheKey&&await cacheLocalAutoroutingPhaseResult({cacheEngine,cacheKey,result:{...simpleRouteJson,traces,...computeCostSummary!==void 0?{computeCostSummary}:{}}});let savedPhasePaths=getAutoroutingPhasePcbTracePaths({group:this.selectAll("group").find(group2=>group2.pcb_group_id===routingPhasePlan.fanoutRegionPcbGroupId)??routingPhasePlan.autoroutingPhase?.getGroup()??this,subcircuit:this,input:simpleRouteJson,traces,isFanout:["fanout","single_layer_fanout","dogbone"].includes(phaseAutorouterConfig.preset??"")});if(this.root?.emit("autorouting:end",{...savedPhasePaths,...computeCostSummary!==void 0?{computeCostSummary}:{},type:"autorouting:end",subcircuit_id:this.subcircuit_id,componentDisplayName:this.getString(),...routingPhasePlan.phaseName!==void 0?{phaseName:routingPhasePlan.phaseName,phaseStageIndex,phaseStageCount}:{},...autoroutingMetadata,simpleRouteJson:outputSimpleRouteJson}),autorouter?.getConnectedOffboardObstacles){let connectedOffboardObstacles=autorouter.getConnectedOffboardObstacles();createSourceTracesFromOffboardConnections({db:db22,connectedOffboardObstacles,simpleRouteJson,subcircuit_id:this.subcircuit_id})}let solver=autorouter?.solver;if(solver?.getOutputJumpers&&outputJumpers.push(...solver.getOutputJumpers()||[]),isRegionReroutePhase&&rerouteOriginalSrj){for(let trace of rerouteOriginalSrj.traces??[])trace.type==="pcb_trace"&&pcbTraceIdsToDelete.add(trace.pcb_trace_id);let reconnectedSrj=Qhe(rerouteOriginalSrj,{...simpleRouteJson,traces:[...simpleRouteJson.traces??[],...traces]});outputTraces.splice(0,outputTraces.length,...reconnectedSrj.traces??[])}else if(isConnectionReroutePhase){let retainedPcbTraces=outputTraces.filter(trace=>!traceMatchesRoutingPhase(trace,routingPhasePlan));outputTraces.splice(0,outputTraces.length,...getAccumulatedPcbTracesWithStageOutputReplacements({accumulatedPcbTraces:retainedPcbTraces,stageOutputPcbTraces:stageOutputTraces}))}else{if(preservesExistingTraceInput)for(let existingTrace of existingRerouteSeedTraces)!isTestPointPhase&&fixedTraceIds.has(existingTrace.pcb_trace_id)||pcbTraceIdsToDelete.add(existingTrace.pcb_trace_id);outputTraces.splice(0,outputTraces.length,...getAccumulatedPcbTracesWithStageOutputReplacements({accumulatedPcbTraces:outputTraces,stageOutputPcbTraces:stageOutputTraces}))}}catch(error2){let{db:db3}=this.root;db3.pcb_autorouting_error.insert({pcb_error_id:`pcb_autorouter_error_subcircuit_${this.subcircuit_id}`,error_type:"pcb_autorouting_error",message:error2 instanceof Error?error2.message:String(error2)});let computeCostSummary=autorouter?.getComputeCostSummary?.();if(this.root?.emit("autorouting:error",{...computeCostSummary!==void 0?{computeCostSummary}:{},type:"autorouting:error",subcircuit_id:this.subcircuit_id,componentDisplayName:this.getString(),...routingPhasePlan.phaseName!==void 0?{phaseName:routingPhasePlan.phaseName,phaseStageIndex,phaseStageCount}:{},...autoroutingMetadata,error:{message:error2 instanceof Error?error2.message:String(error2)},simpleRouteJson}),outputTraces.length===0||!routingError)throw error2;break}finally{autorouter?.stop()}}if(this._asyncAutoroutingResult={output_pcb_traces:outputTraces,output_jumpers:outputJumpers,output_test_points:outputTestPoints,pcb_trace_ids_to_be_replaced:[...pcbTraceIdsToDelete]},this._markDirty("PcbTraceRender"),routingError)throw routingError}_startAsyncAutorouting(){this._hasStartedAsyncAutorouting||(this._hasStartedAsyncAutorouting=!0,this._getAutorouterConfig().local?this._queueAsyncEffect("autorouting",async()=>{try{await this._runLocalAutorouting()}catch(error2){if(!(error2 instanceof RoutingPhasePreparationError))throw error2;let{db:db22}=this.root,pcbErrorId=`pcb_autorouter_error_subcircuit_${this.subcircuit_id}`;throw db22.pcb_autorouting_error.list().some(recordedError=>recordedError.pcb_error_id===pcbErrorId&&recordedError.message===error2.message)||(db22.pcb_autorouting_error.insert({pcb_error_id:pcbErrorId,error_type:"pcb_autorouting_error",message:error2.message,subcircuit_id:this.subcircuit_id??void 0}),this.root?.emit("autorouting:error",{type:"autorouting:error",subcircuit_id:this.subcircuit_id,componentDisplayName:this.getString(),error:{message:error2.message}})),error2}}):this._queueAsyncEffect("make-http-autorouting-request",async()=>this._runEffectMakeHttpAutoroutingRequest()))}doInitialPcbTraceRender(){let debug132=(0,import_debug11.default)("tscircuit:core:doInitialPcbTraceRender");if(!this.isSubcircuit||this.root?.pcbDisabled||this.root?.pcbRoutingDisabled||this.getInheritedProperty("routingDisabled")||this._isInflatedFromCircuitJson||this._isLegacyAutorouterDisabled()||this._shouldUseTraceByTraceRouting())return;if(!this._areChildSubcircuitsRouted()){debug132(`[${this.getString()}] child subcircuits are not routed, skipping async autorouting until subcircuits routed`);return}if(debug132(`[${this.getString()}] no child subcircuits to wait for, initiating async routing`),!this._hasTracesToRoute())return;let shouldSkipBecauseOfPlacementErrors=shouldSkipAutoroutingBecauseOfPlacementErrors({component:this,subcircuit:this}),shouldSkipBecauseOfTraceLengthViolations=shouldSkipAutoroutingBecauseOfTraceLengthViolations({component:this,subcircuit:this});shouldSkipBecauseOfPlacementErrors||shouldSkipBecauseOfTraceLengthViolations||this._startAsyncAutorouting()}doInitialSchematicTraceRender(){this._parsedProps.showAsSchematicBox||Group_doInitialSchematicTraceRender(this)}doInitialSchematicSheetRender(){Group_doInitialSchematicSheetRender(this)}updateSchematicSheetRender(){Group_updateSchematicSheetRender(this)}updatePcbTraceRender(){let debug132=(0,import_debug11.default)("tscircuit:core:updatePcbTraceRender");if(debug132(`[${this.getString()}] updating...`),!this.isSubcircuit||this.root?.pcbDisabled||this.root?.pcbRoutingDisabled||this.getInheritedProperty("routingDisabled")||this._isInflatedFromCircuitJson||this._isLegacyAutorouterDisabled())return;if(this._shouldRouteAsync()&&this._hasTracesToRoute()&&!this._hasStartedAsyncAutorouting){if(this._areChildSubcircuitsRouted()){let shouldSkipBecauseOfPlacementErrors=shouldSkipAutoroutingBecauseOfPlacementErrors({component:this,subcircuit:this}),shouldSkipBecauseOfTraceLengthViolations=shouldSkipAutoroutingBecauseOfTraceLengthViolations({component:this,subcircuit:this});if(shouldSkipBecauseOfPlacementErrors||shouldSkipBecauseOfTraceLengthViolations)return;debug132(`[${this.getString()}] child subcircuits are now routed, starting async autorouting`),this._startAsyncAutorouting()}return}if(!this._asyncAutoroutingResult||this._shouldUseTraceByTraceRouting())return;let{db:db22}=this.root;if(this._asyncAutoroutingResult.output_simple_route_json){debug132(`[${this.getString()}] updating PCB traces from simple route json (${this._asyncAutoroutingResult.output_simple_route_json.traces?.length} traces)`),this._updatePcbTraceRenderFromSimpleRouteJson();return}if(this._asyncAutoroutingResult.output_pcb_traces){debug132(`[${this.getString()}] updating PCB traces from ${this._asyncAutoroutingResult.output_pcb_traces.length} traces`),this._updatePcbTraceRenderFromPcbTraces();return}}_updatePcbTraceRenderFromSimpleRouteJson(){let{db:db22}=this.root,{traces:routedTraces}=this._asyncAutoroutingResult.output_simple_route_json;if(routedTraces)for(let routedTrace of routedTraces){let cjRoute=routedTrace.route.map(point12=>point12.route_type!=="through_obstacle"?point12:{route_type:"through_pad",start:point12.start,end:point12.end,start_layer:point12.from_layer,end_layer:point12.to_layer,width:point12.width,circuitJsonMetadata:point12.circuitJsonMetadata}),pcb_trace23=db22.pcb_trace.insert({subcircuit_id:this.subcircuit_id,route:getCircuitJsonPcbTraceRoute(cjRoute)});claimSrjAssignablePcbViasTraversedByRoute({db:db22,pcbTrace:pcb_trace23,routeWithSrjMetadata:cjRoute})}}_updatePcbTraceRenderFromPcbTraces(){let{output_pcb_traces,output_jumpers,pcb_trace_ids_to_be_replaced}=this._asyncAutoroutingResult;if(!output_pcb_traces)return;let{db:db22}=this.root,testPoints=this._asyncAutoroutingResult.output_test_points;testPoints?.length&&(materializeRoutedTestPoints(db22,testPoints,this.subcircuit_id),this._asyncAutoroutingResult.output_test_points=[]);let pcbStyle3=this.getInheritedMergedProperty("pcbStyle"),{holeDiameter,padDiameter}=getViaDiameterDefaults(pcbStyle3),boardComponent=this._getBoard(),board=boardComponent?.pcb_board_id?db22.pcb_board.get(boardComponent.pcb_board_id):db22.pcb_board.list()[0],routedViaHoleDiameter=board?.min_via_hole_diameter??holeDiameter,routedViaPadDiameter=board?.min_via_pad_diameter??padDiameter;output_jumpers&&output_jumpers.length>0&&insertAutoplacedJumpers({db:db22,output_jumpers,subcircuit_id:this.subcircuit_id}),deleteExistingPcbTracesReplacedBy({group:this,outputPcbTraces:output_pcb_traces,pcbTraceIdsToReplace:pcb_trace_ids_to_be_replaced});let materializedPcbVias=db22.pcb_via.list(),jumperPadInfos=getJumperPadInfos(db22);for(let pcb_trace23 of output_pcb_traces){if(pcb_trace23.type!=="pcb_trace")continue;pcb_trace23.subcircuit_id??(pcb_trace23.subcircuit_id=this.subcircuit_id);let cjRoute=pcb_trace23.route.map(point12=>point12.route_type!=="through_obstacle"?point12:{route_type:"through_pad",start:point12.start,end:point12.end,start_layer:point12.from_layer,end_layer:point12.to_layer,width:point12.width,circuitJsonMetadata:point12.circuitJsonMetadata}),routeSourceTraceId=getSourceTraceIdForRoutedTrace({db:db22,trace:{...pcb_trace23,route:cjRoute},subcircuit_id:this.subcircuit_id});cjRoute=ensureRouteStartsAtSourceTraceStart({db:db22,route:cjRoute,routeThicknessMode:pcb_trace23.route_thickness_mode,sourceTraceId:routeSourceTraceId}),pcb_trace23.route=cjRoute;let segments2=splitPcbTracesOnJumperSegments(cjRoute);segments2===null&&(segments2=[cjRoute]);let processedSegments=addPortIdsToTracesAtJumperPads(segments2,jumperPadInfos);for(let segment5 of processedSegments)if(segment5.length>0){let circuitJsonSegment=getCircuitJsonPcbTraceRoute(segment5),sourceTraceId=getSourceTraceIdForRoutedTrace({db:db22,trace:{...pcb_trace23,route:circuitJsonSegment},subcircuit_id:this.subcircuit_id}),insertedPcbTrace=db22.pcb_trace.insert({...pcb_trace23,pcb_panel_id:getOwningPanel(this)?.pcb_panel_id??void 0,source_trace_id:sourceTraceId,route:circuitJsonSegment});claimSrjAssignablePcbViasTraversedByRoute({db:db22,pcbTrace:insertedPcbTrace,routeWithSrjMetadata:segment5})}}for(let pcb_trace23 of output_pcb_traces)if(pcb_trace23.type!=="pcb_via"&&pcb_trace23.type==="pcb_trace"){let sourceTraceId=getSourceTraceIdForRoutedTrace({db:db22,trace:pcb_trace23,subcircuit_id:this.subcircuit_id}),{connection_name:inputConnectionName}=pcb_trace23,subcircuitConnectivityMapKey;if(sourceTraceId&&(subcircuitConnectivityMapKey=db22.source_trace.get(sourceTraceId)?.subcircuit_connectivity_map_key),!subcircuitConnectivityMapKey&&inputConnectionName){let sourceNet=db22.source_net.get(inputConnectionName);sourceNet&&(subcircuitConnectivityMapKey=sourceNet.subcircuit_connectivity_map_key)}for(let point12 of pcb_trace23.route)if(point12.route_type==="via"){let routedViaPoint=point12,fromLayer=point12.from_layer,toLayer=point12.to_layer,pcbVia={pcb_trace_id:pcb_trace23.pcb_trace_id,x:point12.x,y:point12.y,hole_diameter:routedViaPoint.via_hole_diameter??routedViaPoint.hole_diameter??routedViaHoleDiameter,outer_diameter:routedViaPoint.via_diameter??routedViaPoint.outer_diameter??routedViaPadDiameter,layers:getAutoroutedViaLayers({fromLayer,toLayer,layerCount:this._getSubcircuitLayerCount(),allowBlindAndBuriedVias:board?.allow_blind_and_buried_vias??!1,physicalLayers:routedViaPoint.layers}),from_layer:fromLayer,to_layer:toLayer,subcircuit_id:this.subcircuit_id,pcb_group_id:this.pcb_group_id??void 0,pcb_panel_id:getOwningPanel(this)?.pcb_panel_id??void 0,subcircuit_connectivity_map_key:subcircuitConnectivityMapKey};if(materializedPcbVias.some(materializedPcbVia=>pcbViasSharePhysicalHole(materializedPcbVia,pcbVia)))continue;materializedPcbVias.push(db22.pcb_via.insert(pcbVia))}}}doInitialSchematicComponentRender(){if(this.root?.schematicDisabled)return;let{db:db22}=this.root,{_parsedProps:props}=this,schematic_group23=db22.schematic_group.insert({is_subcircuit:this.isSubcircuit,subcircuit_id:this.getSubcircuit().subcircuit_id??void 0,name:this.name,center:this._getGlobalSchematicPositionBeforeLayout(),width:0,height:0,schematic_component_ids:[],source_group_id:this.source_group_id,show_as_schematic_box:props.showAsSchematicBox??!1});this.schematic_group_id=schematic_group23.schematic_group_id,props.showAsSchematicBox&&Group_doInitialSchematicBoxComponentRender(this);for(let child of this.getDescendants())child.getGroup()?.source_group_id===this.source_group_id&&(child._parsedProps?.showAsSchematicBox||child.schematic_component_id&&db22.schematic_component.update(child.schematic_component_id,{schematic_group_id:schematic_group23.schematic_group_id}))}_getSchematicLayoutMode(){let props=this._parsedProps,schAutoLayoutEnabled=props.schAutoLayoutEnabled??!1;if(props.schLayout?.layoutMode==="none"||props.schLayout?.layoutMode==="relative")return"relative";if(props.schLayout?.matchAdapt)return"match-adapt";if(props.schLayout?.flex)return"flex";if(props.schLayout?.grid)return"grid";if(props.schMatchAdapt)return"match-adapt";if(props.schFlex)return"flex";if(props.schGrid)return"grid";if(props.matchAdapt)return"match-adapt";if(props.flex)return"flex";if(props.grid)return"grid";if(props.relative||props.schRelative)return"relative";let anyLayoutChildHasSchCoords=this.children.some(child=>{let cProps=child._parsedProps;return(child.source_component_id!==null||child.source_group_id!==null)&&(cProps?.schX!==void 0||cProps?.schY!==void 0)}),hasManualEdits=(props.manualEdits?.schematic_placements?.length??0)>0;return schAutoLayoutEnabled&&!hasManualEdits||!anyLayoutChildHasSchCoords&&!hasManualEdits?"match-adapt":"relative"}doInitialSchematicLayout(){if(this._parsedProps.showAsSchematicBox){this._insertSchematicBorder();return}if(this.children.some(c23=>c23.source_component_id!==null&&c23._parsedProps?.schSectionName!==void 0)){this._doInitialSchematicLayoutSections(),this._insertSchematicBorder();return}let schematicLayoutMode=this._getSchematicLayoutMode();schematicLayoutMode==="match-adapt"&&this._doInitialSchematicLayoutMatchpack(),schematicLayoutMode==="grid"&&this._doInitialSchematicLayoutGrid(),schematicLayoutMode==="flex"&&this._doInitialSchematicLayoutFlex(),this._insertSchematicBorder()}_doInitialSchematicLayoutSections(){Group_doInitialSchematicLayoutSections(this)}_doInitialSchematicLayoutMatchAdapt(){Group_doInitialSchematicLayoutMatchAdapt(this)}_doInitialSchematicLayoutMatchpack(){Group_doInitialSchematicLayoutMatchPack(this)}_doInitialSchematicLayoutGrid(){Group_doInitialSchematicLayoutGrid(this)}_doInitialSchematicLayoutFlex(){Group_doInitialSchematicLayoutFlex(this)}_getPcbLayoutMode(){let props=this._parsedProps,rawProps=this.props;if(this._isInflatedFromCircuitJson||props.pcbRelative)return"none";if(props.pcbLayout?.matchAdapt)return"match-adapt";if(props.pcbLayout?.flex)return"flex";if(props.pcbLayout?.grid)return"grid";if(props.pcbLayout?.pack)return"pack";if(props.pcbFlex)return"flex";if(props.pcbGrid)return"grid";if(props.pcbPack||props.pack)return"pack";if(props.matchAdapt)return"match-adapt";if(props.flex)return"flex";if(props.grid)return"grid";let groupHasCoords=props.pcbX!==void 0||props.pcbY!==void 0||props.pcbLeftEdgeX!==void 0||props.pcbRightEdgeX!==void 0||props.pcbTopEdgeY!==void 0||props.pcbBottomEdgeY!==void 0||rawProps.pcbLeftEdgeX!==void 0||rawProps.pcbRightEdgeX!==void 0||rawProps.pcbTopEdgeY!==void 0||rawProps.pcbBottomEdgeY!==void 0,hasManualEdits=(props.manualEdits?.pcb_placements?.length??0)>0,unpositionedDirectChildrenCount=this.children.reduce((count,child)=>{if(!child.pcb_component_id&&!child.pcb_group_id)return count;let childProps=child._parsedProps,rawChildProps=child.props,hasCoords=childProps?.pcbX!==void 0||childProps?.pcbY!==void 0||childProps?.pcbLeftEdgeX!==void 0||childProps?.pcbRightEdgeX!==void 0||childProps?.pcbTopEdgeY!==void 0||childProps?.pcbBottomEdgeY!==void 0||rawChildProps?.pcbLeftEdgeX!==void 0||rawChildProps?.pcbRightEdgeX!==void 0||rawChildProps?.pcbTopEdgeY!==void 0||rawChildProps?.pcbBottomEdgeY!==void 0;return count+(hasCoords?0:1)},0);return!hasManualEdits&&unpositionedDirectChildrenCount>1?"pack":"none"}doInitialPcbLayout(){if(this.root?.pcbDisabled)return;if(this.pcb_group_id){let{db:db22}=this.root,props=this._parsedProps;if(props.pcbX!==void 0||props.pcbY!==void 0){let parentGroup=this.parent?.getGroup?.(),pcbParentGroupId=parentGroup?.pcb_group_id?db22.pcb_group.get(parentGroup.pcb_group_id)?.pcb_group_id:void 0,positionedRelativeToBoardId=pcbParentGroupId?void 0:this._getBoard()?.pcb_board_id??void 0;db22.pcb_group.update(this.pcb_group_id,{position_mode:"relative_to_group_anchor",positioned_relative_to_pcb_group_id:pcbParentGroupId,positioned_relative_to_pcb_board_id:positionedRelativeToBoardId,display_offset_x:formatPcbDisplayOffset(props.pcbX),display_offset_y:formatPcbDisplayOffset(props.pcbY)})}}let pcbLayoutMode=this._getPcbLayoutMode();pcbLayoutMode==="grid"?this._doInitialPcbLayoutGrid():pcbLayoutMode==="pack"?this._doInitialPcbLayoutPack():pcbLayoutMode==="flex"&&this._doInitialPcbLayoutFlex()}_doInitialPcbLayoutGrid(){Group_doInitialPcbLayoutGrid(this)}_doInitialPcbLayoutPack(){Group_doInitialPcbLayoutPack(this)}_doInitialPcbLayoutFlex(){Group_doInitialPcbLayoutFlex(this)}_insertSchematicBorder(){if(this.root?.schematicDisabled)return;let{db:db22}=this.root,props=this._parsedProps;if(!props.border)return;let width10=typeof props.schWidth=="number"?props.schWidth:void 0,height10=typeof props.schHeight=="number"?props.schHeight:void 0,paddingGeneral=typeof props.schPadding=="number"?props.schPadding:0,paddingLeft=typeof props.schPaddingLeft=="number"?props.schPaddingLeft:paddingGeneral,paddingRight=typeof props.schPaddingRight=="number"?props.schPaddingRight:paddingGeneral,paddingTop=typeof props.schPaddingTop=="number"?props.schPaddingTop:paddingGeneral,paddingBottom=typeof props.schPaddingBottom=="number"?props.schPaddingBottom:paddingGeneral,schematicGroup=this.schematic_group_id?db22.schematic_group.get(this.schematic_group_id):null;if(schematicGroup&&(width10===void 0&&typeof schematicGroup.width=="number"&&(width10=schematicGroup.width),height10===void 0&&typeof schematicGroup.height=="number"&&(height10=schematicGroup.height)),width10===void 0||height10===void 0)return;let center2=schematicGroup?.center??this._getGlobalSchematicPositionBeforeLayout(),left=center2.x-width10/2-paddingLeft,bottom=center2.y-height10/2-paddingBottom,finalWidth=width10+paddingLeft+paddingRight,finalHeight=height10+paddingTop+paddingBottom;db22.schematic_box.insert({width:finalWidth,height:finalHeight,x:left,y:bottom,is_dashed:props.border?.dashed??!1})}_determineSideFromPosition(port,component){if(!port.center||!component.center)return"left";let dx22=port.center.x-component.center.x,dy22=port.center.y-component.center.y;return Math.abs(dx22)>Math.abs(dy22)?dx22>0?"right":"left":dy22>0?"bottom":"top"}_calculateSchematicBounds(boxes){if(boxes.length===0)return{minX:0,maxX:0,minY:0,maxY:0};let minX=1/0,maxX=-1/0,minY=1/0,maxY=-1/0;for(let box32 of boxes)minX=Math.min(minX,box32.centerX),maxX=Math.max(maxX,box32.centerX),minY=Math.min(minY,box32.centerY),maxY=Math.max(maxY,box32.centerY);let padding=2;return{minX:minX-padding,maxX:maxX+padding,minY:minY-padding,maxY:maxY+padding}}_getAutorouterConfig(){let autorouter=this._parsedProps.autorouter||this.getInheritedProperty("autorouter");return getPresetAutoroutingConfig(autorouter,this.root?.platform)}_isLegacyAutorouterDisabled(){return getDisabledLegacyAutorouterPreset(this)!==null}_isLaserPrefabAutorouter(autorouterConfig3=this._getAutorouterConfig()){let autorouterProp3=this.props.autorouter,normalize13=value=>value?.replace(/-/g,"_")??value;return autorouterConfig3.preset==="laser_prefab"?!0:typeof autorouterProp3=="string"?normalize13(autorouterProp3)==="laser_prefab":typeof autorouterProp3=="object"&&autorouterProp3?normalize13(autorouterProp3.preset)==="laser_prefab":!1}_isAutoJumperAutorouter(autorouterConfig3=this._getAutorouterConfig()){let autorouterProp3=this.props.autorouter,normalize13=value=>value?.replace(/-/g,"_")??value;return autorouterConfig3.preset==="auto_jumper"?!0:typeof autorouterProp3=="string"?normalize13(autorouterProp3)==="auto_jumper":typeof autorouterProp3=="object"&&autorouterProp3?normalize13(autorouterProp3.preset)==="auto_jumper":!1}_getSubcircuitLayerCount(){let layers=this.getInheritedProperty("layers");return typeof layers=="number"?layers:2}_shouldUseTraceByTraceRouting(){return getDisabledLegacyGroupAutorouterPreset(this)?!1:this._getAutorouterConfig().groupMode==="sequential-trace"}doInitialPcbDesignRuleChecks(){if(this.root?.pcbDisabled||this._isLegacyAutorouterDisabled()||this.root?.pcbRoutingDisabled||this.getInheritedProperty("routingDisabled"))return;let{db:db22}=this.root;if(this.isSubcircuit){let immediateChildrenByName=new Map;for(let child of this.children)if(!child.isSubcircuit&&child._parsedProps.name){let components=immediateChildrenByName.get(child._parsedProps.name)||[];components.push(child),immediateChildrenByName.set(child._parsedProps.name,components)}for(let[name,components]of immediateChildrenByName.entries()){if(components.length<=1)continue;let sameNamedTraces=components.filter(child=>child instanceof Trace),duplicateNameIsOnlyTraces=sameNamedTraces.length===components.length,mutuallyConnectedTraceKeys=sameNamedTraces.map(trace=>trace.subcircuit_connectivity_map_key),sameNamedTracesAreMutuallyConnected=duplicateNameIsOnlyTraces&&mutuallyConnectedTraceKeys.every(Boolean)&&new Set(mutuallyConnectedTraceKeys).size===1;if(!duplicateNameIsOnlyTraces||!sameNamedTracesAreMutuallyConnected){let displaySubcircuitName=this.name||"unnamed",message=duplicateNameIsOnlyTraces?`Trace "${name}" in subcircuit "${displaySubcircuitName}" shares a name with another trace, but the traces are not mutually connected. Same-named traces must have the same subcircuit connectivity map key.`:`Multiple immediate children found with name "${name}" in subcircuit "${displaySubcircuitName}". Names must be unique.`;db22.pcb_trace_error.insert({error_type:"pcb_trace_error",message,source_trace_id:"",pcb_trace_id:"",pcb_component_ids:components.map(c23=>c23.pcb_component_id).filter(Boolean),pcb_port_ids:[]})}}}Group_doInitialStandaloneSubcircuitPcbDesignRuleChecks(this)}doInitialSchematicLabelNetsWithConflictingNames(){this.root?.schematicDisabled||this.getTopLevelRenderable()===this&&assignSchematicNetLabelSuperscripts(this.root.db)}updateSchematicLabelNetsWithConflictingNames(){this.doInitialSchematicLabelNetsWithConflictingNames()}doInitialSchematicReplaceNetLabelsWithSymbols(){if(this.root?.schematicDisabled||!this.isSubcircuit)return;let{db:db22}=this.root,subtree=db22;for(let nl3 of subtree.schematic_net_label.list()){let net=subtree.source_net.get(nl3.source_net_id),text4=nl3.text||net?.name||"",isGroundNet=net?.is_ground||GROUND_NET_REGEX.test(text4),isPowerNet=net?.is_power||POWER_NET_REGEX.test(text4);if(nl3.anchor_side==="top"&&isGroundNet){subtree.schematic_net_label.update(nl3.schematic_net_label_id,{symbol_name:"rail_down"});continue}nl3.anchor_side==="bottom"&&isPowerNet&&subtree.schematic_net_label.update(nl3.schematic_net_label_id,{symbol_name:"rail_up"})}}doInitialSimulationSpiceEngineRender(){Group_doInitialSimulationSpiceEngineRender(this)}doInitialPcbComponentAnchorAlignment(){Group_doInitialPcbComponentAnchorAlignment(this)}updatePcbComponentAnchorAlignment(){this.doInitialPcbComponentAnchorAlignment()}doInitialPcbCalcPlacementResolution(){Group_doInitialPcbCalcPlacementResolution(this)}updatePcbCalcPlacementResolution(){this.doInitialPcbCalcPlacementResolution()}_getMinimumFlexContainerSize(){return super._getMinimumFlexContainerSize()}_repositionOnPcb(position22){return super._repositionOnPcb(position22)}};function inflateSourceGroup(sourceGroup,inflatorContext){let{injectionDb,subcircuit,groupsMap}=inflatorContext,pcbGroup=injectionDb.pcb_group.getWhere({source_group_id:sourceGroup.source_group_id}),groupProps22={name:sourceGroup.name??`inflated_group_${sourceGroup.source_group_id}`};if(pcbGroup?.position_mode==="relative_to_group_anchor"&&pcbGroup.anchor_position){let baseAnchor={x:0,y:0};if(sourceGroup.parent_source_group_id){let parentPcbGroup=injectionDb.pcb_group.getWhere({source_group_id:sourceGroup.parent_source_group_id});parentPcbGroup?.anchor_position&&(baseAnchor=parentPcbGroup.anchor_position)}groupProps22.pcbX=pcbGroup.anchor_position.x-baseAnchor.x,groupProps22.pcbY=pcbGroup.anchor_position.y-baseAnchor.y}pcbGroup?.anchor_alignment&&(groupProps22.pcbAnchorAlignment=pcbGroup.anchor_alignment);let group2=new Group(groupProps22);return group2._isInflatedFromCircuitJson=!0,group2.source_group_id=sourceGroup.source_group_id,groupsMap&&groupsMap.set(sourceGroup.source_group_id,group2),sourceGroup.parent_source_group_id&&groupsMap?.has(sourceGroup.parent_source_group_id)?groupsMap.get(sourceGroup.parent_source_group_id).add(group2):subcircuit.add(group2),group2}var Inductor2=class extends NormalComponent{constructor(){super(...arguments);__publicField(this,"_adjustSilkscreenTextAutomatically",!0)}get config(){return{componentName:"Inductor",schematicSymbolName:this.props.symbolName??"inductor",zodProps:inductorProps,sourceFtype:FTYPE.simple_inductor}}_getSchematicSymbolDisplayValue(){return`${formatSiUnit(this._parsedProps.inductance)}H`}initPorts(){super.initPorts({additionalAliases:{pin1:["anode","pos","left"],pin2:["cathode","neg","right"]}})}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({name:this.name,ftype:FTYPE.simple_inductor,inductance:this.props.inductance,max_current_rating:props.maxCurrentRating===void 0?void 0:parseAndConvertSiUnit(props.maxCurrentRating,"A").value,display_inductance:this._getSchematicSymbolDisplayValue(),supplier_part_numbers:props.supplierPartNumbers,manufacturer_part_number:resolveManufacturerPartNumber(props),are_pins_interchangeable:!0,display_name:props.displayName});this.source_component_id=source_component.source_component_id}};function inflateSourceInductor(sourceElm,inflatorContext){let{injectionDb,subcircuit,groupsMap}=inflatorContext,pcbElm=injectionDb.pcb_component.getWhere({source_component_id:sourceElm.source_component_id}),cadElm=injectionDb.cad_component.getWhere({source_component_id:sourceElm.source_component_id}),{pcbX,pcbY}=getInflatedPcbPlacement({pcbComponent:pcbElm,sourceGroupId:sourceElm.source_group_id,inflatorContext}),inductor=new Inductor2({name:sourceElm.name,inductance:sourceElm.inductance,layer:pcbElm?.layer,pcbX,pcbY,pcbRotation:pcbElm?.rotation,doNotPlace:pcbElm?.do_not_place,obstructsWithinBounds:pcbElm?.obstructs_within_bounds});if(pcbElm){let footprint=inflateFootprintComponent(pcbElm,{...inflatorContext,normalComponent:inductor});footprint&&inductor.add(footprint)}sourceElm.source_group_id&&groupsMap?.has(sourceElm.source_group_id)?groupsMap.get(sourceElm.source_group_id).add(inductor):subcircuit.add(inductor)}var Led=class extends NormalComponent{resolveFootprint(){let footprint=super.resolveFootprint();return isFootprinterString(footprint)?resolveDiodeFootprint(footprint,{name:this.name??"Led",pinLabels:this._resolvePinLabels()}).footprint:footprint}get config(){let symbolMap={laser:"laser_diode"},variantSymbol=this.props.laser?"laser":null,baseSymbolName=variantSymbol?symbolMap[variantSymbol]:this.props.symbolName??"led",compactSize=this.props.schSize==="sm"||this.props.schSize==="xs"?this.props.schSize:void 0,compactSymbolName=compactSize&&baseSymbolName==="led"?`led_${compactSize}`:void 0;return{schematicSymbolName:compactSymbolName&&`${compactSymbolName}_right`in cc?compactSymbolName:baseSymbolName,componentName:"Led",zodProps:ledProps,sourceFtype:"simple_led"}}initPorts(){super.initPorts(getDiodePortOptions(this))}_getSchematicSymbolDisplayValue(){return this._parsedProps.schDisplayValue||this._parsedProps.color||void 0}getFootprinterString(){let baseFootprint=super.getFootprinterString();return baseFootprint&&this.props.color?`${baseFootprint}_color(${this.props.color})`:baseFootprint}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({ftype:"simple_led",name:this.name,wave_length:props.wavelength,color:props.color,symbol_display_value:this._getSchematicSymbolDisplayValue(),manufacturer_part_number:resolveManufacturerPartNumber(props),supplier_part_numbers:props.supplierPartNumbers,are_pins_interchangeable:!1,display_name:props.displayName});this.source_component_id=source_component.source_component_id}get pos(){return this.portMap.pos}get anode(){return this.portMap.anode}get neg(){return this.portMap.neg}get cathode(){return this.portMap.cathode}};function inflateSourceLed(sourceElm,inflatorContext){let{injectionDb,subcircuit,groupsMap}=inflatorContext,pcbElm=injectionDb.pcb_component.getWhere({source_component_id:sourceElm.source_component_id}),cadElm=injectionDb.cad_component.getWhere({source_component_id:sourceElm.source_component_id}),{pcbX,pcbY}=getInflatedPcbPlacement({pcbComponent:pcbElm,sourceGroupId:sourceElm.source_group_id,inflatorContext}),led2=new Led({name:sourceElm.name,color:sourceElm.color,wavelength:sourceElm.wavelength??sourceElm.wave_length,layer:pcbElm?.layer,pcbX,pcbY,pcbRotation:pcbElm?.rotation,doNotPlace:pcbElm?.do_not_place,obstructsWithinBounds:pcbElm?.obstructs_within_bounds});if(pcbElm){let footprint=inflateFootprintComponent(pcbElm,{...inflatorContext,normalComponent:led2});footprint&&led2.add(footprint)}sourceElm.source_group_id&&groupsMap?.has(sourceElm.source_group_id)?groupsMap.get(sourceElm.source_group_id).add(led2):subcircuit.add(led2)}var possibleOrientations=[{gate:"left",drain:"top",source:"bottom"},{gate:"left",drain:"bottom",source:"top"},{gate:"right",drain:"top",source:"bottom"},{gate:"right",drain:"bottom",source:"top"},{gate:"top",drain:"left",source:"right"},{gate:"top",drain:"right",source:"left"},{gate:"bottom",drain:"left",source:"right"},{gate:"bottom",drain:"right",source:"left"}],getBaselineOrientation=rotation6=>{let normalizedRotation=(rotation6%360+360)%360;if(normalizedRotation%90!==0)throw new Error(`Schematic rotation ${rotation6} is not supported for Mosfet`);return[{gate:"left",drain:"top",source:"bottom"},{gate:"top",drain:"right",source:"left"},{gate:"right",drain:"bottom",source:"top"},{gate:"bottom",drain:"left",source:"right"}][normalizedRotation/90]},getRequestedOrientation=props=>{let requestedSides={drain:props.symbolDrainSide,source:props.symbolSourceSide,gate:props.symbolGateSide},baseline=getBaselineOrientation(Number(props.schRotation??0)),matchingOrientations=possibleOrientations.filter(orientation32=>Object.keys(requestedSides).every(portName=>requestedSides[portName]===void 0||requestedSides[portName]===orientation32[portName]));if(matchingOrientations.length===0){let requestedDescription=Object.entries(requestedSides).filter(([,side])=>side!==void 0).map(([portName,side])=>`${portName}=${side}`).join(", ");throw new Error(`Invalid MOSFET symbol port side combination (${requestedDescription}). The gate must be perpendicular to the drain and source, and the drain and source must be opposite.`)}return matchingOrientations.sort((a23,b23)=>{let score=orientation32=>Object.keys(baseline).filter(portName=>orientation32[portName]!==baseline[portName]).length;return score(a23)-score(b23)})[0]},getMosfetSchematicSymbolName=props=>{let mosfetMode=props.mosfetMode==="depletion"?"d":"e",baseSymbolName=`${props.channelType}_channel_${mosfetMode}_mosfet_transistor`;if(!(props.symbolDrainSide!==void 0||props.symbolSourceSide!==void 0||props.symbolGateSide!==void 0))return baseSymbolName;let{gate,drain}=getRequestedOrientation(props);return`${baseSymbolName}_gate_${gate}_drain_${drain}`},Mosfet2=class extends NormalComponent{get config(){return{componentName:"Mosfet",schematicSymbolName:this.props.symbolName??getMosfetSchematicSymbolName(this.props),zodProps:mosfetProps,shouldRenderAsSchematicBox:!1}}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({ftype:"simple_mosfet",name:this.name,manufacturer_part_number:resolveManufacturerPartNumber(props),supplier_part_numbers:props.supplierPartNumbers,mosfet_mode:props.mosfetMode,channel_type:props.channelType,display_name:props.displayName});this.source_component_id=source_component.source_component_id}};function inflateSourceMosfet(sourceElm,inflatorContext){let{injectionDb,subcircuit,groupsMap}=inflatorContext,pcbElm=injectionDb.pcb_component.getWhere({source_component_id:sourceElm.source_component_id}),{pcbX,pcbY}=getInflatedPcbPlacement({pcbComponent:pcbElm,sourceGroupId:sourceElm.source_group_id,inflatorContext}),mosfet=new Mosfet2({name:sourceElm.name,channelType:sourceElm.channel_type,mosfetMode:sourceElm.mosfet_mode,manufacturerPartNumber:sourceElm.manufacturer_part_number,supplierPartNumbers:sourceElm.supplier_part_numbers??void 0,displayName:sourceElm.display_name,layer:pcbElm?.layer,pcbX,pcbY,pcbRotation:pcbElm?.rotation,doNotPlace:pcbElm?.do_not_place,obstructsWithinBounds:pcbElm?.obstructs_within_bounds});if(pcbElm){let footprint=inflateFootprintComponent(pcbElm,{...inflatorContext,normalComponent:mosfet});footprint&&mosfet.add(footprint)}sourceElm.source_group_id&&groupsMap?.has(sourceElm.source_group_id)?groupsMap.get(sourceElm.source_group_id).add(mosfet):subcircuit.add(mosfet)}function inflateSourcePort(sourcePort,inflatorContext){let{injectionDb,subcircuit}=inflatorContext;if(sourcePort.source_component_id!==null)return;let pcbPortFromInjection=injectionDb.pcb_port.getWhere({source_port_id:sourcePort.source_port_id}),port=new Port({name:sourcePort.name,pinNumber:sourcePort.pin_number});subcircuit.add(port),port.source_port_id=sourcePort.source_port_id;let root=subcircuit.root;if(root&&pcbPortFromInjection){let{db:db22}=root,pcb_port23=db22.pcb_port.insert({pcb_component_id:void 0,layers:pcbPortFromInjection.layers,subcircuit_id:subcircuit.subcircuit_id??void 0,pcb_group_id:subcircuit.getGroup()?.pcb_group_id??void 0,x:pcbPortFromInjection.x,y:pcbPortFromInjection.y,source_port_id:sourcePort.source_port_id,is_board_pinout:!1});port.pcb_port_id=pcb_port23.pcb_port_id}}var PushButton2=class extends NormalComponent{get config(){return{componentName:"PushButton",schematicSymbolName:this.props.symbolName??"push_button_normally_open_momentary",zodProps:pushButtonProps,sourceFtype:FTYPE.simple_push_button}}get defaultInternallyConnectedPinNames(){return[]}initPorts(){super.initPorts({pinCount:2,ignoreSymbolPorts:!0});let symbol=cc[this._getSchematicSymbolNameOrThrow()],symPort1=symbol.ports.find(p23=>p23.labels.includes("1")),symPort2=symbol.ports.find(p23=>p23.labels.includes("2")),ports=this.selectAll("port"),pin1Port=ports.find(port=>port.props.pinNumber===1);pin1Port.schematicSymbolPortDef=symPort1;let firstTerminalPorts=new Set(pin1Port._getPortsInternallyConnectedToThisPort()),secondTerminalPort=ports.filter(port=>port!==pin1Port&&!firstTerminalPorts.has(port)).sort((a23,b23)=>(a23.props.pinNumber??0)-(b23.props.pinNumber??0))[0];secondTerminalPort&&(secondTerminalPort.schematicSymbolPortDef=symPort2)}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({name:this.name,ftype:FTYPE.simple_push_button,supplier_part_numbers:props.supplierPartNumbers,manufacturer_part_number:resolveManufacturerPartNumber(props),are_pins_interchangeable:!0,display_name:props.displayName});this.source_component_id=source_component.source_component_id}};function inflateSourcePushButton(sourceElm,inflatorContext){let{injectionDb,subcircuit,groupsMap}=inflatorContext,pcbElm=injectionDb.pcb_component.getWhere({source_component_id:sourceElm.source_component_id}),cadElm=injectionDb.cad_component.getWhere({source_component_id:sourceElm.source_component_id}),{pcbX,pcbY}=getInflatedPcbPlacement({pcbComponent:pcbElm,sourceGroupId:sourceElm.source_group_id,inflatorContext}),pushButton=new PushButton2({name:sourceElm.name,layer:pcbElm?.layer,pcbX,pcbY,pcbRotation:pcbElm?.rotation,doNotPlace:pcbElm?.do_not_place,obstructsWithinBounds:pcbElm?.obstructs_within_bounds});if(pcbElm){let footprint=inflateFootprintComponent(pcbElm,{...inflatorContext,normalComponent:pushButton});footprint&&pushButton.add(footprint)}sourceElm.source_group_id&&groupsMap?.has(sourceElm.source_group_id)?groupsMap.get(sourceElm.source_group_id).add(pushButton):subcircuit.add(pushButton)}var Resistor2=class extends NormalComponent{constructor(){super(...arguments);__publicField(this,"_adjustSilkscreenTextAutomatically",!0)}get config(){let baseSymbolName=this.props.symbolName??"boxresistor",compactSize=this.props.schSize==="sm"||this.props.schSize==="xs"?this.props.schSize:void 0,compactSymbolName=compactSize&&(baseSymbolName==="boxresistor"||baseSymbolName==="resistor")?`${baseSymbolName}_${compactSize}`:void 0;return{componentName:"Resistor",schematicSymbolName:compactSymbolName&&`${compactSymbolName}_right`in cc?compactSymbolName:baseSymbolName,zodProps:resistorProps,sourceFtype:"simple_resistor"}}initPorts(){super.initPorts({additionalAliases:{pin1:["anode","pos","left"],pin2:["cathode","neg","right"]}})}_getSchematicSymbolDisplayValue(){return`${formatSiUnit(this._parsedProps.resistance)}\u03A9`}doInitialCreateNetsFromProps(){this._createNetsFromProps([this.props.pullupFor,this.props.pullupTo,this.props.pulldownFor,this.props.pulldownTo,...this._getNetsFromConnectionsProp()])}doInitialCreateTracesFromProps(){this.props.pullupFor&&this.props.pullupTo&&(this.add(new Trace({from:`${this.getSubcircuitSelector()} > port.1`,to:this.props.pullupFor})),this.add(new Trace({from:`${this.getSubcircuitSelector()} > port.2`,to:this.props.pullupTo}))),this.props.pulldownFor&&this.props.pulldownTo&&(this.add(new Trace({from:`${this.getSubcircuitSelector()} > port.1`,to:this.props.pulldownFor})),this.add(new Trace({from:`${this.getSubcircuitSelector()} > port.2`,to:this.props.pulldownTo}))),this._createTracesFromConnectionsProp()}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({ftype:"simple_resistor",name:this.name,manufacturer_part_number:resolveManufacturerPartNumber(props),supplier_part_numbers:props.supplierPartNumbers,resistance:props.resistance,display_resistance:this._getSchematicSymbolDisplayValue(),are_pins_interchangeable:!0,display_name:props.displayName});this.source_component_id=source_component.source_component_id}};function inflateSourceResistor(sourceElm,inflatorContext){let{injectionDb,subcircuit,groupsMap}=inflatorContext,pcbElm=injectionDb.pcb_component.getWhere({source_component_id:sourceElm.source_component_id}),cadElm=injectionDb.cad_component.getWhere({source_component_id:sourceElm.source_component_id}),{pcbX,pcbY}=getInflatedPcbPlacement({pcbComponent:pcbElm,sourceGroupId:sourceElm.source_group_id,inflatorContext}),resistor=new Resistor2({name:sourceElm.name,resistance:sourceElm.resistance,layer:pcbElm?.layer,pcbX,pcbY,pcbRotation:pcbElm?.rotation,doNotPlace:pcbElm?.do_not_place,obstructsWithinBounds:pcbElm?.obstructs_within_bounds});if(pcbElm){let footprint=inflateFootprintComponent(pcbElm,{...inflatorContext,normalComponent:resistor});footprint&&resistor.add(footprint)}sourceElm.source_group_id&&groupsMap?.has(sourceElm.source_group_id)?groupsMap.get(sourceElm.source_group_id).add(resistor):subcircuit.add(resistor)}function hasSimProps(props){return props.simSwitchFrequency!==void 0||props.simCloseAt!==void 0||props.simOpenAt!==void 0||props.simStartClosed!==void 0||props.simStartOpen!==void 0}var Switch=class extends NormalComponent{_getSwitchType(){let props=this._parsedProps;return props?props.dpdt?"dpdt":props.spst?"spst":props.spdt?"spdt":props.dpst?"dpst":props.type??"spst":"spst"}get config(){let switchType=this._getSwitchType(),isNormallyClosed=this._parsedProps?.isNormallyClosed??!1,symbolMap={spst:isNormallyClosed?"spst_normally_closed_switch":"spst_switch",spdt:isNormallyClosed?"spdt_normally_closed_switch":"spdt_switch",dpst:isNormallyClosed?"dpst_normally_closed_switch":"dpst_switch",dpdt:isNormallyClosed?"dpdt_normally_closed_switch":"dpdt_switch"};return{componentName:"Switch",schematicSymbolName:this.props.symbolName??symbolMap[switchType],zodProps:switchProps,shouldRenderAsSchematicBox:!1}}doInitialSourceRender(){let{db:db22}=this.root,props=this._parsedProps??{},source_component=db22.source_component.insert({ftype:"simple_switch",name:this.name,manufacturer_part_number:resolveManufacturerPartNumber(props),supplier_part_numbers:props.supplierPartNumbers,are_pins_interchangeable:this._getSwitchType()==="spst",display_name:props?.displayName});this.source_component_id=source_component.source_component_id}doInitialSimulationRender(){let{_parsedProps:props}=this;if(!hasSimProps(props))return;let{db:db22}=this.root,simulationSwitch={type:"simulation_switch",source_component_id:this.source_component_id||""};props.simSwitchFrequency!==void 0&&(simulationSwitch.switching_frequency=frequency.parse(props.simSwitchFrequency)),props.simCloseAt!==void 0&&(simulationSwitch.closes_at=ms.parse(props.simCloseAt)),props.simOpenAt!==void 0&&(simulationSwitch.opens_at=ms.parse(props.simOpenAt)),props.simStartOpen!==void 0&&(simulationSwitch.starts_closed=!props.simStartOpen),props.simStartClosed!==void 0&&(simulationSwitch.starts_closed=props.simStartClosed),db22.simulation_switch.insert(simulationSwitch)}},getImportedSwitchProps=(sourceElm,inflatorContext)=>{let sourcePorts=inflatorContext.injectionDb.source_port.list().filter(port=>port.source_component_id===sourceElm.source_component_id),pinLabels={},highestPinNumber=0;for(let sourcePort of sourcePorts){let pinNumber2=sourcePort.pin_number;if(pinNumber2==null)continue;highestPinNumber=Math.max(highestPinNumber,pinNumber2);let labels=Array.from(new Set([sourcePort.name,...sourcePort.port_hints??[]].filter(label=>typeof label=="string"&&label.length>0)));labels.length>0&&(pinLabels[`pin${pinNumber2}`]=labels)}let type="spst";return highestPinNumber>=5?type="dpdt":highestPinNumber===4?type="dpst":highestPinNumber===3&&(type="spdt"),{type,pinLabels:Object.keys(pinLabels).length>0?pinLabels:void 0}};function inflateSourceSwitch(sourceElm,inflatorContext){let{injectionDb,subcircuit,groupsMap}=inflatorContext,pcbElm=injectionDb.pcb_component.getWhere({source_component_id:sourceElm.source_component_id}),{pcbX,pcbY}=getInflatedPcbPlacement({pcbComponent:pcbElm,sourceGroupId:sourceElm.source_group_id,inflatorContext}),importedSwitchProps=getImportedSwitchProps(sourceElm,inflatorContext),switchComponent=new Switch({name:sourceElm.name,displayName:sourceElm.display_name,...importedSwitchProps,layer:pcbElm?.layer,pcbX,pcbY,pcbRotation:pcbElm?.rotation,doNotPlace:pcbElm?.do_not_place,obstructsWithinBounds:pcbElm?.obstructs_within_bounds});if(pcbElm){let footprint=inflateFootprintComponent(pcbElm,{...inflatorContext,normalComponent:switchComponent});footprint&&switchComponent.add(footprint)}sourceElm.source_group_id&&groupsMap?.has(sourceElm.source_group_id)?groupsMap.get(sourceElm.source_group_id).add(switchComponent):subcircuit.add(switchComponent)}var TESTPOINT_DEFAULTS={HOLE_DIAMETER:.5,SMT_CIRCLE_DIAMETER:1.2,SMT_RECT_SIZE:2},TestPoint=class extends NormalComponent{get config(){return{componentName:"TestPoint",schematicSymbolName:this.props.symbolName??"testpoint",zodProps:testpointProps,sourceFtype:FTYPE.simple_test_point}}_getPropsWithDefaults(){let{padShape,holeDiameter,footprintVariant,padDiameter,width:width10,height:height10}=this._parsedProps;return!footprintVariant&&holeDiameter&&(footprintVariant="through_hole"),footprintVariant??(footprintVariant="through_hole"),padShape??(padShape="circle"),footprintVariant==="pad"?padShape==="circle"?padDiameter??(padDiameter=TESTPOINT_DEFAULTS.SMT_CIRCLE_DIAMETER):padShape==="rect"&&(width10??(width10=TESTPOINT_DEFAULTS.SMT_RECT_SIZE),height10??(height10=width10)):footprintVariant==="through_hole"&&(holeDiameter??(holeDiameter=TESTPOINT_DEFAULTS.HOLE_DIAMETER)),{padShape,holeDiameter,footprintVariant,padDiameter,width:width10,height:height10}}_getImpliedFootprintString(){let{padShape,holeDiameter,footprintVariant,padDiameter,width:width10,height:height10}=this._getPropsWithDefaults();if(footprintVariant==="through_hole")return`platedhole_d${holeDiameter}`;if(footprintVariant==="pad"){if(padShape==="circle")return`smtpad_circle_d${padDiameter}`;if(padShape==="rect")return`smtpad_rect_w${width10}_h${height10}`}throw new Error(`Footprint variant "${footprintVariant}" with pad shape "${padShape}" not implemented`)}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,{padShape,holeDiameter,footprintVariant,padDiameter,width:width10,height:height10}=this._getPropsWithDefaults(),source_component=db22.source_component.insert({ftype:FTYPE.simple_test_point,name:this.name,supplier_part_numbers:props.supplierPartNumbers,manufacturer_part_number:resolveManufacturerPartNumber(props),footprint_variant:footprintVariant,pad_shape:padShape,pad_diameter:padDiameter,hole_diameter:holeDiameter,width:width10,height:height10,are_pins_interchangeable:!0,display_name:props.displayName});this.source_component_id=source_component.source_component_id}};function inflateSourceTestPoint(sourceElm,inflatorContext){let{injectionDb,subcircuit,groupsMap}=inflatorContext,pcbElm=injectionDb.pcb_component.getWhere({source_component_id:sourceElm.source_component_id}),{pcbX,pcbY}=getInflatedPcbPlacement({pcbComponent:pcbElm,sourceGroupId:sourceElm.source_group_id,inflatorContext}),testPoint=new TestPoint({name:sourceElm.name,footprint:[],displayName:sourceElm.display_name,footprintVariant:sourceElm.footprint_variant,padShape:sourceElm.pad_shape,padDiameter:sourceElm.pad_diameter,holeDiameter:sourceElm.hole_diameter,width:sourceElm.width,height:sourceElm.height,supplierPartNumbers:sourceElm.supplier_part_numbers,manufacturerPartNumber:sourceElm.manufacturer_part_number,layer:pcbElm?.layer,pcbX,pcbY,pcbRotation:pcbElm?.rotation,doNotPlace:pcbElm?.do_not_place,obstructsWithinBounds:pcbElm?.obstructs_within_bounds});if(pcbElm){let footprint=inflateFootprintComponent(pcbElm,{...inflatorContext,normalComponent:testPoint});footprint&&testPoint.add(footprint)}let parentGroup=sourceElm.source_group_id?groupsMap?.get(sourceElm.source_group_id):void 0;parentGroup?parentGroup.add(testPoint):subcircuit.add(testPoint)}function pcbTraceRouteToPcbPath(route2){if(route2.length<=2)return[];let firstPoint=route2[0],lastPoint=route2[route2.length-1];return route2.slice(1,-1).filter(point12=>{let position22=getRoutePointPosition(point12),firstPosition=getRoutePointPosition(firstPoint),lastPosition=getRoutePointPosition(lastPoint),isSameAsFirst=position22.x===firstPosition.x&&position22.y===firstPosition.y,isSameAsLast=position22.x===lastPosition.x&&position22.y===lastPosition.y;return!isSameAsFirst&&!isSameAsLast}).map(point12=>{if(point12.route_type==="via")return{x:point12.x,y:point12.y,via:!0,fromLayer:point12.from_layer,toLayer:point12.to_layer};let position22=getRoutePointPosition(point12);return{x:position22.x,y:position22.y}})}var getSelectorPath=(component,inflatorContext)=>{let{injectionDb,subcircuit,groupsMap}=inflatorContext,path_parts=[],currentGroupId=component.source_group_id;for(;currentGroupId&&currentGroupId!==subcircuit.source_group_id;){let sourceGroup=injectionDb.source_group.get(currentGroupId),groupInstance=groupsMap?.get(currentGroupId);if(!sourceGroup||!groupInstance)break;let groupName=groupInstance.props.name??groupInstance.fallbackUnassignedName;path_parts.unshift(`.${groupName}`),currentGroupId=sourceGroup.parent_source_group_id}return path_parts.push(`.${component.name}`),path_parts.join(" > ")};function inflateSourceTrace(sourceTrace,inflatorContext){let{injectionDb,subcircuit}=inflatorContext,connectedSelectors=[];for(let sourcePortId of sourceTrace.connected_source_port_ids){let sourcePort=injectionDb.source_port.get(sourcePortId);if(!sourcePort)continue;let selector2;if(sourcePort.source_component_id){let sourceComponent=injectionDb.source_component.get(sourcePort.source_component_id);sourceComponent&&(selector2=`${getSelectorPath({name:sourceComponent.name,source_group_id:sourceComponent.source_group_id},inflatorContext)} > .${sourcePort.name}`)}else selector2=`.${sourcePort.name}`;selector2&&connectedSelectors.push(selector2)}for(let sourceNetId of sourceTrace.connected_source_net_ids){let sourceNet=injectionDb.source_net.get(sourceNetId);sourceNet&&connectedSelectors.push(`net.${sourceNet.name}`)}if(connectedSelectors.length<2)return;let pcbTraces=injectionDb.pcb_trace.list().filter(trace2=>trace2.source_trace_id===sourceTrace.source_trace_id),pcbTrace=pcbTraces[0],pcbPath3;pcbTrace&&(pcbPath3=pcbTraceRouteToPcbPath(pcbTrace.route));let traceWidth=sourceTrace.min_trace_thickness;if(!traceWidth&&pcbTrace?.route){let wirePoint=pcbTrace.route.find(pt22=>pt22.route_type==="wire");wirePoint&&wirePoint.route_type==="wire"&&(traceWidth=wirePoint.width)}let traceProps22={path:connectedSelectors};traceWidth!==void 0&&(traceProps22.thickness=traceWidth),pcbPath3&&pcbPath3.length>0?traceProps22.pcbPath=pcbPath3:!pcbTrace&&sourceTrace.connected_source_port_ids.length===2&&sourceTrace.connected_source_net_ids.length===0&&(traceProps22.pcbStraightLine=!0);let trace=new Trace(traceProps22);trace._inflatedPcbTraces=pcbTraces.length>0?pcbTraces:void 0,trace._inflatedPcbVias=pcbTrace?injectionDb.pcb_via.list().filter(via=>pcbTraces.some(trace2=>via.pcb_trace_id===trace2.pcb_trace_id)):void 0,subcircuit.add(trace)}var SHORT_ALIASES={collector:["c"],base:["b"],emitter:["e"]},Transistor=class extends NormalComponent{get config(){let baseSymbolName=this.props.type==="npn"?"npn_bipolar_transistor":"pnp_bipolar_transistor";return{componentName:"Transistor",schematicSymbolName:this.props.symbolName??baseSymbolName,zodProps:transistorProps,sourceFtype:"simple_transistor",shouldRenderAsSchematicBox:!1}}initPorts(){let additionalAliases={},pinLabels=this._resolvePinLabels(),portLabels=pinLabels?Object.entries(pinLabels).map(([pin,labels])=>[pin,...Array.isArray(labels)?labels:[labels]]):this.getSchematicSymbol()?.ports.map(port=>port.labels)??[];for(let labels of portLabels){let pinNumber2=getPinNumberFromLabels(labels);pinNumber2&&(additionalAliases[`pin${pinNumber2}`]=labels.flatMap(label=>SHORT_ALIASES[label]??[]))}super.initPorts({pinCount:3,additionalAliases})}get collector(){return this.portMap.collector}get base(){return this.portMap.base}get emitter(){return this.portMap.emitter}doInitialCreateNetsFromProps(){this._createNetsFromProps([...this._getNetsFromConnectionsProp()])}doInitialCreateTracesFromProps(){this._createTracesFromConnectionsProp()}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({ftype:"simple_transistor",name:this.name,manufacturer_part_number:resolveManufacturerPartNumber(props),supplier_part_numbers:props.supplierPartNumbers,transistor_type:props.type,display_name:props.displayName});this.source_component_id=source_component.source_component_id}};function inflateSourceTransistor(sourceElm,inflatorContext){let{injectionDb,subcircuit,groupsMap}=inflatorContext,pcbElm=injectionDb.pcb_component.getWhere({source_component_id:sourceElm.source_component_id}),cadElm=injectionDb.cad_component.getWhere({source_component_id:sourceElm.source_component_id}),{pcbX,pcbY}=getInflatedPcbPlacement({pcbComponent:pcbElm,sourceGroupId:sourceElm.source_group_id,inflatorContext}),transistor=new Transistor({name:sourceElm.name,type:sourceElm.transistor_type,layer:pcbElm?.layer,pcbX,pcbY,pcbRotation:pcbElm?.rotation,doNotPlace:pcbElm?.do_not_place,obstructsWithinBounds:pcbElm?.obstructs_within_bounds});if(pcbElm){let footprint=inflateFootprintComponent(pcbElm,{...inflatorContext,normalComponent:transistor});footprint&&transistor.add(footprint)}sourceElm.source_group_id&&groupsMap?.has(sourceElm.source_group_id)?groupsMap.get(sourceElm.source_group_id).add(transistor):subcircuit.add(transistor)}function inflateStandalonePcbPrimitives(inflatorContext){let{injectionDb,subcircuit,groupsMap}=inflatorContext,standalonePrimitiveTypes=["pcb_silkscreen_rect","pcb_silkscreen_circle","pcb_silkscreen_line","pcb_silkscreen_path","pcb_silkscreen_text","pcb_fabrication_note_text","pcb_fabrication_note_path","pcb_fabrication_note_rect","pcb_note_text","pcb_note_rect","pcb_note_path","pcb_note_line","pcb_via","pcb_hole","pcb_plated_hole","pcb_cutout","pcb_soldermask_opening","pcb_solder_paste"],standalonePrimitives=injectionDb.toArray().filter(elm=>{if(!standalonePrimitiveTypes.includes(elm.type))return!1;if(elm.type==="pcb_via"){if(!elm.pcb_trace_id)return!0;let pcbTrace=injectionDb.pcb_trace.get(elm.pcb_trace_id),sourceTraceId=pcbTrace?.source_trace_id;return!(sourceTraceId&&injectionDb.source_trace.get(sourceTraceId)&&pcbTrace?.route.some(point12=>point12.route_type==="via"&&Math.abs(point12.x-elm.x)<1e-4&&Math.abs(point12.y-elm.y)<1e-4))}return elm.type==="pcb_cutout"?!0:elm.type==="pcb_solder_paste"?elm.pcb_component_id===void 0&&!elm.pcb_smtpad_id:elm.type==="pcb_soldermask_opening"?elm.pcb_component_id===void 0:"pcb_component_id"in elm&&(elm.pcb_component_id===null||elm.pcb_component_id===void 0)});if(standalonePrimitives.length===0)return;let components=createComponentsFromCircuitJson({componentName:"",componentRotation:"0deg"},standalonePrimitives);for(let component of components)subcircuit.add(component)}var inflateCircuitJson=(target,circuitJson,children)=>{if(!circuitJson)return;let injectionDb=cju_default(circuitJson);if(circuitJson&&children?.length>0)throw new Error("Component cannot have both circuitJson and children");let inflationCtx={injectionDb,subcircuit:target,groupsMap:new Map},sourceGroups=injectionDb.source_group.list(),renderedGroupIds=new Set,groupsToRender=[...sourceGroups];for(;groupsToRender.length>0;){let groupIndex=groupsToRender.findIndex(g23=>!g23.parent_source_group_id||renderedGroupIds.has(g23.parent_source_group_id));if(groupIndex===-1){let remainingIds=groupsToRender.map(g23=>g23.source_group_id).join(", ");throw new Error(`Cannot inflate source_groups: cyclic dependency or missing parent detected. Remaining groups: ${remainingIds}`)}let groupToRender=groupsToRender[groupIndex];inflateSourceGroup(groupToRender,inflationCtx),renderedGroupIds.add(groupToRender.source_group_id),groupsToRender.splice(groupIndex,1)}let pcbBoards=injectionDb.pcb_board.list();for(let pcbBoard of pcbBoards)inflatePcbBoard(pcbBoard,inflationCtx);let sourceComponents=injectionDb.source_component.list();for(let sourceComponent of sourceComponents)switch(sourceComponent.ftype){case"simple_resistor":inflateSourceResistor(sourceComponent,inflationCtx);break;case"simple_fuse":inflateSourceFuse(sourceComponent,inflationCtx);break;case"simple_capacitor":inflateSourceCapacitor(sourceComponent,inflationCtx);break;case"simple_inductor":inflateSourceInductor(sourceComponent,inflationCtx);break;case"simple_diode":inflateSourceDiode(sourceComponent,inflationCtx);break;case"simple_fiducial":inflateSourceFiducial(sourceComponent,inflationCtx);break;case"simple_led":inflateSourceLed(sourceComponent,inflationCtx);break;case"simple_chip":inflateSourceChip(sourceComponent,inflationCtx);break;case"simple_connector":inflateSourceConnector(sourceComponent,inflationCtx);break;case"simple_transistor":inflateSourceTransistor(sourceComponent,inflationCtx);break;case"simple_mosfet":inflateSourceMosfet(sourceComponent,inflationCtx);break;case"simple_push_button":inflateSourcePushButton(sourceComponent,inflationCtx);break;case"simple_switch":inflateSourceSwitch(sourceComponent,inflationCtx);break;case"simple_test_point":inflateSourceTestPoint(sourceComponent,inflationCtx);break;default:throw new Error(`No inflator implemented for source component ftype: "${sourceComponent.ftype}"`)}let sourcePorts=injectionDb.source_port.list();for(let sourcePort of sourcePorts)inflateSourcePort(sourcePort,inflationCtx);let sourceTraces=injectionDb.source_trace.list();for(let sourceTrace of sourceTraces)inflateSourceTrace(sourceTrace,inflationCtx);inflateStandalonePcbPrimitives(inflationCtx),inflateSimulation(inflationCtx)},resolveBoardMotorMount=board=>{if(boardMountsToPrintedPart(board)){resolvePrintedPartMounts(board);return}let{mountedTo,mountRotation,mountRotationAnchor,mountOrientation}=board._parsedProps;if(!mountedTo){if(mountRotation||mountRotationAnchor||mountOrientation)throw new Error(`board "${board.name}" mounting alignment requires mountedTo`);return}let target=resolveAssemblyMountTarget(board,mountedTo,getComponentsInAssemblyScope(board).filter(isAssemblyMountPart)),motorName=target.part.name;if(target.part.componentName!=="AssemblyMotor"||target.face.name!=="backface")throw new Error(`board "${board.name}" mountedTo "${mountedTo}" must name a motor backface, e.g. "NEMA17.backface"`);let motor=target.part;if(motor._parsedProps.mountedTo){resolvePrintedPartMounts(board);return}let direction4=motor._parsedProps.shaftFacingDirection;if(direction4!=="z+"&&direction4!=="z-")throw new Error(`board "${board.name}" cannot mount to motor "${motorName}" facing ${direction4}: rotated PCB boards are not yet supported; use shaftFacingDirection="z+" or "z-"`);if(mountRotationAnchor&&!mountRotation)throw new Error(`board "${board.name}" mountRotationAnchor requires mountRotation`);if(motor.props.shaftFacingDirection&&mountOrientation&&mountOrientation!==(direction4==="z+"?"top_layer_toward_mount_face":"bottom_layer_toward_mount_face"))throw new Error(`board "${board.name}" mountOrientation "${mountOrientation}" conflicts with motor "${motorName}" shaftFacingDirection "${direction4}"`);return motor},resolveMotorMountedBoard=motor=>{let boards=getComponentsInAssemblyScope(motor).filter(board=>board.componentName==="Board").filter(board=>resolveBoardMotorMount(board)===motor);if(boards.length>1)throw new Error(`assembly.motor "${motor.name}" has multiple mounted boards; only one board may determine its placement`);return boards[0]};function createCircuitJsonDatabase(){if(typeof cju_indexed_default!="function")return cju_default([]);let indexed=cju_indexed_default([],{indexConfig:{byId:!0,byType:!0}});return typeof indexed.insert!="function"||typeof indexed.insertAll!="function"||typeof indexed.subtree!="function"?cju_default([]):indexed}var IsolatedCircuit=class{constructor({platform,projectUrl,cachedSubcircuits,pendingSubcircuitRenders}={}){__publicField(this,"firstChild",null);__publicField(this,"children");__publicField(this,"db");__publicField(this,"root",null);__publicField(this,"isRootCircuit",!1);__publicField(this,"cachedSubcircuits");__publicField(this,"pendingSubcircuitRenders");__publicField(this,"_schematicDisabledOverride");__publicField(this,"pcbDisabled",!1);__publicField(this,"pcbRoutingDisabled",!1);__publicField(this,"_featureMspSchematicTraceRouting",!0);__publicField(this,"_featurePcbViaStitching",!0);__publicField(this,"name");__publicField(this,"platform");__publicField(this,"projectUrl");__publicField(this,"_hasRenderedAtleastOnce",!1);__publicField(this,"_asyncEffectIdsByPhase",new Map);__publicField(this,"_asyncEffectPhaseById",new Map);__publicField(this,"_hasUnrenderedUpdatesFromAsyncEffects",!1);__publicField(this,"_runningAsyncEffectsById",new Map);__publicField(this,"_hasRenderLifecycleListeners",!1);__publicField(this,"_eventListeners",{});this.children=[],this.db=createCircuitJsonDatabase(),this.platform=platform,this.projectUrl=projectUrl,this.pcbDisabled=platform?.pcbDisabled??!1,this.pcbRoutingDisabled=platform?.routingDisabled??!1,this.cachedSubcircuits=cachedSubcircuits,this.pendingSubcircuitRenders=pendingSubcircuitRenders,this.root=this}get schematicDisabled(){return this._schematicDisabledOverride!==void 0?this._schematicDisabledOverride:this.platform?.schematicDisabled!==void 0?this.platform.schematicDisabled:this._getBoard()?._parsedProps?.schematicDisabled??!1}set schematicDisabled(value){this._schematicDisabledOverride=value}add(componentOrElm){let component;(0,import_react10.isValidElement)(componentOrElm)?component=createInstanceFromReactElement(componentOrElm):component=componentOrElm,this.children.push(component)}setPlatform(platform){this.platform={...this.platform,...platform},platform.pcbDisabled!==void 0&&(this.pcbDisabled=platform.pcbDisabled),platform.routingDisabled!==void 0&&(this.pcbRoutingDisabled=platform.routingDisabled)}_getBoard(){let findBoard=components=>{for(let child of components){if(child.componentName==="Board")return child;if(isAssemblyDeviceContainer(child)){let nested=findBoard(child.children);if(nested)return nested}}};return findBoard(this.children)}_guessRootComponent(){if(this.firstChild)return;if(this.children.length===0)throw new Error("Not able to guess root component: IsolatedCircuit has no children (use circuit.add(...))");let panels=this.children.filter(child=>child.lowercaseComponentName==="panel");if(panels.length>1)throw new Error("Only one <panel> is allowed per circuit");if(panels.length===1){if(this.children.length!==1)throw new Error("<panel> must be the root element of the circuit");this.firstChild=panels[0];return}if(this.children.length===1&&(this.children[0].isGroup||isAssemblyDeviceContainer(this.children[0]))){this.firstChild=this.children[0];return}let group2=new Group({subcircuit:!0});group2.parent=this,group2.addAll(this.children),this.children=[group2],this.firstChild=group2}render(){this.firstChild||this._guessRootComponent();let{firstChild,db:db22}=this;if(!firstChild)throw new Error("IsolatedCircuit has no root component");firstChild.parent=this,firstChild.runRenderCycle(),this._hasUnrenderedUpdatesFromAsyncEffects=!1,this._hasRenderedAtleastOnce=!0}async renderUntilSettled(){for(this.db.source_project_metadata.list()?.[0]||this.db.source_project_metadata.insert({software_used_string:`@tscircuit/core@${this.getCoreVersion()}`,...this.projectUrl?{project_url:this.projectUrl}:{}}),this.render();!this.isDoneRendering();)await new Promise(resolve10=>{let resume=()=>{clearTimeout(timer),this.removeListener("asyncEffect:end",resume),resolve10()},timer=setTimeout(resume,100);this.on("asyncEffect:end",resume),this._hasUnrenderedUpdatesFromAsyncEffects&&resume()}),(this._hasUnrenderedUpdatesFromAsyncEffects||this._asyncEffectPhaseById.size===0)&&this.render();this.emit("renderComplete")}isDoneRendering(){return this._hasRenderedAtleastOnce&&!this._hasIncompleteAsyncEffects()}_hasIncompleteAsyncEffects(){return this._asyncEffectPhaseById.size>0||this._hasUnrenderedUpdatesFromAsyncEffects?!0:this.children.some(child=>child._hasIncompleteAsyncEffects())}_hasIncompleteAsyncEffectsForPhase(phase){return(this._asyncEffectIdsByPhase.get(phase)?.size??0)>0}getRunningAsyncEffects(){return Array.from(this._runningAsyncEffectsById.values())}getCircuitJson(){return this._hasRenderedAtleastOnce||this.render(),this.db.toArray()}toJson(){return this.getCircuitJson()}async getSvg(options){let circuitToSvg=await Promise.resolve().then(()=>(init_dist14(),dist_exports2)).catch(e211=>{throw new Error(`To use circuit.getSvg, you must install the "circuit-to-svg" package.
1049
1049
 
1050
1050
  "${e211.message}"`)});if(options.view==="pcb")return circuitToSvg.convertCircuitJsonToPcbSvg(this.getCircuitJson());if(options.view==="schematic")return circuitToSvg.convertCircuitJsonToSchematicSvg(this.getCircuitJson());throw new Error(`Invalid view: ${options.view}`)}getCoreVersion(){let[major,minor,patch]=package_default3.version.split(".").map(Number);return`${major}.${minor}.${patch+1}`}async preview(previewNameOrOpts){let previewOpts=typeof previewNameOrOpts=="object"?previewNameOrOpts:{previewName:previewNameOrOpts};throw new Error("project.preview is not yet implemented")}computeSchematicGlobalTransform(){return identity7()}_computePcbGlobalTransformBeforeLayout(){return identity7()}selectAll(selector2){return this._guessRootComponent(),this.firstChild?.selectAll(selector2)??[]}selectOne(selector2,opts){return this._guessRootComponent(),this.firstChild?.selectOne(selector2,opts)??null}emit(event,...args){if(event==="asyncEffect:start"?this._registerAsyncEffectStart(args[0]):event==="asyncEffect:end"&&this._registerAsyncEffectEnd(args[0]),!!this._eventListeners[event])for(let listener of this._eventListeners[event])listener(...args)}hasEventListener(event){return(this._eventListeners[event]?.length??0)>0}on(event,listener){this._eventListeners[event]||(this._eventListeners[event]=[]),this._eventListeners[event].push(listener),event.startsWith("renderable:renderLifecycle:")&&(this._hasRenderLifecycleListeners=!0)}removeListener(event,listener){this._eventListeners[event]&&(this._eventListeners[event]=this._eventListeners[event].filter(l23=>l23!==listener),event.startsWith("renderable:renderLifecycle:")&&(this._hasRenderLifecycleListeners=Object.entries(this._eventListeners).some(([eventName,listeners])=>eventName.startsWith("renderable:renderLifecycle:")&&listeners.length>0)))}enableDebug(debug132){typeof debug132=="string"?import_debug21.default.enable(debug132):(debug132===null||debug132===!1)&&import_debug21.default.disable()}getClientOrigin(){return typeof window<"u"&&window.location?window.location.origin:typeof self<"u"&&self.location?self.location.origin:""}_registerAsyncEffectStart(payload){if(!payload?.asyncEffectId||!payload.phase)return;let{asyncEffectId,phase}=payload,existingPhase=this._asyncEffectPhaseById.get(asyncEffectId);existingPhase&&existingPhase!==phase&&this._asyncEffectIdsByPhase.get(existingPhase)?.delete(asyncEffectId),this._asyncEffectIdsByPhase.has(phase)||this._asyncEffectIdsByPhase.set(phase,new Set),this._asyncEffectIdsByPhase.get(phase).add(asyncEffectId),this._asyncEffectPhaseById.set(asyncEffectId,phase),this._runningAsyncEffectsById.set(asyncEffectId,{asyncEffectId,effectName:payload.effectName,componentDisplayName:payload.componentDisplayName,phase,error:payload.error})}_registerAsyncEffectEnd(payload){if(!payload?.asyncEffectId)return;let{asyncEffectId}=payload,phase=this._asyncEffectPhaseById.get(asyncEffectId)??payload.phase;if(phase){let phaseSet=this._asyncEffectIdsByPhase.get(phase);phaseSet?.delete(asyncEffectId),phaseSet&&phaseSet.size===0&&this._asyncEffectIdsByPhase.delete(phase)}this._asyncEffectPhaseById.delete(asyncEffectId),this._runningAsyncEffectsById.delete(asyncEffectId),this._hasUnrenderedUpdatesFromAsyncEffects=!0}};function Subcircuit_doInitialRenderIsolatedSubcircuits(subcircuit){if(!subcircuit._isIsolatedSubcircuit||subcircuit._isolatedCircuitJson||!subcircuit.getSubcircuitPropHash)return;let propHash=subcircuit.getSubcircuitPropHash(),cachedSubcircuits=subcircuit.root?.cachedSubcircuits,pendingSubcircuitRenders=subcircuit.root?.pendingSubcircuitRenders,cached=cachedSubcircuits?.get(propHash);if(cached){subcircuit._isolatedCircuitJson=cached,subcircuit.children=[],subcircuit._normalComponentNameMap=null;return}let childrenToRender=[...subcircuit.children];subcircuit.children=[],subcircuit._normalComponentNameMap=null;let parentRoot=subcircuit.root;subcircuit._queueAsyncEffect("render-isolated-subcircuit",async()=>{let cachedResult=cachedSubcircuits?.get(propHash);if(cachedResult){subcircuit._isolatedCircuitJson=cachedResult;return}let pendingRenderPromise=pendingSubcircuitRenders?.get(propHash);if(pendingRenderPromise){subcircuit._isolatedCircuitJson=await pendingRenderPromise;return}let resolveRender,rejectRender,renderPromise=new Promise((resolve10,reject)=>{resolveRender=resolve10,rejectRender=reject});pendingSubcircuitRenders?.set(propHash,renderPromise);try{let isolatedCircuit=new IsolatedCircuit({platform:{...parentRoot.platform,pcbDisabled:parentRoot.pcbDisabled,schematicDisabled:parentRoot.schematicDisabled},cachedSubcircuits,pendingSubcircuitRenders});for(let child of childrenToRender)isolatedCircuit.add(child);await isolatedCircuit.renderUntilSettled();let circuitJson=isolatedCircuit.getCircuitJson();cachedSubcircuits?.set(propHash,circuitJson),subcircuit._isolatedCircuitJson=circuitJson,resolveRender(circuitJson)}catch(error2){throw rejectRender(error2 instanceof Error?error2:new Error(String(error2))),error2}finally{pendingSubcircuitRenders?.delete(propHash)}})}var EXCLUDED_PROPS=new Set(["name","key","pcbX","pcbY","schX","schY","pcbLeftEdgeX","pcbRightEdgeX","pcbTopEdgeY","pcbBottomEdgeY","pcbRotation","schRotation"]);function safeSerialize(value,seen=new WeakSet){if(value===null)return"null";if(value===void 0)return"undefined";let type=typeof value;if(type==="string")return`"${value}"`;if(type==="number"||type==="boolean")return String(value);if(type==="function")return"[function]";if(type==="symbol")return"[symbol]";if(type==="object"){if(seen.has(value))return"[circular]";if(seen.add(value),value.$$typeof!==void 0){let elementType=typeof value.type=="string"?value.type:value.type?.name||"[component]",propsStr=value.props?safeSerialize(value.props,seen):"{}";return`ReactElement(${elementType},${propsStr})`}return Array.isArray(value)?`[${value.map(v23=>safeSerialize(v23,seen)).join(",")}]`:`{${Object.keys(value).sort().map(k23=>`${k23}:${safeSerialize(value[k23],seen)}`).join(",")}}`}return String(value)}function getHashableProps(props){let result={},keys=Object.keys(props).sort();for(let key of keys)!EXCLUDED_PROPS.has(key)&&props[key]!==void 0&&(result[key]=props[key]);return result}function getChildrenHashData(children){return children.map(child=>({componentName:child.componentName,props:getHashableProps(child.props??{}),children:getChildrenHashData(child.children)}))}function fnv1aHash(str10){let hash=2166136261;for(let i23=0;i23<str10.length;i23++)hash^=str10.charCodeAt(i23),hash=Math.imul(hash,16777619);return hash>>>0}function computeHash(data){let serialized=safeSerialize(data),hash1=fnv1aHash(serialized),hash2=fnv1aHash(serialized+hash1.toString());return hash1.toString(16).padStart(8,"0")+hash2.toString(16).padStart(8,"0")}function Subcircuit_getSubcircuitPropHash(subcircuit){let hashableData={props:getHashableProps(subcircuit.props??{}),children:getChildrenHashData(subcircuit.children)};return computeHash(hashableData)}var getBoardCircuitJsonForDrc=board=>{let{db:db22}=board.root;if(!db22.pcb_panel.list().length)return db22.subtree({subcircuit_id:board.subcircuit_id}).toArray();let boardSubcircuitIds=new Set([board.subcircuit_id,...getDescendantSubcircuitIds2(db22,board.subcircuit_id)]),boardCircuitJson=db22.toArray().filter(element2=>element2.type==="pcb_panel"?!1:element2.type==="pcb_board"?element2.pcb_board_id===board.pcb_board_id:"subcircuit_id"in element2&&element2.subcircuit_id?boardSubcircuitIds.has(element2.subcircuit_id):!0);return su(boardCircuitJson).subtree({subcircuit_id:board.subcircuit_id}).toArray()},Board_updatePcbDesignRuleChecks=board=>{let{db:db22}=board.root,routingDisabled=board.root?.pcbRoutingDisabled||board.getInheritedProperty("routingDisabled"),pcbDisabled=board.root?.pcbDisabled,schematicDisabled=board.root?.schematicDisabled,drcChecksDisabled=board.root?.platform?.drcChecksDisabled??board.getInheritedProperty("drcChecksDisabled");if(drcChecksDisabled){board._drcChecksComplete=!0;return}let netlistDrcChecksDisabled=board.root?.platform?.netlistDrcChecksDisabled??board.getInheritedProperty("netlistDrcChecksDisabled"),placementDrcChecksDisabled=board.root?.platform?.placementDrcChecksDisabled??board.getInheritedProperty("placementDrcChecksDisabled"),routingDrcChecksDisabled=board.root?.platform?.routingDrcChecksDisabled??board.getInheritedProperty("routingDrcChecksDisabled"),shouldRunNetlistChecks=!drcChecksDisabled&&!netlistDrcChecksDisabled,shouldRunSchematicChecks=!drcChecksDisabled&&!schematicDisabled,shouldRunPlacementChecks=!drcChecksDisabled&&!pcbDisabled&&!placementDrcChecksDisabled,shouldRunRoutingChecks=!drcChecksDisabled&&!pcbDisabled&&!routingDisabled&&!routingDrcChecksDisabled,fabricatorEngine4=board.root?.platform?.fabricatorEngine,fabricatorPreset=board._parsedProps.fabricatorPreset,shouldRunFabricatorChecks=!drcChecksDisabled&&!pcbDisabled&&!!fabricatorEngine4&&!!fabricatorPreset;if((shouldRunRoutingChecks||shouldRunFabricatorChecks)&&board._hasIncompleteAsyncEffectsInSubtreeForPhase("PcbTraceRender"))return;let hasTracesToRoute=board._hasTracesToRoute();if((shouldRunRoutingChecks||shouldRunFabricatorChecks)&&hasTracesToRoute&&!board._areChildSubcircuitsRouted()||board._drcChecksComplete||board._drcChecksInProgress)return;let runDrcChecks2=async circuitJson=>{let checksToRun=[],queueCheck=(checkName,check)=>{checksToRun.push(Promise.resolve().then(check).catch(error2=>{let cause=error2 instanceof Error?error2.message:String(error2);return db22.source_runtime_error.insert({error_type:"source_runtime_error",phase_name:"PcbDesignRuleChecks",message:`DRC could not complete (${checkName}): ${cause}`}),[]}))},pcbBoardId=board.pcb_board_id;if(shouldRunFabricatorChecks&&fabricatorEngine4&&fabricatorPreset&&pcbBoardId&&queueCheck("fabricator",()=>fabricatorEngine4.runDrcChecks({circuitJson,fabricatorPreset,pcbBoardId})),shouldRunRoutingChecks&&queueCheck("routing",()=>runAllRoutingChecks(circuitJson).then(results=>results.filter(result=>!board._isExpectedCastellatedHoleDrcError(result)))),shouldRunPlacementChecks){let existingPlacementDiagnostics=db22.toArray();queueCheck("placement",()=>runAllPlacementChecks(circuitJson,{consolidateOverlaps:!1}).then(results=>consolidatePcbOverlapErrors(circuitJson,results.filter(result=>!board._isExpectedCastellatedHoleDrcError(result))).filter(result=>!existingPlacementDiagnostics.some(existing=>existing.type===result.type&&"message"in existing&&existing.message===result.message))))}if(shouldRunNetlistChecks&&queueCheck("netlist",()=>runAllNetlistChecks(circuitJson)),shouldRunSchematicChecks&&queueCheck("schematic",()=>runAllSchematicChecks(circuitJson)),!drcChecksDisabled)for(let drcCheck of board.selectAll("drccheck"))queueCheck(drcCheck.getString(),()=>drcCheck.runCustomDrcCheck(circuitJson));let checkResults=await Promise.all(checksToRun);db22.insertAll(consolidatePcbOverlapErrors(circuitJson,dedupePcbDrcErrors(checkResults.flat())))},subcircuitCircuitJson=getBoardCircuitJsonForDrc(board);board._drcChecksInProgress=!0,board._queueAsyncEffect("board:drc-checks",async()=>{try{await runDrcChecks2(subcircuitCircuitJson),board._drcChecksComplete=!0}finally{board._drcChecksInProgress=!1}})},Board_doInitialPcbCopperPourCleanup=board=>{if(!board.root||board.root.pcbDisabled)return;let{db:db22}=board.root;if(db22.pcb_copper_pour.list().length===0)return;let circuitJson=db22.subtree({subcircuit_id:board.subcircuit_id}).toArray();if(db22.pcb_autorouting_error.list().length>0||!circuitJson.some(element2=>element2.type==="pcb_copper_pour"))return;let{floatingPourIds,floatingViaIds}=findFloatingCopper(circuitJson,board._generatedStitchingViaIds);for(let pourId of floatingPourIds)db22.pcb_copper_pour.delete(pourId);for(let viaId of floatingViaIds)board._generatedStitchingViaIds.has(viaId)&&db22.pcb_via.delete(viaId);for(let trace of db22.pcb_trace.list())trace.route.some(point12=>"copper_pour_id"in point12&&point12.copper_pour_id&&floatingPourIds.has(point12.copper_pour_id))&&db22.pcb_trace.update(trace.pcb_trace_id,{route:trace.route.map(point12=>{if(!("copper_pour_id"in point12)||!point12.copper_pour_id||!floatingPourIds.has(point12.copper_pour_id))return point12;let{copper_pour_id,is_inside_copper_pour,...wireOrVia}=point12;return wireOrVia})})},resetPcbTraceRenderInSubtree=renderable=>{renderable._pcbTraceRenderWaitingForPlacementChecks&&(renderable.renderPhaseStates.PcbTraceRender.initialized=!1,renderable.renderPhaseStates.PcbTraceRender.dirty=!1,renderable._pcbTraceRenderWaitingForPlacementChecks=!1);for(let child of renderable.children)resetPcbTraceRenderInSubtree(child)},Board_doInitialPcbPlacementDesignRuleChecks=board=>{if(board.root?.pcbDisabled)return;let placementDrcChecksDisabled=board.root?.platform?.placementDrcChecksDisabled??board.getInheritedProperty("placementDrcChecksDisabled"),drcChecksDisabled=board.root?.platform?.drcChecksDisabled??board.getInheritedProperty("drcChecksDisabled");if(board._pcbPlacementDrcErrorCount=null,board._pcbPlacementDrcCheckError=null,board._pcbPlacementDrcChecksPending=!1,placementDrcChecksDisabled||drcChecksDisabled){board._pcbPlacementDrcErrorCount=0;return}let{db:db22}=board.root,subcircuitCircuitJson=getBoardCircuitJsonForDrc(board),existingPlacementDiagnostics=db22.toArray();board._pcbPlacementDrcChecksPending=!0,board._queueAsyncEffect("board:pre-route-placement-checks",async()=>{try{let placementCheckResults=await runAllPlacementChecks(subcircuitCircuitJson,{consolidateOverlaps:!1}),relevantPlacementCheckResults=consolidatePcbOverlapErrors(subcircuitCircuitJson,placementCheckResults.filter(result=>!board._isExpectedCastellatedHoleDrcError(result))),newPlacementDiagnostics=relevantPlacementCheckResults.filter(result=>!existingPlacementDiagnostics.some(existing=>existing.type===result.type&&"message"in existing&&existing.message===result.message));db22.insertAll(newPlacementDiagnostics),board._pcbPlacementDrcErrorCount=relevantPlacementCheckResults.filter(result=>result.type.endsWith("_error")).length}catch(error2){board._pcbPlacementDrcCheckError=error2 instanceof Error?error2.message:String(error2)}finally{board._pcbPlacementDrcChecksPending=!1,resetPcbTraceRenderInSubtree(board)}})};function Board_doInitialPcbStackupRender(board,importedPcbBoard){let{db:db22}=board.root,{pcb_board_id,subcircuit_id}=board;if(!pcb_board_id||db22.pcb_stackup.getWhere({pcb_board_id}))return;let importedStackup=board._parsedProps.circuitJson?.find(element2=>element2.type==="pcb_stackup"&&element2.pcb_board_id===importedPcbBoard?.pcb_board_id),layers=importedStackup?.layers,{fabricatorPreset}=board._parsedProps;if(!layers&&fabricatorPreset){let{num_layers,thickness:boardThickness,material:material2="fr4"}=importedPcbBoard??db22.pcb_board.get(pcb_board_id),thickness=boardThickness??board.boardThickness;if(layers=getJlcStackup({num_layers,thickness,material:material2})?.layers,!layers){let supportedThicknesses=[...new Set(jlcStackups.filter(stackup=>stackup.num_layers===num_layers&&stackup.material===material2).map(stackup=>stackup.thickness))].sort((a23,b23)=>a23-b23);db22.source_property_ignored_warning.insert({source_component_id:board.source_group_id??"",property_name:"fabricatorPreset",error_type:"source_property_ignored_warning",subcircuit_id:subcircuit_id??void 0,message:`fabricatorPreset "${fabricatorPreset}" has no stackup template for a ${num_layers}-layer ${thickness}mm ${material2} board, so no pcb_stackup was emitted. `+(supportedThicknesses.length>0?`Supported thicknesses for ${num_layers}-layer ${material2}: ${supportedThicknesses.map(t48=>`${t48}mm`).join(", ")}. Set thickness on <board> to one of these.`:`No ${num_layers}-layer ${material2} stackups are supported.`)})}}layers&&db22.pcb_stackup.insert({plated_hole_copper_thickness:importedStackup?.plated_hole_copper_thickness,pcb_board_id,subcircuit_id:subcircuit_id??void 0,layers:structuredClone(layers)})}var CASTELLATED_HOLE_ENDPOINT_TOLERANCE_MM=1e-6,getConnectionTargets2=connectsTo=>connectsTo?Array.isArray(connectsTo)?connectsTo:[connectsTo]:[],BoardCastellatedHole=class _BoardCastellatedHole extends PlatedHole{constructor(outlinePoint,outlinePointIndex){let name=`castellated_hole_${outlinePointIndex+1}`,connectionTargets=getConnectionTargets2(outlinePoint.connectsTo),holeDiameter=distance4.parse(outlinePoint.holeDiameter),padDiameter=distance4.parse(outlinePoint.padDiameter);super({shape:"circle",holeDiameter,outerDiameter:padDiameter,portHints:[name]});__publicField(this,"outlinePointIndex");__publicField(this,"holeDiameter");__publicField(this,"padDiameter");__publicField(this,"port");__publicField(this,"trace");this.outlinePointIndex=outlinePointIndex,this.holeDiameter=holeDiameter,this.padDiameter=padDiameter,this.port=connectionTargets.length>0?new Port({name}):null,this.trace=this.port?new Trace({path:[`port.${name}`,...connectionTargets],displayName:`Castellated hole ${outlinePointIndex+1} connectivity`}):null}static fromBoardOutline(outline){return(outline??[]).flatMap((outlinePoint,outlinePointIndex)=>outlinePoint.isCastellatedHole?[new _BoardCastellatedHole(outlinePoint,outlinePointIndex)]:[])}_getParentBoard(){if(this.parent?.componentName!=="Board")throw new Error("A board castellated hole must be a direct board child");return this.parent}_getPositionFromBoardOutline(){let board=this._getParentBoard(),outlinePoint=(board.pcb_board_id?board.root?.db.pcb_board.get(board.pcb_board_id):null)?.outline?.[this.outlinePointIndex];if(!outlinePoint)throw new Error(`Missing emitted board outline point ${this.outlinePointIndex}`);return outlinePoint}_getGlobalPcbPositionBeforeLayout(){return this._getPositionFromBoardOutline()}doInitialPcbPrimitiveRender(){if(this.root?.pcbDisabled)return;let{db:db22}=this.root,position22=this._getPositionFromBoardOutline(),pcbPlatedHole=db22.pcb_plated_hole.insert({shape:"circle",outer_diameter:this.padDiameter,hole_diameter:this.holeDiameter,...position22,layers:this.getAvailablePcbLayers(),port_hints:this.getNameAndAliases(),subcircuit_id:this.getSubcircuit()?.subcircuit_id??void 0});this.pcb_plated_hole_id=pcbPlatedHole.pcb_plated_hole_id}syncPositionToBoardOutline(){this.pcb_plated_hole_id&&this._setPositionFromLayout(this._getPositionFromBoardOutline())}removePcbPrimitiveRender(){let{db:db22}=this.root;this.pcb_plated_hole_id&&(db22.pcb_plated_hole.delete(this.pcb_plated_hole_id),this.pcb_plated_hole_id=null),this.matchedPort?.pcb_port_id&&(db22.pcb_port.delete(this.matchedPort.pcb_port_id),this.matchedPort.pcb_port_id=null)}isExpectedBoardEdgeDrcError(result){if(!this.pcb_plated_hole_id)return!1;if(result.type==="pcb_placement_error")return result.pcb_placement_error_id===`copper_too_close_to_board_edge_${this.pcb_plated_hole_id}`;if(result.type!=="pcb_trace_error"||!result.pcb_trace_error_id.startsWith("trace_too_close_to_board_"))return!1;let segmentIndexMatch=result.pcb_trace_error_id.match(/_segment_(\d+)$/);if(!segmentIndexMatch)return!1;let pcbTrace=this.root?.db.pcb_trace.get(result.pcb_trace_id),segmentIndex=Number(segmentIndexMatch[1]),segmentEndpoints=[pcbTrace?.route[segmentIndex],pcbTrace?.route[segmentIndex+1]].flatMap(routePoint3=>routePoint3&&"x"in routePoint3&&"y"in routePoint3?[{x:routePoint3.x,y:routePoint3.y}]:[]),platedHole2=this.root?.db.pcb_plated_hole.get(this.pcb_plated_hole_id);return platedHole2?segmentEndpoints.some(endpoint=>Math.hypot(endpoint.x-platedHole2.x,endpoint.y-platedHole2.y)<=CASTELLATED_HOLE_ENDPOINT_TOLERANCE_MM):!1}},MIN_EFFECTIVE_BORDER_RADIUS_MM=.01,DEFAULT_VIA_PAD_DIAMETER_OVER_HOLE_DIAMETER_MM=.15,getRoundedRectOutline=(width10,height10,radius)=>{let w23=width10/2,h23=height10/2,r23=Math.min(radius,w23,h23);if(r23<MIN_EFFECTIVE_BORDER_RADIUS_MM)return[{x:-w23,y:-h23},{x:w23,y:-h23},{x:w23,y:h23},{x:-w23,y:h23}];let segments2=Math.max(1,Math.ceil(Math.PI/2*r23/.1)),step=Math.PI/2/segments2,outline=[];outline.push({x:-w23+r23,y:-h23}),outline.push({x:w23-r23,y:-h23});for(let i23=1;i23<=segments2;i23++){let theta=-Math.PI/2+i23*step;outline.push({x:w23-r23+r23*Math.cos(theta),y:-h23+r23+r23*Math.sin(theta)})}outline.push({x:w23,y:h23-r23});for(let i23=1;i23<=segments2;i23++){let theta=0+i23*step;outline.push({x:w23-r23+r23*Math.cos(theta),y:h23-r23+r23*Math.sin(theta)})}outline.push({x:-w23+r23,y:h23});for(let i23=1;i23<=segments2;i23++){let theta=Math.PI/2+i23*step;outline.push({x:-w23+r23+r23*Math.cos(theta),y:h23-r23+r23*Math.sin(theta)})}outline.push({x:-w23,y:-h23+r23});for(let i23=1;i23<=segments2;i23++){let theta=Math.PI+i23*step;outline.push({x:-w23+r23+r23*Math.cos(theta),y:-h23+r23+r23*Math.sin(theta)})}return outline},Board=class extends Group{constructor(props){super(props);__publicField(this,"pcbFold");__publicField(this,"pcb_board_id",null);__publicField(this,"source_board_id",null);__publicField(this,"_drcChecksComplete",!1);__publicField(this,"_drcChecksInProgress",!1);__publicField(this,"_connectedSchematicPortPairs",new Set);__publicField(this,"_panelPositionOffset",null);__publicField(this,"_castellatedHoles");__publicField(this,"_generatedStitchingViaIds",new Set);this._castellatedHoles=BoardCastellatedHole.fromBoardOutline(this._parsedProps.outline);for(let castellatedHole of this._castellatedHoles)castellatedHole.port&&this.add(castellatedHole.port),this.add(castellatedHole),castellatedHole.trace&&this.add(castellatedHole.trace)}doInitialCadModelRender(){this.root?.pcbDisabled||(resolveBoardMotorMount(this),super.doInitialCadModelRender())}doInitialPcbFlexRender(){if(!this.pcb_board_id)return;let bends=this.root.db.pcb_bend.list().filter(bend=>bend.pcb_board_id===this.pcb_board_id);if(this.pcbFold=void 0,!bends.length)return;let pcbBoard=this.root.db.pcb_board.get(this.pcb_board_id),foldResult=tryCreatePcbFold(bends,this.boardThickness,{outline:pcbBoard.outline?.map(point12=>({x:point12.x-pcbBoard.center.x,y:point12.y-pcbBoard.center.y}))});foldResult.ok?this.pcbFold=foldResult.value:this.root.db.pcb_placement_error.insert({error_type:"pcb_placement_error",subcircuit_id:this.subcircuit_id??void 0,message:`Unable to fold PCB board ${this._parsedProps.name??"unnamed board"}; CAD remains flat: ${getReadablePcbFoldIssueMessage(foldResult.issue,bends)}`})}get isSubcircuit(){return!0}get isGroup(){return!0}get config(){return{componentName:"Board",zodProps:boardProps}}get boardThickness(){return this._parsedProps.thickness??1.6}get allLayers(){return getBoardAvailableLayers(this._parsedProps.layers??2)}_getSubcircuitLayerCount(){return this._parsedProps.layers??2}_computePcbGlobalTransformBeforeLayout(){if(this._panelPositionOffset){let parentTransform=this.parent?._computePcbGlobalTransformBeforeLayout?.()??{a:1,b:0,c:0,d:1,e:0,f:0};return compose3(parentTransform,translate8(this._panelPositionOffset.x,this._panelPositionOffset.y))}return super._computePcbGlobalTransformBeforeLayout()}_getBoardCalcVariables(){let{_parsedProps:props}=this;if((props.width==null||props.height==null)&&!props.outline)return{};let dbBoard=this.pcb_board_id?this.root?.db.pcb_board.get(this.pcb_board_id):null,width10=dbBoard?.width??props.width,height10=dbBoard?.height??props.height;if((width10==null||height10==null)&&props.outline?.length){let outlineBounds=getBoundsFromPoints3(props.outline);outlineBounds&&(width10??(width10=outlineBounds.maxX-outlineBounds.minX),height10??(height10=outlineBounds.maxY-outlineBounds.minY))}let{pcbX,pcbY}=this.getResolvedPcbPositionProp(),center2=dbBoard?.center??{x:pcbX+(props.outlineOffsetX??0),y:pcbY+(props.outlineOffsetY??0)},resolvedWidth=width10??0,resolvedHeight=height10??0;return{"board.minX":center2.x-resolvedWidth/2,"board.maxX":center2.x+resolvedWidth/2,"board.minY":center2.y-resolvedHeight/2,"board.maxY":center2.y+resolvedHeight/2}}doInitialPcbBoardAutoSize(){if(this.root?.pcbDisabled||!this.pcb_board_id)return;let{db:db22}=this.root,{_parsedProps:props}=this,globalPos=this._getGlobalPcbPositionBeforeLayout(),pcbBoard=db22.pcb_board.get(this.pcb_board_id);if(pcbBoard?.width&&pcbBoard?.height||pcbBoard?.outline&&pcbBoard.outline.length>0)return;let minX=1/0,minY=1/0,maxX=-1/0,maxY=-1/0,descendantIds=getDescendantSubcircuitIds2(db22,this.subcircuit_id),allowedSubcircuitIds=new Set([this.subcircuit_id,...descendantIds]),allPcbComponents=db22.pcb_component.list().filter(c23=>c23.subcircuit_id&&allowedSubcircuitIds.has(c23.subcircuit_id)),allPcbGroups=db22.pcb_group.list().filter(g23=>g23.subcircuit_id&&allowedSubcircuitIds.has(g23.subcircuit_id)),hasComponents=!1,updateBounds=(center22,width10,height10)=>{width10===0||height10===0||(hasComponents=!0,minX=Math.min(minX,center22.x-width10/2),minY=Math.min(minY,center22.y-height10/2),maxX=Math.max(maxX,center22.x+width10/2),maxY=Math.max(maxY,center22.y+height10/2))};for(let pcbComponent of allPcbComponents)updateBounds(pcbComponent.center,pcbComponent.width,pcbComponent.height);for(let pcbGroup of allPcbGroups){let width10=pcbGroup.width??0,height10=pcbGroup.height??0;if(pcbGroup.outline&&pcbGroup.outline.length>0){let bounds=getBoundsFromPoints3(pcbGroup.outline);bounds&&(width10=bounds.maxX-bounds.minX,height10=bounds.maxY-bounds.minY)}updateBounds(pcbGroup.center,width10,height10)}if(props.boardAnchorPosition){let{x:x23,y:y23}=props.boardAnchorPosition;minX=Math.min(minX,x23),minY=Math.min(minY,y23),maxX=Math.max(maxX,x23),maxY=Math.max(maxY,y23)}let padding=2,computedWidth=hasComponents?maxX-minX+padding*2:0,computedHeight=hasComponents?maxY-minY+padding*2:0,center2={x:hasComponents?(minX+maxX)/2+(props.outlineOffsetX??0):(props.outlineOffsetX??0)+globalPos.x,y:hasComponents?(minY+maxY)/2+(props.outlineOffsetY??0):(props.outlineOffsetY??0)+globalPos.y},finalWidth=props.width??computedWidth,finalHeight=props.height??computedHeight,outline=props.outline;!outline&&props.borderRadius!=null&&finalWidth>0&&finalHeight>0&&(outline=getRoundedRectOutline(finalWidth,finalHeight,props.borderRadius).map(point12=>({x:point12.x+center2.x,y:point12.y+center2.y})));let update2={width:finalWidth,height:finalHeight,center:center2};outline&&(update2.outline=props.outline?outline.map(point12=>({x:point12.x+(props.outlineOffsetX??0),y:point12.y+(props.outlineOffsetY??0)})):outline),db22.pcb_board.update(this.pcb_board_id,update2)}updatePcbBoardAutoSize(){this.doInitialPcbBoardAutoSize()}_addBoardInformationToSilkscreen(){let platform=this.root?.platform;if(!platform?.printBoardInformationToSilkscreen)return;let pcbBoard=this.root.db.pcb_board.get(this.pcb_board_id);if(!pcbBoard)return;let boardInformation=[];if(platform.projectName&&boardInformation.push(platform.projectName),platform.version&&boardInformation.push(`v${platform.version}`),platform.url&&boardInformation.push(platform.url),boardInformation.length===0)return;let text4=boardInformation.join(`
1051
- `),position22={x:pcbBoard.center.x+pcbBoard.width/2-.25,y:pcbBoard.center.y-pcbBoard.height/2+1};this.root.db.pcb_silkscreen_text.insert({pcb_component_id:this.pcb_board_id,layer:"top",font:"tscircuit2024",font_size:.45,text:text4,ccw_rotation:0,anchor_alignment:"bottom_right",anchor_position:position22})}doInitialSourceRender(){let nestedBoard=this.getDescendants().find(d23=>d23.lowercaseComponentName==="board");if(nestedBoard)throw new Error(`Nested boards are not supported: found board "${nestedBoard.name}" inside board "${this.name}"`);super.doInitialSourceRender();let{db:db22}=this.root,source_board23=db22.source_board.insert({source_group_id:this.source_group_id,title:this.props.title||this.props.name});this.source_board_id=source_board23.source_board_id}getSubcircuitPropHash(){return Subcircuit_getSubcircuitPropHash(this)}doInitialRenderIsolatedSubcircuits(){Subcircuit_doInitialRenderIsolatedSubcircuits(this)}doInitialInflateSubcircuitCircuitJson(){let isolatedJson=this._isolatedCircuitJson;if(isolatedJson){this._isInflatedFromCircuitJson=!0,this._isolatedCircuitJson=null,inflateCircuitJson(this,isolatedJson,[]);return}let{circuitJson,children}=this._parsedProps;circuitJson&&(this._isInflatedFromCircuitJson=!0),inflateCircuitJson(this,circuitJson,children)}doInitialPcbComponentRender(){if(this.root?.pcbDisabled)return;let{db:db22}=this.root,{_parsedProps:props}=this,pcbBoardFromCircuitJson=props.circuitJson?.find(elm=>elm.type==="pcb_board"),viaTenting=getViaTenting(props.defaultViaTenting),rawProps=this.props,resolvedIsViaInPadAllowed=rawProps.isViaInPadAllowed??pcbBoardFromCircuitJson?.is_via_in_pad_allowed,resolvedAllowBlindAndBuriedVias=rawProps.allowBlindAndBuriedVias??pcbBoardFromCircuitJson?.allow_blind_and_buried_vias,computedWidth=props.width??pcbBoardFromCircuitJson?.width??0,computedHeight=props.height??pcbBoardFromCircuitJson?.height??0,globalPos=this._getGlobalPcbPositionBeforeLayout(),center2={x:globalPos.x+(props.outlineOffsetX??0),y:globalPos.y+(props.outlineOffsetY??0)},{boardAnchorPosition,boardAnchorAlignment}=props;if(boardAnchorPosition&&(center2=getBoardCenterFromAnchor({boardAnchorPosition,boardAnchorAlignment:boardAnchorAlignment??"center",width:computedWidth,height:computedHeight})),props.outline){let xValues=props.outline.map(point12=>point12.x),yValues=props.outline.map(point12=>point12.y),minX=Math.min(...xValues),maxX=Math.max(...xValues),minY=Math.min(...yValues),maxY=Math.max(...yValues);computedWidth=maxX-minX,computedHeight=maxY-minY}let outline=props.outline;!outline&&props.borderRadius!=null&&computedWidth>0&&computedHeight>0&&(outline=getRoundedRectOutline(computedWidth,computedHeight,props.borderRadius).map(point12=>({x:point12.x+center2.x,y:point12.y+center2.y})));let outlineTranslation={x:0,y:0};if(props.outline&&outline&&outline.length>0&&(this.parent?.lowercaseComponentName==="panel"||this.parent?.lowercaseComponentName==="subpanel")){let outlineBounds=getBoundsFromPoints3(outline);if(outlineBounds){let outlineCenterX=(outlineBounds.minX+outlineBounds.maxX)/2,outlineCenterY=(outlineBounds.minY+outlineBounds.maxY)/2;outlineTranslation={x:center2.x-outlineCenterX,y:center2.y-outlineCenterY}}}let subcircuitProps2=this.getSubcircuit()._parsedProps,pcbStyle3=this.getInheritedMergedProperty("pcbStyle"),styledViaDimensions=getViaDiameterDefaults(pcbStyle3),configuredViaHoleDiameter=subcircuitProps2.minViaHoleDiameter??(pcbStyle3?.viaHoleDiameter!==void 0?styledViaDimensions.holeDiameter:void 0),resolvedMinViaHoleDiameter=configuredViaHoleDiameter??jlcMinTolerances2.min_via_hole_diameter,resolvedMinViaPadDiameter=subcircuitProps2.minViaPadDiameter??(pcbStyle3?.viaPadDiameter!==void 0?styledViaDimensions.padDiameter:configuredViaHoleDiameter!==void 0?configuredViaHoleDiameter+DEFAULT_VIA_PAD_DIAMETER_OVER_HOLE_DIAMETER_MM:jlcMinTolerances2.min_via_pad_diameter),pcb_board23=db22.pcb_board.insert({source_board_id:this.source_board_id,subcircuit_id:this.subcircuit_id??void 0,center:center2,default_via_tented_on_top:viaTenting.tented_on_top??pcbBoardFromCircuitJson?.default_via_tented_on_top,default_via_tented_on_bottom:viaTenting.tented_on_bottom??pcbBoardFromCircuitJson?.default_via_tented_on_bottom,thickness:this.boardThickness,num_layers:this.allLayers.length,width:computedWidth,height:computedHeight,outline:props.outline?outline?.map(point12=>({x:point12.x+(props.outlineOffsetX??0)+outlineTranslation.x,y:point12.y+(props.outlineOffsetY??0)+outlineTranslation.y})):outline,material:props.material,...resolvedIsViaInPadAllowed!==void 0&&{is_via_in_pad_allowed:resolvedIsViaInPadAllowed},...resolvedAllowBlindAndBuriedVias!==void 0&&{allow_blind_and_buried_vias:resolvedAllowBlindAndBuriedVias},...props.solderMaskColor!==void 0&&{solder_mask_color:props.solderMaskColor},...props.silkscreenColor!==void 0&&{silkscreen_color:props.silkscreenColor},min_trace_width:subcircuitProps2.minTraceWidth??jlcMinTolerances2.min_trace_width,min_via_hole_diameter:resolvedMinViaHoleDiameter,min_via_pad_diameter:resolvedMinViaPadDiameter,min_via_hole_edge_to_via_hole_edge_clearance:subcircuitProps2.minViaHoleEdgeToViaHoleEdgeClearance??jlcMinTolerances2.min_via_hole_edge_to_via_hole_edge_clearance,min_via_edge_to_pad_edge_clearance:subcircuitProps2.minViaEdgeToPadEdgeClearance??jlcMinTolerances2.min_via_edge_to_pad_edge_clearance,min_trace_to_hole_edge_clearance:subcircuitProps2.minTraceToHoleEdgeClearance??jlcMinTolerances2.min_trace_to_hole_edge_clearance,min_trace_to_pad_edge_clearance:subcircuitProps2.minTraceToPadEdgeClearance??jlcMinTolerances2.min_trace_to_pad_edge_clearance,min_pad_edge_to_pad_edge_clearance:subcircuitProps2.minPadEdgeToPadEdgeClearance??jlcMinTolerances2.min_pad_edge_to_pad_edge_clearance,min_plated_hole_drill_edge_to_drill_edge_clearance:subcircuitProps2.minPlatedHoleDrillEdgeToDrillEdgeClearance??jlcMinTolerances2.min_plated_hole_drill_edge_to_drill_edge_clearance,min_board_edge_clearance:subcircuitProps2.minBoardEdgeClearance??jlcMinTolerances2.min_board_edge_clearance});this.pcb_board_id=pcb_board23.pcb_board_id,Board_doInitialPcbStackupRender(this,pcbBoardFromCircuitJson),this._addBoardInformationToSilkscreen()}removePcbComponentRender(){let{db:db22}=this.root;this.pcb_board_id&&(db22.pcb_board.delete(this.pcb_board_id),this.pcb_board_id=null)}doInitialPcbDesignRuleChecks(){super.doInitialPcbDesignRuleChecks(),this.updatePcbDesignRuleChecks()}doInitialPcbPlacementDesignRuleChecks(){Board_doInitialPcbPlacementDesignRuleChecks(this)}doInitialPcbCopperPourCleanup(){Board_doInitialPcbCopperPourCleanup(this)}updatePcbDesignRuleChecks(){Board_updatePcbDesignRuleChecks(this)}runRenderPhaseForChildren(phase){this.root?.emit("board:renderPhaseStarted",{renderId:this._renderId,phase}),super.runRenderPhaseForChildren(phase)}_repositionOnPcb(position22){let{db:db22}=this.root,pcbBoard=this.pcb_board_id?db22.pcb_board.get(this.pcb_board_id):null,oldPos=pcbBoard?.center;if(!oldPos){this.pcb_board_id&&db22.pcb_board.update(this.pcb_board_id,{center:position22});return}let deltaX=position22.x-oldPos.x,deltaY=position22.y-oldPos.y;if(!(Math.abs(deltaX)<1e-6&&Math.abs(deltaY)<1e-6)&&this.pcb_board_id&&(db22.pcb_board.update(this.pcb_board_id,{center:position22}),pcbBoard?.outline)){let outlineBounds=getBoundsFromPoints3(pcbBoard.outline);if(outlineBounds){let oldOutlineCenter={x:(outlineBounds.minX+outlineBounds.maxX)/2,y:(outlineBounds.minY+outlineBounds.maxY)/2},outlineDeltaX=position22.x-oldOutlineCenter.x,outlineDeltaY=position22.y-oldOutlineCenter.y,newOutline=pcbBoard.outline.map(p23=>({x:p23.x+outlineDeltaX,y:p23.y+outlineDeltaY}));db22.pcb_board.update(this.pcb_board_id,{outline:newOutline});for(let castellatedHole of this._castellatedHoles)castellatedHole.syncPositionToBoardOutline()}}}_isExpectedCastellatedHoleDrcError(result){return this._castellatedHoles.some(castellatedHole=>castellatedHole.isExpectedBoardEdgeDrcError(result))}},Subcircuit=class extends Group{constructor(props){super({...props,subcircuit:!0})}getSubcircuitPropHash(){return Subcircuit_getSubcircuitPropHash(this)}doInitialRenderIsolatedSubcircuits(){Subcircuit_doInitialRenderIsolatedSubcircuits(this)}doInitialCreateNetsFromProps(){super.doInitialCreateNetsFromProps(),this._createTracesForExposedConnections()}_createTracesForExposedConnections(){let exposedNets=this._getNetNamesToExpose();if(!exposedNets?.length)return;let parentSubcircuit=this.parent?.getSubcircuit?.();if(parentSubcircuit&&this.name)for(let exposedNetName of exposedNets){let netName=normalizeExposedNetName(exposedNetName),parentNetSelector=`> net.${netName}`,childNetSelector=`.${this.name} > net.${netName}`;if(parentSubcircuit.children.find(child=>child instanceof Net&&child._parsedProps.name===netName)||parentSubcircuit.add(new Net({name:netName})),parentSubcircuit.children.find(child=>{if(!(child instanceof Trace)||!child._exposesSubcircuitConnection)return!1;let childProps=child._parsedProps;return childProps.from===childNetSelector&&childProps.to===parentNetSelector}))continue;let trace=new Trace({from:childNetSelector,to:parentNetSelector,displayName:netName});trace._exposesSubcircuitConnection=!0,parentSubcircuit.add(trace)}}_getNetNamesToExpose(){let explicitExposedNets=this._parsedProps.exposedNets??[];if(!this._parsedProps.exposeNets)return explicitExposedNets;let childNetNames=this.selectAll("net").filter(net=>net instanceof Net&&net.getSubcircuit()===this).map(net=>net._parsedProps.name);return Array.from(new Set([...explicitExposedNets,...childNetNames]))}doInitialInflateSubcircuitCircuitJson(){let isolatedJson=this._isolatedCircuitJson;if(isolatedJson){this._isInflatedFromCircuitJson=!0,this._isolatedCircuitJson=null,inflateCircuitJson(this,isolatedJson,[]);return}let{circuitJson,children}=this._parsedProps;circuitJson&&(this._isInflatedFromCircuitJson=!0),inflateCircuitJson(this,circuitJson,children)}},normalizeExposedNetName=netName=>netName.startsWith("net.")?netName.slice(4):netName,MountedBoard=class extends Subcircuit{constructor(){super(...arguments);__publicField(this,"pcb_board_id",null);__publicField(this,"_connectedSchematicPortPairs",new Set)}get config(){return{componentName:"MountedBoard",zodProps:mountedboardProps}}get boardThickness(){return 1.6}get allLayers(){return["top","bottom"]}_getBoardCalcVariables(){return this._findCarrierBoard()?._getBoardCalcVariables()??{}}_findCarrierBoard(){let current23=this.parent;for(;current23;){if(current23 instanceof Board)return current23;current23=current23.parent}return null}doInitialPcbComponentRender(){if(this.root?.pcbDisabled)return;let{db:db22}=this.root,{_parsedProps:props}=this,globalPos=this._getGlobalPcbPositionBeforeLayout(),pcb_board23=db22.pcb_board.insert({center:{x:globalPos.x,y:globalPos.y},width:props.width??0,height:props.height??0,is_mounted_to_carrier_board:!0});this.pcb_board_id=pcb_board23.pcb_board_id}doInitialPcbBoardAutoSize(){if(!this.pcb_board_id||!this.root)return;let carrierBoard=this._findCarrierBoard();carrierBoard?.pcb_board_id&&this.root.db.pcb_board.update(this.pcb_board_id,{carrier_pcb_board_id:carrierBoard.pcb_board_id})}},PanelTab=class extends PrimitiveComponent{get config(){return{componentName:"PanelTab",zodProps:panelTabProps}}doInitialPcbComponentRender(){if(!this.root?.pcbDisabled&&this.parent?.componentName!=="Panel"&&this.parent?.componentName!=="Subpanel")throw new Error("<paneltab> must be a direct child of <panel> or <subpanel>")}},PanelTabKeepout=class extends PrimitiveComponent{get config(){return{componentName:"PanelTabKeepout",zodProps:panelTabKeepoutProps}}doInitialPcbComponentRender(){if(!this.root?.pcbDisabled&&this.parent?.componentName!=="Panel"&&this.parent?.componentName!=="Subpanel")throw new Error("<paneltabkeepout> must be a direct child of <panel> or <subpanel>")}};function getPointAlongOutline(edges,{perimeterDistance,leftOffsetMm=0}){let perimeter=edges.at(-1).perimeterStart+edges.at(-1).length,wrappedDistance=(perimeterDistance%perimeter+perimeter)%perimeter,edge=edges.find(outlineEdge=>wrappedDistance<=outlineEdge.perimeterStart+outlineEdge.length)??edges.at(-1),ccwRotationDegrees=Math.atan2(edge.end.y-edge.start.y,edge.end.x-edge.start.x)*180/Math.PI;return applyToPoint3(compose3(translate8(edge.start.x,edge.start.y),rotateDEG3(ccwRotationDegrees)),{x:wrappedDistance-edge.perimeterStart,y:leftOffsetMm})}function getOutwardSlotBoundary(route2,options){let normals=route2.slice(1).map((end,routeIndex)=>{let start=route2[routeIndex],length93=Math.hypot(end.x-start.x,end.y-start.y);return{x:options.winding*(end.y-start.y)/length93,y:-options.winding*(end.x-start.x)/length93}});return route2.flatMap((position22,routeIndex)=>{let before=normals[Math.max(0,routeIndex-1)],after=normals[Math.min(normals.length-1,routeIndex)],denominator=1+before.x*after.x+before.y*after.y;return denominator<1e-8?[before,after].map(normal=>applyToPoint3(translate8(normal.x*options.width,normal.y*options.width),position22)):[applyToPoint3(translate8((before.x+after.x)*options.width/denominator,(before.y+after.y)*options.width/denominator),position22)]})}function getOutlineSpan({edges,startPerimeterDistance,endPerimeterDistance}){let perimeter=edges.at(-1).perimeterStart+edges.at(-1).length,route2=[getPointAlongOutline(edges,{perimeterDistance:startPerimeterDistance})];for(let lap of[0,1])for(let edge of edges){let vertexDistance=edge.perimeterStart+lap*perimeter;vertexDistance>startPerimeterDistance+1e-9&&vertexDistance<endPerimeterDistance-1e-9&&route2.push(edge.start)}return route2.push(getPointAlongOutline(edges,{perimeterDistance:endPerimeterDistance})),route2}function generateContinuousPanelRoutingSlots(outline,options){let edges=[],perimeter=0,twiceSignedArea=0;for(let outlineIndex=0;outlineIndex<outline.length;outlineIndex++){let start=outline[outlineIndex],end=outline[(outlineIndex+1)%outline.length],length93=Math.hypot(end.x-start.x,end.y-start.y);length93<1e-9||(edges.push({start,end,length:length93,perimeterStart:perimeter}),perimeter+=length93,twiceSignedArea+=start.x*end.y-end.x*start.y)}if(edges.length<3||Math.abs(twiceSignedArea)<1e-9)return{tabCutouts:[],mouseBites:[],tabBridges:[]};let requestedGapLength=options.gapLength,tabCenters=edges.filter(edge=>edge.length>=requestedGapLength+2*options.cutoutWidth).map(edge=>edge.perimeterStart+edge.length/2);tabCenters.length<2&&(tabCenters=[0,1,2,3].map(quarter=>(quarter+.5)*perimeter/4));let gapLength=Math.min(requestedGapLength,perimeter/(2*tabCenters.length)),tabCutouts=[],mouseBites=[],tabBridges=[];for(let tabIndex=0;tabIndex<tabCenters.length;tabIndex++){let tabCenter=tabCenters[tabIndex],nextTabCenter=tabCenters[(tabIndex+1)%tabCenters.length]+(tabIndex===tabCenters.length-1?perimeter:0),routeStart=tabCenter+gapLength/2,routeEnd=nextTabCenter-gapLength/2,route2=getOutlineSpan({edges,startPerimeterDistance:routeStart,endPerimeterDistance:routeEnd}),outerBoundary=getOutwardSlotBoundary(route2,{width:options.cutoutWidth,winding:Math.sign(twiceSignedArea)});if(tabCutouts.push({type:"pcb_cutout",pcb_cutout_id:`panel_continuous_slot_${tabIndex}`,shape:"polygon",points:[...route2,...outerBoundary.reverse()]}),gapLength>1e-6){let tabRoute=getOutlineSpan({edges,startPerimeterDistance:tabCenter-gapLength/2,endPerimeterDistance:tabCenter+gapLength/2}),tabOuterBoundary=getOutwardSlotBoundary(tabRoute,{width:2*options.cutoutWidth,winding:Math.sign(twiceSignedArea)}),bridgeOutline=[...tabRoute,...tabOuterBoundary.reverse()];if(tabBridges.push(bridgeOutline),options.mouseBites&&options.mouseBiteHoleDiameter>0&&gapLength>=options.mouseBiteHoleDiameter){let pitch=options.mouseBiteHoleDiameter+options.mouseBiteHoleSpacing,holeCount=Math.floor((gapLength-options.mouseBiteHoleDiameter)/pitch)+1;for(let holeIndex=0;holeIndex<holeCount;holeIndex++){let offset3=(holeIndex-(holeCount-1)/2)*pitch,perimeterDistance=tabCenter+offset3,boardEdge=getPointAlongOutline(edges,{perimeterDistance}),routingEdge=getPointAlongOutline(edges,{perimeterDistance,leftOffsetMm:-Math.sign(twiceSignedArea)*options.cutoutWidth});mouseBites.push({boardEdge,outwardNormal:vector$1(point2(boardEdge.x,boardEdge.y),point2(routingEdge.x,routingEdge.y)).normalize(),bridgeOutline})}}}}return{tabCutouts,mouseBites,tabBridges}}function getPanelRoutingSlotPolygon(cutout){if(cutout.shape==="polygon"){let polygon42=new Polygon$1(cutout.points.map(({x:x23,y:y23})=>point2(x23,y23)));return polygon42.orientation()===ORIENTATION.CW?polygon42.reverse():polygon42}let halfWidth=cutout.width/2,halfHeight=cutout.height/2,radius=Math.min(cutout.corner_radius??0,halfWidth,halfHeight),polygon32;if(radius<=0)polygon32=new Polygon$1(new Box(-halfWidth,-halfHeight,halfWidth,halfHeight));else{let arcs=[point2(halfWidth-radius,halfHeight-radius),point2(-halfWidth+radius,halfHeight-radius),point2(-halfWidth+radius,-halfHeight+radius),point2(halfWidth-radius,-halfHeight+radius)].map((center2,cornerIndex)=>new Arc(center2,radius,cornerIndex*Math.PI/2,(cornerIndex+1)*Math.PI/2,!0));polygon32=new Polygon$1(arcs.flatMap((arc32,cornerIndex)=>{let nextArc=arcs[(cornerIndex+1)%arcs.length];return arc32.end.equalTo(nextArc.start)?[arc32]:[arc32,segment(arc32.end,nextArc.start)]}))}let cutoutLocalToCircuitWorldTransform=compose3(translate8(cutout.center.x,cutout.center.y),rotateDEG3(cutout.rotation??0));return polygon32.transform(new Matrix(cutoutLocalToCircuitWorldTransform.a,cutoutLocalToCircuitWorldTransform.b,cutoutLocalToCircuitWorldTransform.c,cutoutLocalToCircuitWorldTransform.d,cutoutLocalToCircuitWorldTransform.e,cutoutLocalToCircuitWorldTransform.f))}var POSITION_TOLERANCE_MM=1e-6;function getRoutingIntervals({routingPolygon,boardEdge,outwardNormal}){let origin=point2(boardEdge.x,boardEdge.y),rayLine=line(origin,origin.translate(outwardNormal)),distances=routingPolygon.intersect(rayLine).map(position22=>vector$1(origin,position22).dot(outwardNormal)).sort((a23,b23)=>a23-b23),intervals=[];for(let boundaryIndex=0;boundaryIndex<distances.length-1;boundaryIndex++){let start=Math.max(0,distances[boundaryIndex]),end=distances[boundaryIndex+1];if(end-start<=POSITION_TOLERANCE_MM)continue;let midpoint32=origin.translate(outwardNormal.multiply((start+end)/2));routingPolygon.contains(midpoint32)&&intervals.push({start,end})}return intervals}function getConnectedIntervalEnd(intervals){let orderedIntervals=intervals.toSorted((a23,b23)=>a23.start-b23.start),end=0;for(let interval of orderedIntervals){if(interval.start>end+POSITION_TOLERANCE_MM)break;end=Math.max(end,interval.end)}return end}function getPanelMouseBitePositions({mouseBites,routingCutouts,minimumDrillPitch}){if(mouseBites.length===0)return[];let routingPolygons=routingCutouts.map(getPanelRoutingSlotPolygon),drillPositions=new Map;for(let{boardEdge}of mouseBites){let positionKey=`${Math.round(boardEdge.x/POSITION_TOLERANCE_MM)},${Math.round(boardEdge.y/POSITION_TOLERANCE_MM)}`;drillPositions.has(positionKey)||drillPositions.set(positionKey,boardEdge)}for(let{boardEdge,outwardNormal,bridgeOutline}of mouseBites){let channelEnd=getConnectedIntervalEnd(routingPolygons.flatMap(routingPolygon=>getRoutingIntervals({routingPolygon,boardEdge,outwardNormal}))),bridgeEnd=getConnectedIntervalEnd(getRoutingIntervals({routingPolygon:new Polygon$1(bridgeOutline.map(({x:x23,y:y23})=>point2(x23,y23))),boardEdge,outwardNormal})),oppositeEdgeDistance=Math.min(channelEnd,bridgeEnd);if(oppositeEdgeDistance<=POSITION_TOLERANCE_MM)throw new Error("Could not locate the routed channel beside a panel tab");let oppositeEdge=point2(boardEdge.x,boardEdge.y).translate(outwardNormal.multiply(oppositeEdgeDistance)),positionKey=`${Math.round(oppositeEdge.x/POSITION_TOLERANCE_MM)},${Math.round(oppositeEdge.y/POSITION_TOLERANCE_MM)}`;if(drillPositions.has(positionKey))continue;[...drillPositions.values()].some(position22=>Math.hypot(position22.x-oppositeEdge.x,position22.y-oppositeEdge.y)<minimumDrillPitch-POSITION_TOLERANCE_MM)||drillPositions.set(positionKey,{x:oppositeEdge.x,y:oppositeEdge.y})}return[...drillPositions.values()]}function getSlotPolygonsWithoutHoles(polygon32){let hole=[...polygon32.faces].find(face2=>face2.orientation()===ORIENTATION.CW);if(!hole)return polygon32.splitToIslands();let bounds=polygon32.box,splitX=hole.box.center.x;return[new Box(bounds.xmin-1,bounds.ymin-1,splitX,bounds.ymax+1),new Box(splitX,bounds.ymin-1,bounds.xmax+1,bounds.ymax+1)].flatMap(half=>getSlotPolygonsWithoutHoles(BooleanOperations.intersect(polygon32,new Polygon$1(half))))}function preservePanelTabBridges(cutouts,tabBridges){let bridges=tabBridges.map(vertices=>{let polygon32=new Polygon$1(vertices.map(({x:x23,y:y23})=>point2(x23,y23)));return polygon32.orientation()===ORIENTATION.CW?polygon32.reverse():polygon32});return cutouts.flatMap(cutout=>{let slot=getPanelRoutingSlotPolygon(cutout),changed=!1;for(let bridge of bridges)slot.box.not_intersect(bridge.box)||BooleanOperations.intersect(slot,bridge).area()<1e-8||(slot=BooleanOperations.subtract(slot,bridge),changed=!0);return changed?getSlotPolygonsWithoutHoles(slot).map(polygon32=>({type:"pcb_cutout",pcb_cutout_id:cutout.pcb_cutout_id,shape:"polygon",points:[...polygon32.faces].flatMap(face2=>face2.shapes.flatMap(shape50=>{if(shape50 instanceof Segment$1)return[{x:shape50.start.x,y:shape50.start.y}];let maxAngle=2*Math.acos(1-Math.min(.001/shape50.r,1)),steps=Math.max(1,Math.ceil(shape50.sweep/maxAngle));return Array.from({length:steps},(_23,arcIndex)=>{let position22=shape50.pointAtLength(shape50.length*arcIndex/steps);return{x:position22.x,y:position22.y}})}))})):[cutout]})}var DEFAULT_TAB_LENGTH=5,DEFAULT_TAB_WIDTH=2,TAB_SCALE_REFERENCE_BOARD_SIZE=20,MIN_TAB_SCALE=.3,MOUSE_BITE_DIAMETER_TO_TAB_WIDTH=.45,MOUSE_BITE_SPACING_TO_DIAMETER=.5;function getScaledPanelTabSize({minimumBoardDimension,tabWidth,tabLength}){let scale52=Math.max(minimumBoardDimension/TAB_SCALE_REFERENCE_BOARD_SIZE,MIN_TAB_SCALE);return{tabWidth:Math.min(tabWidth,DEFAULT_TAB_WIDTH*scale52),tabLength:Math.min(tabLength,DEFAULT_TAB_LENGTH*scale52)}}function getMouseBiteSize({tabWidth}){let diameter=tabWidth*MOUSE_BITE_DIAMETER_TO_TAB_WIDTH;return{diameter,spacing:diameter*MOUSE_BITE_SPACING_TO_DIAMETER}}var generateCutoutsAndMousebitesForOutline=(outline,options)=>{let{gapLength,cutoutWidth,mouseBites:useMouseBites,mouseBiteHoleDiameter,mouseBiteHoleSpacing,vScore}=options,tabCutouts=[],mouseBites=[],tabBridges=[],vScoreLines=[];if(outline.length<2)return{tabCutouts,mouseBites,tabBridges,vScoreLines};if(outline.some((position22,outlineIndex)=>{let previousPosition=outline[(outlineIndex-1+outline.length)%outline.length],nextPosition=outline[(outlineIndex+1)%outline.length],incomingLength=Math.hypot(position22.x-previousPosition.x,position22.y-previousPosition.y),segmentLength=Math.hypot(nextPosition.x-position22.x,nextPosition.y-position22.y),directionCosine=((position22.x-previousPosition.x)*(nextPosition.x-position22.x)+(position22.y-previousPosition.y)*(nextPosition.y-position22.y))/(incomingLength*segmentLength);return incomingLength>1e-9&&segmentLength>1e-9&&segmentLength<gapLength+2*cutoutWidth&&directionCosine>Math.cos(Math.PI/12)})){if(vScore)throw new Error("V-scored panel tabs require straight board edges; curved board outlines cannot be V-scored");return{...generateContinuousPanelRoutingSlots(outline,options),vScoreLines}}let outlinePolygon=new Polygon$1(outline.map(p23=>point2(p23.x,p23.y))),is_ccw;if(outline.length>2){let p03=point2(outline[0].x,outline[0].y),p13=point2(outline[1].x,outline[1].y),segmentDir=vector$1(p03,p13).normalize(),normalToLeft=segmentDir.rotate(Math.PI/2),testPoint=p03.translate(segmentDir.multiply(segment(p03,p13).length/2)).translate(normalToLeft.multiply(.01));is_ccw=outlinePolygon.contains(testPoint)}else is_ccw=outlinePolygon.area()>0;for(let i23=0;i23<outline.length;i23++){let p1_=outline[i23],p2_=outline[(i23+1)%outline.length];if(!p1_||!p2_)continue;let p13=point2(p1_.x,p1_.y),p23=point2(p2_.x,p2_.y),segment5=segment(p13,p23),segmentLength=segment5.length;if(segmentLength<1e-6)continue;let segmentVec=vector$1(p13,p23),segmentDir=segmentVec.normalize(),normalVec=segmentDir.rotate(Math.PI/2),testPoint=segment5.middle().translate(normalVec.multiply(.01));outlinePolygon.contains(testPoint)&&(normalVec=normalVec.multiply(-1));let effectiveGapLength=Math.min(gapLength,segmentLength*.9),holeAndSpacing=mouseBiteHoleDiameter+mouseBiteHoleSpacing,numBitesInGap=mouseBiteHoleDiameter>0&&holeAndSpacing>0?Math.max(0,Math.floor((effectiveGapLength-mouseBiteHoleDiameter)/holeAndSpacing)+1):0,totalBitesLength=numBitesInGap*mouseBiteHoleDiameter+(numBitesInGap-1)*mouseBiteHoleSpacing,gapStartDist=(segmentLength-effectiveGapLength)/2,gapEndDist=gapStartDist+effectiveGapLength,extrusion=normalVec.multiply(cutoutWidth),tabStart=p13.translate(segmentDir.multiply(gapStartDist)),tabEnd=p13.translate(segmentDir.multiply(gapEndDist)),bridgeOutline=[tabStart,tabEnd,tabEnd.translate(extrusion.multiply(2)),tabStart.translate(extrusion.multiply(2))].map(({x:x23,y:y23})=>({x:x23,y:y23}));if(effectiveGapLength>1e-6&&tabBridges.push(bridgeOutline),vScore&&effectiveGapLength>1e-6&&vScoreLines.push([{x:tabStart.x,y:tabStart.y},{x:tabEnd.x,y:tabEnd.y}]),useMouseBites&&numBitesInGap>0&&effectiveGapLength>=totalBitesLength){let firstBiteCenterOffsetInGap=(effectiveGapLength-totalBitesLength)/2+mouseBiteHoleDiameter/2,firstBiteDistFromP1=gapStartDist+firstBiteCenterOffsetInGap;for(let k23=0;k23<numBitesInGap;k23++){let biteDist=firstBiteDistFromP1+k23*holeAndSpacing,pos=p13.translate(segmentDir.multiply(biteDist));mouseBites.push({boardEdge:{x:pos.x,y:pos.y},outwardNormal:normalVec,bridgeOutline})}}let p_prev_=outline[(i23-1+outline.length)%outline.length],p_next_=outline[(i23+2)%outline.length],start_ext=0,end_ext=0;if(p_prev_&&p_next_){let vec_in_p1=vector$1(point2(p_prev_.x,p_prev_.y),p13),p1_cross=vec_in_p1.cross(segmentVec),is_p1_convex=is_ccw?p1_cross>1e-9:p1_cross<-1e-9,vec_out_p2=vector$1(p23,point2(p_next_.x,p_next_.y)),p2_cross=segmentVec.cross(vec_out_p2),is_p2_convex=is_ccw?p2_cross>1e-9:p2_cross<-1e-9;if(is_p1_convex){let angle3=vec_in_p1.angleTo(segmentVec);angle3>Math.PI&&(angle3=2*Math.PI-angle3),start_ext=cutoutWidth*Math.tan(angle3/2)}else start_ext=0;if(is_p2_convex){let angle3=segmentVec.angleTo(vec_out_p2);angle3>Math.PI&&(angle3=2*Math.PI-angle3),end_ext=cutoutWidth*Math.tan(angle3/2)}else end_ext=0}let cutoutParts=effectiveGapLength<1e-6?[{start:0-start_ext,end:segmentLength+end_ext}]:[{start:0-start_ext,end:gapStartDist},{start:gapEndDist,end:segmentLength+end_ext}];for(let part of cutoutParts){let partLength=part.end-part.start;if(partLength<1e-6)continue;let center2=p13.translate(segmentDir.multiply(part.start+partLength/2)).translate(extrusion.multiply(.5)),width10=partLength,height10=cutoutWidth,rotationDeg=segmentDir.slope*180/Math.PI;tabCutouts.push({type:"pcb_cutout",pcb_cutout_id:"panel_tab_slot",shape:"rect",center:{x:center2.x,y:center2.y},width:width10,height:height10,rotation:rotationDeg,corner_radius:cutoutWidth/2})}}return{tabCutouts,mouseBites,tabBridges,vScoreLines}};function generatePanelTabsAndMouseBites(boards,options){let finalTabCutouts=[],allMouseBites=[],tabBridges=[],vScoreLines=[],{tabWidth,tabLength,mouseBites:useMouseBites,vScore=!1}=options,boardDimensions=[];for(let board of boards)if(board.width&&board.height)boardDimensions.push(Math.min(board.width,board.height));else if(board.outline&&board.outline.length>0){let outlinePolygon=new Polygon$1(board.outline.map(p23=>point2(p23.x,p23.y))),area3=Math.abs(outlinePolygon.area());area3>0&&boardDimensions.push(Math.sqrt(area3))}boardDimensions.length>0&&({tabWidth,tabLength}=getScaledPanelTabSize({minimumBoardDimension:Math.min(...boardDimensions),tabWidth,tabLength}));let processedBoards=boards.map(board=>{if((!board.outline||board.outline.length===0)&&board.width&&board.height){let w23=board.width/2,h23=board.height/2;return{...board,outline:[{x:board.center.x-w23,y:board.center.y-h23},{x:board.center.x+w23,y:board.center.y-h23},{x:board.center.x+w23,y:board.center.y+h23},{x:board.center.x-w23,y:board.center.y+h23}]}}return board}),{diameter:mouseBiteDiameter,spacing:mouseBiteSpacing}=getMouseBiteSize({tabWidth});for(let board of processedBoards)if(board.outline&&board.outline.length>0){let generated=generateCutoutsAndMousebitesForOutline(board.outline,{gapLength:tabLength,cutoutWidth:tabWidth,mouseBites:useMouseBites,mouseBiteHoleDiameter:mouseBiteDiameter,mouseBiteHoleSpacing:mouseBiteSpacing,vScore});finalTabCutouts.push(...generated.tabCutouts),allMouseBites.push(...generated.mouseBites),tabBridges.push(...generated.tabBridges),vScoreLines.push(...generated.vScoreLines)}let tabCutouts=preservePanelTabBridges(finalTabCutouts,tabBridges).map((tab,index2)=>({...tab,pcb_cutout_id:`panel_tab_${index2}`})),mouseBitePositions=[];useMouseBites&&(mouseBitePositions=getPanelMouseBitePositions({mouseBites:allMouseBites,routingCutouts:generatePanelOutlineRoutingCutouts(processedBoards,{cutoutWidth:tabWidth}),minimumDrillPitch:mouseBiteDiameter+mouseBiteSpacing}));let mouseBiteHoles=mouseBitePositions.map((bite,index2)=>({type:"pcb_hole",pcb_hole_id:`panel_mouse_bite_${index2}`,hole_shape:"circle",hole_diameter:mouseBiteDiameter,x:bite.x,y:bite.y}));return{tabCutouts,mouseBiteHoles,vScoreLines}}function generatePanelOutlineRoutingCutouts(boards,options){return boards.map(board=>{if((!board.outline||board.outline.length===0)&&board.width&&board.height){let halfWidth=board.width/2,halfHeight=board.height/2;return{...board,outline:[{x:board.center.x-halfWidth,y:board.center.y-halfHeight},{x:board.center.x+halfWidth,y:board.center.y-halfHeight},{x:board.center.x+halfWidth,y:board.center.y+halfHeight},{x:board.center.x-halfWidth,y:board.center.y+halfHeight}]}}return board}).flatMap(board=>{if(!board.outline||board.outline.length===0)return[];let{tabCutouts}=generateCutoutsAndMousebitesForOutline(board.outline,{gapLength:0,cutoutWidth:options.cutoutWidth,mouseBites:!1,mouseBiteHoleDiameter:0,mouseBiteHoleSpacing:0,vScore:!1});return tabCutouts.map(cutout=>({...cutout,pcb_board_id:board.pcb_board_id}))}).map((cutout,outlineRoutingCutoutIndex)=>({...cutout,pcb_cutout_id:`panel_outline_routing_cutout_${outlineRoutingCutoutIndex}`}))}function getRectangularPanelBoardBounds(board){let firstCorner=board.outline?.[0],outline=board.outline?.filter((position22,outlineIndex)=>outlineIndex===0||position22.x!==firstCorner?.x||position22.y!==firstCorner?.y);if(outline?.length){let minX=Math.round(Math.min(...outline.map(position22=>position22.x))*1e6)/1e6,maxX=Math.round(Math.max(...outline.map(position22=>position22.x))*1e6)/1e6,minY=Math.round(Math.min(...outline.map(position22=>position22.y))*1e6)/1e6,maxY=Math.round(Math.max(...outline.map(position22=>position22.y))*1e6)/1e6;if(new Set(outline.map(position22=>`${Math.round(position22.x*1e6)}:${Math.round(position22.y*1e6)}`)).size!==4||outline.some(position22=>Math.abs(position22.x-minX)>1e-6&&Math.abs(position22.x-maxX)>1e-6||Math.abs(position22.y-minY)>1e-6&&Math.abs(position22.y-maxY)>1e-6))throw new Error("Panel tab controls require axis-aligned rectangular board outlines");return{minX,maxX,minY,maxY}}if(board.width===void 0||board.height===void 0||board.width<=0||board.height<=0)throw new Error("Panel tab controls require positive rectangular board dimensions");return{minX:board.center.x-board.width/2,maxX:board.center.x+board.width/2,minY:board.center.y-board.height/2,maxY:board.center.y+board.height/2}}var getPanelTabCentreAlongEdge=({tab,edgeLength})=>tab.boardEdge==="top"||tab.boardEdge==="bottom"?tab.centerOffsetFromBoardLeftEdge??edgeLength-tab.centerOffsetFromBoardRightEdge:tab.centerOffsetFromBoardBottomEdge??edgeLength-tab.centerOffsetFromBoardTopEdge;function generateControlledPanelTabs(boards,options){let tabCutouts=[],mouseBiteHoles=[],tabBridges=[],dimensions6=boards.map(({board})=>getRectangularPanelBoardBounds(board)),minimumBoardDimension=Math.min(...dimensions6.flatMap(bounds=>[bounds.maxX-bounds.minX,bounds.maxY-bounds.minY])),{tabWidth,tabLength}=getScaledPanelTabSize({minimumBoardDimension,tabWidth:options.tabWidth,tabLength:options.tabLength}),mouseBiteSize=getMouseBiteSize({tabWidth}),drillDiameter=mouseBiteSize.diameter,drillPitch=mouseBiteSize.diameter+mouseBiteSize.spacing;for(let control of[...options.tabs??[],...options.tabKeepouts??[]])if(control.boardName&&!boards.some(({boardName})=>boardName===control.boardName))throw new Error(`Unknown board name "${control.boardName}" in panel tabs`);for(let{board,boardName}of boards){let bounds=getRectangularPanelBoardBounds(board),edges=[{side:"top",origin:{x:bounds.minX,y:bounds.maxY},length:bounds.maxX-bounds.minX,ccwRotationDegrees:0,outwardSign:1},{side:"bottom",origin:{x:bounds.minX,y:bounds.minY},length:bounds.maxX-bounds.minX,ccwRotationDegrees:0,outwardSign:-1},{side:"left",origin:{x:bounds.minX,y:bounds.minY},length:bounds.maxY-bounds.minY,ccwRotationDegrees:90,outwardSign:1},{side:"right",origin:{x:bounds.maxX,y:bounds.minY},length:bounds.maxY-bounds.minY,ccwRotationDegrees:90,outwardSign:-1}],boardTabCount=0;for(let edge of edges){let explicitTabs=options.tabs,tabPlacements=explicitTabs===void 0?Array.from({length:options.tabCountPerEdge??1},(_23,tabIndex)=>({centre:(tabIndex+1)*edge.length/((options.tabCountPerEdge??1)+1),length:tabLength})):explicitTabs.filter(tab=>tab.boardEdge===edge.side&&(!tab.boardName||tab.boardName===boardName)).map(tab=>({centre:getPanelTabCentreAlongEdge({tab,edgeLength:edge.length}),length:tab.tabWidth??tabLength})),keepouts=options.tabKeepouts?.filter(keepout=>keepout.boardEdge===edge.side&&(!keepout.boardName||keepout.boardName===boardName))??[],intervals=[];for(let{centre,length:length93}of tabPlacements.sort((firstTab,secondTab)=>firstTab.centre-secondTab.centre)){let start=centre-length93/2,end=centre+length93/2;if(start<0||end>edge.length)throw new Error(`A ${edge.side} tab on ${boardName} extends beyond the board edge. Reduce tabLength or move the tab.`);if(keepouts.some(keepout=>end>=keepout.from&&start<=keepout.to)){if(explicitTabs)throw new Error(`An explicit ${edge.side} tab on ${boardName} overlaps a tab keepout`);continue}if(intervals.at(-1)&&start<intervals.at(-1).end)throw new Error(`The ${edge.side} tabs on ${boardName} overlap. Reduce their count or tabLength.`);let previousTab=intervals.at(-1);if(previousTab&&start-previousTab.end<tabWidth-1e-9)throw new Error(`The ${edge.side} tabs on ${boardName} leave insufficient router clearance. Reduce their count, tabLength, or tabWidth.`);intervals.push({start,end,centre})}boardTabCount+=intervals.length;let edgeToWorldTransform=compose3(translate8(edge.origin.x,edge.origin.y),rotateDEG3(edge.ccwRotationDegrees));for(let interval of intervals)tabBridges.push([{x:interval.start,y:0},{x:interval.end,y:0},{x:interval.end,y:edge.outwardSign*2*tabWidth},{x:interval.start,y:edge.outwardSign*2*tabWidth}].map(point12=>applyToPoint3(edgeToWorldTransform,point12)));let routeStart=-tabWidth;for(let interval of[...intervals,{start:edge.length+tabWidth,end:edge.length+tabWidth,centre:edge.length}]){let routeLength3=interval.start-routeStart;routeLength3>1e-9&&tabCutouts.push({pcb_cutout_id:`pcb_cutout_panel_tab_${board.pcb_board_id}_${tabCutouts.length}`,type:"pcb_cutout",shape:"rect",center:applyToPoint3(edgeToWorldTransform,{x:routeStart+routeLength3/2,y:edge.outwardSign*tabWidth/2}),width:routeLength3,height:tabWidth,rotation:edge.ccwRotationDegrees,corner_radius:Math.min(routeLength3,tabWidth)/2}),routeStart=interval.end}if(options.mouseBites&&drillDiameter>0)for(let interval of intervals){let intervalLength=interval.end-interval.start;if(intervalLength<drillDiameter)continue;let holeCount=Math.floor((intervalLength-drillDiameter)/drillPitch)+1;for(let holeIndex=0;holeIndex<holeCount;holeIndex++){let position22=applyToPoint3(edgeToWorldTransform,{x:interval.centre+(holeIndex-(holeCount-1)/2)*drillPitch,y:0});mouseBiteHoles.push({pcb_hole_id:`pcb_hole_panel_mouse_bite_${board.pcb_board_id}_${mouseBiteHoles.length}`,type:"pcb_hole",hole_shape:"circle",hole_diameter:drillDiameter,...position22})}}}if(boardTabCount===0)throw new Error(`${boardName} has no panel tabs and would be cut free of the panel. Add a <paneltab> for it or narrow its <paneltabkeepout>.`)}return{tabCutouts:preservePanelTabBridges(tabCutouts,tabBridges).map((cutout,cutoutIndex)=>({...cutout,pcb_cutout_id:`pcb_cutout_panel_tab_${cutoutIndex}`})),mouseBiteHoles}}var getBoardDimensionsFromProps=board=>{let props=board._parsedProps,width10=props.width!=null?distance4.parse(props.width):void 0,height10=props.height!=null?distance4.parse(props.height):void 0;if((width10===void 0||height10===void 0)&&props.outline?.length){let outlineBounds=getBoundsFromPoints3(props.outline);outlineBounds&&(width10??(width10=outlineBounds.maxX-outlineBounds.minX),height10??(height10=outlineBounds.maxY-outlineBounds.minY))}if((width10===void 0||height10===void 0)&&props.circuitJson?.length){let pcbBoardFromJson=props.circuitJson.find(elm=>elm.type==="pcb_board");pcbBoardFromJson&&(width10??(width10=pcbBoardFromJson.width),height10??(height10=pcbBoardFromJson.height))}return{width:width10??0,height:height10??0}};function packIntoGrid({items,db:db22,row,col,cellWidth,cellHeight,boardGap,availablePanelWidth,availablePanelHeight}){let itemsWithDims=items.map(item=>{let dims=getItemDimensions(item,db22);return{item,width:dims.width,height:dims.height}}).filter(item=>!(item.width===0&&item.height===0));if(itemsWithDims.length===0)return{positions:[],gridWidth:0,gridHeight:0};let cols,rows,minCellWidth=cellWidth?distance4.parse(cellWidth):0,minCellHeight=cellHeight?distance4.parse(cellHeight):0;if(col!==void 0)cols=col,rows=row??Math.ceil(itemsWithDims.length/cols);else if(row!==void 0)rows=row,cols=Math.ceil(itemsWithDims.length/rows);else if(availablePanelWidth!==void 0&&availablePanelHeight!==void 0){let maxItemWidth=Math.max(...itemsWithDims.map(b23=>b23.width),minCellWidth),maxItemHeight=Math.max(...itemsWithDims.map(b23=>b23.height),minCellHeight),maxCols=Math.max(1,Math.floor((availablePanelWidth+boardGap)/(maxItemWidth+boardGap))),maxRows=Math.max(1,Math.floor((availablePanelHeight+boardGap)/(maxItemHeight+boardGap)));cols=maxCols,rows=Math.ceil(itemsWithDims.length/cols),rows>maxRows&&(rows=maxRows,cols=Math.ceil(itemsWithDims.length/rows),cols>maxCols&&(cols=maxCols,rows=Math.ceil(itemsWithDims.length/cols))),cols=Math.max(1,cols),rows=Math.max(1,rows)}else cols=Math.ceil(Math.sqrt(itemsWithDims.length)),rows=Math.ceil(itemsWithDims.length/cols);let colWidths=Array(cols).fill(0),rowHeights=Array(rows).fill(0);itemsWithDims.forEach((item,i23)=>{let colIdx=i23%cols,rowIdx=Math.floor(i23/cols);rowIdx<rowHeights.length&&item.height>rowHeights[rowIdx]&&(rowHeights[rowIdx]=item.height),colIdx<colWidths.length&&item.width>colWidths[colIdx]&&(colWidths[colIdx]=item.width)});for(let i23=0;i23<colWidths.length;i23++)colWidths[i23]=Math.max(colWidths[i23],minCellWidth);for(let i23=0;i23<rowHeights.length;i23++)rowHeights[i23]=Math.max(rowHeights[i23],minCellHeight);let gridWidth=colWidths.reduce((a23,b23)=>a23+b23,0)+(cols>1?(cols-1)*boardGap:0),gridHeight=rowHeights.reduce((a23,b23)=>a23+b23,0)+(rows>1?(rows-1)*boardGap:0),startX=-gridWidth/2,startY=-gridHeight/2,colXOffsets=[startX];for(let i23=1;i23<cols;i23++)colXOffsets.push(colXOffsets[i23-1]+colWidths[i23-1]+boardGap);let rowYOffsets=[startY];for(let i23=1;i23<rows;i23++)rowYOffsets.push(rowYOffsets[i23-1]+rowHeights[i23-1]+boardGap);let positions=[];return itemsWithDims.forEach((itemWithDims,i23)=>{let colIdx=i23%cols,rowIdx=Math.floor(i23/cols);if(rowIdx>=rowYOffsets.length||colIdx>=colXOffsets.length)return;let x23=colXOffsets[colIdx]+colWidths[colIdx]/2,y23=rowYOffsets[rowIdx]+rowHeights[rowIdx]/2;positions.push({item:itemWithDims.item,pos:{x:x23,y:y23}})}),{positions,gridWidth,gridHeight}}function getItemDimensions(item,db22){if(item.componentName==="Board"){let board=item;if(db22&&board.pcb_board_id){let pcbBoard=db22.pcb_board.get(board.pcb_board_id);if(pcbBoard?.width!==void 0&&pcbBoard?.height!==void 0)return{width:pcbBoard.width,height:pcbBoard.height}}return getBoardDimensionsFromProps(board)}if(item.componentName==="Subpanel"){let subpanel=item,props=subpanel._parsedProps;if(props.width!==void 0&&props.height!==void 0)return{width:distance4.parse(props.width),height:distance4.parse(props.height)};let directBoards=subpanel._getDirectBoardChildren();if(directBoards.length===0){let allBoards=subpanel._getAllBoardInstances();if(allBoards.length===0)return{width:0,height:0};let minX=1/0,minY=1/0,maxX=-1/0,maxY=-1/0;for(let board of allBoards){let dims=getBoardDimensionsFromProps(board);if(dims.width===0||dims.height===0)continue;let offset3=board._panelPositionOffset??{x:0,y:0};minX=Math.min(minX,offset3.x-dims.width/2),maxX=Math.max(maxX,offset3.x+dims.width/2),minY=Math.min(minY,offset3.y-dims.height/2),maxY=Math.max(maxY,offset3.y+dims.height/2)}return minX===1/0?{width:0,height:0}:{width:maxX-minX,height:maxY-minY}}if(directBoards.length===1)return getBoardDimensionsFromProps(directBoards[0]);if(subpanel._cachedGridWidth>0&&subpanel._cachedGridHeight>0){let edgePadding=distance4.parse(props.edgePadding??5);return{width:subpanel._cachedGridWidth+edgePadding*2,height:subpanel._cachedGridHeight+edgePadding*2}}let totalWidth=0,totalHeight=0;for(let board of directBoards){let dims=getBoardDimensionsFromProps(board);totalWidth=Math.max(totalWidth,dims.width),totalHeight=Math.max(totalHeight,dims.height)}return{width:totalWidth,height:totalHeight}}return{width:0,height:0}}var V_SCORE_LINE_LAYER="top",V_SCORE_LINE_STROKE_WIDTH=.1,Subpanel=class _Subpanel extends Group{constructor(){super(...arguments);__publicField(this,"pcb_panel_id",null);__publicField(this,"_panelizationFeaturesGenerated",!1);__publicField(this,"_cachedGridWidth",0);__publicField(this,"_cachedGridHeight",0);__publicField(this,"_panelPositionOffset",null)}get config(){return{componentName:"Subpanel",zodProps:subpanelProps}}get _errorComponentName(){return this.componentName.toLowerCase()}get isGroup(){return!0}get isSubcircuit(){return!0}_getPcbLayoutMode(){return"none"}doInitialSchematicComponentRender(){}doInitialSchematicLayout(){}doInitialSchematicTraceRender(){}add(component){let acceptsToolingRail=this.componentName==="Panel";if(component.lowercaseComponentName!=="board"&&component.lowercaseComponentName!=="subpanel"&&component.lowercaseComponentName!=="trace"&&component.lowercaseComponentName!=="hole"&&component.lowercaseComponentName!=="fiducial"&&component.lowercaseComponentName!=="hole"&&component.lowercaseComponentName!=="fiducial"&&component.lowercaseComponentName!=="silkscreentext"&&component.lowercaseComponentName!=="paneltab"&&component.lowercaseComponentName!=="paneltabkeepout"&&!(acceptsToolingRail&&component.lowercaseComponentName==="toolingrail"))throw new Error(acceptsToolingRail?`<${this._errorComponentName}> can only contain <board>, <subpanel>, <trace>, <hole>, <fiducial>, <silkscreentext>, <paneltab>, <paneltabkeepout>, or <toolingrail> elements`:`<${this._errorComponentName}> can only contain <board>, <subpanel>, <trace>, <hole>, <fiducial>, <silkscreentext>, <paneltab>, or <paneltabkeepout> elements`);super.add(component)}_computePcbGlobalTransformBeforeLayout(){if(this._panelPositionOffset){let parentTransform=this.parent?._computePcbGlobalTransformBeforeLayout?.()??identity7();return compose3(parentTransform,translate8(this._panelPositionOffset.x,this._panelPositionOffset.y))}return super._computePcbGlobalTransformBeforeLayout()}_getAllBoardInstances(){let boards=[];for(let child of this.children)child instanceof Board?boards.push(child):child instanceof _Subpanel&&boards.push(...child._getAllBoardInstances());return boards}_containsBoards(){for(let child of this.children)if(child.componentName==="Board"||child.componentName==="Subpanel"&&"_containsBoards"in child&&child._containsBoards())return!0;return!1}_getDirectBoardChildren(){return this.children.filter(c23=>c23 instanceof Board)}doInitialPanelBoardLayout(){if(this.root?.pcbDisabled)return;let layoutMode=this._parsedProps.layoutMode??"none",gridItems=this.children.filter(c23=>c23 instanceof Board||c23 instanceof _Subpanel);if(layoutMode!=="none")for(let child of gridItems)child instanceof Board&&child._hasUserDefinedPcbPosition()&&this.root.db.source_property_ignored_warning.insert({source_component_id:child.source_component_id,property_name:"pcbX/pcbY",message:`Board has manual positioning but ${this._errorComponentName} layout mode is "${layoutMode}". Manual positioning will be ignored.`,error_type:"source_property_ignored_warning"});if(layoutMode==="none"&&gridItems.length>1&&gridItems.filter(c23=>!c23._hasUserDefinedPcbPosition()).length>1&&this.root.db.pcb_placement_error.insert({error_type:"pcb_placement_error",message:`Multiple boards/subpanels in ${this._errorComponentName} without positions. When layoutMode="none", each item must have explicit positioning. Use layoutMode="grid" for automatic positioning.`}),layoutMode!=="grid")return;let tabWidth=this._parsedProps.tabWidth??DEFAULT_TAB_WIDTH,boardGap=this._parsedProps.boardGap??tabWidth,availablePanelWidth,availablePanelHeight,hasExplicitRowOrCol=this._parsedProps.row!==void 0||this._parsedProps.col!==void 0,hasExplicitWidth=this._parsedProps.width!==void 0,hasExplicitHeight=this._parsedProps.height!==void 0;if(!hasExplicitRowOrCol&&hasExplicitWidth&&hasExplicitHeight){let{edgePadding:edgePaddingProp,edgePaddingLeft:edgePaddingLeftProp,edgePaddingRight:edgePaddingRightProp,edgePaddingTop:edgePaddingTopProp,edgePaddingBottom:edgePaddingBottomProp}=this._parsedProps,edgePadding=distance4.parse(edgePaddingProp??5),edgePaddingLeft=distance4.parse(edgePaddingLeftProp??edgePadding),edgePaddingRight=distance4.parse(edgePaddingRightProp??edgePadding),edgePaddingTop=distance4.parse(edgePaddingTopProp??edgePadding),edgePaddingBottom=distance4.parse(edgePaddingBottomProp??edgePadding),panelWidth=distance4.parse(this._parsedProps.width),panelHeight=distance4.parse(this._parsedProps.height);availablePanelWidth=panelWidth-edgePaddingLeft-edgePaddingRight,availablePanelHeight=panelHeight-edgePaddingTop-edgePaddingBottom}let{positions,gridWidth,gridHeight}=packIntoGrid({items:gridItems,row:this._parsedProps.row,col:this._parsedProps.col,cellWidth:this._parsedProps.cellWidth,cellHeight:this._parsedProps.cellHeight,boardGap,availablePanelHeight,availablePanelWidth});this._cachedGridWidth=gridWidth,this._cachedGridHeight=gridHeight;for(let{item,pos}of positions)item._panelPositionOffset=pos}doInitialPanelLayout(){if(this.root?.pcbDisabled)return;let{db:db22}=this.root;if((this._parsedProps.layoutMode??"none")==="grid"){for(let child of this.children)if(child instanceof Board){if(!child.pcb_board_id||!child._panelPositionOffset)continue;db22.pcb_board.update(child.pcb_board_id,{position_mode:"relative_to_panel_anchor",display_offset_x:`${child._panelPositionOffset.x}mm`,display_offset_y:`${child._panelPositionOffset.y}mm`})}else if(child instanceof _Subpanel&&child._panelPositionOffset)for(let board of child._getAllBoardInstances()){if(!board.pcb_board_id)continue;let boardOffset=board._panelPositionOffset??{x:0,y:0};db22.pcb_board.update(board.pcb_board_id,{position_mode:"relative_to_panel_anchor",display_offset_x:`${child._panelPositionOffset.x+boardOffset.x}mm`,display_offset_y:`${child._panelPositionOffset.y+boardOffset.y}mm`})}this._updatePanelDimensions()}else{let panelGlobalPos=this._getGlobalPcbPositionBeforeLayout();for(let board of this._getDirectBoardChildren()){if(!board.pcb_board_id)continue;let boardDb=db22.pcb_board.get(board.pcb_board_id);if(!boardDb)continue;let relativeX=boardDb.center.x-panelGlobalPos.x,relativeY=boardDb.center.y-panelGlobalPos.y;db22.pcb_board.update(board.pcb_board_id,{position_mode:"relative_to_panel_anchor",display_offset_x:`${relativeX}mm`,display_offset_y:`${relativeY}mm`})}}this._generatePanelizationFeatures()}_updatePanelDimensions(){let{db:db22}=this.root,hasExplicitWidth=this._parsedProps.width!==void 0,hasExplicitHeight=this._parsedProps.height!==void 0,gridWidth=this._cachedGridWidth,gridHeight=this._cachedGridHeight;if(this.pcb_group_id){if(hasExplicitWidth&&hasExplicitHeight)db22.pcb_group.update(this.pcb_group_id,{width:distance4.parse(this._parsedProps.width),height:distance4.parse(this._parsedProps.height)});else if(gridWidth>0||gridHeight>0){let{edgePadding:edgePaddingProp,edgePaddingLeft:edgePaddingLeftProp,edgePaddingRight:edgePaddingRightProp,edgePaddingTop:edgePaddingTopProp,edgePaddingBottom:edgePaddingBottomProp}=this._parsedProps,edgePadding=distance4.parse(edgePaddingProp??5),edgePaddingLeft=distance4.parse(edgePaddingLeftProp??edgePadding),edgePaddingRight=distance4.parse(edgePaddingRightProp??edgePadding),edgePaddingTop=distance4.parse(edgePaddingTopProp??edgePadding),edgePaddingBottom=distance4.parse(edgePaddingBottomProp??edgePadding);db22.pcb_group.update(this.pcb_group_id,{width:hasExplicitWidth?distance4.parse(this._parsedProps.width):gridWidth+edgePaddingLeft+edgePaddingRight,height:hasExplicitHeight?distance4.parse(this._parsedProps.height):gridHeight+edgePaddingTop+edgePaddingBottom})}}}_generatePanelizationFeatures(){if(this._panelizationFeaturesGenerated)return;let{db:db22}=this.root,props=this._parsedProps,panelizationMethod=props.panelizationMethod??"none",tabChildren=this.children.filter(child=>child instanceof PanelTab),keepoutChildren=this.children.filter(child=>child instanceof PanelTabKeepout),hasTabControls=props.tabCountPerEdge!==void 0||tabChildren.length>0||keepoutChildren.length>0;if(hasTabControls&&panelizationMethod!=="tab-routing")throw new Error('Panel tab controls require panelizationMethod="tab-routing"');if(props.tabCountPerEdge!==void 0&&tabChildren.length>0)throw new Error("Use either tabCountPerEdge or <paneltab> children");if(hasTabControls&&props.vScore)throw new Error("vScore is not supported with tabCountPerEdge, <paneltab> or <paneltabkeepout>");let childBoardInstances=this._getAllBoardInstances();if(panelizationMethod!=="none"){let childBoardIds=childBoardInstances.map(c23=>c23.pcb_board_id).filter(id3=>!!id3),boardsInPanel=db22.pcb_board.list().filter(b23=>childBoardIds.includes(b23.pcb_board_id));if(boardsInPanel.length===0)return;let tabWidth=props.tabWidth??DEFAULT_TAB_WIDTH;if(panelizationMethod==="outline_routing"){let outlineRoutingCutouts=generatePanelOutlineRoutingCutouts(boardsInPanel,{cutoutWidth:tabWidth});for(let outlineRoutingCutout of outlineRoutingCutouts)db22.pcb_cutout.insert({...outlineRoutingCutout,pcb_group_id:this.pcb_group_id??void 0,pcb_panel_id:getOwningPanel(this)?.pcb_panel_id??void 0,subcircuit_id:this.subcircuit_id??void 0})}else{let boardGap=props.boardGap??tabWidth,{tabCutouts,mouseBiteHoles,vScoreLines}=hasTabControls?{...generateControlledPanelTabs(boardsInPanel.map(board=>({board,boardName:childBoardInstances.find(childBoard=>childBoard.pcb_board_id===board.pcb_board_id)?.name??"unnamed board"})),{tabCountPerEdge:props.tabCountPerEdge,tabs:tabChildren.length?tabChildren.map(tab=>tab._parsedProps):void 0,tabKeepouts:keepoutChildren.map(keepout=>keepout._parsedProps),tabWidth,tabLength:props.tabLength??DEFAULT_TAB_LENGTH,mouseBites:props.mouseBites??!0}),vScoreLines:[]}:generatePanelTabsAndMouseBites(boardsInPanel,{boardGap,tabWidth,tabLength:props.tabLength??DEFAULT_TAB_LENGTH,mouseBites:props.mouseBites??!0,vScore:props.vScore??!1});for(let tabCutout of tabCutouts)db22.pcb_cutout.insert({...tabCutout,subcircuit_id:this.subcircuit_id??void 0,pcb_panel_id:getOwningPanel(this)?.pcb_panel_id??void 0});for(let mouseBiteHole of mouseBiteHoles)db22.pcb_hole.insert({...mouseBiteHole,subcircuit_id:this.subcircuit_id??void 0});for(let route2 of vScoreLines)db22.pcb_fabrication_note_path.insert({route:route2,layer:V_SCORE_LINE_LAYER,stroke_width:V_SCORE_LINE_STROKE_WIDTH,subcircuit_id:this.subcircuit_id??void 0,pcb_panel_id:getOwningPanel(this)?.pcb_panel_id??void 0})}}this._panelizationFeaturesGenerated=!0}doInitialPcbComponentRender(){if(!this.root?.pcbDisabled){if(!this._containsBoards())throw new Error(`<${this._errorComponentName}> must contain at least one <board>`);super.doInitialPcbComponentRender()}}},DEFAULT_PANEL_EDGE_PADDING=5,Panel=class extends Subpanel{get config(){return{componentName:"Panel",zodProps:panelProps}}doInitialPcbComponentRender(){if(this.root?.pcbDisabled)return;if(!this._containsBoards())throw new Error(`<${this._errorComponentName}> must contain at least one <board>`);let{db:db22}=this.root,props=this._parsedProps,inserted=db22.pcb_panel.insert({width:props.width!==void 0?distance4.parse(props.width):0,height:props.height!==void 0?distance4.parse(props.height):0,thickness:1.6,center:this._getGlobalPcbPositionBeforeLayout(),covered_with_solder_mask:!(props.noSolderMask??!1)});this.pcb_panel_id=inserted.pcb_panel_id}_getEdgePadding(){let{edgePadding=DEFAULT_PANEL_EDGE_PADDING,edgePaddingLeft=edgePadding,edgePaddingRight=edgePadding,edgePaddingTop=edgePadding,edgePaddingBottom=edgePadding}=this._parsedProps;return{left:edgePaddingLeft,right:edgePaddingRight,top:edgePaddingTop,bottom:edgePaddingBottom}}_getPanelSize(){let{width:width10,height:height10}=this._parsedProps;if(width10!==void 0&&height10!==void 0)return{width:width10,height:height10};if(this._cachedGridWidth<=0&&this._cachedGridHeight<=0)return;let edgePadding=this._getEdgePadding();return{width:width10??this._cachedGridWidth+edgePadding.left+edgePadding.right,height:height10??this._cachedGridHeight+edgePadding.top+edgePadding.bottom}}_updatePanelDimensions(){if(!this.pcb_panel_id)return;let panelSize=this._getPanelSize();panelSize&&this.root.db.pcb_panel.update(this.pcb_panel_id,panelSize)}updatePcbComponentRender(){if(this.root?.pcbDisabled||!this.pcb_panel_id)return;let{db:db22}=this.root,props=this._parsedProps,currentPanel=db22.pcb_panel.get(this.pcb_panel_id);db22.pcb_panel.update(this.pcb_panel_id,{width:props.width!==void 0?distance4.parse(props.width):currentPanel?.width,height:props.height!==void 0?distance4.parse(props.height):currentPanel?.height,center:this._getGlobalPcbPositionBeforeLayout(),covered_with_solder_mask:!(props.noSolderMask??!1)})}removePcbComponentRender(){this.pcb_panel_id&&(this.root?.db.pcb_panel.delete(this.pcb_panel_id),this.pcb_panel_id=null)}},GENERATED_ANTENNA_KEEPOUT_CLEARANCE_MM=1,GENERATED_ANTENNA_FEED_OPENING_CLEARANCE_MM=1,getGeneratedAntennaKeepouts=geometry=>{let xCoordinates=geometry.route.map(point12=>point12.x),yCoordinates=geometry.route.map(point12=>point12.y),edgeClearance=geometry.traceWidth/2+GENERATED_ANTENNA_KEEPOUT_CLEARANCE_MM,left=Math.min(...xCoordinates)-edgeClearance,right=Math.max(...xCoordinates)+edgeClearance,bottom=Math.min(...yCoordinates)-edgeClearance,top=Math.max(...yCoordinates)+edgeClearance,feedOpeningPoints=[geometry.feedPoint,...geometry.secondaryPort?[geometry.secondaryPort.point]:[]],openingLeft=Math.min(...feedOpeningPoints.map(point12=>point12.x))-GENERATED_ANTENNA_FEED_OPENING_CLEARANCE_MM,openingRight=Math.max(...feedOpeningPoints.map(point12=>point12.x))+GENERATED_ANTENNA_FEED_OPENING_CLEARANCE_MM,openingBottom=Math.min(...feedOpeningPoints.map(point12=>point12.y))-GENERATED_ANTENNA_FEED_OPENING_CLEARANCE_MM,openingTop=Math.max(...feedOpeningPoints.map(point12=>point12.y))+GENERATED_ANTENNA_FEED_OPENING_CLEARANCE_MM,rects=[],addRect=(rectLeft,rectRight,rectBottom,rectTop)=>{rectRight<=rectLeft||rectTop<=rectBottom||rects.push({center:{x:(rectLeft+rectRight)/2,y:(rectBottom+rectTop)/2},width:rectRight-rectLeft,height:rectTop-rectBottom})};return geometry.feedKeepoutOpeningDirection==="left"?(addRect(left,right,openingTop,top),addRect(left,right,bottom,openingBottom),addRect(openingRight,right,openingBottom,openingTop)):(addRect(left,openingLeft,bottom,openingTop),addRect(openingRight,right,bottom,openingTop),addRect(left,right,openingTop,top)),rects},getGeneratedAntennaGeometry=antennaShape3=>{switch(antennaShape3){case"2.4ghz_quarter_wave_monopole":return{traceWidth:.6,feedPoint:{x:0,y:0},feedKeepoutOpeningDirection:"left",route:[{x:0,y:0},{x:31,y:0}]};case"2.4ghz_meandered_monopole":return{traceWidth:.5,feedPoint:{x:0,y:0},feedKeepoutOpeningDirection:"bottom",route:[{x:0,y:0},{x:0,y:6},{x:3,y:6},{x:3,y:1.5},{x:6,y:1.5},{x:6,y:6},{x:9,y:6},{x:9,y:1.5},{x:12,y:1.5},{x:12,y:6},{x:15,y:6}]};case"2.4ghz_inverted_f":return{traceWidth:.8,feedPoint:{x:0,y:0},feedKeepoutOpeningDirection:"bottom",secondaryPort:{point:{x:-4,y:0},role:"ground"},groundViaPoint:{x:-4,y:0},route:[{x:-4,y:0},{x:-4,y:3},{x:0,y:3},{x:0,y:0},{x:0,y:3},{x:-4,y:3},{x:-4,y:8},{x:22,y:8}]};case"2.4ghz_meandered_inverted_f":return{traceWidth:.5,feedPoint:{x:0,y:0},feedKeepoutOpeningDirection:"bottom",secondaryPort:{point:{x:-1.7,y:0},role:"ground"},groundViaPoint:{x:-1.7,y:0},route:[{x:-1.7,y:0},{x:-1.7,y:4.9},{x:0,y:4.9},{x:0,y:0},{x:0,y:4.9},{x:-1.7,y:4.9},{x:2.3,y:4.9},{x:2.3,y:1.4},{x:5.3,y:1.4},{x:5.3,y:4.9},{x:8.3,y:4.9},{x:8.3,y:1.4},{x:11.3,y:1.4},{x:11.3,y:4.9},{x:13.3,y:4.9}]};case"2.4ghz_folded_dipole":return{traceWidth:.9,feedPoint:{x:0,y:0},feedKeepoutOpeningDirection:"bottom",secondaryPort:{point:{x:1.2,y:0},role:"feed2"},route:[{x:0,y:0},{x:-22.4,y:0},{x:-22.4,y:9},{x:23.6,y:9},{x:23.6,y:0},{x:1.2,y:0}]}}},Antenna=class extends NormalComponent{get config(){return{componentName:"Antenna",zodProps:antennaProps,sourceFtype:FTYPE.simple_chip,shouldRenderAsSchematicBox:!0}}getRefDesPrefixes(){return["ANT"]}initPorts(){let{antennaShape:antennaShape3,pcbPath:pcbPath3}=this._parsedProps,secondaryPortRole=pcbPath3?void 0:antennaShape3==="2.4ghz_inverted_f"||antennaShape3==="2.4ghz_meandered_inverted_f"?"ground":antennaShape3==="2.4ghz_folded_dipole"?"feed2":void 0;super.initPorts({pinCount:secondaryPortRole?2:1,additionalAliases:{pin1:secondaryPortRole==="feed2"?["feed","feed1"]:["feed"],...secondaryPortRole==="ground"?{pin2:["ground","gnd"]}:secondaryPortRole==="feed2"?{pin2:["feed2"]}:{}}})}doInitialReactSubtreesRender(){super.doInitialReactSubtreesRender();let{antennaShape:antennaShape3,pcbPath:pcbPath3}=this._parsedProps;if(!antennaShape3)return;let hasFootprint=this.children.some(child=>child.componentName==="Footprint");if(pcbPath3&&hasFootprint)return;let geometry=pcbPath3?void 0:getGeneratedAntennaGeometry(antennaShape3),generatedFootprint=new Footprint({name:`${this.name}_generated_antenna`});if(hasFootprint||generatedFootprint.add(new SmtPad({shape:"rect",width:.8,height:.8,pcbX:geometry?.feedPoint.x??0,pcbY:geometry?.feedPoint.y??0,layer:"top",portHints:["pin1"],coveredWithSolderMask:!0})),geometry){let keepouts=getGeneratedAntennaKeepouts(geometry);for(let keepout of keepouts)generatedFootprint.add(new Keepout({shape:"rect",pcbX:keepout.center.x,pcbY:keepout.center.y,width:keepout.width,height:keepout.height,layers:[...this.root?._getBoard()?.allLayers??["top","bottom"]],excludeRefs:[this.getSubcircuitSelector()]}));let antennaTrace=new PcbTrace({route:geometry.route.map(point12=>({route_type:"wire",...point12,width:geometry.traceWidth,layer:"top"}))});antennaTrace.isAntennaTrace=!0,generatedFootprint.add(antennaTrace),geometry.secondaryPort&&!geometry.groundViaPoint&&!hasFootprint&&generatedFootprint.add(new SmtPad({shape:"rect",width:.8,height:.8,pcbX:geometry.secondaryPort.point.x,pcbY:geometry.secondaryPort.point.y,layer:"top",portHints:["pin2"],coveredWithSolderMask:!0})),geometry.groundViaPoint&&generatedFootprint.add(new PlatedHole({shape:"circle",pcbX:geometry.groundViaPoint.x,pcbY:geometry.groundViaPoint.y,holeDiameter:.3,outerDiameter:.7,portHints:["pin2"],coveredWithSolderMask:!0}))}this.add(generatedFootprint)}doInitialCreateTracesFromProps(){super.doInitialCreateTracesFromProps();let{pcbPath:pcbPath3}=this._parsedProps;if(!pcbPath3)return;let antennaTrace=new Trace({name:`${this.name}_pcb_path`,path:[`${this.getSubcircuitSelector()} > port.pin1`],pcbPath:pcbPath3});antennaTrace.isAntennaTrace=!0,this.add(antennaTrace)}},Pinout=class extends Chip{constructor(props){super(props)}get config(){return{...super.config,componentName:"Pinout",zodProps:pinoutProps}}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({ftype:"simple_pinout",name:this.name,manufacturer_part_number:resolveManufacturerPartNumber(props),supplier_part_numbers:props.supplierPartNumbers,display_name:props.displayName});this.source_component_id=source_component.source_component_id}},Jumper=class extends NormalComponent{constructor(){super(...arguments);__publicField(this,"schematicDimensions",null)}get config(){return{schematicSymbolName:void 0,componentName:"Jumper",zodProps:jumperProps,shouldRenderAsSchematicBox:!0}}_getSchematicPortArrangement(){let arrangement=super._getSchematicPortArrangement();if(arrangement&&Object.keys(arrangement).length>0)return arrangement;let pinCount=this._parsedProps.pinCount??(Array.isArray(this._parsedProps.pinLabels)?this._parsedProps.pinLabels.length:this._parsedProps.pinLabels?Object.keys(this._parsedProps.pinLabels).length:this.getPortsFromFootprint().length),direction4=this._parsedProps.schDirection??"right";return{leftSize:direction4==="left"?pinCount:0,rightSize:direction4==="right"?pinCount:0}}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,{pcbX,pcbY}=this.getResolvedPcbPositionProp(),source_component=db22.source_component.insert({ftype:"simple_chip",name:this.name,manufacturer_part_number:resolveManufacturerPartNumber(props),supplier_part_numbers:props.supplierPartNumbers,are_pins_interchangeable:!0,display_name:props.displayName});this.source_component_id=source_component.source_component_id}doInitialPcbComponentRender(){if(this.root?.pcbDisabled)return;let{db:db22}=this.root,{_parsedProps:props}=this,{pcbX,pcbY}=this.getResolvedPcbPositionProp(),globalTransformRotation=this.getGlobalTransformRotation(),pcb_component23=db22.pcb_component.insert({footprint_origin:this._getGlobalPcbPositionBeforeLayout(),center:{x:pcbX,y:pcbY},width:2,height:3,layer:props.layer??"top",rotation:normalizeDegrees(globalTransformRotation),insertion_direction:this._getPcbComponentInsertionDirection(props.layer??"top",globalTransformRotation),source_component_id:this.source_component_id,subcircuit_id:this.getSubcircuit().subcircuit_id??void 0,do_not_place:props.doNotPlace??!1,obstructs_within_bounds:props.obstructsWithinBounds??!0,is_allowed_to_be_off_board:props.allowOffBoard??!1,metadata:props.kicadFootprintMetadata?{kicad_footprint:props.kicadFootprintMetadata}:void 0});this.pcb_component_id=pcb_component23.pcb_component_id}doInitialPcbPortAttachment(){let{db:db22}=this.root,pcb_ports=db22.pcb_port.list({pcb_component_id:this.pcb_component_id}),pinLabelToPortId={};for(let i23=0;i23<pcb_ports.length;i23++){let port=pcb_ports[i23],sourcePort=db22.source_port.get(port.source_port_id),pinLabel="";if(typeof sourcePort?.pin_number=="number")pinLabel=sourcePort.pin_number.toString();else if(Array.isArray(sourcePort?.port_hints)){let matchedHint=sourcePort.port_hints.find(h23=>/^(pin)?\d+$/.test(h23));matchedHint&&(/^pin\d+$/.test(matchedHint)?pinLabel=matchedHint.replace(/^pin/,""):pinLabel=matchedHint)}pinLabelToPortId[pinLabel]=port.pcb_port_id}let traces=db22.pcb_trace.list({pcb_component_id:this.pcb_component_id}),updatePortId=portId=>{if(portId&&typeof portId=="string"&&portId.startsWith("{PIN")){let pin=portId.replace("{PIN","").replace("}","");return pinLabelToPortId[pin]||portId}return portId};for(let trace of traces)if(trace.route)for(let segment5 of trace.route)segment5.route_type==="wire"&&(segment5.start_pcb_port_id=updatePortId(segment5.start_pcb_port_id),segment5.end_pcb_port_id=updatePortId(segment5.end_pcb_port_id))}},INTERCONNECT_STANDARD_FOOTPRINTS={"0402":"0402","0603":"0603","0805":"0805",1206:"1206"},Interconnect=class extends NormalComponent{get config(){return{componentName:"Interconnect",zodProps:interconnectProps,shouldRenderAsSchematicBox:!0,sourceFtype:"interconnect"}}get defaultInternallyConnectedPinNames(){let{standard}=this._parsedProps;return standard&&INTERCONNECT_STANDARD_FOOTPRINTS[standard]?[["pin1","pin2"]]:[]}_getImpliedFootprintString(){let{standard}=this._parsedProps;return standard?INTERCONNECT_STANDARD_FOOTPRINTS[standard]??null:null}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({ftype:"interconnect",name:this.name,manufacturer_part_number:resolveManufacturerPartNumber(props),supplier_part_numbers:props.supplierPartNumbers,are_pins_interchangeable:!0,display_name:props.displayName});this.source_component_id=source_component.source_component_id}doInitialSourceParentAttachment(){let{db:db22}=this.root,internallyConnectedPorts=this._getInternallyConnectedPins();for(let ports of internallyConnectedPorts){let sourcePortIds=ports.map(port=>port.source_port_id).filter(id3=>id3!==null);sourcePortIds.length>=2&&db22.source_component_internal_connection.insert({source_component_id:this.source_component_id,subcircuit_id:this.getSubcircuit()?.subcircuit_id,source_port_ids:sourcePortIds})}}},SolderJumper=class extends NormalComponent{constructor(){super(...arguments);__publicField(this,"schematicDimensions",null)}_getPinCountFromFootprintString(footprint){let match2=footprint.match(/^solderjumper([23])(?:_|$)/);return match2?Number(match2[1]):null}_getPinNumberFromBridgedPinsProp(pinName){let numericPinMatch=pinName.match(/^(?:pin)?(\d+)$/i);if(numericPinMatch)return Number(numericPinMatch[1]);let pinLabels=this._parsedProps.pinLabels??this.props.pinLabels;if(Array.isArray(pinLabels)){let labelIndex=pinLabels.findIndex(label=>label===pinName);return labelIndex>=0?labelIndex+1:null}if(pinLabels&&typeof pinLabels=="object")for(let[pinKey,labelOrLabels]of Object.entries(pinLabels)){if(!(Array.isArray(labelOrLabels)?labelOrLabels:[labelOrLabels]).includes(pinName))continue;let pinNumberMatch=pinKey.match(/^(?:pin)?(\d+)$/i);return pinNumberMatch?Number(pinNumberMatch[1]):null}return null}_getBridgedPinNumbersForFootprint(pinCount){let props=this._parsedProps??this.props;return Array.isArray(props.bridgedPins)&&props.bridgedPins.length>0?Array.from(new Set(props.bridgedPins.flat().map(pinName=>this._getPinNumberFromBridgedPinsProp(pinName)).filter(pinNumber2=>pinNumber2!==null&&pinNumber2>=1&&pinNumber2<=pinCount))).sort((a23,b23)=>a23-b23):props.bridged?Array.from({length:pinCount},(_23,index2)=>index2+1):[]}resolveFootprint(){let footprint=super.resolveFootprint();if(typeof footprint!="string")return footprint;let pinCount=this._getPinCountFromFootprintString(footprint);if(!pinCount||/_bridged\d+/.test(footprint))return footprint;let bridgedPinNumbers=this._getBridgedPinNumbersForFootprint(pinCount);return bridgedPinNumbers.length===0?footprint:footprint.replace(/^solderjumper[23]/,`solderjumper${pinCount}_bridged${bridgedPinNumbers.join("")}`)}_getPinNumberFromBridgedPinName(pinName){return this.selectOne(`port.${pinName}`,{type:"port"})?._parsedProps.pinNumber??null}get defaultInternallyConnectedPinNames(){if(this._parsedProps.bridged){let pins=this.children.filter(c23=>c23.componentName==="Port").map(p23=>p23.name);return pins.length>0?[pins]:[]}return this._parsedProps.bridgedPins??[]}get config(){let props=this._parsedProps??this.props,resolvedPinCount=props.pinCount;if(props.pinCount==null&&!props.footprint&&(resolvedPinCount=2),props.pinCount==null){let nums=(props.bridgedPins??[]).flat().map(p_str=>this._getPinNumberFromBridgedPinName(p_str)).filter(n23=>n23!==null),maxPinFromBridged=nums.length>0?Math.max(...nums):0,pinCountFromLabels=props.pinLabels?Object.keys(props.pinLabels).length:0,finalPinCount=Math.max(maxPinFromBridged,pinCountFromLabels);(finalPinCount===2||finalPinCount===3)&&(resolvedPinCount=finalPinCount),resolvedPinCount==null&&props.footprint&&[2,3].includes(this.getPortsFromFootprint().length)&&(resolvedPinCount=this.getPortsFromFootprint().length)}let symbolName="";resolvedPinCount?symbolName+=`solderjumper${resolvedPinCount}`:symbolName="solderjumper";let bridgedPinNumbers=[];return Array.isArray(props.bridgedPins)&&props.bridgedPins.length>0?bridgedPinNumbers=Array.from(new Set(props.bridgedPins.flat().map(pinName=>this._getPinNumberFromBridgedPinName(pinName)).filter(n23=>n23!==null))).sort((a23,b23)=>a23-b23):props.bridged&&resolvedPinCount&&(bridgedPinNumbers=Array.from({length:resolvedPinCount},(_23,i23)=>i23+1)),bridgedPinNumbers.length>0&&(symbolName+=`_bridged${bridgedPinNumbers.join("")}`),{schematicSymbolName:props.symbolName??symbolName,componentName:"SolderJumper",zodProps:solderjumperProps,shouldRenderAsSchematicBox:!0}}_getSchematicPortArrangement(){let arrangement=super._getSchematicPortArrangement();if(arrangement&&Object.keys(arrangement).length>0)return arrangement;let pinCount=this._parsedProps.pinCount??(Array.isArray(this._parsedProps.pinLabels)?this._parsedProps.pinLabels.length:this._parsedProps.pinLabels?Object.keys(this._parsedProps.pinLabels).length:this.getPortsFromFootprint().length);pinCount==null&&!this._parsedProps.footprint&&(pinCount=2);let direction4=this._parsedProps.schDirection??"right";return{leftSize:direction4==="left"?pinCount:0,rightSize:direction4==="right"?pinCount:0}}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,{pcbX,pcbY}=this.getResolvedPcbPositionProp(),source_component=db22.source_component.insert({ftype:"simple_chip",name:this.name,manufacturer_part_number:resolveManufacturerPartNumber(props),supplier_part_numbers:props.supplierPartNumbers,are_pins_interchangeable:!0,display_name:props.displayName});this.source_component_id=source_component.source_component_id}doInitialPcbComponentRender(){if(this.root?.pcbDisabled)return;let{db:db22}=this.root,{_parsedProps:props}=this,{pcbX,pcbY}=this.getResolvedPcbPositionProp(),globalTransformRotation=this.getGlobalTransformRotation(),pcb_component23=db22.pcb_component.insert({footprint_origin:this._getGlobalPcbPositionBeforeLayout(),center:{x:pcbX,y:pcbY},width:2,height:3,layer:props.layer??"top",rotation:normalizeDegrees(globalTransformRotation),insertion_direction:this._getPcbComponentInsertionDirection(props.layer??"top",globalTransformRotation),source_component_id:this.source_component_id,subcircuit_id:this.getSubcircuit().subcircuit_id??void 0,do_not_place:props.doNotPlace??!1,obstructs_within_bounds:props.obstructsWithinBounds??!0,is_allowed_to_be_off_board:props.allowOffBoard??!1,metadata:props.kicadFootprintMetadata?{kicad_footprint:props.kicadFootprintMetadata}:void 0});this.pcb_component_id=pcb_component23.pcb_component_id}doInitialPcbPortAttachment(){let{db:db22}=this.root,pcb_ports=db22.pcb_port.list({pcb_component_id:this.pcb_component_id}),pinLabelToPortId={};for(let i23=0;i23<pcb_ports.length;i23++){let port=pcb_ports[i23],sourcePort=db22.source_port.get(port.source_port_id),pinLabel="";if(typeof sourcePort?.pin_number=="number")pinLabel=sourcePort.pin_number.toString();else if(Array.isArray(sourcePort?.port_hints)){let matchedHint=sourcePort.port_hints.find(h23=>/^(pin)?\d+$/.test(h23));matchedHint&&(/^pin\d+$/.test(matchedHint)?pinLabel=matchedHint.replace(/^pin/,""):pinLabel=matchedHint)}pinLabelToPortId[pinLabel]=port.pcb_port_id}let traces=db22.pcb_trace.list({pcb_component_id:this.pcb_component_id}),updatePortId=portId=>{if(portId&&typeof portId=="string"&&portId.startsWith("{PIN")){let pin=portId.replace("{PIN","").replace("}","");return pinLabelToPortId[pin]||portId}return portId};for(let trace of traces)if(trace.route)for(let segment5 of trace.route)segment5.route_type==="wire"&&(segment5.start_pcb_port_id=updatePortId(segment5.start_pcb_port_id),segment5.end_pcb_port_id=updatePortId(segment5.end_pcb_port_id))}},PowerSource=class extends NormalComponent{constructor(){super(...arguments);__publicField(this,"pos",this.portMap.pin1);__publicField(this,"positive",this.portMap.pin1);__publicField(this,"neg",this.portMap.pin2);__publicField(this,"negative",this.portMap.pin2)}get config(){return{schematicSymbolName:this.props.symbolName??"power_factor_meter_horz",componentName:"PowerSource",zodProps:powerSourceProps,sourceFtype:"simple_power_source"}}initPorts(){this.add(new Port({name:"pin1",pinNumber:1,aliases:["positive","pos"]})),this.add(new Port({name:"pin2",pinNumber:2,aliases:["negative","neg"]}))}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({ftype:"simple_power_source",name:this.name,voltage:props.voltage,supplier_part_numbers:props.supplierPartNumbers,manufacturer_part_number:resolveManufacturerPartNumber(props),are_pins_interchangeable:!1,display_name:props.displayName});this.source_component_id=source_component.source_component_id}},VoltageSource2=class extends NormalComponent{constructor(){super(...arguments);__publicField(this,"simulation_voltage_source_id",null);__publicField(this,"terminal1",this.portMap.terminal1);__publicField(this,"terminal2",this.portMap.terminal2)}get config(){return{componentName:"VoltageSource",schematicSymbolName:this.props.waveShape==="square"?"square_wave":"ac_voltmeter",zodProps:voltageSourceProps,sourceFtype:"simple_voltage_source"}}runRenderPhaseForChildren(phase){if(!phase.startsWith("Pcb"))for(let child of this.children)child.runRenderPhaseForChildren(phase),child.runRenderPhase(phase)}doInitialPcbComponentRender(){let hasExplicitPcbPosition=this._hasUserDefinedPcbPosition();if(!this._parsedProps.footprint){if(!hasExplicitPcbPosition)return;throw new Error("VoltageSource requires a footprint when pcbX/pcbY or pcb edge position props are used")}super.doInitialPcbComponentRender()}initPorts(){super.initPorts({additionalAliases:{pin1:["terminal1"],pin2:["terminal2"]}})}_getSchematicSymbolDisplayValue(){let{voltage:voltage32,frequency:frequency32}=this._parsedProps,parts=[];return voltage32!==void 0&&parts.push(`${formatSiUnit(voltage32)}V`),frequency32!==void 0&&parts.push(`${formatSiUnit(frequency32)}Hz`),parts.length>0?parts.join(" "):void 0}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({ftype:"simple_voltage_source",name:this.name,voltage:props.voltage,frequency:props.frequency,peak_to_peak_voltage:props.peakToPeakVoltage,wave_shape:props.waveShape,phase:props.phase,duty_cycle:props.dutyCycle,pulse_delay:props.pulseDelay,rise_time:props.riseTime,fall_time:props.fallTime,pulse_width:props.pulseWidth,period:props.period,supplier_part_numbers:props.supplierPartNumbers,manufacturer_part_number:resolveManufacturerPartNumber(props),are_pins_interchangeable:!0,display_name:props.displayName});this.source_component_id=source_component.source_component_id}doInitialSimulationRender(){let{db:db22}=this.root,{_parsedProps:props}=this,terminal1Port=this.portMap.terminal1,terminal2Port=this.portMap.terminal2,simulationVoltageSource=db22.simulation_voltage_source.insert({is_dc_source:!1,terminal1_source_port_id:terminal1Port.source_port_id??void 0,terminal2_source_port_id:terminal2Port.source_port_id??void 0,voltage:props.voltage,frequency:props.frequency,peak_to_peak_voltage:props.peakToPeakVoltage,wave_shape:props.waveShape,phase:props.phase,duty_cycle:props.dutyCycle,pulse_delay:props.pulseDelay,rise_time:props.riseTime,fall_time:props.fallTime,pulse_width:props.pulseWidth,period:props.period,ac_magnitude:props.acMagnitude,ac_phase:props.acPhase});this.simulation_voltage_source_id=simulationVoltageSource.simulation_voltage_source_id}},CurrentSource2=class extends NormalComponent{constructor(){super(...arguments);__publicField(this,"simulation_current_source_id",null);__publicField(this,"pos",this.portMap.pos);__publicField(this,"neg",this.portMap.neg)}get config(){return{componentName:"CurrentSource",schematicSymbolName:"current_source",zodProps:currentSourceProps,sourceFtype:"simple_current_source"}}runRenderPhaseForChildren(phase){if(!phase.startsWith("Pcb"))for(let child of this.children)child.runRenderPhaseForChildren(phase),child.runRenderPhase(phase)}doInitialPcbComponentRender(){let hasExplicitPcbPosition=this._hasUserDefinedPcbPosition();if(!this._parsedProps.footprint){if(!hasExplicitPcbPosition)return;throw new Error("CurrentSource requires a footprint when pcbX/pcbY or pcb edge position props are used")}super.doInitialPcbComponentRender()}initPorts(){super.initPorts({additionalAliases:{pin1:["pos"],pin2:["neg"]}})}_getSchematicSymbolDisplayValue(){let{current:current23,frequency:frequency32,peakToPeakCurrent}=this._parsedProps,parts=[];return current23!==void 0&&parts.push(`${formatSiUnit(current23)}A`),peakToPeakCurrent!==void 0&&parts.push(`${formatSiUnit(peakToPeakCurrent)}A p-p`),frequency32!==void 0&&parts.push(`${formatSiUnit(frequency32)}Hz`),parts.length>0?parts.join(" "):void 0}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({ftype:"simple_current_source",name:this.name,current:props.current,frequency:props.frequency,peak_to_peak_current:props.peakToPeakCurrent,wave_shape:props.waveShape,phase:props.phase,duty_cycle:props.dutyCycle,supplier_part_numbers:props.supplierPartNumbers,manufacturer_part_number:resolveManufacturerPartNumber(props),are_pins_interchangeable:!0,display_name:props.displayName});this.source_component_id=source_component.source_component_id}doInitialSimulationRender(){let{db:db22}=this.root,{_parsedProps:props}=this,isAc=props.frequency!==void 0||props.peakToPeakCurrent!==void 0||props.waveShape!==void 0||props.acMagnitude!==void 0||props.acPhase!==void 0,posPort=this.portMap.pos,negPort=this.portMap.neg;if(isAc){let simulationCurrentSource=db22.simulation_current_source.insert({is_dc_source:!1,terminal1_source_port_id:posPort.source_port_id??void 0,terminal2_source_port_id:negPort.source_port_id??void 0,current:props.current,frequency:props.frequency,peak_to_peak_current:props.peakToPeakCurrent,wave_shape:props.waveShape,phase:props.phase,duty_cycle:props.dutyCycle,ac_magnitude:props.acMagnitude,ac_phase:props.acPhase});this.simulation_current_source_id=simulationCurrentSource.simulation_current_source_id}else{if(props.current===void 0)return;let simulationCurrentSource=db22.simulation_current_source.insert({is_dc_source:!0,positive_source_port_id:posPort.source_port_id??void 0,negative_source_port_id:negPort.source_port_id??void 0,current:props.current,ac_magnitude:props.acMagnitude,ac_phase:props.acPhase});this.simulation_current_source_id=simulationCurrentSource.simulation_current_source_id}}},PLACEMENT_MARGIN=.25,rectForComponent=(component,margin)=>({left:component.center.x-component.size.width/2-margin,right:component.center.x+component.size.width/2+margin,bottom:component.center.y-component.size.height/2-margin,top:component.center.y+component.size.height/2+margin}),rectsOverlap4=(a23,b23)=>a23.left<b23.right&&a23.right>b23.left&&a23.bottom<b23.top&&a23.top>b23.bottom,getCandidateCenters=({baseCenter,size:size23})=>{let xStep=size23.width+PLACEMENT_MARGIN*2,yStep=size23.height+PLACEMENT_MARGIN*2;return[baseCenter,{x:baseCenter.x,y:baseCenter.y+yStep},{x:baseCenter.x,y:baseCenter.y-yStep},{x:baseCenter.x+xStep,y:baseCenter.y},{x:baseCenter.x-xStep,y:baseCenter.y},{x:baseCenter.x+xStep,y:baseCenter.y+yStep},{x:baseCenter.x-xStep,y:baseCenter.y+yStep},{x:baseCenter.x+xStep,y:baseCenter.y-yStep},{x:baseCenter.x-xStep,y:baseCenter.y-yStep},{x:baseCenter.x,y:baseCenter.y+yStep*2},{x:baseCenter.x,y:baseCenter.y-yStep*2}]},getConnectedSchematicPort=({ammeterSourcePortId,schematicPorts,sourceTraces})=>{for(let sourceTrace of sourceTraces){if(!sourceTrace.connected_source_port_ids.includes(ammeterSourcePortId))continue;let connectedSourcePortId=sourceTrace.connected_source_port_ids.find(sourcePortId=>sourcePortId!==ammeterSourcePortId);if(connectedSourcePortId===void 0)continue;let schematicPort=schematicPorts.find(port=>port.source_port_id===connectedSourcePortId);if(schematicPort)return schematicPort}return null},midpoint22=ports=>({x:ports.reduce((sum,port)=>sum+port.center.x,0)/ports.length,y:ports.reduce((sum,port)=>sum+port.center.y,0)/ports.length}),shiftAmmeterSchematicElements=({ammeter,db:db22,oldCenter,newCenter})=>{let schematicComponentId=ammeter.schematic_component_id;if(!schematicComponentId)return;let deltaX=newCenter.x-oldCenter.x,deltaY=newCenter.y-oldCenter.y;if(!(deltaX===0&&deltaY===0)){db22.schematic_component.update(schematicComponentId,{center:newCenter});for(let port of db22.schematic_port.list({schematic_component_id:schematicComponentId}))db22.schematic_port.update(port.schematic_port_id,{center:{x:port.center.x+deltaX,y:port.center.y+deltaY}});for(let text4 of db22.schematic_text.list({schematic_component_id:schematicComponentId}))db22.schematic_text.update(text4.schematic_text_id,{position:{x:text4.position.x+deltaX,y:text4.position.y+deltaY}});updateSchematicPrimitivesForLayoutShift({db:db22,schematicComponentId,deltaX,deltaY})}},Ammeter_doInitialSchematicLayout=ammeter=>{let{root}=ammeter;if(!root||root.schematicDisabled||!ammeter.schematic_component_id||ammeter._parsedProps.schX!==void 0||ammeter._parsedProps.schY!==void 0||ammeter.getGroup()?._getSchematicLayoutMode()!=="relative")return;let{db:db22}=root,schematicComponent=db22.schematic_component.get(ammeter.schematic_component_id);if(!schematicComponent)return;let ammeterSourcePortIds=[ammeter.portMap.pos.source_port_id,ammeter.portMap.neg.source_port_id].filter(sourcePortId=>typeof sourcePortId=="string");if(ammeterSourcePortIds.length===0)return;let schematicPorts=db22.schematic_port.list(),sourceTraces=db22.source_trace.list(),connectedSchematicPorts=ammeterSourcePortIds.map(ammeterSourcePortId=>getConnectedSchematicPort({ammeterSourcePortId,schematicPorts,sourceTraces})).filter(port=>port!==null);if(connectedSchematicPorts.length===0)return;let baseCenter=midpoint22(connectedSchematicPorts),obstacles=db22.schematic_component.list().filter(component=>component.schematic_component_id!==schematicComponent.schematic_component_id&&!component.is_schematic_group&&component.schematic_sheet_id===schematicComponent.schematic_sheet_id).map(component=>rectForComponent(component,PLACEMENT_MARGIN)),bestCenter=getCandidateCenters({baseCenter,size:schematicComponent.size}).find(candidateCenter=>{let candidateRect=rectForComponent({...schematicComponent,center:candidateCenter},PLACEMENT_MARGIN);return!obstacles.some(obstacle=>rectsOverlap4(candidateRect,obstacle))})??baseCenter;shiftAmmeterSchematicElements({ammeter,db:db22,oldCenter:schematicComponent.center,newCenter:bestCenter})},Ammeter=class extends NormalComponent{constructor(){super(...arguments);__publicField(this,"simulation_current_probe_id",null);__publicField(this,"pos",this.portMap.pos);__publicField(this,"neg",this.portMap.neg)}get config(){return{componentName:"Ammeter",schematicSymbolName:"dc_ammeter",zodProps:ammeterProps,sourceFtype:"simple_ammeter"}}runRenderPhaseForChildren(phase){if(!phase.startsWith("Pcb"))for(let child of this.children)child.runRenderPhaseForChildren(phase),child.runRenderPhase(phase)}doInitialPcbComponentRender(){let hasExplicitPcbPosition=this._hasUserDefinedPcbPosition();if(!this._parsedProps.footprint){if(!hasExplicitPcbPosition)return;throw new Error("Ammeter requires a footprint when pcbX/pcbY or pcb edge position props are used")}super.doInitialPcbComponentRender()}initPorts(){super.initPorts({ignoreSymbolPorts:!0,pinCount:2,additionalAliases:{pin1:["pos"],pin2:["neg"]}});let symbol=cc[this._getSchematicSymbolNameOrThrow()];this.portMap.pos.schematicSymbolPortDef=symbol.ports.find(port=>port.labels.includes("1"))??null,this.portMap.neg.schematicSymbolPortDef=symbol.ports.find(port=>port.labels.includes("2"))??null}doInitialSourceRender(){let{db:db22}=this.root,{supplierPartNumbers,displayName}=this._parsedProps,source_component=db22.source_component.insert({ftype:"simple_ammeter",name:this.name,supplier_part_numbers:supplierPartNumbers,manufacturer_part_number:resolveManufacturerPartNumber(this._parsedProps),display_name:displayName});this.source_component_id=source_component.source_component_id}doInitialSimulationRender(){let{db:db22}=this.root,{color:color32,graphDisplayName,graphCenter,graphVerticalOffset,graphCurrentPerDiv}=this._parsedProps,posPort=this.portMap.pos,negPort=this.portMap.neg,{simulation_current_probe_id}=db22.simulation_current_probe.insert({type:"simulation_current_probe",name:this.name,source_component_id:this.source_component_id,positive_source_port_id:posPort.source_port_id,negative_source_port_id:negPort.source_port_id,subcircuit_id:this.getSubcircuit()?.subcircuit_id??void 0,color:color32});if(this.simulation_current_probe_id=simulation_current_probe_id,graphDisplayName!==void 0||graphCenter!==void 0||graphVerticalOffset!==void 0||graphCurrentPerDiv!==void 0){let graphCurrentPerDivValue=parseSimulationGraphValue(graphCurrentPerDiv),graphVerticalOffsetValue=parseSimulationGraphValue(graphVerticalOffset);db22.simulation_oscilloscope_trace.insert({simulation_current_probe_id,display_name:graphDisplayName,color:color32,display_center_value:graphCenter,amps_per_div:graphCurrentPerDivValue,display_center_offset_divs:graphVerticalOffsetValue!==void 0&&graphCurrentPerDivValue!==void 0&&graphCurrentPerDivValue!==0?graphVerticalOffsetValue/graphCurrentPerDivValue:void 0})}}doInitialSchematicLayout(){Ammeter_doInitialSchematicLayout(this)}},edgeSpecifiers=["leftedge","rightedge","topedge","bottomedge","center"],Constraint3=class extends PrimitiveComponent{get config(){return{componentName:"Constraint",zodProps:constraintProps}}constructor(props){if(super(props),("xdist"in props||"ydist"in props)&&!("edgeToEdge"in props)&&!("centerToCenter"in props))throw new Error(`edgeToEdge, centerToCenter must be set for xDist or yDist for ${this}`);if("for"in props&&props.for.length<2)throw new Error(`"for" must have at least two selectors for ${this}`)}_getAllReferencedComponents(){let componentsWithSelectors=[],container=this.getPrimitiveContainer();function addComponentFromSelector(selector2){let maybeEdge=selector2.split(" ").pop(),edge=edgeSpecifiers.includes(maybeEdge)?maybeEdge:void 0,componentSelector=edge?selector2.replace(` ${edge}`,""):selector2,component=container.selectOne(componentSelector,{pcbPrimitive:!0});component&&componentsWithSelectors.push({selector:selector2,component,componentSelector,edge})}for(let key of["left","right","top","bottom"])key in this._parsedProps&&addComponentFromSelector(this._parsedProps[key]);if("for"in this._parsedProps)for(let selector2 of this._parsedProps.for)addComponentFromSelector(selector2);return{componentsWithSelectors}}},isSelectionResultPort=connectable=>!connectable||typeof connectable!="object"?!1:typeof connectable.getSourcePort=="function",isSelectionResultNet=connectable=>!connectable||typeof connectable!="object"?!1:typeof connectable.getSourceNet=="function",isSelectionResultComponent=connectable=>!connectable||typeof connectable!="object"?!1:typeof connectable.getPorts=="function",isCircuitJsonElement=connectable=>!connectable||typeof connectable!="object"?!1:typeof connectable.type=="string",isNonEmptyString=value=>typeof value=="string"&&value.length>0,SelectionResultPortImpl=class{constructor(port){__publicField(this,"port");this.port=port}getPcbPort(){let pcbPortId=this.port.pcb_port_id;return pcbPortId?this.port.root?.db.pcb_port.get(pcbPortId)??null:null}getSourcePort(){let sourcePortId=this.port.source_port_id;return sourcePortId?this.port.root?.db.source_port.get(sourcePortId)??null:null}},SelectionResultNetImpl=class{constructor(net){__publicField(this,"net");this.net=net}getSourceNet(){let sourceNetId=this.net.source_net_id;return sourceNetId?this.net.root?.db.source_net.get(sourceNetId)??null:null}},SelectionResultComponentImpl=class{constructor(component){__publicField(this,"component");this.component=component}getPort(name){let port=this.component.selectOne(`port.${name}`,{type:"port"})??this.component.selectOne(`.${name}`,{type:"port"});return port?new SelectionResultPortImpl(port):null}getPorts(){return this.component.selectAll("port").map(port=>new SelectionResultPortImpl(port))}getPcbComponent(){let pcbComponentId=this.component.pcb_component_id;return pcbComponentId?this.component.root?.db.pcb_component.get(pcbComponentId)??null:null}getSourceComponent(){let sourceComponentId=this.component.source_component_id;return sourceComponentId?this.component.root?.db.source_component.get(sourceComponentId)??null:null}},DrcCheck=class extends PrimitiveComponent{get config(){return{componentName:"DrcCheck",zodProps:drcCheckProps}}constructor(props){super(props)}async runCustomDrcCheck(circuitJson){let result=await this._parsedProps.checkFn(this.createCustomDrcCheckContext(circuitJson)),diagnostics=[];return Array.isArray(result)?diagnostics=result:result&&(diagnostics=[result]),diagnostics.map((diagnostic,index2)=>this.createCircuitJsonDiagnostic(diagnostic,index2)).filter(diagnostic=>!!diagnostic)}createCustomDrcCheckContext(circuitJson){return{select:this.selectCustomDrcElement.bind(this),selectAll:this.selectAllCustomDrcElements.bind(this),isConnected:(a23,b23)=>this.isConnected(a23,b23,circuitJson),isPulledUp:a23=>this.isConnected(a23,"net.VCC",circuitJson)||this.isConnected(a23,"net.VDD",circuitJson)||this.getResistanceBetween(a23,"net.VCC",circuitJson)!==null||this.getResistanceBetween(a23,"net.VDD",circuitJson)!==null,isPulledDown:a23=>this.isConnected(a23,"net.GND",circuitJson)||this.getResistanceBetween(a23,"net.GND",circuitJson)!==null,getResistanceBetween:(a23,b23)=>this.getResistanceBetween(a23,b23,circuitJson)}}selectCustomDrcElement(selector2){return this.wrapSelectionResult(this.getSubcircuit().selectOne(selector2))}selectAllCustomDrcElements(selector2){let selectionResults=[];for(let component of this.getSubcircuit().selectAll(selector2)){let selectionResult=this.wrapSelectionResult(component);selectionResult&&selectionResults.push(selectionResult)}return selectionResults}wrapSelectionResult(component){return component?component instanceof Port?new SelectionResultPortImpl(component):component instanceof Net?new SelectionResultNetImpl(component):new SelectionResultComponentImpl(component):null}createCircuitJsonDiagnostic(diagnostic,index2){let diagnosticRecord=diagnostic,diagnosticType="source_component_misconfigured_error";typeof diagnosticRecord.error_type=="string"?diagnosticType=diagnosticRecord.error_type:typeof diagnosticRecord.warning_type=="string"&&(diagnosticType=diagnosticRecord.warning_type);let diagnosticWithCircuitJsonDefaults={...diagnostic};typeof diagnosticRecord.type=="string"?diagnosticWithCircuitJsonDefaults.type=diagnosticRecord.type:diagnosticWithCircuitJsonDefaults.type=diagnosticType,typeof diagnosticRecord.warning_type!="string"&&(typeof diagnosticRecord.error_type=="string"?diagnosticWithCircuitJsonDefaults.error_type=diagnosticRecord.error_type:diagnosticWithCircuitJsonDefaults.error_type=diagnosticType);let diagnosticIdField=`${diagnosticType}_id`;return diagnosticRecord[diagnosticIdField]?diagnosticWithCircuitJsonDefaults[diagnosticIdField]=diagnosticRecord[diagnosticIdField]:diagnosticWithCircuitJsonDefaults[diagnosticIdField]=`${diagnosticType}_${this._renderId}_${index2}`,any_circuit_element.parse(diagnosticWithCircuitJsonDefaults)}isConnected(a23,b23,circuitJson){let aKeys=this.getConnectivityKeys(a23,circuitJson),bKeys=this.getConnectivityKeys(b23,circuitJson);return aKeys.some(key=>bKeys.includes(key))}getResistanceBetween(a23,b23,circuitJson){if(this.isConnected(a23,b23,circuitJson))return 0;let aKeys=this.getConnectivityKeys(a23,circuitJson),bKeys=this.getConnectivityKeys(b23,circuitJson);if(aKeys.length===0||bKeys.length===0)return null;let sourceResistors=circuitJson.filter(elm=>elm.type==="source_component"&&elm.ftype==="simple_resistor"),root=this.root;if(!root)return null;for(let resistor of sourceResistors){let resistorPorts=root.db.source_port.list({source_component_id:resistor.source_component_id});if(resistorPorts.length!==2)continue;let resistorKeys=resistorPorts.map(port=>port.subcircuit_connectivity_map_key),connectsA=resistorKeys.some(key=>key&&aKeys.includes(key)),connectsB=resistorKeys.some(key=>key&&bKeys.includes(key));if(connectsA&&connectsB)return resistor.resistance}return null}getConnectivityKeys(connectable,circuitJson){if(!connectable)return[];if(typeof connectable=="string"){let selected=this.selectCustomDrcElement(connectable);return selected?this.getConnectivityKeys(selected,circuitJson):[]}return isSelectionResultPort(connectable)?[connectable.getSourcePort()?.subcircuit_connectivity_map_key].filter(isNonEmptyString):isSelectionResultNet(connectable)?[connectable.getSourceNet()?.subcircuit_connectivity_map_key].filter(isNonEmptyString):isSelectionResultComponent(connectable)?connectable.getPorts().flatMap(port=>this.getConnectivityKeys(port,circuitJson)):isCircuitJsonElement(connectable)?this.getCircuitJsonElementConnectivityKeys(connectable,circuitJson):[]}getCircuitJsonElementConnectivityKeys(element2,circuitJson){if(!element2)return[];if(element2.type==="source_port")return[element2.subcircuit_connectivity_map_key].filter(isNonEmptyString);if(element2.type==="source_net")return[element2.subcircuit_connectivity_map_key].filter(isNonEmptyString);if(element2.type==="pcb_port")return this.getConnectivityKeys(element2.source_port_id,circuitJson);if(element2.type==="source_component"){let root=this.root;return root?root.db.source_port.list({source_component_id:element2.source_component_id}).map(port=>port.subcircuit_connectivity_map_key).filter(isNonEmptyString):[]}return[]}},AutoroutingPhase=class extends PrimitiveComponent{get config(){return{componentName:"AutoroutingPhase",zodProps:autoroutingPhaseProps}}add(_component){throw new Error("<autoroutingphase> cannot contain children")}},AutoplacedBreakoutPoint=class extends BaseBreakoutPoint{get config(){return{componentName:"AutoplacedBreakoutPoint",zodProps:baseBreakoutPointProps}}_applySolvedBreakoutPoint({sourceTraceId,layer,position:position22}){this.matchedSourceTraceId=sourceTraceId,this._renderPcbBreakoutPoint({layer:layer_ref.parse(layer)}),this._setPositionFromLayout(position22)}},DDR_BYTE0_PORTS=[{id:"DQ0",layer:"inner3",soc:{x:-6,y:-3},ram:{x:3.941917,y:-3.650917}},{id:"DQ1",layer:"inner6",fullLayer:"inner2",soc:{x:-5.5,y:-3},ram:{x:4.591917,y:-3.650917}},{id:"DQ2",layer:"inner5",fullLayer:"inner4",soc:{x:-4.5,y:-3},ram:{x:5.891917,y:-3.650917}},{id:"DQ3",layer:"inner2",fullLayer:"inner6",soc:{x:-4.5,y:-3.5},ram:{x:6.541917,y:-3.650917}},{id:"DQ4",layer:"inner3",fullLayer:"inner2",soc:{x:-6,y:-2.5},ram:{x:6.541917,y:-2.050917}},{id:"DQ5",layer:"inner2",fullLayer:"inner5",soc:{x:-6,y:-2},ram:{x:5.891917,y:-2.050917}},{id:"DQ6",layer:"inner5",fullLayer:"inner4",soc:{x:-5,y:-2},ram:{x:4.591917,y:-2.050917}},{id:"DQ7",layer:"inner4",fullLayer:"inner6",soc:{x:-5.5,y:-2},ram:{x:3.941917,y:-2.050917}},{id:"DM0",layer:"inner4",fullLayer:"inner5",soc:{x:-5,y:-3},ram:{x:4.591917,y:-2.850917}},{id:"DQS0",layer:"inner1",differentialPairId:"DQS0",soc:{x:-4.5,y:-2.5},ram:{x:5.241917,y:-2.850917}},{id:"DQS0_n",layer:"inner1",differentialPairId:"DQS0",soc:{x:-5,y:-2.5},ram:{x:5.891917,y:-2.850917}}],DDR_BYTE1_PORTS=[{id:"DQ8",layer:"inner6",fullLayer:"inner4",soc:{x:-6,y:3},ram:{x:3.941917,y:3.549083}},{id:"DQ9",layer:"inner3",fullLayer:"inner4",soc:{x:-5.5,y:2},ram:{x:4.591917,y:3.549083}},{id:"DQ10",layer:"inner3",fullLayer:"inner2",soc:{x:-4.5,y:2},ram:{x:5.891917,y:3.549083}},{id:"DQ11",layer:"inner6",fullLayer:"inner5",soc:{x:-4.5,y:2.5},ram:{x:6.541917,y:3.549083}},{id:"DQ12",layer:"inner5",fullLayer:"inner1",soc:{x:-6,y:2.5},ram:{x:6.541917,y:1.949083}},{id:"DQ13",layer:"inner2",fullLayer:"inner3",soc:{x:-6.5,y:3},ram:{x:5.891917,y:1.949083}},{id:"DQ14",layer:"inner5",fullLayer:"inner6",soc:{x:-5,y:2.5},ram:{x:4.591917,y:1.949083}},{id:"DQ15",layer:"inner4",fullLayer:"inner1",soc:{x:-4.5,y:3.5},ram:{x:3.941917,y:1.949083}},{id:"DM1",layer:"inner4",fullLayer:"inner5",soc:{x:-5,y:3.5},ram:{x:4.591917,y:2.749083}},{id:"DQS1",layer:"inner1",fullLayer:"bottom",differentialPairId:"DQS1",soc:{x:-4.5,y:3},ram:{x:5.241917,y:2.749083}},{id:"DQS1_n",layer:"inner1",fullLayer:"bottom",differentialPairId:"DQS1",soc:{x:-5,y:3},ram:{x:5.891917,y:2.749083}}],DDR_ADDR_CTRL_PORTS=[{id:"A0",layer:"bottom",soc:{x:-6.5,y:-.5},ram:{x:7.841917,y:-3.650917}},{id:"A1",layer:"inner3",soc:{x:-7,y:-2},ram:{x:8.491917,y:-3.650917}},{id:"A2",layer:"inner3",soc:{x:-7,y:-.5},ram:{x:7.841917,y:1.949083}},{id:"A3",layer:"inner6",soc:{x:-5,y:-1},ram:{x:7.841917,y:2.749083}},{id:"A4",layer:"inner4",soc:{x:-4.5,y:-1.5},ram:{x:7.841917,y:3.549083}},{id:"A5",layer:"inner2",soc:{x:-6.5,y:-2},ram:{x:8.491917,y:3.549083}},{id:"CS0_n",layer:"inner5",soc:{x:-5.5,y:-.5},ram:{x:7.841917,y:-2.050917}},{id:"CKE0",layer:"inner1",soc:{x:-4.5,y:-1},ram:{x:8.491917,y:-2.050917}},{id:"CK0",layer:"bottom",differentialPairId:"CK0",soc:{x:-4.5,y:1},ram:{x:8.491917,y:1.149083}},{id:"CK0_n",layer:"bottom",differentialPairId:"CK0",soc:{x:-5,y:1},ram:{x:8.491917,y:1.949083}},{id:"DDR_LINK_RESET0_n",layer:"inner6",soc:{x:-5,y:-1.5},ram:{x:13.041917,y:3.549083}}],createAm62lExample=options=>{let ports=options.buses.flatMap(bus=>bus.ports),addedPairIds=new Set,makeEndpoints=port=>[{regionId:"soc",position:port.soc},{regionId:"ram",position:port.ram}],connections=[];for(let port of ports){if(!port.differentialPairId){connections.push({id:port.id,endpoints:makeEndpoints(port)});continue}if(addedPairIds.has(port.differentialPairId))continue;addedPairIds.add(port.differentialPairId);let pair=ports.filter(candidate=>candidate.differentialPairId===port.differentialPairId);if(pair.length!==2)throw new Error(`Differential pair ${port.differentialPairId} must have two members`);let[first,second]=pair;connections.push({type:"differential",connections:[{id:first.id,endpoints:makeEndpoints(first)},{id:second.id,endpoints:makeEndpoints(second)}]})}let buses=options.buses.map(bus=>{let solverBus={id:bus.id,connectionIds:bus.ports.map(port=>port.id)};return bus.preferredLayer!==void 0&&(solverBus={...solverBus,preferredLayer:bus.preferredLayer}),bus.preferredLayers!==void 0&&(solverBus={...solverBus,preferredLayers:bus.preferredLayers}),solverBus});return{regions:[{id:"soc",bounds:{minX:-16.62808,maxX:-2.37192,minY:-10.62808,maxY:10.62808},edge:"right"},{id:"ram",bounds:{minX:1.091917,maxX:18.141917,minY:-9.650917,maxY:9.549083},edge:"left"}],connections,buses,boundaryPointSpacing:.48}},ddrByte0Example=createAm62lExample({buses:[{id:"DDR_BYTE0",ports:DDR_BYTE0_PORTS,preferredLayers:["inner1","inner4"]}]}),ddrByte1Example=createAm62lExample({buses:[{id:"DDR_BYTE1",ports:DDR_BYTE1_PORTS,preferredLayers:["inner2","inner5"]}]}),fullDdrExample=createAm62lExample({buses:[{id:"DDR_BYTE0",ports:DDR_BYTE0_PORTS,preferredLayers:["inner1","inner4"]},{id:"DDR_BYTE1",ports:DDR_BYTE1_PORTS,preferredLayers:["inner2","inner5"]},{id:"DDR_ADDR_CTRL",ports:DDR_ADDR_CTRL_PORTS,preferredLayers:["inner3","inner6"]}]}),controlBusExample=createAm62lExample({buses:[{id:"DDR_ADDR_CTRL",ports:DDR_ADDR_CTRL_PORTS,preferredLayers:["inner3","inner6"]}]}),WindingBreakoutInputError=class extends Error{constructor(){super(...arguments);__publicField(this,"name","WindingBreakoutInputError")}},WindingBreakoutInfeasibleError=class extends Error{constructor(){super(...arguments);__publicField(this,"name","WindingBreakoutInfeasibleError")}},WindingBreakoutInvariantError=class extends Error{constructor(){super(...arguments);__publicField(this,"name","WindingBreakoutInvariantError")}},WindingBreakoutOutputUnavailableError=class extends Error{constructor(){super(...arguments);__publicField(this,"name","WindingBreakoutOutputUnavailableError")}},getCanonicalConnections=input2=>{let connections=[];for(let entry of input2.connections)"type"in entry?connections.push(...entry.connections):connections.push(entry);return connections},getBusLayerCandidates=bus=>bus.preferredLayer!==void 0?[bus.preferredLayer]:bus.preferredLayers!==void 0?[...new Set(bus.preferredLayers)]:["top"],getLayerCandidatesByConnection=input2=>{let candidatesByConnection=new Map;for(let bus of input2.buses){let candidates=getBusLayerCandidates(bus);for(let connectionId of bus.connectionIds)candidatesByConnection.set(connectionId,candidates)}return Object.fromEntries(getCanonicalConnections(input2).map(connection=>[connection.id,candidatesByConnection.get(connection.id)??["top"]]))},fail=message=>{throw new WindingBreakoutInputError(`WindingBreakoutSolver: ${message}`)},isRecord=value=>typeof value=="object"&&value!==null&&!Array.isArray(value),requireRecord=(value,label)=>{isRecord(value)||fail(`${label} must be an object`)},requireId=(value,label)=>{(typeof value!="string"||value.trim().length===0)&&fail(`${label} must be a non-empty string`)},requireFinite=(value,label)=>{(typeof value!="number"||!Number.isFinite(value))&&fail(`${label} must be finite`)},requirePositive=(value,label)=>{requireFinite(value,label),value<=0&&fail(`${label} must be positive`)},requireArray=(value,message)=>Array.isArray(value)?value:fail(message),validatePoint=(value,label)=>(requireRecord(value,label),requireFinite(value.x,`${label}.x`),requireFinite(value.y,`${label}.y`),value),validateBounds=(value,label)=>(requireRecord(value,label),requireFinite(value.minX,`${label}.minX`),requireFinite(value.maxX,`${label}.maxX`),requireFinite(value.minY,`${label}.minY`),requireFinite(value.maxY,`${label}.maxY`),(value.minX>=value.maxX||value.minY>=value.maxY)&&fail(`${label} must have positive width and height`),{minX:value.minX,maxX:value.maxX,minY:value.minY,maxY:value.maxY}),pointIsInsideBounds4=(point12,bounds)=>point12.x>=bounds.minX&&point12.x<=bounds.maxX&&point12.y>=bounds.minY&&point12.y<=bounds.maxY,validateWindingBreakoutInput=input2=>{(!Array.isArray(input2.regions)||input2.regions.length===0)&&fail("at least one region is required"),requirePositive(input2.boundaryPointSpacing,"boundaryPointSpacing");let regionIds=new Set,regions=input2.regions.map((value,index2)=>{requireRecord(value,`regions[${index2}]`),requireId(value.id,`regions[${index2}].id`),regionIds.has(value.id)&&fail(`duplicate region id "${value.id}"`),regionIds.add(value.id);let bounds=validateBounds(value.bounds,`region "${value.id}" bounds`);return(typeof value.edge!="string"||!new Set(["left","right","bottom","top"]).has(value.edge))&&fail(`region "${value.id}" has invalid edge`),{id:value.id,bounds,edge:value.edge,center:{x:(bounds.minX+bounds.maxX)/2,y:(bounds.minY+bounds.maxY)/2}}}),vertical=regions.every(region=>region.edge==="left"||region.edge==="right"),horizontal=regions.every(region=>region.edge==="bottom"||region.edge==="top");!vertical&&!horizontal&&fail("all coordinated region edges must be parallel"),(!Array.isArray(input2.connections)||input2.connections.length===0)&&fail("at least one connection is required");let connections=[],connectionIds=new Set,atomicConnectionGroups=[],validateConnection=(value,label)=>{requireRecord(value,label),requireId(value.id,`${label}.id`),connectionIds.has(value.id)&&fail(`duplicate connection id "${value.id}"`),"layer"in value&&fail(`${label}.layer is not accepted; declare layer preferences on a bus`);let endpointValues=requireArray(value.endpoints,`${label}.endpoints must be an array`),endpointRegionIds=new Set,endpoints=endpointValues.map((endpointValue,endpointIndex)=>{let endpointLabel=`${label}.endpoints[${endpointIndex}]`;requireRecord(endpointValue,endpointLabel),requireId(endpointValue.regionId,`${endpointLabel}.regionId`),regionIds.has(endpointValue.regionId)||fail(`${endpointLabel} references unknown region "${endpointValue.regionId}"`),endpointRegionIds.has(endpointValue.regionId)&&fail(`${label} has duplicate endpoint for region "${endpointValue.regionId}"`),endpointRegionIds.add(endpointValue.regionId);let position22=validatePoint(endpointValue.position,`${endpointLabel}.position`),region=regions.find(candidate=>candidate.id===endpointValue.regionId);return pointIsInsideBounds4(position22,region.bounds)||fail(`${label} endpoint for region "${region.id}" is outside its bounds`),{regionId:endpointValue.regionId,position:position22}});for(let region of regions)endpointRegionIds.has(region.id)||fail(`${label} is missing endpoint for region "${region.id}"`);return endpoints.length!==regions.length&&fail(`${label} must contain exactly one endpoint for every region`),connectionIds.add(value.id),{id:value.id,endpoints}};for(let[index2,value]of input2.connections.entries()){let label=`connections[${index2}]`;if(requireRecord(value,label),"type"in value||"connections"in value){value.type!=="differential"&&fail(`${label} has invalid differential-pair type`),"layer"in value&&fail(`${label}.layer is not accepted; declare layer preferences on a bus`);let pairConnections=requireArray(value.connections,`${label}.connections must contain exactly two members`);pairConnections.length!==2&&fail(`${label}.connections must contain exactly two members`);let first=validateConnection(pairConnections[0],`${label}.connections[0]`),second=validateConnection(pairConnections[1],`${label}.connections[1]`);first.id===second.id&&fail(`${label} members must have distinct connection ids`),connections.push(first,second),atomicConnectionGroups.push([first.id,second.id])}else connections.push(validateConnection(value,label))}let busValues=requireArray(input2.buses,"buses must be an array"),busIds=new Set,busByConnection=new Map,buses=busValues.map((value,busIndex)=>{let label=`buses[${busIndex}]`;requireRecord(value,label),requireId(value.id,`${label}.id`);let busId=value.id;busIds.has(busId)&&fail(`duplicate bus id "${busId}"`),busIds.add(busId);let connectionIdValues=requireArray(value.connectionIds,`${label}.connectionIds must be a non-empty array`);connectionIdValues.length===0&&fail(`${label}.connectionIds must be a non-empty array`);let localConnectionIds=new Set,busConnectionIds=connectionIdValues.map((connectionId,connectionIndex)=>{requireId(connectionId,`${label}.connectionIds[${connectionIndex}]`),connectionIds.has(connectionId)||fail(`${label} references unknown connection "${connectionId}"`),localConnectionIds.has(connectionId)&&fail(`${label} contains duplicate connection "${connectionId}"`),localConnectionIds.add(connectionId);let previousBusId=busByConnection.get(connectionId);return previousBusId!==void 0&&fail(`connection "${connectionId}" belongs to multiple buses "${previousBusId}" and "${value.id}"`),busByConnection.set(connectionId,busId),connectionId}),preferredLayer;value.preferredLayer!==void 0&&(requireId(value.preferredLayer,`${label}.preferredLayer`),preferredLayer=value.preferredLayer);let preferredLayers;if(value.preferredLayers!==void 0){let preferredLayerValues=requireArray(value.preferredLayers,`${label}.preferredLayers must be a non-empty array`);preferredLayerValues.length===0&&fail(`${label}.preferredLayers must be a non-empty array`);let uniquePreferredLayers=new Set;preferredLayers=preferredLayerValues.map((layer,layerIndex)=>(requireId(layer,`${label}.preferredLayers[${layerIndex}]`),uniquePreferredLayers.has(layer)&&fail(`${label}.preferredLayers contains duplicate layer "${layer}"`),uniquePreferredLayers.add(layer),layer))}let validatedBus={id:busId,connectionIds:busConnectionIds};return preferredLayer!==void 0&&(validatedBus={...validatedBus,preferredLayer}),preferredLayers!==void 0&&(validatedBus={...validatedBus,preferredLayers}),validatedBus});for(let[firstConnectionId,secondConnectionId]of atomicConnectionGroups){let firstBusId=busByConnection.get(firstConnectionId),secondBusId=busByConnection.get(secondConnectionId);firstBusId!==secondBusId&&fail(`differential pair "${firstConnectionId}/${secondConnectionId}" must belong to the same bus`)}let layerNames=[...new Set([...buses.flatMap(bus=>getBusLayerCandidates(bus)),...connections.filter(connection=>!busByConnection.has(connection.id)).map(()=>"top")])].sort((first,second)=>first.localeCompare(second));return{regions,connections,buses,layerNames,atomicConnectionGroups}},GEOMETRY_EPSILON22=1e-9,isVerticalEdge=edge=>edge==="left"||edge==="right",getAxisMinimum=(region,vertical)=>vertical?region.bounds.minY:region.bounds.minX,getAxisMaximum=(region,vertical)=>vertical?region.bounds.maxY:region.bounds.maxX,getAxisPosition=(position22,vertical)=>vertical?position22.y:position22.x,deriveLayerOffsets=(layerNames,boundaryPointSpacing)=>{let staggerOffset=boundaryPointSpacing/2;return Object.fromEntries(layerNames.map((layer,index2)=>[layer,(index2-(layerNames.length-1)/2)*staggerOffset]))},makeAtomicLayerOrder=({referenceOrder,layer,layerByConnection,atomicGroups})=>{let candidates=referenceOrder.filter(connectionId=>layerByConnection[connectionId]===layer),groupByConnection=new Map(atomicGroups.flatMap(group2=>group2.map(connectionId=>[connectionId,group2]))),addedGroups=new Set,result=[];for(let connectionId of candidates){let group2=groupByConnection.get(connectionId);if(!group2){result.push(connectionId);continue}addedGroups.has(group2)||(addedGroups.add(group2),result.push(...candidates.filter(candidate=>group2.includes(candidate))))}return result},makeGateAxes=({regions,connections,spacing,count,layerOffsets})=>{let vertical=regions.every(region=>isVerticalEdge(region.edge)),minAxis=Math.max(...regions.map(region=>getAxisMinimum(region,vertical))),maxAxis=Math.min(...regions.map(region=>getAxisMaximum(region,vertical))),minimumOffset=Math.min(...Object.values(layerOffsets)),maximumOffset=Math.max(...Object.values(layerOffsets)),span=spacing*Math.max(0,count-1)+maximumOffset-minimumOffset;if(maxAxis-minAxis+GEOMETRY_EPSILON22<span)throw new WindingBreakoutInfeasibleError(`WindingBreakoutSolver: declared breakout edges need ${span.toFixed(2)}mm but expose only ${(maxAxis-minAxis).toFixed(2)}mm`);let meanAxis=regions.reduce((regionSum,region)=>{let positions=connections.map(connection=>connection.endpoints.find(endpoint=>endpoint.regionId===region.id).position);return regionSum+positions.reduce((sum,position22)=>sum+getAxisPosition(position22,vertical),0)/positions.length},0)/regions.length,start=Math.max(minAxis-minimumOffset,Math.min(maxAxis-spacing*Math.max(0,count-1)-maximumOffset,meanAxis-spacing*Math.max(0,count-1)/2));return{vertical,axes:Array.from({length:count},(_23,index2)=>start+index2*spacing)}},pointOnEdge=(region,axis,vertical)=>{if(vertical){let x23=region.bounds.maxX;return region.edge==="left"&&(x23=region.bounds.minX),{x:x23,y:axis}}let y23=region.bounds.maxY;return region.edge==="bottom"&&(y23=region.bounds.minY),{x:axis,y:y23}},placeBreakoutGates=({regions,connections,referenceOrder,layerNames,layerByConnection,boundaryPointSpacing,atomicGroups})=>{let layerOffsets=deriveLayerOffsets(layerNames,boundaryPointSpacing),gateOrderByLayer=Object.fromEntries(layerNames.map(layer=>[layer,makeAtomicLayerOrder({referenceOrder,layer,layerByConnection,atomicGroups})])),maxLayerNetCount=Math.max(...layerNames.map(layer=>connections.filter(connection=>layerByConnection[connection.id]===layer).length)),{vertical,axes:axes2}=makeGateAxes({regions,connections,spacing:boundaryPointSpacing,count:maxLayerNetCount,layerOffsets});return{breakoutPoints:regions.flatMap(region=>layerNames.flatMap(layer=>gateOrderByLayer[layer].map((connectionId,slotIndex)=>({regionId:region.id,connectionId,layer,...pointOnEdge(region,axes2[slotIndex]+layerOffsets[layer],vertical)}))))}},getAtomicUnits=(connectionIds,atomicGroups)=>{let connectionSet=new Set(connectionIds),groupByConnection=new Map(atomicGroups.flatMap(group2=>group2.map(connectionId=>[connectionId,group2]))),addedGroups=new Set,units=[];for(let connectionId of connectionIds){let group2=groupByConnection.get(connectionId);if(!group2){units.push([connectionId]);continue}addedGroups.has(group2)||(addedGroups.add(group2),units.push(group2.filter(memberId=>connectionSet.has(memberId))))}return units},assignConnectionLayers=({validated,referenceOrder})=>{let assignments=new Map;for(let bus of validated.buses){let busConnectionSet=new Set(bus.connectionIds),orderedBusConnections=referenceOrder.filter(connectionId=>busConnectionSet.has(connectionId)),candidates=getBusLayerCandidates(bus),units=getAtomicUnits(orderedBusConnections,validated.atomicConnectionGroups);for(let[unitIndex,unit2]of units.entries()){let layer=candidates[unitIndex%candidates.length];for(let connectionId of unit2)assignments.set(connectionId,layer)}}for(let connectionId of referenceOrder)assignments.has(connectionId)||assignments.set(connectionId,"top");let layerByConnection=Object.fromEntries(referenceOrder.map(connectionId=>[connectionId,assignments.get(connectionId)])),layerNames=[...new Set(Object.values(layerByConnection))].sort((first,second)=>first.localeCompare(second));return{layerByConnection,layerNames}},getLayerNames=input2=>[...new Set(Object.values(getLayerCandidatesByConnection(input2)).flat())].sort((first,second)=>first.localeCompare(second)),CONNECTION_COLORS=["#2563eb","#dc2626","#059669","#7c3aed","#d97706","#0891b2","#db2777","#4f46e5","#65a30d","#c2410c","#0f766e","#9333ea"],getConnectionColor=connectionId=>{let hash=2166136261;for(let character of connectionId)hash^=character.charCodeAt(0),hash=Math.imul(hash,16777619);return CONNECTION_COLORS[(hash>>>0)%CONNECTION_COLORS.length]},getGraphicsLayer3=(input2,layerIds)=>{let signalLayerIds=getLayerNames(input2),indexes=[...new Set(layerIds)].map(layerId=>{let index2=signalLayerIds.indexOf(layerId);if(index2<0)throw new Error(`Cannot visualize unknown signal layer "${layerId}"`);return index2});if(indexes.length===0)throw new Error("Cannot create graphics metadata without a signal layer");return indexes.sort((first,second)=>first-second),`z${indexes.join(",")}`},createInputGraphics=(input2,activeLayer)=>{let graphics={circles:[],rects:[],texts:[]},displayedLayers=getLayerNames(input2);activeLayer&&(displayedLayers=[activeLayer]);let visibleLayers=getGraphicsLayer3(input2,displayedLayers),connections=getCanonicalConnections(input2),layerCandidatesByConnection=getLayerCandidatesByConnection(input2),endpointRadius=Math.min(.12,input2.boundaryPointSpacing/4);for(let region of input2.regions){let center2={x:(region.bounds.minX+region.bounds.maxX)/2,y:(region.bounds.minY+region.bounds.maxY)/2};graphics.rects.push({center:center2,width:region.bounds.maxX-region.bounds.minX,height:region.bounds.maxY-region.bounds.minY,fill:"rgba(226, 232, 240, 0.035)",stroke:"rgba(71, 85, 105, 0.55)",layer:visibleLayers});for(let connection of connections){let layerCandidates=layerCandidatesByConnection[connection.id];if(activeLayer&&!layerCandidates.includes(activeLayer))continue;let endpoint=connection.endpoints.find(candidate=>candidate.regionId===region.id);if(!endpoint)continue;let color32=getConnectionColor(connection.id);graphics.circles.push({center:endpoint.position,radius:endpointRadius,fill:`${color32}70`,stroke:color32,layer:getGraphicsLayer3(input2,layerCandidates)})}graphics.texts.push({x:center2.x,y:region.bounds.maxY+.35,text:region.id,anchorSide:"bottom_center",color:"#334155",fontSize:.34,layer:visibleLayers})}return graphics},createStateGraphics=(input2,state2,activeLayer)=>{let connections=getCanonicalConnections(input2),breakoutPoints=state2.breakoutPoints.filter(point12=>!activeLayer||point12.layer===activeLayer),sharedGateSlots=new Map;for(let point12 of state2.breakoutPoints){let key=`${point12.regionId}:${point12.x.toFixed(9)}:${point12.y.toFixed(9)}`,slot=sharedGateSlots.get(key)??{x:point12.x,y:point12.y,layers:new Set};slot.layers.add(point12.layer),sharedGateSlots.set(key,slot)}return{lines:state2.referenceOrder.flatMap(connectionId=>{let connection=connections.find(candidate=>candidate.id===connectionId);if(!connection)return[];let connectionBreakouts=breakoutPoints.filter(point12=>point12.connectionId===connectionId),layer=connectionBreakouts[0]?.layer;if(!layer||activeLayer&&layer!==activeLayer)return[];if(connectionBreakouts.length!==input2.regions.length)return[];let points=input2.regions.flatMap((region,regionIndex)=>{let endpoint=connection.endpoints.find(candidate=>candidate.regionId===region.id),breakout=connectionBreakouts.find(candidate=>candidate.regionId===region.id);return!endpoint||!breakout?[]:regionIndex===0?[endpoint.position,breakout]:[breakout,endpoint.position]});return points.length<2?[]:[{points,strokeColor:`${getConnectionColor(connectionId)}55`,strokeWidth:.012,strokeDash:[.025,.07],layer:getGraphicsLayer3(input2,[layer])}]}),circles:[...sharedGateSlots.values()].flatMap(slot=>{let layers=[...slot.layers].filter(layer=>!activeLayer||layer===activeLayer);return layers.length===0?[]:[{center:slot,radius:.11,fill:"rgba(15, 23, 42, 0.06)",stroke:"#475569",layer:getGraphicsLayer3(input2,layers)}]}),points:breakoutPoints.map(point12=>({x:point12.x,y:point12.y,color:getConnectionColor(point12.connectionId),label:`${point12.connectionId} \xB7 ${point12.layer}`,layer:getGraphicsLayer3(input2,[point12.layer])}))}},createSolverPhaseVisualization=({input:input2,phase,detail,activeLayer,referenceOrder,referenceRegionId,showReferenceNumbers=!1,state:state2})=>{let inputGraphics=createInputGraphics(input2,activeLayer),stateGraphics;state2&&(stateGraphics=createStateGraphics(input2,state2,activeLayer));let displayedLayers=getLayerNames(input2);activeLayer&&(displayedLayers=[activeLayer]);let textLayer=getGraphicsLayer3(input2,displayedLayers),maxY=Math.max(...input2.regions.map(region=>region.bounds.maxY)),minX=Math.min(...input2.regions.map(region=>region.bounds.minX)),texts=[...inputGraphics.texts??[],...stateGraphics?.texts??[],{x:minX,y:maxY+1.05,text:phase,anchorSide:"bottom_left",color:"#0f172a",fontSize:.42,layer:textLayer},{x:minX,y:maxY+.68,text:detail,anchorSide:"bottom_left",color:"#475569",fontSize:.25,layer:textLayer}],referenceLines=[],referenceCircles=[];if(showReferenceNumbers&&referenceOrder){let referenceRegion=input2.regions.find(region=>region.id===referenceRegionId)??input2.regions[0],connections=getCanonicalConnections(input2),layerCandidatesByConnection=getLayerCandidatesByConnection(input2),orderedPositions=[];for(let[index2,connectionId]of referenceOrder.entries()){let connection=connections.find(candidate=>candidate.id===connectionId),layerCandidates=layerCandidatesByConnection[connectionId];if(!connection||!layerCandidates||activeLayer&&!layerCandidates.includes(activeLayer))continue;let endpoint=connection.endpoints.find(candidate=>candidate.regionId===referenceRegion.id);endpoint&&(orderedPositions.push(endpoint.position),texts.push({x:endpoint.position.x+.18,y:endpoint.position.y+.18,text:`${index2+1} \xB7 ${connectionId}`,anchorSide:"bottom_left",color:getConnectionColor(connectionId),fontSize:.21,layer:getGraphicsLayer3(input2,layerCandidates)}))}let center2={x:(referenceRegion.bounds.minX+referenceRegion.bounds.maxX)/2,y:(referenceRegion.bounds.minY+referenceRegion.bounds.maxY)/2};referenceLines.push(...orderedPositions.map(position22=>({points:[center2,position22],strokeColor:"rgba(100, 116, 139, 0.35)",strokeWidth:.01,strokeDash:[.03,.05],layer:textLayer}))),orderedPositions.length>1&&referenceLines.push({points:orderedPositions,strokeColor:"rgba(15, 23, 42, 0.65)",strokeWidth:.018,strokeDash:[.04,.04],label:`${referenceRegion.id} angular winding order`,layer:textLayer}),referenceCircles.push({center:center2,radius:.07,fill:"#0f172a",stroke:"#ffffff",label:`${referenceRegion.id} angular reference center`,layer:textLayer})}return{title:phase,coordinateSystem:"cartesian",rects:inputGraphics.rects,polygons:inputGraphics.polygons,lines:[...stateGraphics?.lines??[],...referenceLines],circles:[...inputGraphics.circles??[],...stateGraphics?.circles??[],...referenceCircles],points:stateGraphics?.points,texts}},getSharedGateSlotCount=points=>new Set(points.map(point12=>`${point12.regionId}:${point12.x.toFixed(9)}:${point12.y.toFixed(9)}`)).size,GatePlacementSolver=class extends BaseSolver{constructor(params){super();__publicField(this,"params");__publicField(this,"batchIndex",0);__publicField(this,"output");__publicField(this,"plannedPlacement");__publicField(this,"placementBatches");__publicField(this,"visibleBreakoutPoints",[]);__publicField(this,"layerByConnection");__publicField(this,"visualizationLayer");this.params=params,this.visualizationLayer=params.visualizationLayer;let assignment=assignConnectionLayers({validated:params.validated,referenceOrder:params.ordering.referenceOrder});this.layerByConnection=assignment.layerByConnection,this.placementBatches=params.validated.regions.flatMap(region=>assignment.layerNames.map(layer=>({regionId:region.id,layer}))),this.MAX_ITERATIONS=this.placementBatches.length+2}setVisualizationLayer(layer){this.visualizationLayer=layer}_step(){if(!this.plannedPlacement){this.plannedPlacement=placeBreakoutGates({regions:this.params.validated.regions,connections:this.params.validated.connections,referenceOrder:this.params.ordering.referenceOrder,layerNames:[...new Set(Object.values(this.layerByConnection))].sort((first,second)=>first.localeCompare(second)),layerByConnection:this.layerByConnection,boundaryPointSpacing:this.params.input.boundaryPointSpacing,atomicGroups:this.params.validated.atomicConnectionGroups}),this.stats={phase:"plan-gate-grid",regionLayerBatches:this.placementBatches.length,placedBreakpoints:0};return}let batch=this.placementBatches[this.batchIndex];if(batch){this.visibleBreakoutPoints.push(...this.plannedPlacement.breakoutPoints.filter(point12=>point12.regionId===batch.regionId&&point12.layer===batch.layer)),this.batchIndex+=1,this.stats={phase:"place-region-layer-batch",regionId:batch.regionId,layer:batch.layer,completedBatches:this.batchIndex,totalBatches:this.placementBatches.length,placedBreakpoints:this.visibleBreakoutPoints.length};return}this.output=this.plannedPlacement,this.stats={phase:"finalize-shared-gate-slots",placedBreakpoints:this.output.breakoutPoints.length,sharedGateSlots:getSharedGateSlotCount(this.output.breakoutPoints)},this.solved=!0}computeProgress(){let completedMicrosteps=this.batchIndex;return this.plannedPlacement&&(completedMicrosteps+=1),this.output&&(completedMicrosteps+=1),completedMicrosteps/this.MAX_ITERATIONS}getConstructorParams(){return[this.params]}getOutput(){if(!this.solved||!this.output)throw new WindingBreakoutInvariantError("WindingBreakoutSolver: gate placement requested before placement completed");return this.output}visualize(){let detail="Next microstep: derive layer offsets, atomic gate orders, and the common boundary slot grid";if(this.plannedPlacement&&this.batchIndex===0)detail=`Gate grid planned \xB7 ${this.placementBatches.length} region/layer batches remain`;else if(this.plannedPlacement&&!this.output){let latestBatch=this.placementBatches[this.batchIndex-1];detail=`Placed region \u201C${latestBatch.regionId}\u201D on layer \u201C${latestBatch.layer}\u201D \xB7 ${this.batchIndex}/${this.placementBatches.length} batches`}else if(this.output){let sharedGateSlotCount=getSharedGateSlotCount(this.output.breakoutPoints);detail=`${this.output.breakoutPoints.length} gates placed; coincident layer positions form ${sharedGateSlotCount} shared slots`}let visualizationState;if(this.plannedPlacement){let breakoutPoints=this.visibleBreakoutPoints;this.output&&(breakoutPoints=this.output.breakoutPoints),visualizationState={referenceOrder:this.params.ordering.referenceOrder,breakoutPoints}}let graphics=createSolverPhaseVisualization({input:this.params.input,activeLayer:this.visualizationLayer,phase:"Step 2 \xB7 Place boundary gates",detail,state:visualizationState}),plannedSlotGuides=(this.plannedPlacement?.breakoutPoints??[]).filter(point12=>!this.visualizationLayer||point12.layer===this.visualizationLayer).map(point12=>({center:point12,radius:.065,fill:"rgba(255, 255, 255, 0.75)",stroke:"rgba(100, 116, 139, 0.5)",label:`planned slot ${point12.regionId} \xB7 ${point12.layer}`,layer:getGraphicsLayer3(this.params.input,[point12.layer])}));return{...graphics,circles:[...graphics.circles??[],...plannedSlotGuides]}}},getNaturalWindingOrder=(region,connections)=>connections.map(connection=>{let position22=connection.endpoints.find(endpoint=>endpoint.regionId===region.id).position;return{id:connection.id,angle:Math.atan2(position22.y-region.center.y,position22.x-region.center.x),radius:Math.hypot(position22.x-region.center.x,position22.y-region.center.y)}}).sort((first,second)=>first.angle-second.angle||second.radius-first.radius||first.id.localeCompare(second.id)).map(connection=>connection.id),getReferenceWindingOrder=(naturalOrder,atomicGroups,buses)=>{let groupByConnection=new Map(atomicGroups.flatMap(group2=>group2.map(connectionId=>[connectionId,group2]))),addedGroups=new Set,result=[];for(let connectionId of naturalOrder){let group2=groupByConnection.get(connectionId);if(!group2){result.push(connectionId);continue}addedGroups.has(group2)||(addedGroups.add(group2),result.push(...naturalOrder.filter(candidate=>group2.includes(candidate))))}let busByConnection=new Map(buses.flatMap(bus=>bus.connectionIds.map(connectionId=>[connectionId,bus]))),addedBuses=new Set,busContiguousResult=[];for(let connectionId of result){let bus=busByConnection.get(connectionId);if(!bus){busContiguousResult.push(connectionId);continue}if(addedBuses.has(bus))continue;addedBuses.add(bus);let busConnectionIds=new Set(bus.connectionIds);busContiguousResult.push(...result.filter(candidate=>busConnectionIds.has(candidate)))}return busContiguousResult},ReferenceOrderingSolver=class extends BaseSolver{constructor(params){super();__publicField(this,"params");__publicField(this,"naturalOrderByRegion",{});__publicField(this,"currentRegionIndex",0);__publicField(this,"output");__publicField(this,"visualizedOrder");__publicField(this,"visualizedRegionId");__publicField(this,"visualizationLayer");this.params=params,this.visualizationLayer=params.visualizationLayer,this.MAX_ITERATIONS=params.validated.regions.length+1}setVisualizationLayer(layer){this.visualizationLayer=layer}_step(){let region=this.params.validated.regions[this.currentRegionIndex];if(region){let naturalOrder=getNaturalWindingOrder(region,this.params.validated.connections);this.naturalOrderByRegion[region.id]=naturalOrder,this.visualizedRegionId=region.id,this.visualizedOrder=naturalOrder,this.currentRegionIndex+=1,this.stats={phase:"derive-natural-order",regionId:region.id,completedRegions:this.currentRegionIndex,totalRegions:this.params.validated.regions.length,naturalOrder};return}let firstRegion=this.params.validated.regions[0],referenceOrder=getReferenceWindingOrder(this.naturalOrderByRegion[firstRegion.id],this.params.validated.atomicConnectionGroups,this.params.validated.buses);this.output={naturalOrderByRegion:this.naturalOrderByRegion,referenceOrder},this.visualizedRegionId=firstRegion.id,this.visualizedOrder=referenceOrder,this.stats={phase:"atomicize-reference-order",referenceRegion:firstRegion.id,referenceOrder},this.solved=!0}computeProgress(){let completedMicrosteps=this.currentRegionIndex;return this.output&&(completedMicrosteps+=1),completedMicrosteps/this.MAX_ITERATIONS}getConstructorParams(){return[this.params]}getOutput(){if(!this.solved||!this.output)throw new WindingBreakoutInvariantError("WindingBreakoutSolver: reference order requested before ordering completed");return this.output}visualize(){let firstRegionId=this.params.validated.regions[0].id,detail=`Next microstep: derive natural order for region \u201C${firstRegionId}\u201D`;return this.visualizedRegionId&&!this.output&&(detail=`Natural order for region \u201C${this.visualizedRegionId}\u201D \xB7 ${this.currentRegionIndex}/${this.params.validated.regions.length} regions processed`),this.output&&(detail=`Reference region \u201C${firstRegionId}\u201D finalized; buses are contiguous and differential pairs are atomic`),createSolverPhaseVisualization({input:this.params.input,activeLayer:this.visualizationLayer,phase:"Step 1 \xB7 Derive reference order",detail,referenceOrder:this.visualizedOrder,referenceRegionId:this.visualizedRegionId,showReferenceNumbers:!0})}},validateBreakoutPoints=({points,connectionIds,regions,atomicGroups})=>{let regionIds=regions.map(region=>region.id),endpointCounts=new Map,layerByConnection=new Map,connectionLayersAreValid=!0;for(let point12 of points){let key=`${point12.regionId}:${point12.connectionId}`;endpointCounts.set(key,(endpointCounts.get(key)??0)+1);let previousLayer=layerByConnection.get(point12.connectionId);previousLayer!==void 0&&previousLayer!==point12.layer&&(connectionLayersAreValid=!1),layerByConnection.set(point12.connectionId,point12.layer)}let expected=regionIds.flatMap(regionId=>connectionIds.map(connectionId=>`${regionId}:${connectionId}`)),endpointsAreValid=endpointCounts.size===expected.length&&expected.every(endpoint=>endpointCounts.get(endpoint)===1),atomicGroupsAreValid=atomicGroups.every(group2=>{let layer=layerByConnection.get(group2[0]);return!layer||group2.some(connectionId=>layerByConnection.get(connectionId)!==layer)?!1:regions.every(region=>{let layerPoints=points.filter(point12=>point12.regionId===region.id&&point12.layer===layer),vertical=region.edge==="left"||region.edge==="right",orderedConnectionIds=[...layerPoints].sort((first,second)=>vertical?first.y-second.y:first.x-second.x).map(point12=>point12.connectionId),firstIndex=orderedConnectionIds.indexOf(group2[0]),secondIndex=orderedConnectionIds.indexOf(group2[1]);return firstIndex!==-1&&secondIndex!==-1&&Math.abs(firstIndex-secondIndex)===1})});return endpointsAreValid&&connectionLayersAreValid&&atomicGroupsAreValid},finalizeWindingBreakoutOutput=({validated,placement})=>{if(!validateBreakoutPoints({points:placement.breakoutPoints,connectionIds:validated.connections.map(connection=>connection.id),regions:validated.regions,atomicGroups:validated.atomicConnectionGroups}))throw new WindingBreakoutInvariantError("WindingBreakoutSolver: generated invalid breakout points");return{breakoutPoints:placement.breakoutPoints}},PIPELINE_STAGE_NAMES=["referenceOrdering","gatePlacement"],WindingBreakoutSolver=class extends BasePipelineSolver{constructor(input2){super(input2);__publicField(this,"validatedInput");__publicField(this,"output");__publicField(this,"visualizationLayer");__publicField(this,"pipelineDef",[definePipelineStep("referenceOrdering",ReferenceOrderingSolver,pipeline=>[{input:pipeline.inputProblem,validated:pipeline.getValidatedInput(),visualizationLayer:pipeline.visualizationLayer}]),definePipelineStep("gatePlacement",GatePlacementSolver,pipeline=>[{input:pipeline.inputProblem,validated:pipeline.getValidatedInput(),ordering:pipeline.getRequiredStageOutput("referenceOrdering"),visualizationLayer:pipeline.visualizationLayer}])])}_setup(){this.validatedInput=validateWindingBreakoutInput(this.inputProblem),this.stats={phase:"setup-input-validation",regionCount:this.validatedInput.regions.length,connectionCount:this.validatedInput.connections.length,layerCount:this.validatedInput.layerNames.length}}getValidatedInput(){if(!this.validatedInput)throw new Error("WindingBreakoutSolver: input has not been validated");return this.validatedInput}_step(){super._step(),!this.output&&!this.activeSubSolver&&this.currentPipelineStageIndex>=this.pipelineDef.length&&(this.output=finalizeWindingBreakoutOutput({validated:this.getValidatedInput(),placement:this.getRequiredStageOutput("gatePlacement")}),this.solved=!0),this.stats={phase:this.getCurrentStageName(),completedStages:this.currentPipelineStageIndex,totalStages:this.pipelineDef.length},this.solved&&(this.stats.phase="finalize-output-validation"),this.output&&(this.stats.valid=!0,this.stats.breakoutPointCount=this.output.breakoutPoints.length)}getRequiredStageOutput(stageName){let output=this.getStageOutput(stageName);if(output===void 0)throw new Error(`WindingBreakoutSolver: pipeline stage \u201C${stageName}\u201D has no output`);return output}setVisualizationLayer(layer){this.visualizationLayer=layer;for(let stageName of PIPELINE_STAGE_NAMES){let solver=this.getSolver(stageName);solver&&"setVisualizationLayer"in solver&&solver.setVisualizationLayer(layer)}}getConstructorParams(){return[this.inputProblem]}getOutput(){if(!this.solved||!this.output)throw new WindingBreakoutOutputUnavailableError("WindingBreakoutSolver: getOutput() called before successful completion");return this.output}initialVisualize(){return createSolverPhaseVisualization({input:this.inputProblem,activeLayer:this.visualizationLayer,phase:"Input \xB7 Validated during setup",detail:"Region bounds, breakout edges, bus layer preferences, and canonical endpoints"})}finalVisualize(){if(!this.output)return null;let ordering=this.getRequiredStageOutput("referenceOrdering");return createSolverPhaseVisualization({input:this.inputProblem,activeLayer:this.visualizationLayer,phase:"Output \xB7 Validated after gate placement",detail:"Valid: one bus-constrained breakout point per connection and region; pairs are adjacent",state:{referenceOrder:ordering.referenceOrder,breakoutPoints:this.output.breakoutPoints}})}visualize(){return{...super.visualize(),title:"Winding breakout solver \xB7 step-by-step pipeline",coordinateSystem:"cartesian"}}},toWindingConnection=connection=>({id:connection.connectionId,endpoints:connection.endpoints}),defaultImplicitBreakoutPointSolverFn=input2=>{let windingInput={regions:input2.regions.map(region=>({id:region.regionId,bounds:region.bounds,edge:region.edge})),connections:input2.connections.map(connection=>"type"in connection?{type:"differential",connections:connection.connections.map(toWindingConnection)}:toWindingConnection(connection)),buses:input2.buses.map(bus=>({id:bus.busId,connectionIds:bus.connectionIds,preferredLayers:bus.targetLayers})),boundaryPointSpacing:input2.boundaryPointSpacing},solver=new WindingBreakoutSolver(windingInput);return solver.solve(),solver.getOutput()},getFanoutBounds=pcbGroup=>{let outlineBounds=pcbGroup.outline?getBoundsFromPoints3(pcbGroup.outline):null,width10=pcbGroup.width??(outlineBounds?outlineBounds.maxX-outlineBounds.minX:void 0),height10=pcbGroup.height??(outlineBounds?outlineBounds.maxY-outlineBounds.minY:void 0);return width10===void 0||height10===void 0?null:{minX:pcbGroup.center.x-width10/2,maxX:pcbGroup.center.x+width10/2,minY:pcbGroup.center.y-height10/2,maxY:pcbGroup.center.y+height10/2}},getAxisGap2=(firstMin,firstMax,secondMin,secondMax)=>Math.max(firstMin-secondMax,secondMin-firstMax,0),Breakout_doInitialPcbPlacementDesignRuleChecks=breakout=>{if(breakout.root?.pcbDisabled||!breakout.pcb_group_id)return;let root=breakout.root;if(!root)return;let siblingFanouts=breakout.parent?.children.filter(sibling=>sibling instanceof breakout.constructor);if(!siblingFanouts)return;let breakoutIndex=siblingFanouts.indexOf(breakout);if(breakoutIndex<0)return;let{db:db22}=root,pcbGroup=db22.pcb_group.get(breakout.pcb_group_id);if(!pcbGroup)return;let bounds=getFanoutBounds(pcbGroup);if(bounds)for(let otherFanout of siblingFanouts.slice(breakoutIndex+1)){if(!otherFanout.pcb_group_id)continue;let otherPcbGroup=db22.pcb_group.get(otherFanout.pcb_group_id);if(!otherPcbGroup)continue;let otherBounds=getFanoutBounds(otherPcbGroup);if(!otherBounds)continue;let breakoutMargin=breakout._parsedProps.fanoutMargin,otherFanoutMargin=otherFanout._parsedProps.fanoutMargin,requiredMargin=Math.max(typeof breakoutMargin=="number"?breakoutMargin:0,typeof otherFanoutMargin=="number"?otherFanoutMargin:0),horizontalGap=getAxisGap2(bounds.minX,bounds.maxX,otherBounds.minX,otherBounds.maxX),verticalGap=getAxisGap2(bounds.minY,bounds.maxY,otherBounds.minY,otherBounds.maxY),horizontalOverlap=Math.min(bounds.maxX,otherBounds.maxX)-Math.max(bounds.minX,otherBounds.minX),verticalOverlap=Math.min(bounds.maxY,otherBounds.maxY)-Math.max(bounds.minY,otherBounds.minY),boundariesOverlap=horizontalOverlap>0&&verticalOverlap>0,violatesMargin=requiredMargin>0&&horizontalGap<requiredMargin&&verticalGap<requiredMargin;if(!boundariesOverlap&&!violatesMargin)continue;let message=boundariesOverlap?`Fanout boundaries "${breakout.name}" and "${otherFanout.name}" overlap. Fanout boundaries may not overlap.`:`Fanout boundaries "${breakout.name}" and "${otherFanout.name}" do not maintain the required ${requiredMargin}mm fanoutMargin.`;db22.pcb_placement_error.list().some(error2=>error2.message===message)||db22.pcb_placement_error.insert({error_type:"pcb_placement_error",message,subcircuit_id:breakout.subcircuit_id??void 0})}},reportWindingBreakoutInfeasibleError=(breakout,error2)=>{if(!(error2 instanceof WindingBreakoutInfeasibleError)||!breakout.root||!breakout.pcb_group_id)return!1;let componentNames=breakout.root.db.pcb_component.list().filter(pcbComponent=>pcbComponent.pcb_group_id===breakout.pcb_group_id).map(pcbComponent=>pcbComponent.source_component_id?breakout.root.db.source_component.get(pcbComponent.source_component_id)?.name:void 0).filter(name=>!!name);return breakout.root.db.pcb_autorouting_error.insert({pcb_error_id:`pcb_autorouting_error_winding_breakout_${breakout.pcb_group_id}`,error_type:"pcb_autorouting_error",message:`Winding fanout failed for ${componentNames.join(", ")||breakout.name}: ${error2.message}. The connections could not escape to the breakout boundary. Give the fanout more room by increasing the breakout's padding, or by extending the breakout to include the parts crowding it (decoupling capacitors, series resistors).`}),!0},EDGES=["right","left","top","bottom"],isVerticalBreakoutEdge=edge=>edge==="left"||edge==="right",getBreakoutEdgeLength=(bounds,edge)=>isVerticalBreakoutEdge(edge)?bounds.maxY-bounds.minY:bounds.maxX-bounds.minX,canonicalBusFanoutDirections2=new Set(canonicalBusFanoutDirectionValues),getBreakoutEdgeForFanoutDirection=fanoutDirection=>{let direction4=typeof fanoutDirection=="string"?fanoutDirection:fanoutDirection.direction;if(direction4==="center"||!canonicalBusFanoutDirections2.has(direction4))return;let[side,position22]=direction4.split("side_");if(position22==="center")return{edge:side,band:"center"};let startPosition=isVerticalBreakoutEdge(side)?"bottom":"left";return{edge:side,band:position22===startPosition?"start":"end"}},distanceFromPointToEdge=(bounds,target,edge)=>{let edgePoint=isVerticalBreakoutEdge(edge)?{x:edge==="left"?bounds.minX:bounds.maxX,y:Math.max(bounds.minY,Math.min(bounds.maxY,target.y))}:{x:Math.max(bounds.minX,Math.min(bounds.maxX,target.x)),y:edge==="bottom"?bounds.minY:bounds.maxY};return Math.hypot(target.x-edgePoint.x,target.y-edgePoint.y)},assignSingleRegionBreakoutEdges=({bounds,connectionIds,pinPositionByConnectionId,externalPositionsByConnectionId,atomicGroups,buses,busFanoutDirections,fallbackEdge,boundaryPointSpacing,layerCount})=>{let parent=new Map(connectionIds.map(id3=>[id3,id3])),find2=id3=>{let root=id3;for(;parent.get(root)!==root;)root=parent.get(root);return parent.set(id3,root),root},union3=ids=>{let members=ids.filter(id3=>parent.has(id3));for(let id3 of members.slice(1)){let firstRoot=find2(members[0]),root=find2(id3);firstRoot!==root&&parent.set(root,firstRoot)}};for(let group2 of atomicGroups)union3(group2);for(let bus of buses)union3(bus.connectionIds);let unitsByRoot=new Map;for(let id3 of connectionIds){let root=find2(id3),unit2=unitsByRoot.get(root)??[];unit2.push(id3),unitsByRoot.set(root,unit2)}let forcedPlacementByRoot=new Map;for(let bus of[...buses].sort((a23,b23)=>a23.busId.localeCompare(b23.busId))){let fanoutDirection=busFanoutDirections?.[bus.busId],firstMember=bus.connectionIds.find(id3=>parent.has(id3));if(!fanoutDirection||!firstMember)continue;let placement=getBreakoutEdgeForFanoutDirection(fanoutDirection),root=find2(firstMember);placement&&!forcedPlacementByRoot.has(root)&&forcedPlacementByRoot.set(root,placement)}let regionDiagonal=Math.hypot(bounds.maxX-bounds.minX,bounds.maxY-bounds.minY),getConnectionCost=(id3,edge)=>{let externalPositions=externalPositionsByConnectionId.get(id3)??[];if(externalPositions.length===0)return edge===fallbackEdge?0:regionDiagonal;let pin=pinPositionByConnectionId.get(id3);if(!pin)return Math.min(...externalPositions.map(position22=>distanceFromPointToEdge(bounds,position22,edge)));let exit=isVerticalBreakoutEdge(edge)?{x:edge==="left"?bounds.minX:bounds.maxX,y:pin.y}:{x:pin.x,y:edge==="bottom"?bounds.minY:bounds.maxY};return Math.hypot(exit.x-pin.x,exit.y-pin.y)+Math.min(...externalPositions.map(position22=>Math.hypot(position22.x-exit.x,position22.y-exit.y)))},units=[...unitsByRoot.entries()].map(([root,ids])=>{let costByEdge=new Map(EDGES.map(edge2=>[edge2,ids.reduce((sum,id3)=>sum+getConnectionCost(id3,edge2),0)])),forcedPlacement=forcedPlacementByRoot.get(root),edge=forcedPlacement?.edge??EDGES.reduce((bestEdge,candidate)=>costByEdge.get(candidate)<costByEdge.get(bestEdge)?candidate:bestEdge);return{key:ids[0],connectionIds:ids,costByEdge,edge,band:forcedPlacement?.band,forced:!!forcedPlacement}}),getEdgeCapacity=edge=>(Math.floor(getBreakoutEdgeLength(bounds,edge)/boundaryPointSpacing)+1)*Math.max(1,layerCount),getEdgeLoad=edge=>units.filter(unit2=>unit2.edge===edge).reduce((sum,unit2)=>sum+unit2.connectionIds.length,0);for(let edge of EDGES)for(;getEdgeLoad(edge)>getEdgeCapacity(edge);){let bestMove;for(let unit2 of units)if(!(unit2.edge!==edge||unit2.forced))for(let targetEdge of EDGES){if(targetEdge===edge||getEdgeLoad(targetEdge)+unit2.connectionIds.length>getEdgeCapacity(targetEdge))continue;let penalty=unit2.costByEdge.get(targetEdge)-unit2.costByEdge.get(edge);(!bestMove||penalty<bestMove.penalty||penalty===bestMove.penalty&&unit2.key.localeCompare(bestMove.unit.key)<0)&&(bestMove={unit:unit2,targetEdge,penalty})}if(!bestMove)break;bestMove.unit.edge=bestMove.targetEdge}let connectionOrder=new Map(connectionIds.map((id3,index2)=>[id3,index2])),groups=[];for(let edge of EDGES)for(let band of[void 0,"start","center","end"]){let groupConnectionIds=units.filter(unit2=>unit2.edge===edge&&unit2.band===band).flatMap(unit2=>unit2.connectionIds).sort((a23,b23)=>connectionOrder.get(a23)-connectionOrder.get(b23));groupConnectionIds.length!==0&&groups.push({edge,...band?{band}:{},connectionIds:groupConnectionIds})}return groups},getRoutingScopeOrThrow=breakout=>{let routingScope=breakout.parent;if(!routingScope?.selectAll)throw new Error(`Automatic breakout "${breakout.name}" has no coordinated routing scope`);return routingScope},getAutomaticBreakouts=(routingScope,breakoutToSolve)=>{let automaticBreakouts=[];for(let group2 of routingScope.selectAll("group")){if(!group2.isRoutingDirective||group2.parent!==routingScope)continue;let breakout=group2;breakout.children.some(child=>child instanceof AutoplacedBreakoutPoint)&&automaticBreakouts.push(breakout)}let getSourceTraceIds=breakout=>new Set(collectBreakoutRegionGeometry(breakout).endpointBySourceTraceId.keys()),sourceTraceIdsToSolve=getSourceTraceIds(breakoutToSolve);return automaticBreakouts.filter(automaticBreakout=>{let automaticBreakoutSourceTraceIds=getSourceTraceIds(automaticBreakout);return automaticBreakoutSourceTraceIds.size===sourceTraceIdsToSolve.size&&[...sourceTraceIdsToSolve].every(sourceTraceId=>automaticBreakoutSourceTraceIds.has(sourceTraceId))})},collectBreakoutRegionGeometry=breakout=>{if(!breakout.root||!breakout.pcb_group_id)throw new Error(`Automatic breakout "${breakout.name}" has no PCB region`);let pcbGroup=breakout.root.db.pcb_group.get(breakout.pcb_group_id);if(!pcbGroup||!pcbGroup.width||!pcbGroup.height)throw new Error(`Automatic breakout "${breakout.name}" has invalid PCB region bounds`);let bounds={minX:pcbGroup.center.x-pcbGroup.width/2,maxX:pcbGroup.center.x+pcbGroup.width/2,minY:pcbGroup.center.y-pcbGroup.height/2,maxY:pcbGroup.center.y+pcbGroup.height/2},center2={x:(bounds.minX+bounds.maxX)/2,y:(bounds.minY+bounds.maxY)/2},endpointBySourceTraceId=new Map,sourcePortIdBySourceTraceId=new Map;for(let breakoutPoint of breakout.children.filter(child=>child instanceof AutoplacedBreakoutPoint)){let matchedPort=breakoutPoint.matchedPort;if(!matchedPort?.pcb_port_id||!matchedPort.source_port_id)throw new Error(`Automatic breakout "${breakout.name}" is missing a PCB endpoint`);let sourceTraceId=breakoutPoint.matchedSourceTraceId;if(!sourceTraceId){let matchingSourceTraces=breakout.root.db.source_trace.list().filter(sourceTrace=>sourceTrace.connected_source_port_ids.includes(matchedPort.source_port_id));if(matchingSourceTraces.length===0)throw new Error(`Automatic breakout "${breakout.name}" has a point without a source trace identity`);let boundaryCrossingSourceTraces=matchingSourceTraces.filter(sourceTrace=>sourceTrace.connected_source_port_ids.some(sourcePortId=>{if(sourcePortId===matchedPort.source_port_id)return!1;let pcbPort2=breakout.root.db.pcb_port.getWhere({source_port_id:sourcePortId});return!pcbPort2||pcbPort2.pcb_group_id===breakout.pcb_group_id?!1:!(pcbPort2.x>=bounds.minX&&pcbPort2.x<=bounds.maxX&&pcbPort2.y>=bounds.minY&&pcbPort2.y<=bounds.maxY)}));sourceTraceId=(boundaryCrossingSourceTraces.length>0?boundaryCrossingSourceTraces:matchingSourceTraces).slice().sort((first,second)=>first.source_trace_id.localeCompare(second.source_trace_id))[0].source_trace_id,breakoutPoint.matchedSourceTraceId=sourceTraceId}if(endpointBySourceTraceId.has(sourceTraceId))throw new Error(`Connection "${sourceTraceId}" has duplicate endpoint for region "${breakout.pcb_group_id}"`);let pcbPort=breakout.root.db.pcb_port.get(matchedPort.pcb_port_id);if(!pcbPort)throw new Error(`Connection "${sourceTraceId}" references unknown PCB endpoint "${matchedPort.pcb_port_id}"`);if(pcbPort.pcb_group_id!==breakout.pcb_group_id)throw new Error(`Connection "${sourceTraceId}" endpoint references unknown region "${pcbPort.pcb_group_id??"unassigned"}" instead of "${breakout.pcb_group_id}"`);if(pcbPort.x===void 0||pcbPort.y===void 0)throw new Error(`Connection "${sourceTraceId}" is missing endpoint coordinates for region "${breakout.pcb_group_id}"`);endpointBySourceTraceId.set(sourceTraceId,{regionId:breakout.pcb_group_id,position:{x:pcbPort.x,y:pcbPort.y}}),sourcePortIdBySourceTraceId.set(sourceTraceId,matchedPort.source_port_id)}return{breakout,pcbGroupId:breakout.pcb_group_id,bounds,center:center2,endpointBySourceTraceId,sourcePortIdBySourceTraceId}},sortRegionsByPlacement=regions=>{let xCoordinates=regions.map(region=>region.center.x),yCoordinates=regions.map(region=>region.center.y),xSpan=Math.max(...xCoordinates)-Math.min(...xCoordinates),ySpan=Math.max(...yCoordinates)-Math.min(...yCoordinates),horizontalPlacement=xSpan>=ySpan;return regions.sort((firstRegion,secondRegion)=>{if(horizontalPlacement){let xDifference=firstRegion.center.x-secondRegion.center.x;if(xDifference!==0)return xDifference;let yDifference=firstRegion.center.y-secondRegion.center.y;if(yDifference!==0)return yDifference}else{let yDifference=firstRegion.center.y-secondRegion.center.y;if(yDifference!==0)return yDifference;let xDifference=firstRegion.center.x-secondRegion.center.x;if(xDifference!==0)return xDifference}return firstRegion.breakout.name.localeCompare(secondRegion.breakout.name)}),{regions,horizontalPlacement}},getFacingEdge=({region,regionIndex,regions,horizontalPlacement,singleRegionPreferredEdge})=>{if(regions.length===1&&singleRegionPreferredEdge)return singleRegionPreferredEdge;let otherRegions=regions.filter(candidate=>candidate!==region),otherCenter=otherRegions.reduce((sum,candidate)=>({x:sum.x+candidate.center.x/otherRegions.length,y:sum.y+candidate.center.y/otherRegions.length}),{x:0,y:0});return horizontalPlacement?otherCenter.x>region.center.x?"right":otherCenter.x<region.center.x?"left":regionIndex<regions.length/2?"right":"left":otherCenter.y>region.center.y?"top":otherCenter.y<region.center.y?"bottom":regionIndex<regions.length/2?"top":"bottom"},getExternalPositionsBySourceTraceId=({region,sourceTraces})=>{let externalPositionsBySourceTraceId=new Map,root=region.breakout.root;if(!root)return externalPositionsBySourceTraceId;let internalSourcePortIds=new Set(region.sourcePortIdBySourceTraceId.values());for(let sourceTrace of sourceTraces)if(sourceTrace.connected_source_port_ids.some(sourcePortId=>internalSourcePortIds.has(sourcePortId)))for(let sourcePortId of sourceTrace.connected_source_port_ids){if(internalSourcePortIds.has(sourcePortId))continue;let pcbPort=root.db.pcb_port.getWhere({source_port_id:sourcePortId});if(!pcbPort?.pcb_port_id||pcbPort.x===void 0||pcbPort.y===void 0||pcbPort.pcb_group_id===region.pcbGroupId)continue;let externalPositions=externalPositionsBySourceTraceId.get(sourceTrace.source_trace_id)??new Map;externalPositions.set(pcbPort.pcb_port_id,{x:pcbPort.x,y:pcbPort.y}),externalPositionsBySourceTraceId.set(sourceTrace.source_trace_id,externalPositions)}return externalPositionsBySourceTraceId},getSingleRegionPreferredEdge=({region,externalPositionsBySourceTraceId})=>{let externalPcbPorts=new Map;for(let externalPositions of externalPositionsBySourceTraceId.values())for(let[pcbPortId,position22]of externalPositions)position22.x>=region.bounds.minX&&position22.x<=region.bounds.maxX&&position22.y>=region.bounds.minY&&position22.y<=region.bounds.maxY||externalPcbPorts.set(pcbPortId,position22);if(externalPcbPorts.size===0)return;let distanceToEdge=(target,edge)=>{let edgePoint=edge==="left"||edge==="right"?{x:edge==="left"?region.bounds.minX:region.bounds.maxX,y:Math.max(region.bounds.minY,Math.min(region.bounds.maxY,target.y))}:{x:Math.max(region.bounds.minX,Math.min(region.bounds.maxX,target.x)),y:edge==="bottom"?region.bounds.minY:region.bounds.maxY};return Math.hypot(target.x-edgePoint.x,target.y-edgePoint.y)},edges=["right","left","top","bottom"];return edges.reduce((bestEdge,edge)=>{let bestCost=[...externalPcbPorts.values()].reduce((sum,target)=>sum+distanceToEdge(target,bestEdge),0);return[...externalPcbPorts.values()].reduce((sum,target)=>sum+distanceToEdge(target,edge),0)<bestCost?edge:bestEdge},edges[0])},getSourceTraceForConnectionOrThrow=({connectionOwner,connectionOwnerLabel,connectionSelector,sourceTraces})=>{let matchingSourceTraces=sourceTraces.filter(sourceTrace=>sourceTrace.name===connectionSelector);if(matchingSourceTraces.length===0){let selectedPort=connectionOwner.getSubcircuit().selectOne(connectionSelector,{type:"port"});selectedPort?.source_port_id&&(matchingSourceTraces=sourceTraces.filter(sourceTrace=>sourceTrace.connected_source_port_ids.includes(selectedPort.source_port_id)))}if(matchingSourceTraces.length===0)throw new Error(`Could not resolve "${connectionSelector}" in ${connectionOwnerLabel}`);if(matchingSourceTraces.length>1)throw new Error(`Connection "${connectionSelector}" resolves to multiple source traces in ${connectionOwnerLabel}`);return matchingSourceTraces[0]},getImplicitBreakoutSolverBuses=({routingScope,sourceTraces,coordinatedSourceTraceIds,availableLayers})=>{let solverBuses=[],subcircuitId=routingScope.getSubcircuit().subcircuit_id;for(let bus of routingScope.selectAll("bus")){if(bus.getSubcircuit().subcircuit_id!==subcircuitId)continue;let connectionIds=[];for(let connectionSelector of bus._parsedProps.connections){let sourceTrace=getSourceTraceForConnectionOrThrow({connectionOwner:bus,connectionOwnerLabel:`bus "${bus.name}"`,connectionSelector,sourceTraces});coordinatedSourceTraceIds.has(sourceTrace.source_trace_id)&&connectionIds.push(sourceTrace.source_trace_id)}if(connectionIds.length===0)continue;let solverBus={busId:bus.name,connectionIds};if(bus._parsedProps.preferredLayer!==void 0)solverBus={...solverBus,targetLayers:[bus._parsedProps.preferredLayer]};else if(bus._parsedProps.preferredLayers!==void 0)solverBus={...solverBus,targetLayers:bus._parsedProps.preferredLayers};else{let targetLayers=bus._parsedProps.pcbAllowedLayers??availableLayers;solverBus={...solverBus,targetLayers:[...new Set(targetLayers)]}}solverBuses.push(solverBus)}return solverBuses},getDifferentialPairSourceTraces=({routingScope,sourceTraces})=>{let subcircuitId=routingScope.getSubcircuit().subcircuit_id,pairs32=[];for(let differentialPair of routingScope.selectAll("differentialpair")){if(differentialPair.getSubcircuit().subcircuit_id!==subcircuitId)continue;let positiveSourceTrace=getSourceTraceForConnectionOrThrow({connectionOwner:differentialPair,connectionOwnerLabel:`differential pair "${differentialPair.name}"`,connectionSelector:differentialPair._parsedProps.positiveConnection,sourceTraces}),negativeSourceTrace=getSourceTraceForConnectionOrThrow({connectionOwner:differentialPair,connectionOwnerLabel:`differential pair "${differentialPair.name}"`,connectionSelector:differentialPair._parsedProps.negativeConnection,sourceTraces});pairs32.push({differentialPair,positiveSourceTraceId:positiveSourceTrace.source_trace_id,negativeSourceTraceId:negativeSourceTrace.source_trace_id})}return pairs32},getBoundaryPointSpacing=breakout=>{let board=breakout.root?.db.pcb_board.list()[0],traceWidth=board?.min_trace_width??.15,traceToPadClearance=board?.min_trace_to_pad_edge_clearance??.2,viaPadDiameter=board?.min_via_pad_diameter??.3;return getFanoutBoundaryPointSpacing({traceWidth,traceToPadClearance,viaPadDiameter})},getCoordinatedFanoutLayers=({routingScope,automaticBreakouts})=>{let coordinatedLayers=getBoardAvailableLayers(routingScope._getSubcircuitLayerCount());for(let automaticBreakout of automaticBreakouts){let fanoutRoutingLayers=automaticBreakout._parsedProps.fanoutRoutingLayers?.map(String);if(!fanoutRoutingLayers)continue;let fanoutLayerSet=new Set(fanoutRoutingLayers);coordinatedLayers=coordinatedLayers.filter(layer=>fanoutLayerSet.has(layer))}if(coordinatedLayers.length===0)throw new Error(`Automatic breakouts in routing scope "${routingScope.name}" have no shared fanout routing layer`);return coordinatedLayers},warnAboutUnknownFanoutDirectionBuses=({breakout,routingScope,busFanoutDirections})=>{if(!busFanoutDirections||!breakout.root)return;let sourceComponentId=breakout.root.db.pcb_component.list().find(pcbComponent=>pcbComponent.pcb_group_id===breakout.pcb_group_id)?.source_component_id;if(!sourceComponentId)return;let subcircuitId=routingScope.getSubcircuit().subcircuit_id,busNames=new Set(routingScope.selectAll("bus").filter(bus=>bus.getSubcircuit().subcircuit_id===subcircuitId).map(bus=>bus.name));for(let busName of Object.keys(busFanoutDirections))busNames.has(busName)||breakout.root.db.source_property_ignored_warning.insert({source_component_id:sourceComponentId,property_name:"busFanoutDirections",error_type:"source_property_ignored_warning",message:`Breakout "${breakout.name}" busFanoutDirections names unknown bus "${busName}"; the entry is ignored`,subcircuit_id:subcircuitId??void 0})},createImplicitBreakoutPointSolverContext=breakout=>{if(!breakout.root)throw new Error(`Automatic breakout "${breakout.name}" has no circuit root`);let routingScope=getRoutingScopeOrThrow(breakout),automaticBreakouts=getAutomaticBreakouts(routingScope,breakout),regionIds=new Set,collectedRegions=automaticBreakouts.map(automaticBreakout=>{let region=collectBreakoutRegionGeometry(automaticBreakout);if(regionIds.has(region.pcbGroupId))throw new Error(`Duplicate automatic breakout region "${region.pcbGroupId}"`);return regionIds.add(region.pcbGroupId),region}),{regions,horizontalPlacement}=sortRegionsByPlacement(collectedRegions),sourceTraceIds=new Set;for(let region of regions)for(let sourceTraceId of region.endpointBySourceTraceId.keys())sourceTraceIds.add(sourceTraceId);let sourceTraces=breakout.root.db.source_trace.list().filter(sourceTrace=>sourceTrace.subcircuit_id===routingScope.getSubcircuit().subcircuit_id),sourceTraceById=new Map;for(let sourceTrace of sourceTraces){if(sourceTraceById.has(sourceTrace.source_trace_id))throw new Error(`Duplicate connection identity "${sourceTrace.source_trace_id}"`);sourceTraceById.set(sourceTrace.source_trace_id,sourceTrace)}let sortedSourceTraceIds=[...sourceTraceIds].sort((firstSourceTraceId,secondSourceTraceId)=>{let firstName=sourceTraceById.get(firstSourceTraceId)?.name??firstSourceTraceId,secondName=sourceTraceById.get(secondSourceTraceId)?.name??secondSourceTraceId,nameDifference=firstName.localeCompare(secondName);return nameDifference!==0?nameDifference:firstSourceTraceId.localeCompare(secondSourceTraceId)});for(let sourceTraceId of sortedSourceTraceIds){if(!sourceTraceById.has(sourceTraceId))throw new Error(`Unknown connection identity "${sourceTraceId}"`);for(let region of regions)if(!region.endpointBySourceTraceId.has(sourceTraceId))throw new Error(`Connection "${sourceTraceId}" is missing endpoint for region "${region.pcbGroupId}"`)}let buses=getImplicitBreakoutSolverBuses({routingScope,sourceTraces,coordinatedSourceTraceIds:sourceTraceIds,availableLayers:getCoordinatedFanoutLayers({routingScope,automaticBreakouts})}),endpointsBySourceTraceId=new Map;for(let sourceTraceId of sortedSourceTraceIds)endpointsBySourceTraceId.set(sourceTraceId,regions.map(region=>region.endpointBySourceTraceId.get(sourceTraceId)));let differentialPairBySourceTraceId=new Map;for(let pair of getDifferentialPairSourceTraces({routingScope,sourceTraces})){let positiveIsCoordinated=sourceTraceIds.has(pair.positiveSourceTraceId),negativeIsCoordinated=sourceTraceIds.has(pair.negativeSourceTraceId);if(positiveIsCoordinated!==negativeIsCoordinated)throw new Error(`Differential pair "${pair.differentialPair.name}" is missing one coordinated member`);if(positiveIsCoordinated){if(differentialPairBySourceTraceId.has(pair.positiveSourceTraceId)||differentialPairBySourceTraceId.has(pair.negativeSourceTraceId))throw new Error("A connection belongs to multiple differential pairs");differentialPairBySourceTraceId.set(pair.positiveSourceTraceId,pair),differentialPairBySourceTraceId.set(pair.negativeSourceTraceId,pair)}}let connections=[],addedDifferentialPairs=new Set;for(let sourceTraceId of sortedSourceTraceIds){let differentialPair=differentialPairBySourceTraceId.get(sourceTraceId);if(!differentialPair){connections.push({connectionId:sourceTraceId,endpoints:endpointsBySourceTraceId.get(sourceTraceId)});continue}addedDifferentialPairs.has(differentialPair.differentialPair)||(addedDifferentialPairs.add(differentialPair.differentialPair),connections.push({type:"differential",connections:[{connectionId:differentialPair.positiveSourceTraceId,endpoints:endpointsBySourceTraceId.get(differentialPair.positiveSourceTraceId)},{connectionId:differentialPair.negativeSourceTraceId,endpoints:endpointsBySourceTraceId.get(differentialPair.negativeSourceTraceId)}]}))}let sourcePortIdByConnectionIdByRegionId=new Map,externalPositionsBySourceTraceId=regions.length===1?getExternalPositionsBySourceTraceId({region:regions[0],sourceTraces}):void 0,singleRegionPreferredEdge=externalPositionsBySourceTraceId?getSingleRegionPreferredEdge({region:regions[0],externalPositionsBySourceTraceId}):void 0,solverRegions=regions.map((region,regionIndex)=>(sourcePortIdByConnectionIdByRegionId.set(region.pcbGroupId,region.sourcePortIdBySourceTraceId),{regionId:region.pcbGroupId,bounds:region.bounds,edge:getFacingEdge({region,regionIndex,regions,horizontalPlacement,singleRegionPreferredEdge})})),boundaryPointSpacing=getBoundaryPointSpacing(breakout),singleRegionEdgeGroups;if(externalPositionsBySourceTraceId){let region=regions[0],busFanoutDirections=region.breakout._parsedProps.busFanoutDirections;warnAboutUnknownFanoutDirectionBuses({breakout:region.breakout,routingScope,busFanoutDirections}),singleRegionEdgeGroups=assignSingleRegionBreakoutEdges({bounds:region.bounds,connectionIds:sortedSourceTraceIds,pinPositionByConnectionId:new Map([...region.endpointBySourceTraceId].map(([sourceTraceId,endpoint])=>[sourceTraceId,endpoint.position])),externalPositionsByConnectionId:new Map([...externalPositionsBySourceTraceId].map(([sourceTraceId,positions])=>[sourceTraceId,[...positions.values()]])),atomicGroups:[...new Set(differentialPairBySourceTraceId.values())].map(pair=>[pair.positiveSourceTraceId,pair.negativeSourceTraceId]),buses,busFanoutDirections,fallbackEdge:solverRegions[0].edge,boundaryPointSpacing,layerCount:getCoordinatedFanoutLayers({routingScope,automaticBreakouts}).length})}return{input:{regions:solverRegions,connections,buses,boundaryPointSpacing},sourcePortIdByConnectionIdByRegionId,...singleRegionEdgeGroups?{singleRegionEdgeGroups}:{}}},GEOMETRY_EPSILON32=1e-9,packBreakoutEdgeGroups=({bounds,edge,blocks,boundaryPointSpacing})=>{let vertical=isVerticalBreakoutEdge(edge),edgeMin=vertical?bounds.minY:bounds.minX,edgeMax=vertical?bounds.maxY:bounds.maxX,edgeLength=getBreakoutEdgeLength(bounds,edge),getAxis3=point12=>vertical?point12.y:point12.x,placedBlocks=blocks.filter(block=>block.points.length>0).map(block=>{let axes2=block.points.map(getAxis3),low=Math.min(...axes2),length93=Math.max(...axes2)-low,targetLow=low;return block.band==="start"?targetLow=edgeMin+edgeLength/6-length93/2:block.band==="end"?targetLow=edgeMax-edgeLength/6-length93/2:block.band==="center"&&(targetLow=(edgeMin+edgeMax-length93)/2),targetLow=Math.max(edgeMin,Math.min(edgeMax-length93,targetLow)),{...block,low,length:length93,placedLow:targetLow}}).sort((first,second)=>first.placedLow-second.placedLow),cursor=edgeMin;for(let block of placedBlocks)block.placedLow=Math.max(block.placedLow,cursor),cursor=block.placedLow+block.length+boundaryPointSpacing;let limit=edgeMax;for(let block of[...placedBlocks].reverse())block.placedLow=Math.min(block.placedLow,limit-block.length),limit=block.placedLow-boundaryPointSpacing;let firstBlock=placedBlocks[0];if(firstBlock&&firstBlock.placedLow<edgeMin-GEOMETRY_EPSILON32){let neededLength=placedBlocks.reduce((sum,block)=>sum+block.length,0)+boundaryPointSpacing*(placedBlocks.length-1);throw new WindingBreakoutInfeasibleError(`WindingBreakoutSolver: ${edge} breakout edge needs ${neededLength.toFixed(2)}mm but exposes only ${edgeLength.toFixed(2)}mm`)}return placedBlocks.flatMap(block=>{let shift=block.placedLow-block.low;return block.points.map(point12=>vertical?{...point12,y:point12.y+shift}:{...point12,x:point12.x+shift})})},cachedSolutionsByRoutingScope=new WeakMap,runSolverSynchronously=(solverFn,input2)=>{let output=solverFn(input2);if(output instanceof Promise)throw new Error("Implicit breakout point solvers must return synchronously during PCB layout");return output.breakoutPoints},solveSingleRegionEdgeGroups=(context,solverFn)=>{let{input:input2,singleRegionEdgeGroups}=context,region=input2.regions[0],blocksByEdge=new Map;for(let group2 of singleRegionEdgeGroups){let groupConnectionIds=new Set(group2.connectionIds),points=runSolverSynchronously(solverFn,{...input2,regions:[{...region,edge:group2.edge}],connections:input2.connections.filter(connection=>"type"in connection?groupConnectionIds.has(connection.connections[0].connectionId):groupConnectionIds.has(connection.connectionId)),buses:input2.buses.map(bus=>({...bus,connectionIds:bus.connectionIds.filter(connectionId=>groupConnectionIds.has(connectionId))})).filter(bus=>bus.connectionIds.length>0)}),blocks=blocksByEdge.get(group2.edge)??[];blocks.push({band:group2.band,points}),blocksByEdge.set(group2.edge,blocks)}return[...blocksByEdge].flatMap(([edge,blocks])=>packBreakoutEdgeGroups({bounds:region.bounds,edge,blocks,boundaryPointSpacing:input2.boundaryPointSpacing}))},solveScope=(breakout,solverFn)=>{let context=createImplicitBreakoutPointSolverContext(breakout),singleRegionEdgeGroups=context.singleRegionEdgeGroups,outputBreakoutPoints=singleRegionEdgeGroups!==void 0&&(singleRegionEdgeGroups.length>1||singleRegionEdgeGroups[0]?.band!==void 0)?solveSingleRegionEdgeGroups(context,solverFn):runSolverSynchronously(solverFn,context.input),expectedConnectionCount=0;for(let connection of context.input.connections){if("type"in connection){expectedConnectionCount+=connection.connections.length;continue}expectedConnectionCount+=1}let breakoutPointsByRegionId=new Map,outputPointKeys=new Set;for(let region of context.input.regions)breakoutPointsByRegionId.set(region.regionId,[]);for(let breakoutPoint of outputBreakoutPoints){let regionBreakoutPoints=breakoutPointsByRegionId.get(breakoutPoint.regionId);if(!regionBreakoutPoints)throw new Error(`Implicit breakout point solver returned unknown region "${breakoutPoint.regionId}"`);let outputPointKey=`${breakoutPoint.regionId}:${breakoutPoint.connectionId}`;if(outputPointKeys.has(outputPointKey))throw new Error(`Implicit breakout point solver returned duplicate endpoint for connection "${breakoutPoint.connectionId}" in region "${breakoutPoint.regionId}"`);outputPointKeys.add(outputPointKey);let sourcePortId=context.sourcePortIdByConnectionIdByRegionId.get(breakoutPoint.regionId)?.get(breakoutPoint.connectionId);if(!sourcePortId)throw new Error(`Implicit breakout point solver returned unknown connection "${breakoutPoint.connectionId}" for region "${breakoutPoint.regionId}"`);regionBreakoutPoints.push({sourcePortId,sourceTraceId:breakoutPoint.connectionId,layer:breakoutPoint.layer,x:breakoutPoint.x,y:breakoutPoint.y})}for(let[regionId,regionBreakoutPoints]of breakoutPointsByRegionId)if(regionBreakoutPoints.length!==expectedConnectionCount)throw new Error(`Implicit breakout point solver output is missing endpoints for region "${regionId}"`);return{breakoutPointsByRegionId}},solveImplicitBreakoutPoints=(breakout,solverFn)=>{let routingScope=breakout.parent;if(!routingScope||!breakout.pcb_group_id)throw new Error(`Automatic breakout "${breakout.name}" has no coordinated PCB region`);let cachedSolutions=cachedSolutionsByRoutingScope.get(routingScope);(!cachedSolutions||cachedSolutions.solverFn!==solverFn)&&(cachedSolutions={solverFn,solutions:[]},cachedSolutionsByRoutingScope.set(routingScope,cachedSolutions));let solution2=cachedSolutions.solutions.find(candidateSolution=>candidateSolution.breakoutPointsByRegionId.has(breakout.pcb_group_id));solution2||(solution2=solveScope(breakout,solverFn),cachedSolutions.solutions.push(solution2));let breakoutPoints=solution2.breakoutPointsByRegionId.get(breakout.pcb_group_id);if(!breakoutPoints)throw new Error(`Automatic breakout "${breakout.name}" references unknown implicit-breakout region "${breakout.pcb_group_id}"`);return breakoutPoints},Breakout=class extends Group{get isDogboneFanout(){let autorouter=this._parsedProps.autorouter;return(typeof autorouter=="string"?autorouter:autorouter?.preset)==="dogbone"}get isRoutingDirective(){return!0}get config(){return{...super.config,zodProps:breakoutProps}}doInitialCreateAutoplacedBreakoutPoints(){for(let path of this._parsedProps.pcbTracePaths??[]){let exit=path.route.at(-1),point12=new SavedFanoutPoint({connection:path.connection,pcbX:exit.x,pcbY:exit.y});if(point12.exitLayer=exit.route_type==="wire"?exit.layer:exit.to_layer,this.add(point12),point12._matchConnection(),!point12.matchedPort||!this.selectAll("port").includes(point12.matchedPort))throw new Error(`Fanout trace path "${path.connection}" must select a port inside the fanout`);if(this.children.some(child=>!(child instanceof BreakoutPoint)||child===point12?!1:(child._matchConnection(),child.matchedPort===point12.matchedPort)))throw new Error(`Duplicate fanout exit for "${path.connection}"`)}let portsInBreakout=this.selectAll("port"),breakoutPortSet=new Set(portsInBreakout),manualBreakoutPoints=this.children.filter(c23=>c23 instanceof BreakoutPoint),manuallyMappedPorts=new Set(manualBreakoutPoints.map(bp22=>(bp22._matchConnection(),bp22.matchedPort)).filter(Boolean)),allTraces=this.getSubcircuit().selectAll("trace"),autoPlacedPorts=new Set;for(let trace of allTraces){let result=trace._findConnectedPorts();if(!(!result.allPortsFound||!result.ports))for(let port of result.ports){let isInside2=breakoutPortSet.has(port),hasOutsidePort=result.ports.some(p23=>!breakoutPortSet.has(p23));if(!isInside2||!hasOutsidePort&&!this.isDogboneFanout||manuallyMappedPorts.has(port)||autoPlacedPorts.has(port))continue;autoPlacedPorts.add(port);let breakoutPoint=new AutoplacedBreakoutPoint({});breakoutPoint.matchedPort=port,breakoutPoint.matchedSourceTraceId=trace.source_trace_id,this.add(breakoutPoint)}}}doInitialPcbAutoplaceBreakoutPoints(){if(this.root?.pcbDisabled)return;if(this.isDogboneFanout&&this._parsedProps.pcbTracePaths===void 0){for(let point12 of this.children){if(!(point12 instanceof AutoplacedBreakoutPoint))continue;let port=this.root.db.pcb_port.get(point12.matchedPort.pcb_port_id);point12._applySolvedBreakoutPoint({sourceTraceId:point12.matchedSourceTraceId,layer:port.layers[0],position:port})}return}let ownAutorouter=this.props.autorouter,inheritedAutorouter=ownAutorouter===void 0?this.parent?.getInheritedProperty("autorouter"):void 0,implicitBreakoutPointSolverFn=typeof ownAutorouter=="object"?ownAutorouter.implicitBreakoutPointSolverFn:typeof inheritedAutorouter=="object"?inheritedAutorouter.implicitBreakoutPointSolverFn:void 0,autoBreakoutPoints=this.children.filter(child=>child instanceof AutoplacedBreakoutPoint);if(autoBreakoutPoints.length===0||!this.root||!this.pcb_group_id)return;let pcbGroup=this.root.db.pcb_group.get(this.pcb_group_id);if(!pcbGroup?.width||!pcbGroup.height)return;let bounds={minX:pcbGroup.center.x-pcbGroup.width/2,maxX:pcbGroup.center.x+pcbGroup.width/2,minY:pcbGroup.center.y-pcbGroup.height/2,maxY:pcbGroup.center.y+pcbGroup.height/2},solvedBreakoutPoints;try{solvedBreakoutPoints=solveImplicitBreakoutPoints(this,implicitBreakoutPointSolverFn??defaultImplicitBreakoutPointSolverFn)}catch(error2){if(implicitBreakoutPointSolverFn||!reportWindingBreakoutInfeasibleError(this,error2))throw error2;return}let BOUNDARY_INSET_MM=1e-4,insetWithinBounds=(x23,y23)=>({x:Math.max(bounds.minX+BOUNDARY_INSET_MM,Math.min(bounds.maxX-BOUNDARY_INSET_MM,x23)),y:Math.max(bounds.minY+BOUNDARY_INSET_MM,Math.min(bounds.maxY-BOUNDARY_INSET_MM,y23))});for(let solvedPoint of solvedBreakoutPoints){let matchingBreakoutPoint=autoBreakoutPoints.find(child=>child.matchedPort?.source_port_id===solvedPoint.sourcePortId);if(matchingBreakoutPoint){let insetPoint=insetWithinBounds(solvedPoint.x,solvedPoint.y);matchingBreakoutPoint._applySolvedBreakoutPoint({sourceTraceId:solvedPoint.sourceTraceId,layer:solvedPoint.layer,position:insetPoint})}}}doInitialPcbPrimitiveRender(){super.doInitialPcbPrimitiveRender()}doInitialPcbPlacementDesignRuleChecks(){Breakout_doInitialPcbPlacementDesignRuleChecks(this)}},SilkscreenGraphic=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"pcb_silkscreen_graphic_id",null);__publicField(this,"pcb_silkscreen_graphic_ids",[]);__publicField(this,"pcb_silkscreen_path_ids",[]);__publicField(this,"isPcbPrimitive",!0)}get config(){return{componentName:"SilkscreenGraphic",zodProps:silkscreenGraphicProps}}doInitialPcbPrimitiveRender(){this.root?.pcbDisabled||this._queueAsyncEffect("SilkscreenGraphicRender",async()=>{if(this.root?.pcbDisabled)return;let{db:db22}=this.root,{_parsedProps:props}=this,{maybeFlipLayer}=this._getPcbPrimitiveFlippedHelpers(),layer=maybeFlipLayer(props.layer??"top");if(layer!=="top"&&layer!=="bottom")throw new Error(`Invalid layer "${layer}" for SilkscreenGraphic. Must be "top" or "bottom".`);let sourceImage=await loadImageSource(props.imageUrl);if(sourceImage.mimetype!==SVG_MIMETYPE2&&sourceImage.mimetype!==PNG_MIMETYPE)throw new Error(`Unsupported imageUrl for SilkscreenGraphic: "${props.imageUrl}". Expected an SVG or PNG image.`);let imageAsset={project_relative_path:sourceImage.projectRelativePath,url:sourceImage.dataUrl,mimetype:sourceImage.mimetype},brepShapes=sourceImage.mimetype===SVG_MIMETYPE2?getSvgBRepShapes({svg:sourceImage.text,width:props.width,height:props.height,transform:this._computePcbGlobalTransformBeforeLayout()}):[this.getPlacementBoxBRepShape()],pcbComponentId=this.parent?.pcb_component_id??this.getPrimitiveContainer()?.pcb_component_id??"";for(let brepShape of brepShapes){let graphic=db22.insert({type:"pcb_silkscreen_graphic",pcb_component_id:pcbComponentId,pcb_group_id:this.getGroup()?.pcb_group_id??void 0,subcircuit_id:this.getSubcircuit()?.subcircuit_id??void 0,layer,shape:"brep",brep_shape:brepShape,image_asset:imageAsset});this.pcb_silkscreen_graphic_ids.push(graphic.pcb_silkscreen_graphic_id)}this.pcb_silkscreen_graphic_id=this.pcb_silkscreen_graphic_ids[0]??null,sourceImage.mimetype===SVG_MIMETYPE2&&this.insertRenderableSilkscreenPaths(sourceImage.text,layer)})}insertRenderableSilkscreenPaths(svg,layer){let{db:db22}=this.root,{_parsedProps:props}=this,transform22=this._computePcbGlobalTransformBeforeLayout(),pcb_component_id=this.parent?.pcb_component_id??this.getPrimitiveContainer()?.pcb_component_id??"";for(let route2 of getTransformedSvgPathRoutes({svg,width:props.width,height:props.height,transform:transform22})){if(route2.length<2)continue;let path=db22.pcb_silkscreen_path.insert({pcb_component_id,layer,route:route2,stroke_width:Math.max(Math.min(props.width,props.height)/60,.05),subcircuit_id:this.getSubcircuit()?.subcircuit_id??void 0,pcb_group_id:this.getGroup()?.pcb_group_id??void 0});this.pcb_silkscreen_path_ids.push(path.pcb_silkscreen_path_id)}}getPcbSize(){let{_parsedProps:props}=this;return{width:props.width,height:props.height}}getPlacementBoxBRepShape(){let{_parsedProps:props}=this,halfWidth=props.width/2,halfHeight=props.height/2,transform22=this._computePcbGlobalTransformBeforeLayout();return{outer_ring:{vertices:ensureClockwise([{x:-halfWidth,y:halfHeight},{x:halfWidth,y:halfHeight},{x:halfWidth,y:-halfHeight},{x:-halfWidth,y:-halfHeight}]).map(point12=>applyToPoint3(transform22,point12))},inner_rings:[]}}_moveCircuitJsonElements({deltaX,deltaY}){if(this.root?.pcbDisabled)return;let{db:db22}=this.root,moveVertex=vertex=>({...vertex,x:vertex.x+deltaX,y:vertex.y+deltaY});for(let graphicId of this.pcb_silkscreen_graphic_ids){let graphic=db22.pcb_silkscreen_graphic.get(graphicId);graphic&&db22.pcb_silkscreen_graphic.update(graphicId,{brep_shape:{outer_ring:{vertices:graphic.brep_shape.outer_ring.vertices.map(moveVertex)},inner_rings:graphic.brep_shape.inner_rings.map(ring23=>({vertices:ring23.vertices.map(moveVertex)}))}})}for(let pathId of this.pcb_silkscreen_path_ids){let path=db22.pcb_silkscreen_path.get(pathId);path&&db22.pcb_silkscreen_path.update(pathId,{route:path.route.map(point12=>({...point12,x:point12.x+deltaX,y:point12.y+deltaY}))})}}},Fiducial=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"pcb_smtpad_id",null);__publicField(this,"isPcbPrimitive",!0)}get config(){return{componentName:"Fiducial",zodProps:fiducialProps,sourceFtype:"simple_fiducial"}}doInitialPcbPrimitiveRender(){if(this.root?.pcbDisabled)return;let{db:db22}=this.root,{_parsedProps:props}=this,position22=this._getGlobalPcbPositionBeforeLayout(),{maybeFlipLayer}=this._getPcbPrimitiveFlippedHelpers(),pcb_component_id=this.parent?.pcb_component_id??this.getPrimitiveContainer()?.pcb_component_id??void 0,pcb_smtpad23=db22.pcb_smtpad.insert({pcb_component_id,subcircuit_id:this.getSubcircuit()?.subcircuit_id??void 0,pcb_group_id:this.getGroup()?.pcb_group_id??void 0,layer:maybeFlipLayer(props.layer||"top"),shape:"circle",x:position22.x,y:position22.y,radius:distance4.parse(props.padDiameter)/2,soldermask_margin:props.soldermaskPullback?distance4.parse(props.soldermaskPullback):distance4.parse(props.padDiameter)/2,is_covered_with_solder_mask:!0});this.pcb_smtpad_id=pcb_smtpad23.pcb_smtpad_id}getPcbSize(){let{_parsedProps:props}=this,d23=distance4.parse(props.padDiameter);return{width:d23,height:d23}}_setPositionFromLayout(newCenter){if(!this.pcb_smtpad_id)return;let{db:db22}=this.root;db22.pcb_smtpad.update(this.pcb_smtpad_id,{x:newCenter.x,y:newCenter.y})}_moveCircuitJsonElements({deltaX,deltaY}){if(this.root?.pcbDisabled)return;let{db:db22}=this.root;if(!this.pcb_smtpad_id)return;let pad2=db22.pcb_smtpad.get(this.pcb_smtpad_id);pad2&&(pad2.shape==="rect"||pad2.shape==="circle"||pad2.shape==="rotated_rect"||pad2.shape==="pill"?this._setPositionFromLayout({x:pad2.x+deltaX,y:pad2.y+deltaY}):pad2.shape==="polygon"&&db22.pcb_smtpad.update(this.pcb_smtpad_id,{points:pad2.points.map(p23=>({x:p23.x+deltaX,y:p23.y+deltaY}))}))}},EPSILON30=1e-9,isWireRoutePoint=routePoint3=>routePoint3.route_type==="wire",getWirePointKey=point12=>`${point12.layer}:${point12.x}:${point12.y}`,isPointOnSegment42=(p23,a23,b23)=>{if(Math.hypot(b23.x-a23.x,b23.y-a23.y)<=EPSILON30)return Math.hypot(p23.x-a23.x,p23.y-a23.y)<=EPSILON30;let cross52=(p23.y-a23.y)*(b23.x-a23.x)-(p23.x-a23.x)*(b23.y-a23.y);if(Math.abs(cross52)>EPSILON30)return!1;let dot23=(p23.x-a23.x)*(b23.x-a23.x)+(p23.y-a23.y)*(b23.y-a23.y);if(dot23<-EPSILON30)return!1;let squaredLength6=(b23.x-a23.x)**2+(b23.y-a23.y)**2;return!(dot23-squaredLength6>EPSILON30)},isPointInRing2=(point12,ring23)=>{if(ring23.length<3)return!1;let inside42=!1,previous=ring23[ring23.length-1];for(let current23 of ring23){if(isPointOnSegment42(point12,previous,current23))return!0;current23.y>point12.y!=previous.y>point12.y&&point12.x<(previous.x-current23.x)*(point12.y-current23.y)/(previous.y-current23.y)+current23.x&&(inside42=!inside42),previous=current23}return inside42},isPointInRectPour=(p23,pour)=>{let{center:center2,width:width10,height:height10}=pour,rotationRad=(pour.rotation??0)*Math.PI/180,cosR=Math.cos(-rotationRad),sinR=Math.sin(-rotationRad),dx22=p23.x-center2.x,dy22=p23.y-center2.y,localX=dx22*cosR-dy22*sinR,localY=dx22*sinR+dy22*cosR;return Math.abs(localX)<=width10/2+EPSILON30&&Math.abs(localY)<=height10/2+EPSILON30},isPointInBrepPour=(p23,pour)=>isPointInRing2(p23,pour.brep_shape.outer_ring.vertices)&&!pour.brep_shape.inner_rings.some(ring23=>isPointInRing2(p23,ring23.vertices)),isPointInCopperPour=(point12,pour)=>pour.shape==="rect"?isPointInRectPour(point12,pour):pour.shape==="brep"?isPointInBrepPour(point12,pour):!1,isTraceConnectedToSourceNet=(trace,sourceNetId,sourceTraceById)=>{if(trace.source_trace_id===sourceNetId)return!0;if(!trace.source_trace_id)return!1;let sourceTrace=sourceTraceById.get(trace.source_trace_id);return sourceTrace?sourceTrace.connected_source_net_ids.includes(sourceNetId):!1},isSegmentFullyInsideCopperPour=(start,end,pour)=>{let dx22=end.x-start.x,dy22=end.y-start.y;if(Math.hypot(dx22,dy22)<=EPSILON30||!isPointInCopperPour(start,pour)||!isPointInCopperPour(end,pour))return!1;if(pour.shape==="rect")return!0;if(pour.shape!=="brep")return!1;for(let ring23 of[pour.brep_shape.outer_ring,...pour.brep_shape.inner_rings]){let vertices=ring23.vertices;for(let edgeIndex=0;edgeIndex<vertices.length;edgeIndex++)if(doesTraceSegmentTouchPourBoundaryEdge(start,end,vertices[edgeIndex],vertices[(edgeIndex+1)%vertices.length]))return!1}return!0},doesTraceSegmentTouchPourBoundaryEdge=(traceStart,traceEnd,boundaryStart,boundaryEnd)=>{if(isPointOnSegment42(traceStart,boundaryStart,boundaryEnd)||isPointOnSegment42(traceEnd,boundaryStart,boundaryEnd)||isPointOnSegment42(boundaryStart,traceStart,traceEnd)||isPointOnSegment42(boundaryEnd,traceStart,traceEnd))return!0;let side=(start,end,point12)=>(end.x-start.x)*(point12.y-start.y)-(end.y-start.y)*(point12.x-start.x),oppositeSides=(first,second)=>first>EPSILON30&&second<-EPSILON30||first<-EPSILON30&&second>EPSILON30;return oppositeSides(side(traceStart,traceEnd,boundaryStart),side(traceStart,traceEnd,boundaryEnd))&&oppositeSides(side(boundaryStart,boundaryEnd,traceStart),side(boundaryStart,boundaryEnd,traceEnd))},markTraceSegmentsInsideCopperPour=({db:db22,copperPour})=>{let sourceNetId=copperPour.source_net_id;if(!sourceNetId)return;let sourceTraceById=new Map(db22.source_trace.list().map(sourceTrace=>[sourceTrace.source_trace_id,sourceTrace])),traceCoverage=db22.pcb_trace.list().filter(trace=>isTraceConnectedToSourceNet(trace,sourceNetId,sourceTraceById)).map(trace=>({trace,coveredSegments:trace.route.slice(0,-1).map((from,segmentIndex)=>{let to3=trace.route[segmentIndex+1];return isWireRoutePoint(from)&&isWireRoutePoint(to3)&&from.layer===copperPour.layer&&to3.layer===copperPour.layer&&isSegmentFullyInsideCopperPour(from,to3,copperPour)})})),exposedPoints=new Set;for(let{trace,coveredSegments}of traceCoverage)for(let[routeIndex,point12]of trace.route.entries()){let coveredBefore=routeIndex===0||coveredSegments[routeIndex-1],coveredAfter=routeIndex===trace.route.length-1||coveredSegments[routeIndex];isWireRoutePoint(point12)&&(!coveredBefore||!coveredAfter)&&exposedPoints.add(getWirePointKey(point12))}for(let{trace,coveredSegments}of traceCoverage){let routeChanged=!1,nextRoute=trace.route.map(routePoint3=>{let point12={...routePoint3};return isWireRoutePoint(point12)&&coveredSegments.length>0&&!exposedPoints.has(getWirePointKey(point12))&&(point12.is_inside_copper_pour=!0,point12.copper_pour_id=copperPour.pcb_copper_pour_id,routeChanged=!0),point12});routeChanged&&db22.pcb_trace.update(trace.pcb_trace_id,{route:nextRoute})}},pendingCopperPourRenders=new WeakMap,DEFAULT_THERMAL_RELIEF_SPOKE_WIDTH_MM=.3,renderAllCopperPoursForSubcircuit=async subcircuit=>{if(!subcircuit.root)return;let{db:db22}=subcircuit.root,copperPours=subcircuit.selectAll("copperpour").filter(copperPour=>copperPour.getSubcircuit()===subcircuit),resolvedCopperPours=[];for(let copperPour of copperPours){let{_parsedProps:props}=copperPour,sourceNetId=subcircuit.selectOne(props.connectsTo)?.source_net_id;if(!sourceNetId){copperPour.renderError(`Net "${props.connectsTo}" not found for copper pour`);continue}resolvedCopperPours.push({copperPour,sourceNetId})}if(resolvedCopperPours.length===0)return;let circuitJson=db22.toArray(),boardComponent=subcircuit._getBoard(),pcbBoard=boardComponent?.pcb_board_id?db22.pcb_board.get(boardComponent.pcb_board_id):void 0,resolvedPcbBoardOutline=pcbBoard?.outline?.length?pcbBoard.outline:void 0;if(!resolvedPcbBoardOutline&&pcbBoard?.width!==void 0&&pcbBoard.height!==void 0){let{center:center2,width:width10,height:height10}=pcbBoard;resolvedPcbBoardOutline=[{x:center2.x-width10/2,y:center2.y-height10/2},{x:center2.x+width10/2,y:center2.y-height10/2},{x:center2.x+width10/2,y:center2.y+height10/2},{x:center2.x-width10/2,y:center2.y+height10/2}]}let inputProblem=convertCircuitJsonToInputProblem(circuitJson,resolvedCopperPours.map(({copperPour,sourceNetId})=>{let{_parsedProps:props}=copperPour,clearance=props.clearance??.2;return{pcb_board_id:pcbBoard?.pcb_board_id,layer:props.layer,crosshatch:props.crosshatch,crosshatchPitch:props.crosshatchPitch,crosshatchWidth:props.crosshatchWidth,subcircuit_id:subcircuit.subcircuit_id??void 0,source_net_id:sourceNetId,pad_margin:props.padMargin??clearance,trace_margin:props.traceMargin??clearance,pour_margin:clearance,board_edge_margin:props.boardEdgeMargin??clearance,board_edge_outline:copperPour._isImplicitCopperPour?resolvedPcbBoardOutline:void 0,cutout_margin:props.cutoutMargin??clearance,...props.useThermalReliefs?{use_thermal_reliefs:!0,thermal_relief_spoke_width:DEFAULT_THERMAL_RELIEF_SPOKE_WIDTH_MM}:{},outline:props.outline??resolvedPcbBoardOutline}}));await initializeManifoldGeometry();let solver=new CopperPourPipelineSolver(inputProblem);subcircuit.root.emit("solver:started",{type:"solver:started",solverName:"CopperPourPipelineSolver",solverParams:inputProblem,solverConstructorArgs:[inputProblem],componentName:subcircuit.getString()});let{brep_shapes_by_region}=solver.getOutput();for(let[regionIndex,{copperPour,sourceNetId}]of resolvedCopperPours.entries()){let{_parsedProps:props}=copperPour,coveredWithSolderMask=props.coveredWithSolderMask??!1;for(let brepShape of brep_shapes_by_region[regionIndex]??[]){let insertedPour=db22.pcb_copper_pour.insert({shape:"brep",layer:props.layer,brep_shape:brepShape,source_net_id:sourceNetId,subcircuit_id:subcircuit.subcircuit_id??void 0,covered_with_solder_mask:coveredWithSolderMask});markTraceSegmentsInsideCopperPour({db:db22,copperPour:insertedPour})}}};function CopperPour_doInitialPcbCopperPourRender(copperPour){copperPour.root?.pcbDisabled||copperPour._queueAsyncEffect("PcbCopperPourRender",async()=>{let subcircuit=copperPour.getSubcircuit(),pendingRender=pendingCopperPourRenders.get(subcircuit);if(pendingRender){await pendingRender;return}let renderPromise=renderAllCopperPoursForSubcircuit(subcircuit);pendingCopperPourRenders.set(subcircuit,renderPromise);try{await renderPromise}finally{pendingCopperPourRenders.delete(subcircuit)}})}var renderViaStitchingForCopperPours=copperPour=>{let subcircuit=copperPour.getSubcircuit();if(!subcircuit.root)return;let copperPours=subcircuit.selectAll("copperpour").filter(candidateCopperPour=>candidateCopperPour.getSubcircuit()===subcircuit);if(copperPours[0]!==copperPour)return;let sourceNetIds=copperPours.flatMap(candidateCopperPour=>{let net=subcircuit.selectOne(candidateCopperPour._parsedProps.connectsTo);return net?.source_net_id?[net.source_net_id]:[]});if(sourceNetIds.length===0)return;let{db:db22}=subcircuit.root,pcbStyle3=copperPour.getInheritedMergedProperty("pcbStyle"),{holeDiameter,padDiameter}=getViaDiameterDefaults(pcbStyle3),boardComponent=copperPour._getBoard(),pcbBoard=boardComponent?.pcb_board_id?db22.pcb_board.get(boardComponent.pcb_board_id):void 0,solverInput={circuitJson:db22.toArray(),options:{sourceNetIds:[...new Set(sourceNetIds)],viaHoleDiameter:pcbBoard?.min_via_hole_diameter??holeDiameter,viaOuterDiameter:pcbBoard?.min_via_pad_diameter??padDiameter,viaStitchPitch:boardComponent?._parsedProps.viaStitchPitch}},solver=new ViaStitchSolver(solverInput);if(subcircuit.root.emit("solver:started",{type:"solver:started",solverName:"ViaStitchSolver",solverParams:solverInput,solverConstructorArgs:[solverInput],componentName:subcircuit.getString()}),solver.solve(),solver.failed)throw new Error(solver.error??"Via stitching solver failed");for(let pcbVia of solver.getOutput().pcbVias){let{pcb_via_id:_solverViaId,...pcbViaInput}=pcb_via.parse(pcbVia),insertedVia=db22.pcb_via.insert({...pcbViaInput,tented_on_top:void 0,tented_on_bottom:void 0});boardComponent?._generatedStitchingViaIds?.add(insertedVia.pcb_via_id)}};function CopperPour_doInitialPcbViaStitchRender(copperPour){copperPour.root?.pcbDisabled||!copperPour.root?._featurePcbViaStitching||copperPour._getBoard()?._parsedProps.enableViaStitching&&copperPour._queueAsyncEffect("PcbViaStitchRender",async()=>{renderViaStitchingForCopperPours(copperPour)})}var CopperPour=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"isPcbPrimitive",!0);__publicField(this,"_isImplicitCopperPour",!1)}get config(){return{componentName:"CopperPour",zodProps:copperPourProps}}getPcbSize(){return{width:0,height:0}}doInitialCreateNetsFromProps(){let{_parsedProps:props}=this;createNetsFromProps(this,[props.connectsTo])}doInitialPcbCopperPourRender(){CopperPour_doInitialPcbCopperPourRender(this)}doInitialPcbViaStitchRender(){CopperPour_doInitialPcbViaStitchRender(this)}},AssemblyComponent=class _AssemblyComponent extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"cadAssemblyBomItemId")}get shouldRenderAssemblyBom(){return!0}getParentAssemblyBomId(){let ancestor=this.parent;for(;ancestor;){if(ancestor instanceof _AssemblyComponent&&ancestor.shouldRenderAssemblyBom)return ancestor.ensureAssemblyBomItem();ancestor=ancestor.parent}}ensureAssemblyBomItem(){if(!(!this.root||!this.shouldRenderAssemblyBom))return this.cadAssemblyBomItemId||(this.cadAssemblyBomItemId=this.root.db.cad_assembly_bom_item.insert({name:this._parsedProps.displayName||this.name||"Unnamed assembly",quantity:1,parent_cad_assembly_bom_item_id:this.getParentAssemblyBomId()}).cad_assembly_bom_item_id),this.cadAssemblyBomItemId}doInitialCadAssemblyBomRender(){if(!this.root)return;if(!this.shouldRenderAssemblyBom){this.cadAssemblyBomItemId&&this.root.db.cad_assembly_bom_item.delete(this.cadAssemblyBomItemId),this.cadAssemblyBomItemId=void 0;return}let cadAssemblyBomItemId=this.ensureAssemblyBomItem(),cadComponentIds=this.source_component_id?this.root.db.cad_component.list().filter(cad=>cad.source_component_id===this.source_component_id).map(cad=>cad.cad_component_id):[];this.root.db.cad_assembly_bom_item.update(cadAssemblyBomItemId,{name:this._parsedProps.displayName||this.name||"Unnamed assembly",quantity:1,parent_cad_assembly_bom_item_id:this.getParentAssemblyBomId(),source_component_id:this.source_component_id??void 0,cad_component_ids:cadComponentIds.length?cadComponentIds:void 0,supplier_part_numbers:this._parsedProps.supplierPartNumbers,purchase_urls:this._parsedProps.purchaseUrls})}updateCadAssemblyBomRender(){this.doInitialCadAssemblyBomRender()}removeCadAssemblyBomRender(){super.removeCadAssemblyBomRender(),this.root&&this.cadAssemblyBomItemId&&this.root.db.cad_assembly_bom_item.delete(this.cadAssemblyBomItemId),this.cadAssemblyBomItemId=void 0}onPropsChange(){this._markDirty("CadAssemblyBomRender");let markDescendants=parent=>{for(let child of parent.children)child._markDirty("CadAssemblyBomRender"),markDescendants(child)};markDescendants(this)}},resolveAssemblyModel=props=>{if(props.model!==void 0)return/^https?:\/\//i.test(props.model)?resolveAssemblyModelUrl(props.model):{glbUrl:`https://modelcdn.tscircuit.com/jscad_models/${encodeURIComponent(props.model)}.glb`};if(props.modelUrl!==void 0)return resolveAssemblyModelUrl(props.modelUrl)},AssemblyDevice=class extends AssemblyComponent{constructor(){super(...arguments);__publicField(this,"isAssemblyDeviceContainer",!0)}get config(){return{componentName:"AssemblyDevice",zodProps:assemblyDeviceProps}}doInitialAssignNameToUnnamedComponents(){}computeSchematicGlobalTransform(){return identity7()}_computePcbGlobalTransformBeforeLayout(){return identity7()}get shouldRenderAssemblyBom(){let props=this._parsedProps;return props.model!==void 0||props.modelUrl!==void 0||props.purchaseUrls!==void 0||props.supplierPartNumbers!==void 0}doInitialSourceRender(){this._parsedProps.modelUrl===void 0&&this._parsedProps.model===void 0||!this.root||(this.source_component_id=this.root.db.source_component.insert({ftype:"subassembly",name:this.name}).source_component_id)}doInitialCadModelRender(){let model110=resolveAssemblyModel(this._parsedProps);!this.root||this.root.pcbDisabled||!this.source_component_id||!model110||(this.cad_component_id=renderAssemblyCadModel(this,model110,{position:{x:0,y:0,z:0},pcbRotation:0,layer:"top"}))}},resolveBoardMountRotationAnchor=board=>{let anchor3=board._parsedProps.mountRotationAnchor??"rightedge",transform22=board._computePcbGlobalTransformBeforeLayout();switch(anchor3){case"rightedge":return[transform22.a,transform22.b,0];case"leftedge":return[-transform22.a,-transform22.b,0];case"topedge":return[transform22.c,transform22.d,0];case"bottomedge":return[-transform22.c,-transform22.d,0]}let components=board.getDescendants().filter(component2=>matchesAssemblyIdentity(component2,anchor3));if(components.length!==1)throw new Error(`board "${board.name}" mountRotationAnchor "${anchor3}" matched ${components.length} components; expected exactly one on this board`);let component=components[0],pcbComponent=component.pcb_component_id&&board.root.db.pcb_component.get(component.pcb_component_id);if(!pcbComponent)throw new Error(`board "${board.name}" mountRotationAnchor "${anchor3}" has no PCB component geometry`);let pcbBoard=board.root.db.pcb_board.get(board.pcb_board_id),x23=pcbComponent.center.x-pcbBoard.center.x,y23=pcbComponent.center.y-pcbBoard.center.y;if(Math.hypot(x23,y23)<1e-6)throw new Error(`board "${board.name}" mountRotationAnchor "${anchor3}" is on the mounting axis and has no direction`);return[x23,y23,0]},radians2=degrees22=>degrees22*Math.PI/180,degrees3=angle3=>normalizeDegrees(angle3*180/Math.PI),shaftRotation=direction4=>{switch(direction4){case"x+":return{x:0,y:90,z:0};case"x-":return{x:0,y:270,z:0};case"y+":return{x:270,y:0,z:0};case"y-":return{x:90,y:0,z:0};default:return{x:0,y:0,z:0}}},resolveAssemblyMotorRotation=(motor,placement)=>{let alignment=shaftRotation(motor._parsedProps.shaftFacingDirection),board=resolveMotorMountedBoard(motor),input2=board?._parsedProps.mountRotation;if(!board||!input2)return alignment;let bottom=placement.layer==="bottom",sign=bottom?-1:1,orientation32=mat4_exports.create();mat4_exports.rotateX(orientation32,orientation32,radians2(alignment.x)),mat4_exports.rotateY(orientation32,orientation32,radians2(alignment.y+(bottom?180:0))),mat4_exports.rotateZ(orientation32,orientation32,radians2(sign*placement.pcbRotation));let expression3=input2.startsWith("calc(")?input2.match(/^calc\(\s*(.*?)\s*(?:([+-])\s*((?:\d+(?:\.\d*)?|\.\d+))\s*(degcw|degccw))?\s*\)$/):[input2,input2],path=expression3[1],separator=path.lastIndexOf("."),motorIdentity=path.slice(0,separator),directionName=path.slice(separator+1);if(!matchesAssemblyIdentity(motor,motorIdentity))throw new Error(`board "${board.name}" mountRotation "${input2}" must reference its mounted motor "${motor.name}"`);let direction4=Object.entries(motor.motorReferencePoints).find(([name])=>name===directionName)?.[1];if(!direction4)throw new Error(`assembly.motor "${motor.name}" has no ${directionName} reference`);if(Math.abs(direction4.direction.z)>1e-6)throw new Error(`board "${board.name}" mountRotation "${input2}" must reference a direction in the mounting face, e.g. "${motorIdentity}.wireside"`);let clockwiseAngle=radians2((expression3[2]==="-"?-1:1)*Number(expression3[3]??0)*(expression3[4]==="degccw"?-1:1)),anchor3=vec3_exports.normalize(vec3_exports.create(),resolveBoardMountRotationAnchor(board)),shaft=vec3_exports.transformMat4(vec3_exports.create(),[0,0,1],orientation32),turn=mat4_exports.fromRotation(mat4_exports.create(),-clockwiseAngle,shaft),target=vec3_exports.transformMat4(vec3_exports.create(),anchor3,turn),motorDirection=vec3_exports.transformMat4(vec3_exports.create(),[direction4.direction.x,direction4.direction.y,direction4.direction.z],orientation32),spin=Math.atan2(vec3_exports.dot(shaft,vec3_exports.cross(vec3_exports.create(),motorDirection,target)),vec3_exports.dot(motorDirection,target));mat4_exports.rotateZ(orientation32,orientation32,spin);let pitch=Math.asin(Math.max(-1,Math.min(1,orientation32[8]))),nonsingular=Math.abs(orientation32[8])<.999999,roll=nonsingular?Math.atan2(-orientation32[9],orientation32[10]):Math.atan2(orientation32[6],orientation32[5]),yaw=nonsingular?Math.atan2(-orientation32[4],orientation32[0]):0;return{x:degrees3(roll),y:degrees3(pitch)-(bottom?180:0),z:sign*degrees3(yaw)-placement.pcbRotation}},resolveAssemblyMotorPlacement=motor=>{let printedPartPlacement=resolveMotorPrintedPartPlacement(motor);if(printedPartPlacement)return printedPartPlacement;let board=resolveMotorMountedBoard(motor),orientation32=board?._parsedProps.mountOrientation,layer=orientation32?orientation32==="bottom_layer_toward_mount_face"?"bottom":"top":motor._parsedProps.shaftFacingDirection==="z-"?"bottom":"top";if(!board)return{position:{x:0,y:0,z:0},pcbRotation:0,layer};let pcbBoard=board.root.db.pcb_board.get(board.pcb_board_id);if(!pcbBoard)throw new Error(`Mounted board "${board.name}" has no PCB geometry`);let sign=layer==="bottom"?-1:1,boardTransform=board._computePcbGlobalTransformBeforeLayout();return{position:{...pcbBoard.center,z:sign*(-motor.motorReferencePoints.backface.position.z+(board._parsedProps.mountGap??0)+pcbBoard.thickness/2)},pcbRotation:normalizeDegrees(Math.atan2(boardTransform.b,boardTransform.a)*180/Math.PI),layer,subcircuit_id:pcbBoard.subcircuit_id}},resolveMotorFaceMount=motor=>{let parent=findParentAssembly(motor);if(!parent&&!getComponentsInAssemblyScope(motor).some(part=>part.componentName==="AssemblyMotor"&&part._parsedProps.mountedTo))return;let{transforms:transforms3,roots,motorMountRoots,subcircuitId}=resolvePrintedPartMounts(motor);if(!parent&&!motorMountRoots.has(roots.get(motor)))return;let world=transforms3.get(motor);return{position:{x:world[12],y:world[13],z:world[14]},rotation:getAssemblyCadRotation(world),subcircuit_id:subcircuitId}},AssemblyMotor=class extends AssemblyComponent{get config(){return{componentName:"AssemblyMotor",zodProps:assemblyMotorProps}}get motorModelString(){let base=this._parsedProps.model??this._parsedProps.standard,wireConnection=this._parsedProps.wireConnection;return wireConnection===void 0?base:`${base}_${wireConnection}`}get motorModel(){let model110=(()=>{try{return parseModelString(this.motorModelString)}catch(cause){throw new Error(`assembly.motor "${this.name}" requires a NEMA modelprinter model: ${cause instanceof Error?cause.message:cause}`,{cause})}})();if(model110.fn!=="nema")throw new Error(`assembly.motor "${this.name}" requires a NEMA modelprinter model`);return model110}get motorReferencePoints(){let{fn:fn3,...parameters}=this.motorModel;return getNemaMotorReferencePoints2(parameters)}doInitialSourceRender(){this.motorModel,this.source_component_id=this.root.db.source_component.insert({ftype:"motor",name:this.name}).source_component_id}doInitialCadModelRender(){if(!this.root||this.root.pcbDisabled||!this.source_component_id)return;let model110=resolveAssemblyModel({model:this.motorModelString}),faceMount=resolveMotorFaceMount(this);if(faceMount){this.cad_component_id=renderAssemblyCadModel(this,{...model110,rotationOffset:faceMount.rotation},{...faceMount,pcbRotation:0,layer:"top"});return}let placement=resolveAssemblyMotorPlacement(this);this.cad_component_id=renderAssemblyCadModel(this,{...model110,rotationOffset:resolveAssemblyMotorRotation(this,placement)},placement)}},formatMillimetersForModelprinter=millimeters=>Number(millimeters.toFixed(6)).toString(),getDefaultFlexScreenModel=component=>{let{width:width10,height:height10}=component._parsedProps;if(width10===void 0||height10===void 0)throw new Error(`assembly.screen "${component.name}" requires both width and height when cadModel is omitted`);return`flexscreen_w${formatMillimetersForModelprinter(width10)}mm_h${formatMillimetersForModelprinter(height10)}mm`},AssemblyScreen_doInitialCadModelRender=component=>{if(!component.root||component.root.pcbDisabled||!component.source_component_id)return;let placement=resolveAssemblyPlacement(component);component.cad_component_id=renderAssemblyCadModel(component,resolveAssemblyModel(component._parsedProps)??component._parsedProps.cadModel??getDefaultFlexScreenModel(component),placement)},AssemblyScreen=class extends AssemblyComponent{constructor(){super(...arguments);__publicField(this,"isAssemblyDeviceContainer",!0)}get config(){return{componentName:"AssemblyScreen",zodProps:assemblyScreenProps}}doInitialAssignNameToUnnamedComponents(){if(!this._parsedProps.name)throw new Error("assembly.screen requires a non-empty name")}doInitialSourceRender(){let sourceComponent=this.root.db.source_component.insert({ftype:"subassembly",name:this.name});this.source_component_id=sourceComponent.source_component_id}doInitialCadModelRender(){AssemblyScreen_doInitialCadModelRender(this)}},renderPartReferenceSurfaces=part=>{let surfaces=getPartReferenceSurfaces(part);if(!surfaces.length)return;let{transforms:transforms3,subcircuitId}=resolvePrintedPartMounts(part),world=transforms3.get(part),rotation6=mat3_exports.fromMat4(mat3_exports.create(),world),toPoint=vector7=>({x:vector7[0],y:vector7[1],z:vector7[2]});for(let surface6 of surfaces){let child=part.children.find(child2=>child2.componentName==="AssemblyReferenceSurface"&&child2.name===surface6.name);part.root.db.cad_reference_surface.insert({source_component_id:part.source_component_id,name:surface6.name,shape:"rect",center:toPoint(vec3_exports.transformMat4(vec3_exports.create(),surface6.origin,world)),normal:toPoint(vec3_exports.normalize(vec3_exports.create(),vec3_exports.transformMat3(vec3_exports.create(),surface6.normal,rotation6))),x_axis:toPoint(vec3_exports.normalize(vec3_exports.create(),vec3_exports.transformMat3(vec3_exports.create(),surface6.xAxis,rotation6))),width:child?._parsedProps.width,height:child?._parsedProps.height,subcircuit_id:subcircuitId})}},AssemblySubassembly=class extends AssemblyComponent{constructor(){super(...arguments);__publicField(this,"isAssemblyDeviceContainer",!0)}get config(){return{componentName:"AssemblySubassembly",zodProps:assemblySubassemblyProps}}doInitialAssignNameToUnnamedComponents(){if(!this._parsedProps.name)throw new Error("assembly.subassembly requires a non-empty name")}doInitialReactSubtreesRender(){(0,import_react11.isValidElement)(this.props.cadModel)&&this.add(createInstanceFromReactElement(this.props.cadModel))}doInitialSourceRender(){getPartReferenceSurfaces(this);let sourceComponent=this.root.db.source_component.insert({ftype:"subassembly",name:this.name});this.source_component_id=sourceComponent.source_component_id}doInitialCadModelRender(){if(!this.root||this.root.pcbDisabled||!this.source_component_id)return;renderPartReferenceSurfaces(this);let placement=resolveAssemblyPlacement(this),model110=resolveAssemblyModel(this._parsedProps)??this._parsedProps.cadModel;model110&&!(typeof model110=="object"&&"type"in model110)&&(this.cad_component_id=renderAssemblyCadModel(this,model110,placement))}},assemblyPath=assembly2=>{let names=[],ancestor=assembly2;for(;ancestor;)["AssemblyDevice","AssemblySubassembly","AssemblyBolt","AssemblyPart","AssemblyPrintedPart","AssemblyScreen","AssemblyMotor"].includes(ancestor.componentName)&&names.unshift(ancestor.name||"unnamed assembly"),ancestor=ancestor.parent;return names.join(".")},hasRemovedAncestor=part=>{let parent=part.parent;for(;parent;){if(parent.shouldBeRemoved)return!0;parent=parent.parent}return!1},resolveAssemblyExplosionStages=roots=>{let stages=roots.flatMap(root=>[root,...root.getDescendants()]).filter(part=>part.componentName==="AssemblyExplosionStage"&&!part.shouldBeRemoved&&!hasRemovedAncestor(part)),stageRef=stage=>`${assemblyPath(stage.parent)}.${stage.name}`,byRef=new Map;for(let stage of stages){let ref=stageRef(stage);if(byRef.has(ref))throw new Error(`Duplicate explosion stage "${ref}"`);byRef.set(ref,stage)}let edges=new Map,indegrees=new Map(stages.map(stage=>[stage,0]));for(let stage of stages)for(let direction4 of["prevStageRef","nextStageRef"]){let ref=stage._parsedProps[direction4];if(!ref)continue;let ownerPath=assemblyPath(stage.parent),resolved=byRef.get(`${ownerPath}.${ref}`)??(ref.startsWith(`${ownerPath.split(".")[0]}.`)?byRef.get(ref):void 0);if(!resolved)throw new Error(`Explosion stage "${stageRef(stage)}" references unknown stage "${ref}"`);let before=direction4==="nextStageRef"?stage:resolved,after=direction4==="nextStageRef"?resolved:stage,successors=edges.get(before)??new Set;successors.has(after)||(successors.add(after),edges.set(before,successors),indegrees.set(after,indegrees.get(after)+1))}let remaining=new Set(stages),ordered=[];for(;remaining.size;){let eligible=stages.find(stage=>remaining.has(stage)&&indegrees.get(stage)===0);if(!eligible)throw new Error(`Explosion stage ordering cycle: ${[...remaining].map(stageRef).join(", ")}`);remaining.delete(eligible),ordered.push(eligible);for(let successor of edges.get(eligible)??[])indegrees.set(successor,indegrees.get(successor)-1)}return ordered},pointPlus=(point12,offset3)=>({x:point12.x+offset3.x,y:point12.y+offset3.y,z:point12.z+offset3.z}),zero5=()=>({x:0,y:0,z:0});function getAssemblyExplosion(circuit,options={}){if(!circuit.firstChild?.renderPhaseStates.CadModelRender.initialized)throw new Error("Render the assembly before evaluating explosion stages");let progress=options.stageProgress??1;if(!Number.isFinite(progress)||progress<0||progress>1)throw new Error("Explosion stage progress must be between 0 and 1");let ordered=resolveAssemblyExplosionStages(circuit.children),stages=ordered.map(stage=>`${assemblyPath(stage.parent)}.${stage.name}`),stop=options.throughStageRef===void 0?ordered.length-1:stages.indexOf(options.throughStageRef);if(options.throughStageRef!==void 0&&stop<0)throw new Error(`Unknown explosion stage "${options.throughStageRef}"`);let assembled=circuit.getCircuitJson();if(assembled.some(record=>record.type==="cad_explosion_move"&&record.targets.some(target=>target.type==="cad_explosion_stage")))return{...getCircuitJsonAssemblyExplosion(assembled,options),collisionCheckStatus:getRenderedExplosionCollisionCheckStatus(circuit.firstChild)};let sourceOffsets=new Map,partOffsets=new Map,lines=[];for(let[stageIndex,stage]of ordered.entries()){let owner=stage.parent,instructions=stage.children.filter(move=>!move.shouldBeRemoved);for(let[moveIndex,instruction]of instructions.entries()){let move=instruction,targets=new Map;for(let targetRef of move._parsedProps.targetRefs){let target=owner;for(let segment5 of targetRef.split(".")){let matches=target.children.filter(part=>!part.shouldBeRemoved&&part.name===segment5&&["AssemblyBolt","AssemblyPart","AssemblyPrintedPart","AssemblySubassembly","AssemblyScreen","AssemblyMotor"].includes(part.componentName));if(matches.length!==1)throw new Error(`Explosion stage "${stages[stageIndex]}" target "${targetRef}" matched ${matches.length} assembly parts; expected one`);target=matches[0]}if([target,...target.getDescendants()].some(part=>part.pcb_component_id||part.componentName==="Board"||part.componentName==="AssemblyCable"))throw new Error(`Explosion target "${targetRef}" includes PCB or cable geometry; this prototype moves mechanical CAD parts only`);targets.has(target)||targets.set(target,targetRef)}if(stageIndex>stop)continue;let fraction=stageIndex===stop?Math.max(0,Math.min(1,progress*instructions.length-moveIndex)):1;if(!fraction)continue;let placement=isPositionedAssembly(owner)?resolveAssemblyPlacement(owner):void 0,frame=placement?.worldTransform?mat4_exports.clone(placement.worldTransform):mat4_exports.create();placement&&!placement.worldTransform&&(mat4_exports.rotateZ(frame,frame,placement.pcbRotation*Math.PI/180),placement.layer==="bottom"&&mat4_exports.rotateY(frame,frame,Math.PI));let displacement=vec3_exports.transformMat3(vec3_exports.create(),[(move._parsedProps.offX??0)*fraction,(move._parsedProps.offY??0)*fraction,(move._parsedProps.offZ??0)*fraction],mat3_exports.fromMat4(mat3_exports.create(),frame)),offset3={x:displacement[0],y:displacement[1],z:displacement[2]},movedParts=new Set;for(let[target,targetRef]of targets){let descendants2=[target,...target.getDescendants()],targetCad=assembled.find(cad=>cad.type==="cad_component"&&cad.source_component_id===target.source_component_id),targetSources=new Set(descendants2.map(part=>part.source_component_id)),currentCadPositions=assembled.filter(cad=>cad.type==="cad_component"&&targetSources.has(cad.source_component_id)).map(cad=>pointPlus(cad.position,sourceOffsets.get(cad.source_component_id)??zero5())),centroid=currentCadPositions.length?{x:currentCadPositions.reduce((sum,position22)=>sum+position22.x,0)/currentCadPositions.length,y:currentCadPositions.reduce((sum,position22)=>sum+position22.y,0)/currentCadPositions.length,z:currentCadPositions.reduce((sum,position22)=>sum+position22.z,0)/currentCadPositions.length}:void 0,anchor3=(targetCad?pointPlus(targetCad.position,sourceOffsets.get(targetCad.source_component_id)??zero5()):void 0)??centroid??(isPositionedAssembly(target)?pointPlus(resolveAssemblyPlacement(target).position,partOffsets.get(target)??zero5()):void 0);if(!anchor3)throw new Error(`Explosion target "${targetRef}" has no resolved assembly pose`);let from=anchor3;Math.hypot(offset3.x,offset3.y,offset3.z)>0&&lines.push({stageRef:stages[stageIndex],targetRef,points:[from,pointPlus(from,offset3)]});for(let part of descendants2)movedParts.add(part)}let movedSources=new Set;for(let part of movedParts)partOffsets.set(part,pointPlus(partOffsets.get(part)??zero5(),offset3)),part.source_component_id&&movedSources.add(part.source_component_id);for(let sourceId of movedSources)sourceOffsets.set(sourceId,pointPlus(sourceOffsets.get(sourceId)??zero5(),offset3))}}return{circuitJson:structuredClone(assembled).filter(record=>record.type!=="cad_explosion_stage"&&record.type!=="cad_explosion_move").map(record=>{if(record.type!=="cad_component"&&record.type!=="cad_reference_surface")return record;let offset3=sourceOffsets.get(record.source_component_id);return offset3?record.type==="cad_component"?{...record,position:pointPlus(record.position,offset3)}:{...record,center:pointPlus(record.center,offset3)}:record}),stages,lines,collisionCheckStatus:getRenderedExplosionCollisionCheckStatus(circuit.firstChild)}}function resolveAssemblyExplosionRecords(roots,assembled,getStageId){let ordered=resolveAssemblyExplosionStages(roots),stages=ordered.map((stage,order)=>({type:"cad_explosion_stage",cad_explosion_stage_id:getStageId(stage),name:`${assemblyPath(stage.parent)}.${stage.name}`,order,cad_component_ids:[],cad_reference_surface_ids:[]})),moves=[],moveComponents=[];for(let[stageIndex,stage]of ordered.entries()){let owner=stage.parent,placement=isPositionedAssembly(owner)?resolveAssemblyPlacement(owner):void 0,frame=placement?.worldTransform?mat4_exports.clone(placement.worldTransform):mat4_exports.create();placement&&!placement.worldTransform&&(mat4_exports.rotateZ(frame,frame,placement.pcbRotation*Math.PI/180),placement.layer==="bottom"&&mat4_exports.rotateY(frame,frame,Math.PI));for(let[order,instruction]of stage.children.filter(child=>!child.shouldBeRemoved).entries()){let move=instruction,targets=[];for(let targetRef of move._parsedProps.targetRefs){let qualified=`${assemblyPath(owner)}.${targetRef}`,targetStage=stages.find(candidate=>candidate.name===qualified||targetRef.startsWith(`${assemblyPath(owner).split(".")[0]}.`)&&candidate.name===targetRef),target=owner,matchedPart=!0,matchCount=0;for(let segment5 of targetRef.split(".")){let matches=target.children.filter(part=>!part.shouldBeRemoved&&part.name===segment5&&["AssemblyBolt","AssemblyPart","AssemblyPrintedPart","AssemblySubassembly","AssemblyScreen","AssemblyMotor"].includes(part.componentName));if(matchCount=matches.length,matches.length!==1){matchedPart=!1;break}target=matches[0]}if(targetStage&&matchedPart)throw new Error(`Ambiguous explosion target "${targetRef}" names both a part and a stage`);if(targetStage){targets.push({type:"cad_explosion_stage",cad_explosion_stage_id:targetStage.cad_explosion_stage_id});continue}if(!matchedPart)throw new Error(`Explosion stage "${stages[stageIndex].name}" target "${targetRef}" matched ${matchCount} assembly parts; expected one or a matching stage`);let descendants2=[target,...target.getDescendants()];if(descendants2.some(part=>part.pcb_component_id||part.componentName==="Board"||part.componentName==="AssemblyCable"))throw new Error(`Explosion target "${targetRef}" includes unsupported PCB or cable geometry`);let sources=new Set(descendants2.map(part=>part.source_component_id).filter(Boolean)),geometry=assembled.filter(record=>(record.type==="cad_component"||record.type==="cad_reference_surface")&&sources.has(record.source_component_id));if(!geometry.length)throw new Error(`Explosion target "${targetRef}" has no emitted geometry`);for(let record of geometry)record.type==="cad_component"&&targets.push({type:"cad_component",cad_component_id:record.cad_component_id}),record.type==="cad_reference_surface"&&targets.push({type:"cad_reference_surface",cad_reference_surface_id:record.cad_reference_surface_id})}let displacement=vec3_exports.transformMat3(vec3_exports.create(),[move._parsedProps.offX??0,move._parsedProps.offY??0,move._parsedProps.offZ??0],mat3_exports.fromMat4(mat3_exports.create(),frame));moveComponents.push(move),moves.push({type:"cad_explosion_move",cad_explosion_stage_id:stages[stageIndex].cad_explosion_stage_id,order,targets,translation:{x:displacement[0],y:displacement[1],z:displacement[2]}})}}let resolved=new Set,visiting=new Set,resolveMembership=stage=>{if(resolved.has(stage.cad_explosion_stage_id))return;if(visiting.has(stage.cad_explosion_stage_id))throw new Error(`Explosion stage membership cycle at "${stage.name}"`);visiting.add(stage.cad_explosion_stage_id);let cad=new Set(stage.cad_component_ids),surfaces=new Set(stage.cad_reference_surface_ids);for(let move of moves.filter(move2=>move2.cad_explosion_stage_id===stage.cad_explosion_stage_id))for(let target of move.targets)if(target.type==="cad_component")cad.add(target.cad_component_id);else if(target.type==="cad_reference_surface")surfaces.add(target.cad_reference_surface_id);else{let memberStage=stages.find(candidate=>candidate.cad_explosion_stage_id===target.cad_explosion_stage_id);resolveMembership(memberStage);for(let id3 of memberStage.cad_component_ids)cad.add(id3);for(let id3 of memberStage.cad_reference_surface_ids??[])surfaces.add(id3)}stage.cad_component_ids=[...cad],stage.cad_reference_surface_ids=[...surfaces],visiting.delete(stage.cad_explosion_stage_id),resolved.add(stage.cad_explosion_stage_id)};for(let stage of stages)resolveMembership(stage);return{stages:new Map(ordered.map((stage,i23)=>[stage,stages[i23]])),moves:new Map(moveComponents.map((move,i23)=>[move,moves[i23]]))}}function getRenderedAssemblyExplosionRecords(component){let root=component.root;return resolveAssemblyExplosionRecords(root.children,root.db.toArray(),stage=>{if(!stage.cad_explosion_stage_id)throw new Error(`Explosion stage "${stage.name}" has not rendered its identity`);return stage.cad_explosion_stage_id})}function markAssemblyExplosionDirty(component){for(let root of component.root?.children??[])for(let part of[root,...root.getDescendants()])(part.componentName==="AssemblyExplosionStage"||part.componentName==="AssemblyExplosionMove")&&part._markDirty("CadExplosionRender")}var AssemblyExplosionStage=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"cad_explosion_stage_id",null)}get config(){return{componentName:"AssemblyExplosionStage",zodProps:assemblyExplosionStageProps}}doInitialSourceRender(){if(this.parent?.componentName!=="AssemblyDevice"&&this.parent?.componentName!=="AssemblySubassembly")throw new Error(`Explosion stage "${this.name}" must belong to an assembly device or subassembly`);if(this.children.some(child=>child.componentName!=="AssemblyExplosionMove"))throw new Error(`Explosion stage "${this.name}" can contain only explosion moves`)}onPropsChange(){markAssemblyExplosionDirty(this)}doInitialCadExplosionStageRender(){!this.root||this.root.pcbDisabled||(this.cad_explosion_stage_id=this.root.db.cad_explosion_stage.insert({name:`${assemblyPath(this.parent)}.${this.name}`,order:0,cad_component_ids:[],cad_reference_surface_ids:[]}).cad_explosion_stage_id,markAssemblyExplosionDirty(this))}doInitialCadExplosionRender(){if(!this.root||this.root.pcbDisabled||!this.cad_explosion_stage_id)return;let stage=getRenderedAssemblyExplosionRecords(this).stages.get(this);this.root.db.cad_explosion_stage.update(this.cad_explosion_stage_id,stage)}updateCadExplosionRender(){this.doInitialCadExplosionRender()}removeCadExplosionStageRender(){if(!(!this.root||!this.cad_explosion_stage_id)){for(let move of this.children)move.removeCadExplosionStageRender();this.root.db.cad_explosion_stage.delete(this.cad_explosion_stage_id),this.cad_explosion_stage_id=null,markAssemblyExplosionDirty(this)}}},AssemblyExplosionMove=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"cad_explosion_move_id",null)}get config(){return{componentName:"AssemblyExplosionMove",zodProps:assemblyExplosionMoveProps}}doInitialAssignNameToUnnamedComponents(){}doInitialSourceRender(){if(this.parent?.componentName!=="AssemblyExplosionStage")throw new Error("An explosion move must belong to an explosion stage")}onPropsChange(){markAssemblyExplosionDirty(this)}doInitialCadExplosionStageRender(){markAssemblyExplosionDirty(this)}doInitialCadExplosionRender(){if(!this.root||this.root.pcbDisabled||this.parent?.shouldBeRemoved)return;let move=getRenderedAssemblyExplosionRecords(this).moves.get(this);this.cad_explosion_move_id=this.root.db.cad_explosion_move.insert(move).cad_explosion_move_id}updateCadExplosionRender(){if(!this.root||this.root.pcbDisabled||this.parent?.shouldBeRemoved)return;if(!this.cad_explosion_move_id){this.doInitialCadExplosionRender();return}let move=getRenderedAssemblyExplosionRecords(this).moves.get(this);this.root.db.cad_explosion_move.update(this.cad_explosion_move_id,move)}removeCadExplosionStageRender(){this.root&&this.cad_explosion_move_id&&this.root.db.cad_explosion_move.delete(this.cad_explosion_move_id),this.cad_explosion_move_id=null,markAssemblyExplosionDirty(this)}},AssemblyPart=class extends AssemblyComponent{constructor(){super(...arguments);__publicField(this,"isAssemblyDeviceContainer",!0)}get config(){return{componentName:"AssemblyPart",zodProps:assemblyPartProps}}doInitialReactSubtreesRender(){(0,import_react12.isValidElement)(this.props.cadModel)&&this.add(createInstanceFromReactElement(this.props.cadModel))}doInitialSourceRender(){getPartReferenceSurfaces(this),this.source_component_id=this.root.db.source_component.insert({ftype:"subassembly",name:this.name,display_name:this._parsedProps.displayName}).source_component_id}doInitialCadModelRender(){if(!this.root||this.root.pcbDisabled||!this.source_component_id)return;renderPartReferenceSurfaces(this);let model110=resolveAssemblyModel(this._parsedProps)??this._parsedProps.cadModel;model110&&!(typeof model110=="object"&&"type"in model110)&&(this.cad_component_id=renderAssemblyCadModel(this,model110,resolveAssemblyPlacement(this)))}},AssemblyReferenceSurface=class extends PrimitiveComponent{get config(){return{componentName:"AssemblyReferenceSurface",zodProps:assemblyReferenceSurfaceProps}}doInitialSourceRender(){if(this.parent?.componentName!=="AssemblyBolt"&&this.parent?.componentName!=="AssemblyPart"&&this.parent?.componentName!=="AssemblyPrintedPart"&&this.parent?.componentName!=="AssemblySubassembly")throw new Error(`Reference surface "${this.name}" must be a child of assembly.part, assembly.printedpart, assembly.bolt, or assembly.subassembly`)}get referenceFrame(){let{name,plane,normalDirection,centerXOffset,centerYOffset,centerZOffset}=this._parsedProps,sign=normalDirection.endsWith("-")?-1:1;return{name,origin:[centerXOffset,centerYOffset,centerZOffset],normal:plane==="xy"?[0,0,sign]:plane==="xz"?[0,sign,0]:[sign,0,0],xAxis:plane==="yz"?[0,1,0]:[1,0,0]}}},getModelReachAboveOrigin=({cad,authoredModel})=>{let bounds=cad.model_bounds??authoredModel?.modelBounds,origin=cad.model_origin_position??authoredModel?.modelOriginPosition;if(!bounds?.min||!bounds?.max||!origin)return;let normal=cad.model_board_normal_direction??authoredModel?.modelBoardNormalDirection??"z+",axis=normal[0];if(axis!=="x"&&axis!=="y"&&axis!=="z")return;let min4=bounds.min[axis],max5=bounds.max[axis],at22=origin[axis];if(min4===void 0||max5===void 0||at22===void 0)return;let reach=normal.endsWith("-")?at22-min4:max5-at22;return Number.isFinite(reach)&&reach>=0?reach:void 0},getComponentBody=({owner,pcbComponent,cadComponent,boardSurfaceZ})=>{let cadModelProp22=owner?._parsedProps?.cadModel,authoredModel=cadModelProp22&&typeof cadModelProp22=="object"?cadModelProp22:void 0,size23=cadComponent?.size??authoredModel?.size,x23=size23?.x,y23=size23?.y,z20=size23?.z,reach=cadComponent?getModelReachAboveOrigin({cad:cadComponent,authoredModel}):void 0,originZ=cadComponent?.position?.z,aboveBoardHeight=reach!==void 0&&originZ!==void 0?reach+Math.abs(originZ-boardSurfaceZ):void 0;return{size:x23!==void 0&&y23!==void 0?{x:x23,y:y23,z:z20}:void 0,aboveBoardHeight,rotation:cadComponent?.rotation?.z??pcbComponent.rotation??0,footprint:{width:pcbComponent.width,height:pcbComponent.height}}},getNearestBoardWall=({point:point12,board})=>{let halfWidth=(board.width??0)/2,halfHeight=(board.height??0)/2,distances=[["x_neg",Math.abs(point12.x-(board.center.x-halfWidth))],["x_pos",Math.abs(point12.x-(board.center.x+halfWidth))],["y_neg",Math.abs(point12.y-(board.center.y-halfHeight))],["y_pos",Math.abs(point12.y-(board.center.y+halfHeight))]];return distances.sort((a23,b23)=>a23[1]-b23[1]),distances[0][0]},getSolverWall=boardWall=>boardWall,INSERTION_DIRECTION_TO_BOARD_WALL={from_top:"y_pos",from_bottom:"y_neg",from_left:"x_neg",from_right:"x_pos"},getFdmEnclosureSolverInput=(apertureComponent,{board,pcbBoard})=>{let owner=apertureComponent.parent;for(;owner&&owner!==board&&!owner.pcb_component_id;)owner=owner.parent;let pcbComponent=owner?.pcb_component_id?apertureComponent.root?.db.pcb_component.get(owner.pcb_component_id):null;if(!pcbComponent)throw new Error("<enclosure.cutoutaperture /> must be nested inside a component with a PCB footprint");let aperture=apertureComponent._parsedProps,apertureAxisDirection=owner?._getEnclosureApertureAxisDirection?.(pcbComponent.layer,pcbComponent.rotation??0),apertureDirection=apertureAxisDirection?apertureAxisDirection.z!==0?apertureAxisDirection.z>0?"from_above":"from_below":Math.abs(apertureAxisDirection.x)>=Math.abs(apertureAxisDirection.y)?apertureAxisDirection.x>=0?"from_right":"from_left":apertureAxisDirection.y>=0?"from_top":"from_bottom":pcbComponent.insertion_direction,verticalFace=apertureDirection==="from_above"?"z_pos":apertureDirection==="from_below"?"z_neg":void 0,boardSide=pcbComponent.layer==="bottom"?"bottom":"top",face2,center2;if(verticalFace)face2=verticalFace,center2={x:pcbComponent.center.x-pcbBoard.center.x,y:pcbComponent.center.y-pcbBoard.center.y};else{let point12=pcbComponent.cable_insertion_center??pcbComponent.center,boardWall=INSERTION_DIRECTION_TO_BOARD_WALL[apertureDirection]??getNearestBoardWall({point:point12,board:pcbBoard}),cableDelta=pcbComponent.cable_insertion_center?{x:pcbComponent.cable_insertion_center.x-pcbComponent.center.x,y:pcbComponent.cable_insertion_center.y-pcbComponent.center.y}:null,cableProjectionMatchesWall=cableDelta!=null&&(boardWall==="x_neg"||boardWall==="x_pos"?Math.abs(cableDelta.x)>=Math.abs(cableDelta.y):Math.abs(cableDelta.y)>=Math.abs(cableDelta.x)),tangentPoint=apertureAxisDirection?pcbComponent.center:cableProjectionMatchesWall?point12:pcbComponent.center;face2=getSolverWall(boardWall),center2={x:tangentPoint.x-pcbBoard.center.x,y:tangentPoint.y-pcbBoard.center.y}}let cadComponent=apertureComponent.root?.db.cad_component.getWhere({pcb_component_id:pcbComponent.pcb_component_id})??null,boardSurfaceZ=(boardSide==="bottom"?-1:1)*((pcbBoard.thickness??board.boardThickness)/2),componentBody=getComponentBody({owner,pcbComponent,cadComponent,boardSurfaceZ}),commonInput={face:face2,center:center2,boardSide,apertureAxisDirection,rotation:pcbComponent.rotation??void 0,depth:aperture.depth,componentBody,widthDimensionOffset:aperture.widthDimensionOffset,heightDimensionOffset:aperture.heightDimensionOffset,margin:aperture.margin};switch(aperture.shape){case"pill":case"rect":return{...commonInput,shape:aperture.shape,width:aperture.width,height:aperture.height};case"circle":return{...commonInput,shape:"circle",radius:aperture.radius}}},EnclosureCutoutAperture=class extends PrimitiveComponent{get config(){return{componentName:"EnclosureCutoutAperture",zodProps:enclosureCutoutApertureProps}}getFdmEnclosureSolverInput(params){return getFdmEnclosureSolverInput(this,params)}},getReferencedEnclosureBoard=(component,boardRef)=>{let rootComponent=component.root?.firstChild,selectedComponent=rootComponent?selectOne(boardRef,rootComponent,{adapter:cssSelectPrimitiveComponentAdapter}):null,board=selectedComponent instanceof Board?selectedComponent:[rootComponent,...rootComponent?.getDescendants()??[]].find(descendant=>descendant instanceof Board&&descendant.isMatchingNameOrAlias(boardRef));if(!(board instanceof Board))throw new Error(`Could not find a <board /> matching enclosure boardRef "${boardRef}"`);return board},EnclosureFdmBox_doInitialCadModelRender=component=>{let root=component.root;if(!root||root.pcbDisabled||!component.source_component_id||!component.pcb_component_id)return;let{db:db22}=root,props=component._parsedProps,board=getReferencedEnclosureBoard(component,props.boardRef),pcbBoard=board.pcb_board_id?db22.pcb_board.get(board.pcb_board_id):null;if(!pcbBoard?.width||!pcbBoard.height)throw new Error(`Could not resolve dimensions for boardRef "${props.boardRef}"`);let boardThickness=pcbBoard.thickness??board.boardThickness,inputProblem={board:{width:pcbBoard.width,height:pcbBoard.height,thickness:boardThickness},width:props.width,height:props.height,depth:props.depth,wallThickness:props.wallThickness,floorThickness:props.floorThickness,lidThickness:props.lidThickness,boardClearance:props.boardClearance,standoffHeight:props.standoffHeight,topHeadroom:props.topHeadroom,lidLipDepth:props.lidLipDepth,apertures:props.disableCutouts?[]:board.getDescendants().filter(descendant=>descendant instanceof EnclosureCutoutAperture).map(aperture=>aperture.getFdmEnclosureSolverInput({board,pcbBoard}))},solver=new CreateFdmEnclosureSolver(inputProblem),solverConstructorArgs=solver.getConstructorParams();if(root.emit("solver:started",{type:"solver:started",solverName:"CreateFdmEnclosureSolver",solverParams:solverConstructorArgs[0],solverConstructorArgs,componentName:component.getString()}),solver.solve(),solver.failed)throw new Error(solver.error??"Failed to create FDM enclosure");let output=solver.getOutput();db22.pcb_component.update(component.pcb_component_id,{center:pcbBoard.center,width:output.dimensions.width,height:output.dimensions.height});let position22={x:pcbBoard.center.x,y:pcbBoard.center.y,z:-boardThickness/2-output.dimensions.floorThickness-output.dimensions.standoffHeight},cadComponents=output.parts.map(part=>db22.cad_component.insert({position:position22,rotation:{x:0,y:0,z:0},pcb_component_id:component.pcb_component_id,source_component_id:component.source_component_id,model_jscad:part.jscadPlan,model_unit_to_mm_scale_factor:1,model_object_fit:"contain_within_bounds",model_origin_alignment:"bottom_center_of_component",anchor_alignment:"center",show_as_translucent_model:!1,show_hidden_edges:props.showHiddenEdges}));component.cad_component_id=cadComponents[0]?.cad_component_id??null},EnclosureFdmBox=class _EnclosureFdmBox extends PrimitiveComponent{get config(){return{componentName:"EnclosureFdmBox",zodProps:enclosureFdmBoxProps}}doInitialAssignNameToUnnamedComponents(){if(this._parsedProps.name)return;let top=this;for(;top.parent instanceof PrimitiveComponent;)top=top.parent;let index2=[top,...top.getDescendants()].filter(component=>component instanceof _EnclosureFdmBox).indexOf(this);this.fallbackUnassignedName=`unnamed_enclosure_fdm_box_${index2===-1?0:index2+1}`}doInitialSourceRender(){let sourceComponent=this.root.db.source_component.insert({ftype:"simple_chip",name:this.name});this.source_component_id=sourceComponent.source_component_id}doInitialPcbComponentRender(){let root=this.root;if(!root||root.pcbDisabled||!this.source_component_id)return;let board=getReferencedEnclosureBoard(this,this._parsedProps.boardRef),center2=(board.pcb_board_id?root.db.pcb_board.get(board.pcb_board_id):null)?.center??board._getGlobalPcbPositionBeforeLayout(),pcbComponent=root.db.pcb_component.insert({center:center2,width:0,height:0,layer:"top",rotation:0,source_component_id:this.source_component_id,obstructs_within_bounds:!1,do_not_place:!0,is_allowed_to_be_off_board:!0});this.pcb_component_id=pcbComponent.pcb_component_id}doInitialCadModelRender(){EnclosureFdmBox_doInitialCadModelRender(this)}},Battery=class extends NormalComponent{get config(){return{componentName:"Battery",schematicSymbolName:this.props.symbolName??"battery",zodProps:batteryProps,sourceFtype:"simple_power_source"}}initPorts(){super.initPorts({additionalAliases:{pin1:["anode","pos","left"],pin2:["cathode","neg","right"]}})}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({name:this.name,ftype:"simple_power_source",capacity:props.capacity,supplier_part_numbers:props.supplierPartNumbers,manufacturer_part_number:resolveManufacturerPartNumber(props),are_pins_interchangeable:!1,display_name:props.displayName});this.source_component_id=source_component.source_component_id}},PinHeader2=class extends NormalComponent{_getPcbRotationBeforeLayout(){let orientationRotation=this.props.pcbOrientation==="vertical"?-90:0;return(super._getPcbRotationBeforeLayout()??0)+orientationRotation}get config(){return{componentName:"PinHeader",zodProps:pinHeaderProps,shouldRenderAsSchematicBox:!0}}_getImpliedFootprintString(){let pinCount=this._parsedProps.pinCount??(Array.isArray(this._parsedProps.pinLabels)?this._parsedProps.pinLabels.length:this._parsedProps.pinLabels?Object.keys(this._parsedProps.pinLabels).length:0),holeDiameter=this._parsedProps.holeDiameter,platedDiameter=this._parsedProps.platedDiameter,pitch=this._parsedProps.pitch,showSilkscreenPinLabels=this._parsedProps.showSilkscreenPinLabels,rows=this._parsedProps.doubleRow?2:1,gender=this._parsedProps.gender;if(pinCount>0){let footprintString;if(pitch)!holeDiameter&&!platedDiameter?footprintString=`pinrow${pinCount}_p${pitch}`:footprintString=`pinrow${pinCount}_p${pitch}_id${holeDiameter}_od${platedDiameter}`;else if(!holeDiameter&&!platedDiameter)footprintString=`pinrow${pinCount}`;else return null;return showSilkscreenPinLabels!==!0&&(footprintString+="_nopinlabels"),gender==="female"&&(footprintString+="_female"),rows>1&&(footprintString+=`_rows${rows}`),footprintString}return null}initPorts(){let pinCount=this._parsedProps.pinCount??(Array.isArray(this._parsedProps.pinLabels)?this._parsedProps.pinLabels.length:this._parsedProps.pinLabels?Object.keys(this._parsedProps.pinLabels).length:1);for(let i23=1;i23<=pinCount;i23++){let rawLabel=Array.isArray(this._parsedProps.pinLabels)?this._parsedProps.pinLabels[i23-1]:this._parsedProps.pinLabels?.[`pin${i23}`];if(rawLabel){let primaryLabel=Array.isArray(rawLabel)?rawLabel[0]:rawLabel,otherLabels=Array.isArray(rawLabel)?rawLabel.slice(1):[];this.add(new Port({pinNumber:i23,name:primaryLabel,aliases:[`pin${i23}`,...otherLabels]}))}else this.add(new Port({pinNumber:i23,name:`pin${i23}`}))}}_getSchematicPortArrangement(){let pinCount=this._parsedProps.pinCount??1,facingDirection=this._parsedProps.schFacingDirection??this._parsedProps.facingDirection??"right",schPinArrangement=this._parsedProps.schPinArrangement,pins=Array.from({length:pinCount},(_23,i23)=>`pin${i23+1}`);return facingDirection==="left"?{leftSide:{direction:schPinArrangement?.leftSide?.direction??"top-to-bottom",pins:schPinArrangement?.leftSide?.pins??pins}}:facingDirection==="up"?{topSide:{direction:schPinArrangement?.topSide?.direction??"left-to-right",pins:schPinArrangement?.topSide?.pins??pins}}:facingDirection==="down"?{bottomSide:{direction:schPinArrangement?.bottomSide?.direction??"left-to-right",pins:schPinArrangement?.bottomSide?.pins??pins}}:{rightSide:{direction:schPinArrangement?.rightSide?.direction??"top-to-bottom",pins:schPinArrangement?.rightSide?.pins??pins}}}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({ftype:"simple_pin_header",name:this.name,supplier_part_numbers:props.supplierPartNumbers,manufacturer_part_number:resolveManufacturerPartNumber(props),pin_count:props.pinCount,gender:props.gender,are_pins_interchangeable:!0,display_name:props.displayName});this.source_component_id=source_component.source_component_id}};function getResonatorSymbolName(variant){switch(variant){case"two_ground_pins":return"crystal_4pin";case"ground_pin":return"resonator";case"no_ground":return"crystal";default:return"crystal"}}var Resonator=class extends NormalComponent{get config(){return{componentName:"Resonator",schematicSymbolName:this.props.symbolName??getResonatorSymbolName(this.props.pinVariant),zodProps:resonatorProps,shouldRenderAsSchematicBox:!1}}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,pinVariant=props.pinVariant||"no_ground",source_component=db22.source_component.insert({ftype:"simple_resonator",name:this.name,manufacturer_part_number:resolveManufacturerPartNumber(props),frequency:props.frequency,load_capacitance:props.loadCapacitance,supplier_part_numbers:props.supplierPartNumbers,pin_variant:pinVariant,are_pins_interchangeable:pinVariant==="no_ground"||pinVariant==="ground_pin",display_name:props.displayName});this.source_component_id=source_component.source_component_id}_getSchematicSymbolDisplayValue(){let freqDisplay=`${formatSiUnit(this._parsedProps.frequency)}Hz`;return this._parsedProps.loadCapacitance?`${freqDisplay} / ${formatSiUnit(this._parsedProps.loadCapacitance)}F`:freqDisplay}};function getPotentiometerSymbolName(variant){switch(variant){case"three_pin":return"potentiometer3";case"two_pin":return"potentiometer2";default:return"potentiometer2"}}var Potentiometer2=class extends NormalComponent{get config(){return{componentName:"Potentiometer",schematicSymbolName:this.props.symbolName??getPotentiometerSymbolName(this.props.pinVariant),zodProps:potentiometerProps,shouldRenderAsSchematicBox:!1}}_getSchematicSymbolDisplayValue(){return`${formatSiUnit(this._parsedProps.maxResistance)}\u03A9`}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,pinVariant=props.pinVariant||"two_pin",source_component=db22.source_component.insert({ftype:"simple_potentiometer",name:this.name,manufacturer_part_number:resolveManufacturerPartNumber(props),supplier_part_numbers:props.supplierPartNumbers,max_resistance:props.maxResistance,pin_variant:pinVariant,are_pins_interchangeable:pinVariant==="two_pin",display_name:props.displayName,display_max_resistance:this._getSchematicSymbolDisplayValue()});this.source_component_id=source_component.source_component_id}},DEFAULT_CRYSTAL_MAX_TRACE_LENGTH_MM=10,DEFAULT_CRYSTAL_MAX_VIA_COUNT=0,Crystal2=class extends NormalComponent{get config(){return{schematicSymbolName:this.props.symbolName??(this.props.pinVariant==="four_pin"?"crystal_4pin":"crystal"),componentName:"Crystal",zodProps:crystalProps,sourceFtype:"simple_crystal"}}initPorts(){let additionalAliases=this.props.pinVariant==="four_pin"?{pin1:["left1","1","X1"],pin2:["top1","2","gnd1"],pin3:["right1","3","X2"],pin4:["bottom1","4","gnd2"]}:{pin1:["pos","left","X1"],pin2:["neg","right","X2"]};super.initPorts({additionalAliases})}_getSchematicSymbolDisplayValue(){let freqDisplay=`${formatSiUnit(this._parsedProps.frequency)}Hz`;return this._parsedProps.loadCapacitance?`${freqDisplay} / ${formatSiUnit(this._parsedProps.loadCapacitance)}F`:freqDisplay}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({name:this.name,ftype:"simple_crystal",manufacturer_part_number:resolveManufacturerPartNumber(props),supplier_part_numbers:props.supplierPartNumbers,frequency:props.frequency,load_capacitance:props.loadCapacitance,display_frequency:`${formatSiUnit(props.frequency)}Hz`,display_load_capacitance:`${formatSiUnit(props.loadCapacitance)}F`,pin_variant:props.pinVariant||"two_pin",are_pins_interchangeable:(props.pinVariant||"two_pin")==="two_pin",display_name:props.displayName});this.source_component_id=source_component.source_component_id}doInitialSourceDesignRuleChecks(){if(super.doInitialSourceDesignRuleChecks(),!this.source_component_id)return;let{db:db22}=this.root,maximumTraceLength=this._parsedProps.maxTraceLength??DEFAULT_CRYSTAL_MAX_TRACE_LENGTH_MM,crystalSignalSourcePortIds=new Set,crystalSignalConnectivityMapKeys=new Set;for(let signalPort of[this.portMap.X1,this.portMap.X2]){if(!signalPort.source_port_id)continue;let sourcePort=db22.source_port.get(signalPort.source_port_id);sourcePort&&(crystalSignalSourcePortIds.add(signalPort.source_port_id),sourcePort.subcircuit_connectivity_map_key&&crystalSignalConnectivityMapKeys.add(sourcePort.subcircuit_connectivity_map_key))}for(let sourceTrace of db22.source_trace.list()){let isDirectlyConnectedToCrystal=sourceTrace.connected_source_port_ids.some(sourcePortId=>crystalSignalSourcePortIds.has(sourcePortId)),isOnCrystalNet=sourceTrace.subcircuit_connectivity_map_key!==void 0&&crystalSignalConnectivityMapKeys.has(sourceTrace.subcircuit_connectivity_map_key);if(!isDirectlyConnectedToCrystal&&!isOnCrystalNet)continue;let needsMaximumTraceLength=typeof sourceTrace.max_length!="number"||sourceTrace.max_length>maximumTraceLength,needsMaximumViaCount=sourceTrace.max_via_count!==DEFAULT_CRYSTAL_MAX_VIA_COUNT;!needsMaximumTraceLength&&!needsMaximumViaCount||db22.source_trace.update(sourceTrace.source_trace_id,{...needsMaximumTraceLength?{max_length:maximumTraceLength}:{},...needsMaximumViaCount?{max_via_count:DEFAULT_CRYSTAL_MAX_VIA_COUNT}:{}})}}},OpAmp=class extends NormalComponent{constructor(){super(...arguments);__publicField(this,"inverting_input",this.portMap.inverting_input);__publicField(this,"non_inverting_input",this.portMap.non_inverting_input);__publicField(this,"output",this.portMap.output);__publicField(this,"positive_supply",this.portMap.positive_supply);__publicField(this,"negative_supply",this.portMap.negative_supply)}getSchematicSymbolName(){return this.props.symbolName?this.props.symbolName:this.props.connections?.positive_supply||this.props.connections?.negative_supply?"opamp_with_power":"opamp_no_power"}get config(){return{componentName:"OpAmp",schematicSymbolName:this.getSchematicSymbolName(),zodProps:opampProps,sourceFtype:"simple_op_amp"}}initPorts(){let additionalAliases={pin1:["non_inverting_input"],pin2:["inverting_input"]};this.getSchematicSymbolName()==="opamp_with_power"?Object.assign(additionalAliases,{pin4:["output"],pin5:["positive_supply","vcc","vdd"],pin3:["negative_supply","vee","vss","gnd"]}):Object.assign(additionalAliases,{pin3:["output"],pin4:["positive_supply","vcc","vdd"],pin5:["negative_supply","vee","vss","gnd"]}),super.initPorts({pinCount:5,additionalAliases})}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({ftype:"simple_op_amp",name:this.name,supplier_part_numbers:props.supplierPartNumbers,manufacturer_part_number:resolveManufacturerPartNumber(props),display_name:props.displayName});this.source_component_id=source_component.source_component_id}doInitialSimulationRender(){let{db:db22}=this.root,invertingInputPort=this.portMap.inverting_input,nonInvertingInputPort=this.portMap.non_inverting_input,outputPort=this.portMap.output,positiveSupplyPort=this.portMap.positive_supply,negativeSupplyPort=this.portMap.negative_supply;!invertingInputPort?.source_port_id||!nonInvertingInputPort?.source_port_id||!outputPort?.source_port_id||!positiveSupplyPort?.source_port_id||!negativeSupplyPort?.source_port_id||db22.simulation_op_amp.insert({type:"simulation_op_amp",source_component_id:this.source_component_id,inverting_input_source_port_id:invertingInputPort.source_port_id,non_inverting_input_source_port_id:nonInvertingInputPort.source_port_id,output_source_port_id:outputPort.source_port_id,positive_supply_source_port_id:positiveSupplyPort.source_port_id,negative_supply_source_port_id:negativeSupplyPort.source_port_id})}},SchematicSymbol_doInitialSchematicComponentRender=schematicSymbol=>{if(schematicSymbol.root?.schematicDisabled||schematicSymbol.getCollapsedSchematicBoxAncestor())return;let{db:db22}=schematicSymbol.root,symbolName=schematicSymbol._getSchematicSymbolNameOrThrow(),symbol=cc[symbolName];if(!symbol)throw new Error(`No schematic symbol found for "${symbolName}"`);let center2=schematicSymbol._getGlobalSchematicPositionBeforeLayout(),schematicSheetId=schematicSymbol._resolveSchematicSheetId(),subcircuitId=schematicSymbol.getSubcircuit().subcircuit_id??void 0,schematicComponent=db22.schematic_component.insert({center:center2,size:{...symbol.size},is_box_with_pins:!0,symbol_name:symbolName,source_component_id:schematicSymbol.source_component_id??void 0,schematic_sheet_id:schematicSheetId});schematicSymbol.schematic_component_id=schematicComponent.schematic_component_id;for(let symbolPort of symbol.ports){let port=schematicSymbol.getPortForSymbolPort(symbolPort);if(!port?.source_port_id)throw new Error(`Missing source port for schematic symbol port "${symbolPort.labels.join("/")}" on ${schematicSymbol.getString()}`);let portCenter={x:center2.x+symbolPort.x-symbol.center.x,y:center2.y+symbolPort.y-symbol.center.y},schematicPort=db22.schematic_port.insert({schematic_component_id:schematicComponent.schematic_component_id,center:portCenter,source_port_id:port.source_port_id,facing_direction:getRelativeDirection(center2,portCenter),distance_from_component_edge:.4,pin_number:port._parsedProps.pinNumber,display_pin_label:port._parsedProps.aliases?.[0],is_connected:!1,schematic_sheet_id:schematicSheetId,subcircuit_id:subcircuitId});port.schematic_port_id=schematicPort.schematic_port_id}},getSingleConnectionTarget=(connectionName,target)=>{let targets=Array.isArray(target)?target:[target];if(targets.length!==1)throw new Error(`SchematicSymbol connection "${connectionName}" must select exactly one physical port`);return targets[0]},SchematicSymbol_doInitialPortMatching=schematicSymbol=>{let{db:db22}=schematicSymbol.root,{chipRef,connections}=schematicSymbol._parsedProps;if(chipRef&&!connections){db22.source_property_ignored_warning.insert({source_component_id:schematicSymbol.source_component_id,property_name:"chipRef",message:`${schematicSymbol.getString()} has chipRef "${chipRef}" without connections. chipRef will be ignored.`,error_type:"source_property_ignored_warning",subcircuit_id:schematicSymbol.getSubcircuit().subcircuit_id??void 0});return}if(connections&&!chipRef){db22.source_property_ignored_warning.insert({source_component_id:schematicSymbol.source_component_id,property_name:"connections",message:`${schematicSymbol.getString()} has connections without chipRef. connections will be ignored.`,error_type:"source_property_ignored_warning",subcircuit_id:schematicSymbol.getSubcircuit().subcircuit_id??void 0});return}if(!chipRef||!connections)return;let referencedChip=schematicSymbol.getSubcircuit().selectOne(chipRef);if(!referencedChip?.source_component_id)throw new Error(`Could not resolve chipRef "${chipRef}" for ${schematicSymbol.getString()}`);let usedConnectionNames=new Set;for(let schematicPort of schematicSymbol.ports){let symbolPort=schematicPort.schematicSymbolPortDef,matchingConnections=Object.entries(connections).filter(([connectionName2])=>schematicPort.isMatchingAnyOf([connectionName2]));if(matchingConnections.length===0)throw new Error(`${schematicSymbol.getString()} is missing an explicit connection for symbol port "${symbolPort.labels.join("/")}"`);if(matchingConnections.length>1)throw new Error(`${schematicSymbol.getString()} has multiple connections for symbol port "${symbolPort.labels.join("/")}"`);let[connectionName,connectionTarget5]=matchingConnections[0];usedConnectionNames.add(connectionName);let targetSelector=getSingleConnectionTarget(connectionName,connectionTarget5),physicalPort=schematicSymbol.getSubcircuit().selectOne(targetSelector,{type:"port"});if(!physicalPort?.source_port_id)throw new Error(`Could not resolve connection "${connectionName}" target "${targetSelector}" for ${schematicSymbol.getString()}`);if(db22.source_port.get(physicalPort.source_port_id)?.source_component_id!==referencedChip.source_component_id)throw new Error(`Connection "${connectionName}" target "${targetSelector}" does not belong to chipRef "${chipRef}"`);schematicPort.source_port_id=physicalPort.source_port_id,schematicPort.source_component_id=physicalPort.source_component_id}let unusedConnectionNames=Object.keys(connections).filter(connectionName=>!usedConnectionNames.has(connectionName));if(unusedConnectionNames.length>0)throw new Error(`${schematicSymbol.getString()} has connections that do not match symbol ports: ${unusedConnectionNames.join(", ")}`)},SchematicSymbol=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"isSchematicPrimitive",!0);__publicField(this,"isPrimitiveContainer",!0)}get config(){return{componentName:"SchematicSymbol",schematicSymbolName:this.props.symbolName,zodProps:schematicSymbolProps}}initPorts(){let symbol=cc[this._getSchematicSymbolNameOrThrow()],shouldCreateSourcePort=!(this._parsedProps.chipRef&&this._parsedProps.connections);for(let symbolPort of symbol.ports){let pinNumber2=getPinNumberFromLabels(symbolPort.labels);if(!pinNumber2)throw new Error(`Schematic symbol port must have a numeric pin label: ${symbolPort.labels.join("/")}`);let existingPort=this.ports.find(port2=>port2._parsedProps.pinNumber===pinNumber2);if(existingPort){existingPort.schematicSymbolPortDef=symbolPort;continue}let aliases23=symbolPort.labels.filter(label=>label!==pinNumber2.toString()&&label!==`pin${pinNumber2}`),port=new Port({pinNumber:pinNumber2,aliases:aliases23},{shouldCreateSourcePort});port.schematicSymbolPortDef=symbolPort,this.add(port)}}doInitialInitializePortsFromChildren(){this.initPorts()}updateInitializePortsFromChildren(){this.initPorts()}get ports(){return this.children.filter(child=>child instanceof Port)}getPortForSymbolPort(symbolPort){return this.ports.find(port=>port.schematicSymbolPortDef===symbolPort)??null}doInitialSourceRender(){let sourceComponent=this.root.db.source_component.insert({ftype:"simple_chip",name:this.name,display_name:this._parsedProps.displayName,are_pins_interchangeable:!1});this.source_component_id=sourceComponent.source_component_id}doInitialPortMatching(){SchematicSymbol_doInitialPortMatching(this)}doInitialSchematicComponentRender(){SchematicSymbol_doInitialSchematicComponentRender(this)}},SchematicSection=class _SchematicSection extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"isSchematicPrimitive",!0)}get config(){return{componentName:"SchematicSection",zodProps:schematicSectionProps}}_computeSectionBounds(board,sectionName,schematicSheetId){let{db:db22}=this.root,members=board.getDescendants().filter(c23=>c23.getSchematicSectionName()===sectionName);if(members.length===0)return null;let positions=[];for(let member of members){let schematicComponentId=member.schematic_component_id;if(!schematicComponentId)continue;let schComp=db22.schematic_component.get(schematicComponentId);if(!schComp||schComp.schematic_sheet_id!==schematicSheetId)continue;let hw22=schComp.size.width/2,hh22=schComp.size.height/2;positions.push({minX:schComp.center.x-hw22,maxX:schComp.center.x+hw22,minY:schComp.center.y-hh22,maxY:schComp.center.y+hh22});for(let text4 of db22.schematic_text.list({schematic_component_id:schematicComponentId}))positions.push(getSchematicTextBounds2({text:text4.text,position:text4.position,anchor:text4.anchor,fontSize:text4.font_size}))}return positions.length===0?null:computeBoundsFromCellContents(positions)}doInitialSchematicSectionRender(){if(this.root?.schematicDisabled)return;let board=this.root?._getBoard();if(!board)return;let schematicSheetId=this._resolveSchematicSheetId(),allSections=board.getDescendants().filter(component=>component instanceof _SchematicSection&&component._resolveSchematicSheetId()===schematicSheetId);if(allSections[0]!==this)return;let{db:db22}=this.root,PADDING=.5,LABEL_PADDING=.2,STROKE_WIDTH=.02,TOL42=.001,namedSectionsWithBounds=allSections.map(section=>{let bounds=section._computeSectionBounds(board,section._parsedProps.name,schematicSheetId);return bounds?{displayName:section._parsedProps.displayName,sectionTitleFontSize:section._parsedProps.sectionTitleFontSize,rawBounds:bounds,cell:{minX:bounds.minX-PADDING,maxX:bounds.maxX+PADDING,minY:bounds.minY-PADDING,maxY:bounds.maxY+PADDING}}:null}).filter(s23=>s23!==null),unsectionedBounds=this._computeSectionBounds(board,null,schematicSheetId),allSectionsWithBounds=[...namedSectionsWithBounds];if(unsectionedBounds&&allSectionsWithBounds.push({displayName:void 0,sectionTitleFontSize:void 0,rawBounds:unsectionedBounds,cell:{minX:unsectionedBounds.minX-PADDING,maxX:unsectionedBounds.maxX+PADDING,minY:unsectionedBounds.minY-PADDING,maxY:unsectionedBounds.maxY+PADDING}}),allSectionsWithBounds.length===0)return;let allCells=allSectionsWithBounds.map(s23=>s23.cell),outer=computeBoundsFromCellContents(allCells),dividers=calculateCellBoundaries2(allSectionsWithBounds.map(s23=>s23.rawBounds),{cellMargin:1});for(let line4 of dividers)db22.schematic_line.insert({x1:line4.start.x,y1:line4.start.y,x2:line4.end.x,y2:line4.end.y,stroke_width:STROKE_WIDTH,color:"#000000",is_dashed:!0,schematic_sheet_id:schematicSheetId});let hDividers=dividers.filter(l23=>Math.abs(l23.start.y-l23.end.y)<TOL42),vDividers=dividers.filter(l23=>Math.abs(l23.start.x-l23.end.x)<TOL42);for(let sectionWithBounds of allSectionsWithBounds){let{displayName,sectionTitleFontSize,rawBounds,cell}=sectionWithBounds;if(!displayName)continue;let overlapsAnotherSection=allSectionsWithBounds.some(section=>section!==sectionWithBounds&&doBoundsOverlap(section.rawBounds,rawBounds)),dividersAbove=hDividers.map(l23=>l23.start.y).filter(y23=>y23>rawBounds.maxY),topBoundary=dividersAbove.length>0?Math.min(...dividersAbove):outer.maxY,dividersToLeft=vDividers.map(l23=>l23.start.x).filter(x23=>x23<rawBounds.minX),leftBoundary=outer.minX;overlapsAnotherSection&&(leftBoundary=cell.minX),dividersToLeft.length>0&&(leftBoundary=Math.max(...dividersToLeft));let fontSize=sectionTitleFontSize??.18;db22.schematic_text.insert({anchor:"top_left",text:displayName,font_size:fontSize,color:"#000000",position:{x:leftBoundary+LABEL_PADDING,y:Math.max(topBoundary-LABEL_PADDING,rawBounds.maxY+LABEL_PADDING+fontSize)},rotation:0,schematic_sheet_id:schematicSheetId})}}},getCircuitJsonSchematicSheetSize=sheetSize=>schematic_sheet_size.parse(sheetSize.toLowerCase()),SCHEMATIC_SHEET_DIMENSIONS_MM={a4:{width:297,height:210},ansi_b:{width:431.8,height:279.4}},resolveCircuitJsonSchematicSheetProperties=({sheetSize,sheetWidth,sheetHeight})=>{let circuitJsonSheetSize=getCircuitJsonSchematicSheetSize(sheetSize),defaultDimensions=SCHEMATIC_SHEET_DIMENSIONS_MM[circuitJsonSheetSize];return{sheetSize:circuitJsonSheetSize,sheetWidth:sheetWidth??defaultDimensions.width,sheetHeight:sheetHeight??defaultDimensions.height}},SCHEMATIC_UNIT_TO_MM2=10.16/1.1,SCHEMATIC_SHEET_INNER_MARGIN2=5/SCHEMATIC_UNIT_TO_MM2,BOUNDS_EPSILON=1e-6,getSchematicElementId=schematicElement=>{switch(schematicElement.type){case"schematic_component":return schematicElement.schematic_component_id;case"schematic_net_label":return schematicElement.schematic_net_label_id;case"schematic_trace":return schematicElement.schematic_trace_id}},warnIfSchematicElementsOutsideSheet=({db:db22,schematicSheetId,schematicSheetName,schematicSheetCenter,sheetWidth,sheetHeight})=>{let sheetWidthInSchematicUnits=sheetWidth/SCHEMATIC_UNIT_TO_MM2,sheetHeightInSchematicUnits=sheetHeight/SCHEMATIC_UNIT_TO_MM2,sheetContentBounds={minX:schematicSheetCenter.x-sheetWidthInSchematicUnits/2+SCHEMATIC_SHEET_INNER_MARGIN2,maxX:schematicSheetCenter.x+sheetWidthInSchematicUnits/2-SCHEMATIC_SHEET_INNER_MARGIN2,minY:schematicSheetCenter.y-sheetHeightInSchematicUnits/2+SCHEMATIC_SHEET_INNER_MARGIN2,maxY:schematicSheetCenter.y+sheetHeightInSchematicUnits/2-SCHEMATIC_SHEET_INNER_MARGIN2},checkedElements=[...db22.schematic_component.list(),...db22.schematic_net_label.list(),...db22.schematic_trace.list()].filter(schematicElement=>schematicElement.schematic_sheet_id===schematicSheetId);for(let schematicElement of checkedElements){let elementBounds=getSchematicElementBounds(schematicElement);if(!elementBounds||!(elementBounds.minX<sheetContentBounds.minX-BOUNDS_EPSILON||elementBounds.maxX>sheetContentBounds.maxX+BOUNDS_EPSILON||elementBounds.minY<sheetContentBounds.minY-BOUNDS_EPSILON||elementBounds.maxY>sheetContentBounds.maxY+BOUNDS_EPSILON))continue;let schematicElementId=getSchematicElementId(schematicElement);db22.schematic_element_outside_sheet_warning.insert({warning_type:"schematic_element_outside_sheet_warning",message:`${schematicElement.type} ${schematicElementId} extends outside the drawing area of schematic sheet "${schematicSheetName}"`,schematic_sheet_id:schematicSheetId,schematic_element_type:schematicElement.type,schematic_element_id:schematicElementId})}},SchematicSheet=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"isSchematicPrimitive",!0);__publicField(this,"resolvedSchematicSheetDisplayName","Schematic Sheet")}get config(){return{componentName:"SchematicSheet",zodProps:schematicSheetProps}}doInitialSourceGroupRender(){if(this.root?.schematicDisabled)return;let{db:db22}=this.root,{_parsedProps:props}=this,explicitlyReservedSheetIndices=new Set(this.root.children.flatMap(component=>[component,...component.getDescendants()]).filter(component=>component.componentName==="SchematicSheet").map(component=>component._parsedProps.sheetIndex).filter(sheetIndex2=>sheetIndex2!==void 0)),occupiedSheetIndices=new Set([...explicitlyReservedSheetIndices,...db22.schematic_sheet.list().map(schematicSheet2=>schematicSheet2.sheet_index).filter(sheetIndex2=>sheetIndex2!==void 0)]),nextAvailableSheetIndex=0;for(;occupiedSheetIndices.has(nextAvailableSheetIndex);)nextAvailableSheetIndex+=1;let sheetIndex=props.sheetIndex??nextAvailableSheetIndex,name=props.name??props.displayName??`Sheet ${sheetIndex+1}`,displayName=props.displayName??name;this.resolvedSchematicSheetDisplayName=displayName;let resolvedSheetProperties=resolveCircuitJsonSchematicSheetProperties(props),schematicSheet=db22.schematic_sheet.insert({name,display_name:displayName,sheet_index:sheetIndex,sheet_size:resolvedSheetProperties.sheetSize,sheet_width:resolvedSheetProperties.sheetWidth,sheet_height:resolvedSheetProperties.sheetHeight,subcircuit_id:this.getSubcircuit().subcircuit_id??void 0});this.schematic_sheet_id=schematicSheet.schematic_sheet_id;let defaultSheetProperties=resolveCircuitJsonSchematicSheetProperties({sheetSize:"A4"});(resolvedSheetProperties.sheetSize!==defaultSheetProperties.sheetSize||resolvedSheetProperties.sheetWidth!==defaultSheetProperties.sheetWidth||resolvedSheetProperties.sheetHeight!==defaultSheetProperties.sheetHeight)&&db22.schematic_sheet_styling_warning.insert({warning_type:"schematic_sheet_styling_warning",styling_issue_type:"non_default_sheet_size",schematic_sheet_id:this.schematic_sheet_id,subcircuit_id:schematicSheet.subcircuit_id,message:`Schematic sheet "${displayName}" uses a non-default size (${resolvedSheetProperties.sheetWidth} \xD7 ${resolvedSheetProperties.sheetHeight} mm). Prefer the default A4 sheet size (297 \xD7 210 mm) for consistent schematic styling.`})}doInitialSchematicSheetRender(){if(this.root?.schematicDisabled||!this.schematic_sheet_id)return;let{db:db22}=this.root,resolvedSheetProperties=resolveCircuitJsonSchematicSheetProperties(this._parsedProps);if(this._parsedProps.sheetWidth!==void 0||this._parsedProps.sheetHeight!==void 0){warnIfSchematicElementsOutsideSheet({db:db22,schematicSheetId:this.schematic_sheet_id,schematicSheetName:this.resolvedSchematicSheetDisplayName,schematicSheetCenter:{x:0,y:0},sheetWidth:resolvedSheetProperties.sheetWidth,sheetHeight:resolvedSheetProperties.sheetHeight});return}let schematicElements=[...db22.schematic_component.list(),...db22.schematic_port.list(),...db22.schematic_text.list(),...db22.schematic_line.list(),...db22.schematic_rect.list(),...db22.schematic_circle.list(),...db22.schematic_arc.list(),...db22.schematic_path.list()].filter(element2=>element2.schematic_sheet_id===this.schematic_sheet_id),schematicSheetCenter={x:0,y:0};if(schematicElements.length>0){let bounds=getBoundsForSchematic(schematicElements);Number.isFinite(bounds.minX)&&Number.isFinite(bounds.maxX)&&Number.isFinite(bounds.minY)&&Number.isFinite(bounds.maxY)&&(schematicSheetCenter={x:(bounds.minX+bounds.maxX)/2,y:(bounds.minY+bounds.maxY)/2},db22.schematic_sheet.update(this.schematic_sheet_id,{center:schematicSheetCenter}))}warnIfSchematicElementsOutsideSheet({db:db22,schematicSheetId:this.schematic_sheet_id,schematicSheetName:this.resolvedSchematicSheetDisplayName,schematicSheetCenter,sheetWidth:resolvedSheetProperties.sheetWidth,sheetHeight:resolvedSheetProperties.sheetHeight})}},SchematicGraphic=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"isSchematicPrimitive",!0);__publicField(this,"schematic_graphic_id")}get config(){return{componentName:"SchematicGraphic",zodProps:schematicGraphicProps}}doInitialSchematicPrimitiveRender(){if(this.root?.schematicDisabled||this.getCollapsedSchematicBoxAncestor())return;let{db:db22}=this.root,{imageUrl,svgContent,width:width10,height:height10}=this._parsedProps;if(imageUrl!==void 0){this._queueAsyncEffect("SchematicGraphicRender",async()=>{if(this.root?.schematicDisabled)return;let resolvedImageUrl=await resolveStaticFileImport(imageUrl,this.root?.platform),sourceImage=await loadImageSource(resolvedImageUrl).catch(error2=>{if(svgContent===void 0||resolvedImageUrl.startsWith("data:"))throw error2;return null});if(sourceImage===null){let asset32={project_relative_path:imageUrl.startsWith("data:")?"inline":imageUrl,url:resolvedImageUrl,mimetype:SVG_MIMETYPE2},schematicGraphic2=this.root.db.schematic_graphic.insert({asset:asset32,schematic_sheet_id:this._resolveSchematicSheetId(),svg_content:svgContent,...width10===void 0?{}:{width:width10},...height10===void 0?{}:{height:height10}});this.schematic_graphic_id=schematicGraphic2.schematic_graphic_id;return}if(sourceImage.mimetype!==SVG_MIMETYPE2)throw new Error(`Unsupported imageUrl for SchematicGraphic: "${imageUrl}". Expected an SVG image.`);let asset23={project_relative_path:imageUrl.startsWith("data:")?sourceImage.projectRelativePath:imageUrl,url:sourceImage.dataUrl,mimetype:sourceImage.mimetype},fallbackSvgContent=sourceImage.dataUrl.startsWith("data:")?svgContent:sourceImage.text,schematicGraphic=this.root.db.schematic_graphic.insert({asset:asset23,schematic_sheet_id:this._resolveSchematicSheetId(),...fallbackSvgContent===void 0?{}:{svg_content:fallbackSvgContent},...width10===void 0?{}:{width:width10},...height10===void 0?{}:{height:height10}});this.schematic_graphic_id=schematicGraphic.schematic_graphic_id});return}if(svgContent!==void 0){let asset23={project_relative_path:"inline",url:`data:image/svg+xml,${encodeURIComponent(svgContent)}`,mimetype:SVG_MIMETYPE2},schematicGraphic=db22.schematic_graphic.insert({asset:asset23,schematic_sheet_id:this._resolveSchematicSheetId(),...width10===void 0?{}:{width:width10},...height10===void 0?{}:{height:height10}});this.schematic_graphic_id=schematicGraphic.schematic_graphic_id}}},SchematicTable=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"isSchematicPrimitive",!0);__publicField(this,"schematic_table_id",null)}get config(){return{componentName:"SchematicTable",zodProps:schematicTableProps}}doInitialSchematicPrimitiveRender(){if(this.root?.schematicDisabled||this.getCollapsedSchematicBoxAncestor())return;let{db:db22}=this.root,{_parsedProps:props}=this,rows=this.children.filter(c23=>c23.componentName==="SchematicRow");if(rows.length===0)return;let grid22=[],maxCols=0;for(let row of rows){let cells=row.children.filter(c23=>c23.componentName==="SchematicCell");maxCols=Math.max(maxCols,cells.length)}for(let i23=0;i23<rows.length;i23++)grid22[i23]=[];for(let i23=0;i23<rows.length;i23++){let cells=rows[i23].children.filter(c23=>c23.componentName==="SchematicCell"),k23=0;for(let j23=0;j23<cells.length;j23++){for(;grid22[i23][k23];)k23++;let cell=cells[j23],colSpan=cell._parsedProps.colSpan??1,rowSpan=cell._parsedProps.rowSpan??1;for(let r23=0;r23<rowSpan;r23++)for(let c23=0;c23<colSpan;c23++)grid22[i23+r23]||(grid22[i23+r23]=[]),grid22[i23+r23][k23+c23]=cell;k23+=colSpan}}maxCols=Math.max(0,...grid22.map(r23=>r23.length));let rowHeights=rows.map((row,i23)=>row._parsedProps.height??1),colWidths=Array.from({length:maxCols},(_23,j23)=>{let maxWidth=0;for(let i23=0;i23<rows.length;i23++){let cell=grid22[i23]?.[j23];if(cell){let text4=cell._parsedProps.text??cell._parsedProps.children,cellWidth=cell._parsedProps.width??(text4?.length??2)*.5;cellWidth>maxWidth&&(maxWidth=cellWidth)}}return maxWidth||10}),anchorPos=this._getGlobalSchematicPositionBeforeLayout(),table=db22.schematic_table.insert({anchor_position:anchorPos,column_widths:colWidths,row_heights:rowHeights,cell_padding:props.cellPadding,border_width:props.borderWidth,anchor:props.anchor,subcircuit_id:this.getSubcircuit()?.subcircuit_id||"",schematic_component_id:this.parent?.schematic_component_id||"",schematic_sheet_id:this._resolveSchematicSheetId()});this.schematic_table_id=table.schematic_table_id;let processedCells=new Set,yOffset=0;for(let i23=0;i23<rows.length;i23++){let xOffset=0;for(let j23=0;j23<maxCols;j23++){let cell=grid22[i23]?.[j23];if(cell&&!processedCells.has(cell)){processedCells.add(cell);let cellProps=cell._parsedProps,rowSpan=cellProps.rowSpan??1,colSpan=cellProps.colSpan??1,cellWidth=0;for(let c23=0;c23<colSpan;c23++)cellWidth+=colWidths[j23+c23];let cellHeight=0;for(let r23=0;r23<rowSpan;r23++)cellHeight+=rowHeights[i23+r23];db22.schematic_table_cell.insert({schematic_table_id:this.schematic_table_id,start_row_index:i23,end_row_index:i23+rowSpan-1,start_column_index:j23,end_column_index:j23+colSpan-1,text:cellProps.text??cellProps.children,center:{x:anchorPos.x+xOffset+cellWidth/2,y:anchorPos.y-yOffset-cellHeight/2},width:cellWidth,height:cellHeight,horizontal_align:cellProps.horizontalAlign,vertical_align:cellProps.verticalAlign,font_size:cellProps.fontSize??props.fontSize,subcircuit_id:this.getSubcircuit()?.subcircuit_id||""})}colWidths[j23]&&(xOffset+=colWidths[j23])}yOffset+=rowHeights[i23]}}},SchematicRow=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"isSchematicPrimitive",!0)}get config(){return{componentName:"SchematicRow",zodProps:schematicRowProps}}},SchematicCell=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"isSchematicPrimitive",!0);__publicField(this,"canHaveTextChildren",!0)}get config(){return{componentName:"SchematicCell",zodProps:schematicCellProps}}},AnalogSimulation=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"simulation_experiment_id",null)}get config(){return{componentName:"AnalogSimulation",zodProps:analogSimulationProps}}getSpiceEngineName(){return this._parsedProps.spiceEngine}usesIndependentGraphAxes(){return this._parsedProps.graphIndependentAxes===!0}doInitialSimulationRender(){let{db:db22}=this.root,{duration,name,startTime,timePerStep,spiceOptions:spiceOptions3}=this._parsedProps,durationMs=duration||10,timePerStepMs=timePerStep||.01,simulationExperiment=db22.simulation_experiment.insert({name:name??"spice_transient_analysis",experiment_type:"spice_transient_analysis",end_time_ms:durationMs,start_time_ms:startTime,time_per_step:timePerStepMs,spice_options:spiceOptions3});this.simulation_experiment_id=simulationExperiment.simulation_experiment_id}},AnalogAnalysisSimulation=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"simulation_experiment_id",null)}getSpiceEngineName(){return typeof this.props.spiceEngine=="string"?this.props.spiceEngine:void 0}usesIndependentGraphAxes(){return this.props.graphIndependentAxes===!0}getOrCreateSimulationExperiment(){if(this.simulation_experiment_id)return this.root?.db.simulation_experiment.get(this.simulation_experiment_id)??null;if(this.children.filter(child=>child.componentName==="AnalogSweepParameter").length>1)return this.renderError("An analog simulation can contain at most one sweep parameter."),null;let simulationExperiment=this.insertSimulationExperiment();return this.simulation_experiment_id=simulationExperiment?.simulation_experiment_id??null,simulationExperiment}doInitialSimulationRender(){this.getOrCreateSimulationExperiment()}};function resolveExternalSimulationPort({declaration,selector:selector2}){let ports=declaration.getSubcircuit().selectAll(selector2).filter(port=>port.componentName==="Port");if(ports.length!==1||!ports[0].source_port_id)throw new Error(`Simulation pin selector "${selector2}" must identify exactly one physical source pin.`);return ports[0]}function resolveExternalTransientSimulation({declaration,selector:selector2}){let simulations=declaration.getSubcircuit().selectAll(selector2).filter(simulation3=>simulation3.componentName==="AnalogTransientSimulation");if(simulations.length!==1)throw new Error(`Simulation selector "${selector2}" must identify one transient in this subcircuit.`);let simulation2=simulations[0];if(simulation2.getSpiceEngineName()!=="pcb_spice")throw new Error(`Simulation "${selector2}" requires spiceEngine="pcb_spice" for IBIS declarations.`);return simulation2.getOrCreateSimulationExperiment(),simulation2}function AnalogTransientSimulation_validateIbisBindings(simulation2){if(simulation2.getSpiceEngineName()!=="pcb_spice")return;let models2=simulation2.getSubcircuit().selectAll("ibismodel").filter(model110=>!model110.shouldBeRemoved).map(model110=>simulation2.root.db.simulation_ibis_model.get(model110.simulation_ibis_model_id));for(let selector2 of Object.keys(simulation2._parsedProps.ibisPinStates??{})){let port=resolveExternalSimulationPort({declaration:simulation2,selector:selector2});if(models2.filter(model110=>Object.values(model110.ibis_pin_name_to_source_port_id).includes(port.source_port_id)).length!==1)throw new Error(`Simulation "${simulation2._parsedProps.name??"transient"}" pin "${selector2}" requires exactly one IBIS model binding in this subcircuit.`)}}function AnalogTransientSimulation_getPcbSpiceChannel(declaration){if(declaration.getInheritedProperty("analogSimulationDisabled"))return;let channel23=declaration._parsedProps.pcbSpiceChannel;if(!channel23)return;let resolvePort=selector2=>resolveExternalSimulationPort({declaration,selector:selector2}).source_port_id,extraction=channel23.extraction;return{reduction:channel23.reduction,sections:channel23.sections,lanes:channel23.lanes.map(lane=>({name:lane.name,driver_source_port_id:resolvePort(lane.from),receiver_source_port_id:resolvePort(lane.to)})),reference_source_port_id:resolvePort(channel23.referencePinRef),passive_source_component_ids:channel23.passiveComponentRefs?.map(selector2=>{let components=declaration.getSubcircuit().selectAll(selector2).filter(component=>component.source_component_id);if(components.length!==1)throw new Error(`PCB SPICE passive component selector "${selector2}" must identify one component in this subcircuit.`);return components[0].source_component_id}),extraction:{minimum_frequency_hz:extraction.minimumFrequency,maximum_frequency_hz:extraction.maximumFrequency,model_frequency_hz:extraction.modelFrequency,filaments:extraction.filaments,refinement_filaments:extraction.refinementFilaments,convergence_tolerance:extraction.convergenceTolerance,capacitance_tolerance:extraction.capacitanceTolerance,reciprocity_tolerance:extraction.reciprocityTolerance,dc_resistance_tolerance:extraction.dcResistanceTolerance,max_panel_length_mm:extraction.maxPanelLength,ground_mesh_size_mm:extraction.groundMeshSize},relative_permittivity:channel23.relativePermittivity,via_plating_thickness_mm:channel23.via?.platingThickness,via_equivalent_width_mm:channel23.via?.equivalentWidth,omit_through_via_stubs:channel23.via?.omitThroughViaStubs,straightened_stage_profiles:channel23.straightenedStageProfiles&&Object.fromEntries(Object.entries(channel23.straightenedStageProfiles).map(([layer,profile5])=>[layer,{spacing_mm:profile5.spacing,relative_permittivity:profile5.relativePermittivity,return:{width_mm:profile5.return.width,thickness_mm:profile5.return.thickness,length_factor:profile5.return.lengthFactor,center_y_mm:profile5.return.centerY,center_z_mm:profile5.return.centerZ}}]))}}var AnalogTransientSimulation=class extends AnalogAnalysisSimulation{get config(){return{componentName:"AnalogTransientSimulation",zodProps:analogTransientSimulationProps}}doInitialSimulationSpiceEngineRender(){this.getInheritedProperty("analogSimulationDisabled")||AnalogTransientSimulation_validateIbisBindings(this)}updateSimulationSpiceEngineRender(){this.doInitialSimulationSpiceEngineRender()}onPropsChange(){if(this._markDirty("SimulationRender"),!this.simulation_experiment_id)return;let subcircuit=this.getSubcircuit();for(let declaration of[...subcircuit.selectAll("analogdigitalstimulus"),...subcircuit.selectAll("analogeyediagram")])declaration.getSubcircuit()===subcircuit&&declaration._markDirty("SimulationSpiceEngineRender")}updateSimulationRender(){this.insertSimulationExperiment()}removeIbisPinStates(){for(let state2 of this.root.db.simulation_ibis_pin_state.list({simulation_experiment_id:this.simulation_experiment_id}))this.root.db.simulation_ibis_pin_state.delete(state2.simulation_ibis_pin_state_id)}removeSimulationRender(){this.simulation_experiment_id&&(this.removeIbisPinStates(),this.root.db.simulation_experiment.delete(this.simulation_experiment_id),this.simulation_experiment_id=null)}insertSimulationExperiment(){let{db:db22}=this.root,{duration,name,startTime,timePerStep,spiceOptions:spiceOptions3}=this._parsedProps,ibisPinStates=this.getInheritedProperty("analogSimulationDisabled")?{}:this._parsedProps.ibisPinStates,pins=Object.entries(ibisPinStates??{}).map(([selector2,state2])=>{let pin={source_port_id:resolveExternalSimulationPort({declaration:this,selector:selector2}).source_port_id,is_output:state2.isOutput};return state2.isOutput?{...pin,is_output_enabled:state2.isOutputEnabled}:pin});if(new Set(pins.map(pin=>pin.source_port_id)).size!==pins.length)throw new Error(`Simulation "${name??"transient"}" assigns multiple states to the same physical pin.`);let experimentProps={name:name??"spice_transient_analysis",experiment_type:"spice_transient_analysis",end_time_ms:duration,start_time_ms:startTime,time_per_step:timePerStep,spice_options:spiceOptions3,spice_engine:this.getSpiceEngineName(),pcb_spice_channel:AnalogTransientSimulation_getPcbSpiceChannel(this),subcircuit_id:this.getSubcircuit().subcircuit_id},experiment=this.simulation_experiment_id?db22.simulation_experiment.update(this.simulation_experiment_id,experimentProps):db22.simulation_experiment.insert(experimentProps);this.simulation_experiment_id&&this.removeIbisPinStates();for(let pin of pins)db22.simulation_ibis_pin_state.insert({simulation_experiment_id:experiment.simulation_experiment_id,...pin});return experiment}};function AnalogDigitalStimulus_getSimulationDigitalStimulus(declaration){let props=declaration._parsedProps,simulation2=resolveExternalTransientSimulation({declaration,selector:props.simulationRef}),port=resolveExternalSimulationPort({declaration,selector:props.sourcePinRef}),experiment=simulation2.getOrCreateSimulationExperiment();if(props.startTime>=experiment.end_time_ms)throw new Error(`Stimulus "${props.name}" starts outside its simulation.`);let pinState=declaration.root.db.simulation_ibis_pin_state.list({simulation_experiment_id:experiment.simulation_experiment_id}).find(state2=>state2.source_port_id===port.source_port_id);if(pinState?.is_output!==!0||pinState.is_output_enabled!==!0)throw new Error(`Stimulus "${props.name}" must drive a pin declared as an enabled output in its simulation.`);if(declaration.root.db.simulation_digital_stimulus.list({simulation_experiment_id:experiment.simulation_experiment_id}).some(stimulus=>stimulus.simulation_digital_stimulus_id!==declaration.simulation_digital_stimulus_id&&(stimulus.source_port_id===port.source_port_id||stimulus.name===props.name)))throw new Error(`Stimulus "${props.name}" duplicates a driven pin or stimulus name in this simulation.`);return{type:"simulation_digital_stimulus",name:props.name,simulation_experiment_id:experiment.simulation_experiment_id,source_port_id:port.source_port_id,bit_duration_ms:props.bitDuration,start_time_ms:props.startTime,initial_state:props.initialState,inverted:props.inverted,transmission_pattern:{transmission_type:props.transmittedData.transmissionType,bits:props.transmittedData.bits,repeat:props.transmittedData.repeat}}}var AnalogDigitalStimulus=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"simulation_digital_stimulus_id",null)}get config(){return{componentName:"AnalogDigitalStimulus",zodProps:analogDigitalStimulusProps}}doInitialSimulationRender(){if(this.getInheritedProperty("analogSimulationDisabled"))return;let stimulus=AnalogDigitalStimulus_getSimulationDigitalStimulus(this);this.simulation_digital_stimulus_id?this.root.db.simulation_digital_stimulus.update(this.simulation_digital_stimulus_id,stimulus):this.simulation_digital_stimulus_id=this.root.db.simulation_digital_stimulus.insert(stimulus).simulation_digital_stimulus_id}onPropsChange(){this._markDirty("SimulationSpiceEngineRender")}updateSimulationSpiceEngineRender(){this.doInitialSimulationRender()}removeSimulationRender(){this.simulation_digital_stimulus_id&&this.root.db.simulation_digital_stimulus.delete(this.simulation_digital_stimulus_id),this.simulation_digital_stimulus_id=null}};function AnalogEyeDiagram_getSimulationEyeDiagram(declaration){let props=declaration._parsedProps,experiment=resolveExternalTransientSimulation({declaration,selector:props.simulationRef}).getOrCreateSimulationExperiment(),probes=declaration.getSubcircuit().selectAll(props.probeRef).filter(probe2=>probe2.componentName==="VoltageProbe");if(probes.length!==1)throw new Error(`Eye probe selector "${props.probeRef}" must identify one voltage probe in this subcircuit.`);let probe=probes[0];if(!probe.simulation_voltage_probe_id)throw new Error(`Eye probe "${props.probeRef}" did not render a voltage probe.`);let start=props.startTime??experiment.start_time_ms??0,end=props.endTime??experiment.end_time_ms,firstBoundary=(start-props.timeOrigin)/props.unitInterval+.5,lastBoundary=(end-props.timeOrigin)/props.unitInterval-1.5,roundingTolerance=8*Number.EPSILON*Math.max(1,Math.abs(firstBoundary),Math.abs(lastBoundary));if(start<(experiment.start_time_ms??0)||end>experiment.end_time_ms||end<=start||Math.ceil(firstBoundary-roundingTolerance)>Math.floor(lastBoundary+roundingTolerance))throw new Error(`Eye "${props.name}" needs a gate within its simulation containing at least two bit intervals forming a complete two-UI eye window aligned to timeOrigin after recording starts.`);return{type:"simulation_eye_diagram",name:props.name,simulation_experiment_id:experiment.simulation_experiment_id,simulation_voltage_probe_id:probe.simulation_voltage_probe_id,unit_interval_ms:props.unitInterval,time_origin_ms:props.timeOrigin,start_time_ms:start,end_time_ms:end}}var AnalogEyeDiagram=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"simulation_eye_diagram_id",null)}get config(){return{componentName:"AnalogEyeDiagram",zodProps:analogEyeDiagramProps}}doInitialSimulationSpiceEngineRender(){if(this.getInheritedProperty("analogSimulationDisabled"))return;let eye=AnalogEyeDiagram_getSimulationEyeDiagram(this);this.simulation_eye_diagram_id?this.root.db.simulation_eye_diagram.update(this.simulation_eye_diagram_id,eye):this.simulation_eye_diagram_id=this.root.db.simulation_eye_diagram.insert(eye).simulation_eye_diagram_id}onPropsChange(){this._markDirty("SimulationSpiceEngineRender")}updateSimulationSpiceEngineRender(){this.doInitialSimulationSpiceEngineRender()}removeSimulationSpiceEngineRender(){this.simulation_eye_diagram_id&&this.root.db.simulation_eye_diagram.delete(this.simulation_eye_diagram_id),this.simulation_eye_diagram_id=null}};function IbisModel_getSimulationIbisModel(declaration){let props=declaration._parsedProps,chips=declaration.getSubcircuit().selectAll(props.componentRef).filter(chip2=>chip2.source_component_id);if(chips.length!==1)throw new Error(`IBIS component selector "${props.componentRef}" must identify one component in this subcircuit.`);let chip=chips[0];if(declaration.root.db.simulation_ibis_model.list({source_component_id:chip.source_component_id}).some(model110=>model110.simulation_ibis_model_id!==declaration.simulation_ibis_model_id))throw new Error(`Component "${props.componentRef}" already has an IBIS model.`);let pinMap=Object.fromEntries(Object.entries(props.ibisPinNameToPortLabel).map(([pin,label])=>[pin,resolveExternalSimulationPort({declaration,selector:`${props.componentRef} > .${label}`}).source_port_id])),ibisPinNameBySourcePortId=new Map;for(let[pin,sourcePortId]of Object.entries(pinMap)){let previousPin=ibisPinNameBySourcePortId.get(sourcePortId);if(previousPin!==void 0)throw new Error(`IBIS pins "${previousPin}" and "${pin}" on "${props.componentRef}" resolve to the same physical pin.`);ibisPinNameBySourcePortId.set(sourcePortId,pin)}for(let pin of[...Object.keys(props.ibisPinNameToReferencePortLabels??{}),...Object.keys(props.ibisPinNameToModelName??{})])if(!Object.hasOwn(props.ibisPinNameToPortLabel,pin))throw new Error(`IBIS pin "${pin}" is referenced but not present in ibisPinNameToPortLabel.`);let references4;if(props.ibisPinNameToReferencePortLabels){references4={};for(let[pin,pinReferences]of Object.entries(props.ibisPinNameToReferencePortLabels)){references4[pin]={};for(let[role,sourcePortIdField]of[["pullup","pullup_reference_source_port_id"],["pulldown","pulldown_reference_source_port_id"],["powerClamp","power_clamp_reference_source_port_id"],["groundClamp","ground_clamp_reference_source_port_id"],["external","external_reference_source_port_id"]]){let label=pinReferences[role];label!==void 0&&(references4[pin][sourcePortIdField]=resolveExternalSimulationPort({declaration,selector:`${props.componentRef} > .${label}`}).source_port_id)}}}return{type:"simulation_ibis_model",source_component_id:chip.source_component_id,ibis_model_asset:props.ibisModelAsset,ibis_component_name:props.ibisComponentName,model_value_corner:props.modelValueCorner,include_package_parasitics:props.includePackageParasitics,ibis_pin_name_to_model_name:props.ibisPinNameToModelName,ibis_pin_name_to_source_port_id:pinMap,ibis_pin_name_to_reference_source_port_ids:references4}}var IbisModel=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"simulation_ibis_model_id",null)}get config(){return{componentName:"IbisModel",zodProps:ibisModelProps}}onPropsChange(){this._markDirty("SimulationRender")}markIbisBindingsDirty(){for(let node2=this.parent;node2;node2=node2.parent){if(!node2.isSubcircuit)continue;let subcircuit=node2.getSubcircuit();for(let simulation2 of subcircuit.selectAll("analogtransientsimulation"))simulation2.getSubcircuit()===subcircuit&&simulation2._markDirty("SimulationSpiceEngineRender")}}doInitialSimulationRender(){if(this.getInheritedProperty("analogSimulationDisabled"))return;let model110=IbisModel_getSimulationIbisModel(this);this.simulation_ibis_model_id?this.root.db.simulation_ibis_model.update(this.simulation_ibis_model_id,model110):this.simulation_ibis_model_id=this.root.db.simulation_ibis_model.insert(model110).simulation_ibis_model_id,this.markIbisBindingsDirty()}updateSimulationRender(){this.doInitialSimulationRender()}removeSimulationRender(){this.simulation_ibis_model_id&&this.root.db.simulation_ibis_model.delete(this.simulation_ibis_model_id),this.simulation_ibis_model_id=null,this.markIbisBindingsDirty()}},AnalogDcOperatingPointSimulation=class extends AnalogAnalysisSimulation{get config(){return{componentName:"AnalogDcOperatingPointSimulation",zodProps:analogDcOperatingPointSimulationProps}}insertSimulationExperiment(){let{name,spiceOptions:spiceOptions3}=this._parsedProps;return this.root.db.simulation_experiment.insert({name:name??"spice_dc_operating_point",experiment_type:"spice_dc_operating_point",spice_options:spiceOptions3})}},AnalogDcSweepSimulation=class extends AnalogAnalysisSimulation{get config(){return{componentName:"AnalogDcSweepSimulation",zodProps:analogDcSweepSimulationProps}}insertSimulationExperiment(){let{name,spiceOptions:spiceOptions3,sweepSource,sweepStart,sweepStop,sweepStep}=this._parsedProps,sweepSourceComponent=(this.getGroup()??this.getSubcircuit())?.selectOne(sweepSource),dcSweepSourceFields;if(sweepSourceComponent instanceof VoltageSource2){sweepSourceComponent.runRenderPhase("SimulationRender");let simulationVoltageSourceId=sweepSourceComponent.simulation_voltage_source_id;if(!simulationVoltageSourceId)return this.renderError(`DC sweep source "${sweepSource}" must resolve to one voltage or current source.`),null;dcSweepSourceFields={dc_sweep_voltage_source_id:simulationVoltageSourceId,dc_sweep_unit:"V"}}else if(sweepSourceComponent instanceof CurrentSource2){sweepSourceComponent.runRenderPhase("SimulationRender");let simulationCurrentSourceId=sweepSourceComponent.simulation_current_source_id;if(!simulationCurrentSourceId)return this.renderError(`DC sweep source "${sweepSource}" must resolve to one voltage or current source.`),null;dcSweepSourceFields={dc_sweep_current_source_id:simulationCurrentSourceId,dc_sweep_unit:"A"}}else return this.renderError(`DC sweep source "${sweepSource}" must resolve to one voltage or current source.`),null;return this.root.db.simulation_experiment.insert({name:name??"spice_dc_sweep",experiment_type:"spice_dc_sweep",spice_options:spiceOptions3,...dcSweepSourceFields,dc_sweep_start:sweepStart,dc_sweep_stop:sweepStop,dc_sweep_step:sweepStep})}},AnalogAcSweepSimulation=class extends AnalogAnalysisSimulation{get config(){return{componentName:"AnalogAcSweepSimulation",zodProps:analogAcSweepSimulationProps}}insertSimulationExperiment(){let{name,spiceOptions:spiceOptions3,sweepType,samplesPerInterval,sampleCount,startFrequency,stopFrequency}=this._parsedProps;return this.root.db.simulation_experiment.insert({name:name??"spice_ac_analysis",experiment_type:"spice_ac_analysis",spice_options:spiceOptions3,ac_sweep_type:sweepType,ac_samples_per_interval:samplesPerInterval,ac_sample_count:sampleCount,ac_start_frequency_hz:startFrequency,ac_stop_frequency_hz:stopFrequency})}},parameterUnits={resistance:"\u03A9",capacitance:"F",inductance:"H",voltage:"V",current:"A"},isParameterSweepCoordinateInRange=({parameterSweepCoordinate,stop,step})=>{let tolerance=Math.abs(step)*1e-9;return step>0?parameterSweepCoordinate<=stop+tolerance:parameterSweepCoordinate>=stop-tolerance},getGeneratedParameterSweepCoordinates=({start,stop,step})=>{let parameterSweepCoordinates=[];for(let parameterSweepCoordinate=start;isParameterSweepCoordinateInRange({parameterSweepCoordinate,stop,step});parameterSweepCoordinate=start+parameterSweepCoordinates.length*step)if(parameterSweepCoordinates.push(parameterSweepCoordinate),parameterSweepCoordinates.length>1e6)throw new Error("Parameter sweep exceeds 1,000,000 points");return parameterSweepCoordinates},getParameterSweepTargetSelector=props=>props.parameterType==="resistance"?props.resistorRef:props.parameterType==="capacitance"?props.capacitorRef:props.parameterType==="inductance"?props.inductorRef:props.parameterType==="voltage"?props.net:props.currentSourceRef,AnalogSweepParameter_doInitialSimulationRender=analogSweepParameter=>{if(!(analogSweepParameter.parent instanceof AnalogAnalysisSimulation)){analogSweepParameter.renderError("analog.sweepparameter must be nested directly in an analog simulation.");return}let simulationExperiment=analogSweepParameter.parent.getOrCreateSimulationExperiment();if(!simulationExperiment)return;let props=analogSweepParameter._parsedProps,parameterSweepCoordinates=props.values??getGeneratedParameterSweepCoordinates({start:props.start,stop:props.stop,step:props.step}),simulationScope=analogSweepParameter.parent.getGroup()??analogSweepParameter.parent.getSubcircuit(),targetSelector=getParameterSweepTargetSelector(props),parameterUnit=parameterUnits[props.parameterType],simulationParameterSweepTable=analogSweepParameter.root.db.simulation_parameter_sweep,simulationParameterSweepFields={simulation_experiment_id:simulationExperiment.simulation_experiment_id,name:props.name,parameter_type:props.parameterType,parameter_values:parameterSweepCoordinates,parameter_unit:parameterUnit},simulationParameterSweepId;if(props.parameterType==="voltage"){let sweepNet=simulationScope?.selectOne(targetSelector,{type:"net"});if(!sweepNet?.source_net_id){analogSweepParameter.renderError(`Voltage sweep net "${targetSelector}" could not be resolved.`);return}simulationParameterSweepId=simulationParameterSweepTable.insert({...simulationParameterSweepFields,parameter_type:"voltage",source_net_id:sweepNet.source_net_id}).simulation_parameter_sweep_id}else{let sourceComponentId=simulationScope?.selectOne(targetSelector)?.source_component_id;if(!sourceComponentId){analogSweepParameter.renderError(`Parameter sweep target "${targetSelector}" could not be resolved.`);return}props.parameterType==="resistance"?simulationParameterSweepId=simulationParameterSweepTable.insert({...simulationParameterSweepFields,parameter_type:"resistance",resistor_source_component_id:sourceComponentId}).simulation_parameter_sweep_id:props.parameterType==="capacitance"?simulationParameterSweepId=simulationParameterSweepTable.insert({...simulationParameterSweepFields,parameter_type:"capacitance",capacitor_source_component_id:sourceComponentId}).simulation_parameter_sweep_id:props.parameterType==="inductance"?simulationParameterSweepId=simulationParameterSweepTable.insert({...simulationParameterSweepFields,parameter_type:"inductance",inductor_source_component_id:sourceComponentId}).simulation_parameter_sweep_id:simulationParameterSweepId=simulationParameterSweepTable.insert({...simulationParameterSweepFields,parameter_type:"current",current_source_component_id:sourceComponentId}).simulation_parameter_sweep_id}analogSweepParameter.simulation_parameter_sweep_id=simulationParameterSweepId},AnalogSweepParameter=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"simulation_parameter_sweep_id",null)}get config(){return{componentName:"AnalogSweepParameter",zodProps:analogSweepParameterProps}}doInitialSimulationRender(){AnalogSweepParameter_doInitialSimulationRender(this)}},PcbReturnCurrentSimulation=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"simulation_experiment_id",null)}get config(){return{componentName:"PcbReturnCurrentSimulation",zodProps:pcbReturnCurrentSimulationProps}}doInitialSimulationRender(){if(this.root?.pcbDisabled)return;this.parent?.componentName==="PcbReturnCurrentSimulation"&&this.renderError("A PCB return-current simulation cannot contain another simulation."),this.children.some(child=>child.componentName!=="PcbReturnCurrentExcitation")&&this.renderError("A PCB return-current simulation can contain only return-current excitations.");let experiment=this.root.db.simulation_experiment.insert({name:this._parsedProps.name??"PCB return current",experiment_type:"pcb_return_current"});this.simulation_experiment_id=experiment.simulation_experiment_id}updateSimulationRender(){this.simulation_experiment_id&&this.root.db.simulation_experiment.update(this.simulation_experiment_id,{name:this._parsedProps.name??"PCB return current"})}removeSimulationRender(){this.simulation_experiment_id&&(this.root.db.simulation_experiment.delete(this.simulation_experiment_id),this.simulation_experiment_id=null)}},positionToleranceMm=1e-6;function PcbReturnCurrentExcitation_doInitialPcbSimulationRender(excitation){if(excitation.root?.pcbDisabled)return;let{db:db22}=excitation.root,props=excitation._parsedProps,simulation2=excitation.parent;if(simulation2?.componentName!=="PcbReturnCurrentSimulation"){excitation.renderError("A PCB return-current excitation must be directly inside a PCB return-current simulation.");return}if(!simulation2.simulation_experiment_id){excitation.renderError("The PCB return-current simulation has not been declared.");return}let subcircuit=excitation.getSubcircuit(),resolvePcbPort=(selector2,role)=>{let ports=subcircuit.selectAll(selector2).filter(component=>component.componentName==="Port");ports.length!==1&&excitation.renderError(`${role} selector "${selector2}" must identify exactly one physical PCB port.`);let port=ports[0],pcbPort=port?.pcb_port_id?db22.pcb_port.get(port.pcb_port_id):null,hasPhysicalPad=pcbPort&&(db22.pcb_smtpad.list({pcb_port_id:pcbPort.pcb_port_id}).length>0||db22.pcb_plated_hole.list({pcb_port_id:pcbPort.pcb_port_id}).length>0);return(!pcbPort||!hasPhysicalPad)&&excitation.renderError(`${role} selector "${selector2}" needs a physical PCB pad or plated-hole port.`),pcbPort},signalSource=resolvePcbPort(props.source,"Signal source"),signalLoad=resolvePcbPort(props.load,"Signal load"),returnSource=resolvePcbPort(props.returnSource,"Return source (load-side ground)"),returnSink=resolvePcbPort(props.returnSink,"Return sink (driver-side ground)");new Set([signalSource.pcb_port_id,signalLoad.pcb_port_id,returnSource.pcb_port_id,returnSink.pcb_port_id]).size!==4&&excitation.renderError("Signal source, signal load, return source and return sink must be four distinct physical PCB ports.");let groundNets=subcircuit.selectAll(props.ground.startsWith("net.")?"net":props.ground).filter(component=>component.componentName==="Net"&&(!props.ground.startsWith("net.")||component.getPortSelector()===props.ground));(groundNets.length!==1||!groundNets[0].source_net_id)&&excitation.renderError(`Ground selector "${props.ground}" must identify exactly one source net.`);let groundNet=db22.source_net.get(groundNets[0].source_net_id),groundConnectivityKey=groundNet.subcircuit_connectivity_map_key;for(let[pcbPort,selector2]of[[signalSource,props.source],[signalLoad,props.load]])groundConnectivityKey&&db22.source_port.get(pcbPort.source_port_id)?.subcircuit_connectivity_map_key===groundConnectivityKey&&excitation.renderError(`Signal terminal "${selector2}" is electrically connected to ground net "${groundNet.name}".`);for(let[pcbPort,selector2]of[[returnSource,props.returnSource],[returnSink,props.returnSink]]){let sourcePort=db22.source_port.get(pcbPort.source_port_id);(!groundConnectivityKey||sourcePort?.subcircuit_connectivity_map_key!==groundConnectivityKey)&&excitation.renderError(`Return contact "${selector2}" is not electrically connected to ground net "${groundNet.name}".`)}let contact=(pcbPort,selector2,requestedLayer,role)=>{let layers=[...new Set(pcbPort.layers)];!requestedLayer&&layers.length!==1&&excitation.renderError(`${role} "${selector2}" spans multiple layers; specify ${role==="Return source"?"returnSourceLayer":"returnSinkLayer"}.`);let layer=requestedLayer??layers[0];return layers.includes(layer)||excitation.renderError(`${role} "${selector2}" has no physical port on layer "${layer}".`),{contact_type:"pcb_port",pcb_port_id:pcbPort.pcb_port_id,x:pcbPort.x,y:pcbPort.y,layer}},returnSourceContact=contact(returnSource,props.returnSource,props.returnSourceLayer,"Return source"),returnSinkContact=contact(returnSink,props.returnSink,props.returnSinkLayer,"Return sink");for(let[signalPort,referenceContact]of[[signalSource,returnSinkContact],[signalLoad,returnSourceContact]])Math.hypot(signalPort.x-referenceContact.x,signalPort.y-referenceContact.y)<=positionToleranceMm&&signalPort.layers.includes(referenceContact.layer)&&excitation.renderError("A signal terminal and its ground reference must occupy different physical PCB locations on the same layer.");let selectedSourceTraceId;if(props.trace){let traces2=subcircuit.selectAll(props.trace).filter(component=>component.componentName==="Trace");(traces2.length!==1||!traces2[0].source_trace_id)&&excitation.renderError(`Trace selector "${props.trace}" must identify exactly one routed source trace.`),selectedSourceTraceId=traces2[0].source_trace_id}let endpointMatches=(endpoint,pcbPort,end)=>endpoint?.route_type==="wire"&&Math.hypot(endpoint.x-pcbPort.x,endpoint.y-pcbPort.y)<=positionToleranceMm&&pcbPort.layers.includes(endpoint.layer)&&(!endpoint[`${end}_pcb_port_id`]||endpoint[`${end}_pcb_port_id`]===pcbPort.pcb_port_id),traces=db22.pcb_trace.list().filter(pcbTrace=>{if(pcbTrace.subcircuit_id!==subcircuit.subcircuit_id||selectedSourceTraceId&&pcbTrace.source_trace_id!==selectedSourceTraceId)return!1;let sourceTrace=pcbTrace.source_trace_id?db22.source_trace.get(pcbTrace.source_trace_id):null;if(!sourceTrace||sourceTrace.connected_source_port_ids.length!==2||!sourceTrace.connected_source_port_ids.includes(signalSource.source_port_id)||!sourceTrace.connected_source_port_ids.includes(signalLoad.source_port_id))return!1;let first=pcbTrace.route[0],last=pcbTrace.route.at(-1);return endpointMatches(first,signalSource,"start")&&endpointMatches(last,signalLoad,"end")||endpointMatches(first,signalLoad,"start")&&endpointMatches(last,signalSource,"end")});traces.length!==1&&excitation.renderError(`The connection from "${props.source}" to "${props.load}" must have exactly one complete routed PCB trace${props.trace?` selected by "${props.trace}"`:"; use trace to disambiguate multiple routes"}. Split or branched routes are not supported.`);let previousExcitations=db22.simulation_return_current_excitation.list({simulation_experiment_id:simulation2.simulation_experiment_id});previousExcitations.some(previous=>previous.pcb_trace_id===traces[0].pcb_trace_id)&&excitation.renderError("A PCB return-current simulation can excite each signal trace only once. Use separate experiments to compare different currents or directions."),previousExcitations.some(previous=>previous.ground_source_net_id!==groundNet.source_net_id)&&excitation.renderError("All excitations in a PCB return-current simulation must use the same ground net. Use separate experiments for different ground nets.");let inserted=db22.simulation_return_current_excitation.insert({simulation_experiment_id:simulation2.simulation_experiment_id,pcb_trace_id:traces[0].pcb_trace_id,ground_source_net_id:groundNet.source_net_id,current:props.current,return_source:returnSourceContact,return_sink:returnSinkContact,source_port:{signal_pcb_port_id:signalSource.pcb_port_id,reference_pcb_port_id:returnSink.pcb_port_id,reference_layer:returnSinkContact.layer,resistance:props.sourceImpedance},load_port:{signal_pcb_port_id:signalLoad.pcb_port_id,reference_pcb_port_id:returnSource.pcb_port_id,reference_layer:returnSourceContact.layer,resistance:props.loadImpedance}});excitation.simulation_return_current_excitation_id=inserted.simulation_return_current_excitation_id}var PcbReturnCurrentExcitation=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"simulation_return_current_excitation_id",null)}get config(){return{componentName:"PcbReturnCurrentExcitation",zodProps:pcbReturnCurrentExcitationProps}}doInitialPcbSimulationRender(){PcbReturnCurrentExcitation_doInitialPcbSimulationRender(this)}updatePcbSimulationRender(){this.removePcbSimulationRender(),this.doInitialPcbSimulationRender()}removePcbSimulationRender(){this.simulation_return_current_excitation_id&&(this.root.db.simulation_return_current_excitation.delete(this.simulation_return_current_excitation_id),this.simulation_return_current_excitation_id=null)}};function getLabelBounds3(probePosition,labelText,alignment,labelOffset=.3){let labelWidth=Math.max(labelText.length*.1,.3),labelHeightWithPadding=.25+.2,anchorX=probePosition.x,anchorY=probePosition.y,offsetMultiplier=labelOffset+labelWidth/2;alignment.includes("top")?anchorY+=offsetMultiplier:alignment.includes("bottom")&&(anchorY-=offsetMultiplier),alignment.includes("right")?anchorX+=offsetMultiplier:alignment.includes("left")&&(anchorX-=offsetMultiplier);let minX,maxX,minY,maxY;return alignment.includes("left")?(minX=anchorX,maxX=anchorX+labelWidth):alignment.includes("right")?(minX=anchorX-labelWidth,maxX=anchorX):(minX=anchorX-labelWidth/2,maxX=anchorX+labelWidth/2),alignment.includes("top")?(minY=anchorY-labelHeightWithPadding,maxY=anchorY):alignment.includes("bottom")?(minY=anchorY,maxY=anchorY+labelHeightWithPadding):(minY=anchorY-labelHeightWithPadding/2,maxY=anchorY+labelHeightWithPadding/2),{minX,maxX,minY,maxY}}function getElementBounds(elm){let cx22,cy22,w23,h23;if(elm.type==="schematic_component")cx22=elm.center?.x,cy22=elm.center?.y,w23=elm.size?.width,h23=elm.size?.height;else if(elm.type==="schematic_text")cx22=elm.position?.x,cy22=elm.position?.y,w23=(elm.text?.length??0)*.1,h23=.2;else return null;return typeof cx22=="number"&&typeof cy22=="number"&&typeof w23=="number"&&typeof h23=="number"?{minX:cx22-w23/2,maxX:cx22+w23/2,minY:cy22-h23/2,maxY:cy22+h23/2}:null}function getOverlapArea(a23,b23){if(!doBoundsOverlap(a23,b23))return 0;let overlapWidth=Math.min(a23.maxX,b23.maxX)-Math.max(a23.minX,b23.minX),overlapHeight=Math.min(a23.maxY,b23.maxY)-Math.max(a23.minY,b23.minY);return overlapWidth*overlapHeight}function selectBestLabelAlignment({probePosition,labelText,schematicElements,defaultAlignment="top_right"}){let orderedAlignments=[defaultAlignment,...["top_right","top_left","bottom_right","bottom_left","top_center","bottom_center","center_right","center_left"].filter(a23=>a23!==defaultAlignment)],bestAlignment=defaultAlignment,minOverlapArea=1/0;for(let alignment of orderedAlignments){let labelBounds=getLabelBounds3(probePosition,labelText,alignment),totalOverlapArea=0;for(let element2 of schematicElements){let elementBounds=getElementBounds(element2);elementBounds&&(totalOverlapArea+=getOverlapArea(labelBounds,elementBounds))}if(totalOverlapArea===0)return alignment;totalOverlapArea<minOverlapArea&&(minOverlapArea=totalOverlapArea,bestAlignment=alignment)}return bestAlignment}var VoltageProbe=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"simulation_voltage_probe_id",null);__publicField(this,"schematic_voltage_probe_id",null);__publicField(this,"finalProbeName",null);__publicField(this,"color",null)}get config(){return{componentName:"VoltageProbe",zodProps:voltageProbeProps}}doInitialSimulationRender(){let{db:db22}=this.root,{connectsTo,name,referenceTo,color:color32,graphDisplayName,graphCenter,graphVerticalOffset,graphVoltagePerDiv}=this._parsedProps,subcircuit=this.getSubcircuit();if(!subcircuit){this.renderError("VoltageProbe must be inside a subcircuit");return}let targets=Array.isArray(connectsTo)?connectsTo:[connectsTo];if(targets.length!==1){this.renderError("VoltageProbe must connect to exactly one port or net");return}let targetSelector=targets[0],port=subcircuit.selectOne(targetSelector,{type:"port"}),net=port?null:subcircuit.selectOne(targetSelector,{type:"net"});if(net&&net.componentName!=="Net"){this.renderError(`VoltageProbe connection target "${targetSelector}" resolved to a non-net component "${net.componentName}".`);return}if(!port&&!net){this.renderError(`VoltageProbe could not find connection target "${targetSelector}"`);return}let connectedId=port?.source_port_id??net?.source_net_id;if(!connectedId){this.renderError("Could not identify connected source for VoltageProbe");return}let referencePort=null,referenceNet=null;if(referenceTo){let referenceTargets=Array.isArray(referenceTo)?referenceTo:[referenceTo];if(referenceTargets.length!==1){this.renderError("VoltageProbe must reference exactly one port or net");return}let referenceSelector=referenceTargets[0];if(referencePort=subcircuit.selectOne(referenceSelector,{type:"port"}),referenceNet=referencePort?null:subcircuit.selectOne(referenceSelector,{type:"net"}),referenceNet&&referenceNet.componentName!=="Net"){this.renderError(`VoltageProbe reference target "${referenceSelector}" resolved to a non-net component "${referenceNet.componentName}".`);return}if(!referencePort&&!referenceNet){this.renderError(`VoltageProbe could not find reference target "${referenceSelector}"`);return}}this.color=color32??getSimulationColorForId(connectedId);let finalName=name;finalName||(finalName=targets[0].split(" > ").map(s23=>s23.replace(/^\./,"")).join(".")),this.finalProbeName=finalName??null;let{simulation_voltage_probe_id}=db22.simulation_voltage_probe.insert({name:finalName,signal_input_source_port_id:port?.source_port_id??void 0,signal_input_source_net_id:net?.source_net_id??void 0,reference_input_source_port_id:referencePort?.source_port_id??void 0,reference_input_source_net_id:referenceNet?.source_net_id??void 0,subcircuit_id:subcircuit.subcircuit_id||void 0,color:this.color});if(this.simulation_voltage_probe_id=simulation_voltage_probe_id,graphDisplayName!==void 0||graphCenter!==void 0||graphVerticalOffset!==void 0||graphVoltagePerDiv!==void 0){let graphVoltagePerDivValue=parseSimulationGraphValue(graphVoltagePerDiv),graphVerticalOffsetValue=parseSimulationGraphValue(graphVerticalOffset);db22.simulation_oscilloscope_trace.insert({simulation_voltage_probe_id,display_name:graphDisplayName,color:color32??void 0,display_center_value:graphCenter,volts_per_div:graphVoltagePerDivValue,display_center_offset_divs:graphVerticalOffsetValue!==void 0&&graphVoltagePerDivValue!==void 0&&graphVoltagePerDivValue!==0?graphVerticalOffsetValue/graphVoltagePerDivValue:void 0})}}doInitialSchematicReplaceNetLabelsWithSymbols(){if(this.root?.schematicDisabled)return;let{db:db22}=this.root,{connectsTo,name}=this._parsedProps,subcircuit=this.getSubcircuit();if(!subcircuit)return;let targets=Array.isArray(connectsTo)?connectsTo:[connectsTo];if(targets.length!==1)return;let targetSelector=targets[0],port=subcircuit.selectOne(targetSelector,{type:"port"});if(!port||!port.schematic_port_id)return;let position22=port._getGlobalSchematicPositionAfterLayout(),targetTraceId=null;for(let trace of db22.schematic_trace.list()){for(let edge of trace.edges)if(Math.abs(edge.from.x-position22.x)<1e-6&&Math.abs(edge.from.y-position22.y)<1e-6||Math.abs(edge.to.x-position22.x)<1e-6&&Math.abs(edge.to.y-position22.y)<1e-6){targetTraceId=trace.schematic_trace_id;break}if(targetTraceId)break}if(!targetTraceId)return;let probeName=this.finalProbeName,labelAlignment=selectBestLabelAlignment({probePosition:position22,labelText:probeName,schematicElements:[...db22.schematic_component.list(),...db22.schematic_text.list()],defaultAlignment:"top_right"}),schematic_voltage_probe23=db22.schematic_voltage_probe.insert({name:probeName,position:position22,schematic_trace_id:targetTraceId,subcircuit_id:subcircuit.subcircuit_id||void 0,color:this.color??void 0,label_alignment:labelAlignment});this.schematic_voltage_probe_id=schematic_voltage_probe23.schematic_voltage_probe_id}},SpiceModel=class extends PrimitiveComponent{get config(){return{componentName:"SpiceModel",zodProps:spicemodelProps}}doInitialSimulationRender(){if(this.getInheritedProperty("analogSimulationDisabled"))return;let parent=this.parent;if(!parent)return;let parentSourceComponentId=parent.source_component_id;if(!parentSourceComponentId){this._insertSpiceModelError("spicemodel must be attached to a source component.",this._parsedProps);return}let{source,spicePinMapping}=this._parsedProps,subckt=parseSpiceNetlist(source).subckts[0]??null,spicePinNames=subckt?.pins.map(pin=>pin.name);if(!subckt||!spicePinNames||spicePinNames.length===0){this._insertSpiceModelError("spicemodel source must contain a .subckt declaration with a model name and pins.",source);return}let mapping=spicePinMapping??{};for(let spicePinName of Object.keys(mapping))if(!spicePinNames.includes(spicePinName)){this._insertSpiceModelError(`spicePinMapping references SPICE pin "${spicePinName}", but it is not present in .subckt ${subckt.name}.`,mapping);return}let spicePinToSourcePortMap={},seenSourcePortIds=new Set;for(let spicePinName of spicePinNames){let componentPinName=mapping[spicePinName]??spicePinName,matchingPorts=parent.selectAll("port").filter(port=>port instanceof Port&&port.isMatchingAnyOf([componentPinName]));if(matchingPorts.length!==1||!matchingPorts[0].source_port_id){this._insertSpiceModelError(`Could not resolve SPICE pin "${spicePinName}" to exactly one component port using "${componentPinName}".`,mapping);return}let sourcePortId=matchingPorts[0].source_port_id;if(seenSourcePortIds.has(sourcePortId)){this._insertSpiceModelError(`spicePinMapping maps more than one SPICE pin to component port "${componentPinName}".`,mapping);return}seenSourcePortIds.add(sourcePortId),spicePinToSourcePortMap[spicePinName]=sourcePortId}this.root.db.simulation_spice_subcircuit.insert({source_component_id:parentSourceComponentId,spice_pin_to_source_port_map:spicePinToSourcePortMap,subcircuit_source:source})}_insertSpiceModelError(message,propertyValue){this.root.db.source_invalid_component_property_error.insert({source_component_id:this.parent?.source_component_id||"",property_name:"spiceModel",property_value:propertyValue,message,error_type:"source_invalid_component_property_error"})}};function getPcbFlexBoardTransform(primitive){let boardId=primitive._getBoard()?.pcb_board_id,board=boardId?primitive.root.db.pcb_board.get(boardId):null;if(!board)throw new Error(`${primitive.componentName} must be inside a board`);let transform22=compose3(translate8(-board.center.x,-board.center.y),primitive._computePcbGlobalTransformBeforeLayout());return{board,transform:transform22}}var PcbBend=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"pcb_bend_id",null);__publicField(this,"tearReliefCutoutIds",[])}get config(){return{componentName:"PcbBend",zodProps:pcbBendProps}}doInitialPcbFlexRender(){if(this.root?.pcbDisabled)return;let{db:db22}=this.root,props=this._parsedProps,{board,transform:transform22}=getPcbFlexBoardTransform(this),bend=db22.pcb_bend.insert({pcb_board_id:board.pcb_board_id,pcb_group_id:this.getGroup()?.pcb_group_id??void 0,subcircuit_id:this.getSubcircuit().subcircuit_id??void 0,name:props.name,start:applyToPoint3(transform22,{x:props.x1,y:props.y1}),end:applyToPoint3(transform22,{x:props.x2,y:props.y2}),bend_angle:props.bendAngle,bend_radius:props.bendRadius,bend_side:props.bendSide});if(this.pcb_bend_id=bend.pcb_bend_id,props.tearReliefRadius!==void 0)for(let endpoint of[bend.start,bend.end]){let cutout=db22.pcb_cutout.insert({shape:"circle",center:{x:endpoint.x+board.center.x,y:endpoint.y+board.center.y},radius:props.tearReliefRadius,pcb_board_id:board.pcb_board_id,pcb_group_id:bend.pcb_group_id,subcircuit_id:bend.subcircuit_id});this.tearReliefCutoutIds.push(cutout.pcb_cutout_id)}}removePcbFlexRender(){for(let cutoutId of this.tearReliefCutoutIds)this.root.db.pcb_cutout.delete(cutoutId);this.tearReliefCutoutIds=[],this.pcb_bend_id&&(this.root.db.pcb_bend.delete(this.pcb_bend_id),this.pcb_bend_id=null)}},PcbStiffener=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"pcb_stiffener_id",null)}get config(){return{componentName:"PcbStiffener",zodProps:pcbStiffenerProps}}doInitialPcbFlexRender(){if(this.root?.pcbDisabled)return;let{db:db22}=this.root,props=this._parsedProps,{board,transform:transform22}=getPcbFlexBoardTransform(this),base={pcb_board_id:board.pcb_board_id,pcb_group_id:this.getGroup()?.pcb_group_id??void 0,subcircuit_id:this.getSubcircuit().subcircuit_id??void 0,name:props.name,layer:props.layer,material:props.material,thickness:props.thickness,adhesive_thickness:props.adhesiveThickness},geometry=props.shape==="rect"?{shape:"rect",center:applyToPoint3(transform22,{x:0,y:0}),rotation:decomposeTSR2(transform22).rotation.angle*180/Math.PI,width:props.width,height:props.height}:{shape:"polygon",outline:props.outline.map(point12=>applyToPoint3(transform22,point12))};this.pcb_stiffener_id=db22.pcb_stiffener.insert({...base,...geometry}).pcb_stiffener_id}doRemovePcbFlexRender(){this.pcb_stiffener_id&&(this.root.db.pcb_stiffener.delete(this.pcb_stiffener_id),this.pcb_stiffener_id=null)}},getAssemblyEulerAngles=transform22=>{let y23=Math.asin(Math.max(-1,Math.min(1,-transform22[2])));return(Math.abs(Math.cos(y23))>1e-8?[Math.atan2(transform22[6],transform22[10]),y23,Math.atan2(transform22[1],transform22[0])]:[0,y23,Math.atan2(-transform22[4],transform22[5])]).map(angle3=>angle3===0?0:angle3)},AssemblyPrintedPart=class extends AssemblyComponent{constructor(){super(...arguments);__publicField(this,"isAssemblyDeviceContainer",!0);__publicField(this,"compiledJscadInput");__publicField(this,"compiledJscad")}get config(){return{componentName:"AssemblyPrintedPart",zodProps:assemblyPrintedPartProps}}get printedPartPlan(){if(this._parsedProps.jscad){if(!this.compiledJscad||this.compiledJscadInput!==this._parsedProps.jscad){let{geometry,referencePlanes}=(0,import_jscad_planner9.resolveReferencePlanes)(renderToJscadPlan(this._parsedProps.jscad));if(!geometry)throw new Error(`assembly.printedpart "${this.name}" needs solid geometry in addition to references`);this.compiledJscad={geometry,referencePlanes},this.compiledJscadInput=this._parsedProps.jscad}return this.compiledJscad}}doInitialReactSubtreesRender(){(0,import_react13.isValidElement)(this.props.cadModel)&&this.add(createInstanceFromReactElement(this.props.cadModel))}doInitialSourceRender(){this.printedPartPlan,getPartReferenceSurfaces(this),this.source_component_id=this.root.db.source_component.insert({ftype:"printedpart",name:this.name,color:this._parsedProps.color,material:this._parsedProps.material}).source_component_id}doInitialCadModelRender(){if(!this.root||this.root.pcbDisabled||!this.source_component_id)return;renderPartReferenceSurfaces(this);let plan=this.printedPartPlan;if(!plan){let model110=resolveAssemblyModel(this._parsedProps)??this._parsedProps.cadModel,placement=resolveAssemblyPlacement(this);if(!model110||typeof model110=="object"&&"type"in model110)return;if(typeof model110=="object"&&"jscad"in model110){let{geometry}=(0,import_jscad_planner9.resolveReferencePlanes)(model110.jscad);if(!geometry)throw new Error(`assembly.printedpart "${this.name}" needs solid geometry in addition to references`);model110={...model110,jscad:geometry}}this.cad_component_id=renderAssemblyCadModel(this,model110,placement);return}let{transforms:transforms3,subcircuitId}=resolvePrintedPartMounts(this),transform22=transforms3.get(this),angles=getAssemblyEulerAngles(transform22);this.cad_component_id=renderAssemblyCadModel(this,{jscad:{type:"rotate",angles,shape:plan.geometry}},{position:{x:transform22[12],y:transform22[13],z:transform22[14]},pcbRotation:0,layer:"top",subcircuit_id:subcircuitId})}},bulletDiameterSchema2=external_exports.union([external_exports.literal(2),external_exports.literal(3),external_exports.literal(3.5),external_exports.literal(4),external_exports.literal(5),external_exports.literal(5.5),external_exports.literal(6),external_exports.literal(8)]),bulletGenderSchema2=external_exports.enum(["male","female"]);function getBulletConnector({diameter,gender,pinCount=1,pitch=diameter+2}){let contactDepth=diameter*2,bodyDiameter=diameter+(gender==="female"?1:.6);return{kind:gender==="male"?"bullet_male":"bullet_female",diameter,contactDepth,pinCount,pitch,bodyWidth:bodyDiameter+(pinCount-1)*pitch,bodyHeight:bodyDiameter,bodyDepth:contactDepth+diameter*1.5}}var cableStandardSchema2=external_exports.enum(["usb_c","jst_sh","jst_ph","us_mains","bullet","adaptercable"]),dimension2=external_exports.number().finite().positive(),color4=external_exports.string().regex(/^#[0-9a-fA-F]{6}$/),body2={bodyWidth:dimension2,bodyHeight:dimension2,bodyDepth:dimension2},cableConnectorSchema2=external_exports.discriminatedUnion("kind",[external_exports.object({kind:external_exports.literal("bullet_male"),...body2,diameter:bulletDiameterSchema2,pinCount:external_exports.number().int().min(1).max(16).default(1),pitch:dimension2,contactDepth:dimension2}).strict(),external_exports.object({kind:external_exports.literal("bullet_female"),...body2,diameter:bulletDiameterSchema2,pinCount:external_exports.number().int().min(1).max(16).default(1),pitch:dimension2,contactDepth:dimension2}).strict(),external_exports.object({kind:external_exports.literal("usb_c_plug"),...body2,shellWidth:dimension2,shellHeight:dimension2,shellDepth:dimension2}).strict(),external_exports.object({kind:external_exports.literal("jst_sh_housing"),...body2,pinCount:external_exports.number().int().min(2).max(15),pitch:external_exports.literal(1)}).strict(),external_exports.object({kind:external_exports.literal("jst_ph_housing"),...body2,pinCount:external_exports.number().int().min(2).max(16),pitch:external_exports.literal(2)}).strict(),external_exports.object({kind:external_exports.literal("nema_5_15p"),...body2}).strict(),external_exports.object({kind:external_exports.literal("iec_c13"),...body2}).strict()]),cableCrossSectionSchema2=external_exports.discriminatedUnion("kind",[external_exports.object({kind:external_exports.literal("round_jacket"),diameter:dimension2,color:color4}).strict(),external_exports.object({kind:external_exports.literal("wire_bundle"),wires:external_exports.array(external_exports.object({diameter:dimension2,color:color4}).strict()).min(2),wirePitch:dimension2}).strict()]),cableDefinitionSchema2=external_exports.object({standard:cableStandardSchema2,connectorA:cableConnectorSchema2,connectorB:cableConnectorSchema2,crossSection:cableCrossSectionSchema2}).strict().superRefine((cable,ctx)=>{let{connectorA,connectorB,crossSection}=cable,expected={usb_c:["usb_c_plug","usb_c_plug"],jst_sh:["jst_sh_housing","jst_sh_housing"],jst_ph:["jst_ph_housing","jst_ph_housing"],us_mains:["nema_5_15p","iec_c13"],bullet:[connectorA.kind,connectorB.kind],adaptercable:[connectorA.kind,connectorB.kind]}[cable.standard];if((connectorA.kind!==expected[0]||connectorB.kind!==expected[1])&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"Connector kinds must match the cable standard"}),cable.standard==="bullet"){(!("diameter"in connectorA)||!("diameter"in connectorB)||connectorA.diameter!==connectorB.diameter||"pinCount"in connectorA&&"pinCount"in connectorB&&connectorA.pinCount!==connectorB.pinCount)&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"Bullet connectors require supported nominal diameters and matching contact counts"}),"pinCount"in connectorA&&(connectorA.pinCount===1&&crossSection.kind!=="round_jacket"||connectorA.pinCount>1&&crossSection.kind!=="wire_bundle")&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"Bullet cables require one insulated wire per contact"});for(let connector of[connectorA,connectorB])"diameter"in connector&&(connector.bodyHeight<=connector.diameter||connector.pitch<connector.bodyHeight||Math.abs(connector.bodyWidth-(connector.bodyHeight+(connector.pinCount-1)*connector.pitch))>1e-6||crossSection.kind==="wire_bundle"&&(crossSection.wirePitch!==connector.pitch||crossSection.wires.some(wire=>wire.diameter>connector.bodyHeight))||connector.contactDepth>=connector.bodyDepth||crossSection.kind==="round_jacket"&&crossSection.diameter>connector.bodyHeight)&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"Bullet contact, body, and wire dimensions must fit"})}else cable.standard!=="adaptercable"&&("diameter"in connectorA||"diameter"in connectorB)&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"Bullet connectors require the bullet cable standard"});if(cable.standard==="adaptercable"){"pinCount"in connectorA&&"pinCount"in connectorB&&connectorA.pinCount!==connectorB.pinCount&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"Adapter connector pin counts must match"}),"pinCount"in connectorA&&"pinCount"in connectorB&&connectorA.pinCount>1&&crossSection.kind!=="wire_bundle"&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"Adapter cables require one wire per explicit contact"});for(let connector of[connectorA,connectorB])"diameter"in connector&&(connector.bodyHeight<=connector.diameter||connector.pitch<connector.bodyHeight||Math.abs(connector.bodyWidth-(connector.bodyHeight+(connector.pinCount-1)*connector.pitch))>1e-6||connector.contactDepth>=connector.bodyDepth||connector.pinCount===1&&(crossSection.kind!=="round_jacket"||crossSection.diameter>connector.bodyHeight)||connector.pinCount>1&&(crossSection.kind!=="wire_bundle"||crossSection.wires.some(wire=>wire.diameter>connector.bodyHeight)))&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"Bullet contact, body, and wire dimensions must fit"})}if(crossSection.kind==="wire_bundle"){for(let connector of[connectorA,connectorB])(!("pinCount"in connector)||connector.pinCount!==crossSection.wires.length)&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"Bundle wire count must match each connector pin count"}),"pitch"in connector&&crossSection.wires.some(wire=>wire.diameter>connector.pitch)&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"Insulated wires must fit each connector pitch"});crossSection.wires.some(wire=>wire.diameter>crossSection.wirePitch)&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"Bundle wires must not overlap in the cross section"})}else(cable.standard==="jst_sh"||cable.standard==="jst_ph")&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"JST cables require a wire bundle"})}),adapterCableInputSchema2=external_exports.object({standard:external_exports.literal("adaptercable"),connectorA:cableConnectorSchema2,connectorB:cableConnectorSchema2,crossSection:cableCrossSectionSchema2.optional()}).strict(),color22=external_exports.string().regex(/^#[0-9a-fA-F]{6}$/),jacket2={jacketDiameter:external_exports.number().finite().positive().default(4),color:color22.default("#263449")},cableInputSchema2=external_exports.discriminatedUnion("standard",[external_exports.object({standard:external_exports.literal("bullet"),diameter:bulletDiameterSchema2,pinCount:external_exports.number().int().min(1).max(16).default(1),genderA:bulletGenderSchema2.default("male"),genderB:bulletGenderSchema2.default("female"),wireDiameter:external_exports.number().finite().positive().default(2),color:color22.default("#263449")}).strict(),external_exports.object({standard:external_exports.literal("usb_c"),...jacket2}).strict(),external_exports.object({standard:external_exports.literal("jst_sh"),pinCount:external_exports.number().int().min(2).max(15).default(4),wireDiameter:external_exports.number().finite().min(.4).max(.8).default(.6)}).strict(),external_exports.object({standard:external_exports.literal("jst_ph"),pinCount:external_exports.number().int().min(2).max(16).default(2),wireDiameter:external_exports.number().finite().min(.8).max(1.5).default(1.2)}).strict(),external_exports.object({standard:external_exports.literal("us_mains"),...jacket2,jacketDiameter:jacket2.jacketDiameter.default(6.2)}).strict(),adapterCableInputSchema2]),wireColors=["#df4049","#263449","#e1b13c","#347dc9","#27a782","#af62bd"];function getAdapterCableDefinition(input2){let cable=adapterCableInputSchema2.parse({standard:"adaptercable",...input2}),{connectorA,connectorB}=cable,bundled="pinCount"in connectorA&&"pinCount"in connectorB&&connectorA.pinCount>1,pitches=[connectorA,connectorB].flatMap(connector=>"pitch"in connector?[connector.pitch]:[]),wireDiameter=Math.min(2,...pitches.map(pitch=>pitch*.6));return cableDefinitionSchema2.parse({...cable,crossSection:cable.crossSection??(bundled?{kind:"wire_bundle",wirePitch:Math.max(...pitches),wires:Array.from({length:connectorA.pinCount},(_23,index2)=>({diameter:wireDiameter,color:wireColors[index2%wireColors.length]}))}:{kind:"round_jacket",diameter:Math.min(4,connectorA.bodyHeight,connectorB.bodyHeight,...pitches.map(pitch=>Math.min(2,pitch*.6))),color:"#263449"})})}var wireColors2=["#df4049","#263449","#e1b13c","#347dc9","#27a782","#af62bd"];function getCableDefinition(cableInput){let cable=cableInputSchema2.parse(cableInput);if(cable.standard==="adaptercable")return getAdapterCableDefinition(cable);if(cable.standard==="bullet"){let pitch=cable.diameter+2;return cableDefinitionSchema2.parse({standard:"bullet",connectorA:getBulletConnector({diameter:cable.diameter,gender:cable.genderA,pinCount:cable.pinCount,pitch}),connectorB:getBulletConnector({diameter:cable.diameter,gender:cable.genderB,pinCount:cable.pinCount,pitch}),crossSection:cable.pinCount===1?{kind:"round_jacket",diameter:cable.wireDiameter,color:cable.color}:{kind:"wire_bundle",wirePitch:pitch,wires:Array.from({length:cable.pinCount},(_23,index2)=>({diameter:cable.wireDiameter,color:wireColors2[index2%wireColors2.length]}))}})}if(cable.standard==="usb_c"){let connector2={kind:"usb_c_plug",bodyWidth:12,bodyHeight:6,bodyDepth:18,shellWidth:8.25,shellHeight:2.4,shellDepth:6.5};return cableDefinitionSchema2.parse({standard:cable.standard,connectorA:connector2,connectorB:{...connector2},crossSection:{kind:"round_jacket",diameter:cable.jacketDiameter,color:cable.color}})}if(cable.standard==="us_mains")return cableDefinitionSchema2.parse({standard:cable.standard,connectorA:{kind:"nema_5_15p",bodyWidth:32,bodyHeight:28,bodyDepth:35},connectorB:{kind:"iec_c13",bodyWidth:24,bodyHeight:18,bodyDepth:30},crossSection:{kind:"round_jacket",diameter:cable.jacketDiameter,color:cable.color}});let isSh=cable.standard==="jst_sh",connector={kind:isSh?"jst_sh_housing":"jst_ph_housing",pinCount:cable.pinCount,pitch:isSh?1:2,bodyWidth:isSh?cable.pinCount+1:(cable.pinCount-1)*2+3.8,bodyHeight:isSh?2.8:4.5,bodyDepth:isSh?5:6.85};return cableDefinitionSchema2.parse({standard:cable.standard,connectorA:connector,connectorB:{...connector},crossSection:{kind:"wire_bundle",wirePitch:connector.pitch,wires:Array.from({length:cable.pinCount},(_23,index2)=>({diameter:cable.wireDiameter,color:wireColors2[index2%wireColors2.length]}))}})}function parseConnectorString(connectorString){let name=connectorString.trim().toLowerCase(),bullet=/^bullet([1-9][0-9]*)?_(.+)$/.exec(name);if(bullet){let diameter,gender,seen=new Set;for(let parameter of bullet[2].split("_")){let match2=/^d([0-9]+(?:\.[0-9]+)?)mm$/.exec(parameter)??/^g(male|female)$/.exec(parameter),key=parameter[0];if(!match2||seen.has(key))throw new Error(`Invalid or duplicate connector parameter: "${parameter}"`);seen.add(key),key==="d"?diameter=Number(match2[1]):gender=match2[1]}if(diameter===void 0||gender===void 0)throw new Error("Bullet connector strings require dNmm and gmale or gfemale");return getCableDefinition({standard:"bullet",diameter:bulletDiameterSchema2.parse(diameter),pinCount:bullet[1]?Number(bullet[1]):1,genderA:gender}).connectorA}let jst2=/^(jst_sh|jst_ph)(?:_pins([0-9]+))?$/.exec(name);if(jst2)return getCableDefinition({standard:jst2[1],...jst2[2]?{pinCount:Number(jst2[2])}:{}}).connectorA;if(name==="usb_c")return getCableDefinition({standard:"usb_c"}).connectorA;if(name==="nema_5_15p")return getCableDefinition({standard:"us_mains"}).connectorA;if(name==="iec_c13")return getCableDefinition({standard:"us_mains"}).connectorB;throw new Error(`Unsupported connector string: "${connectorString}"`)}function parseCableString2(cableString){let cableName=cableString.trim().toLowerCase();if(cableName.startsWith("adaptercable")){let adapter2=/^adaptercable_(a|b)\(([^()]+)\)_(a|b)\(([^()]+)\)$/.exec(cableName);if(!adapter2||adapter2[1]===adapter2[3])throw new Error("Adapter cables require exactly one named a(CONNECTOR) and b(CONNECTOR)");let first=parseConnectorString(adapter2[2]),second=parseConnectorString(adapter2[4]);return getAdapterCableDefinition({connectorA:adapter2[1]==="a"?first:second,connectorB:adapter2[1]==="b"?first:second})}if(cableName==="usb_c"||cableName==="us_mains")return getCableDefinition({standard:cableName});let bulletMatch=/^bullet([1-9][0-9]*)?_(.+)$/.exec(cableName);if(bulletMatch){let diameter,genderA,genderB,seen=new Set;for(let parameter of bulletMatch[2].split("_")){let match2=/^d([0-9]+(?:\.[0-9]+)?)mm$/.exec(parameter)??/^(a|b)(male|female)$/.exec(parameter),key=parameter[0];if(!match2||seen.has(key))throw new Error(`Invalid or duplicate bullet parameter: "${parameter}"`);seen.add(key),key==="d"?diameter=Number(match2[1]):key==="a"?genderA=match2[2]:genderB=match2[2]}if(diameter===void 0)throw new Error("Bullet cables require dNmm");return getCableDefinition({standard:"bullet",diameter:bulletDiameterSchema2.parse(diameter),pinCount:bulletMatch[1]?Number(bulletMatch[1]):1,genderA:genderA??"male",genderB:genderB??"female"})}let jstMatch=/^(jst_sh|jst_ph)(?:_pins([0-9]+))?$/.exec(cableName);if(jstMatch)return getCableDefinition({standard:jstMatch[1],...jstMatch[2]?{pinCount:Number(jstMatch[2])}:{}});throw new Error(`Unsupported cable string: "${cableString}". Expected usb_c, jst_sh[_pinsN], jst_ph[_pinsN], us_mains, bullet[CONTACTS]_dNmm[_amale][_bfemale], or adaptercable_a(CONNECTOR)_b(CONNECTOR).`)}function getConnectorPins(cable,connector){let db22=cable.root.db;return db22.source_port.list().flatMap(sourcePort=>{if(sourcePort.source_component_id!==connector.source_component_id)return[];let pcbPort=db22.pcb_port.list().find(port=>port.source_port_id===sourcePort.source_port_id&&port.pcb_component_id===connector.pcb_component_id);if(!pcbPort)return[];let hint=[sourcePort.name,...sourcePort.port_hints??[]].find(name=>/^(?:pin)?\d+$/.test(name)),pin=sourcePort.pin_number??(hint?Number(hint.replace(/^pin/,"")):void 0);return[{position:pcbPort,pin}]})}function resolveAssemblyCableContactRowCenter(cable,connector,outward,rowOffset){let pins=getConnectorPins(cable,connector),first=pins.find(({pin})=>pin===1)?.position;if(!first||pins.length<2)return;let center2=pins.reduce((sum,{position:position22})=>({x:sum.x+position22.x/pins.length,y:sum.y+position22.y/pins.length}),{x:0,y:0}),row=vec3_exports.normalize(vec3_exports.create(),[center2.x-first.x,center2.y-first.y,0]),towardHoldDowns=vec3_exports.cross(vec3_exports.create(),[outward.x,outward.y,outward.z],row);return{x:center2.x+towardHoldDowns[0]*rowOffset,y:center2.y+towardHoldDowns[1]*rowOffset}}function resolveAssemblyCablePin1Position(cable,connector,matingCenter,outward){let pins=getConnectorPins(cable,connector),pin1=pins.find(({pin})=>pin===1)?.position;if(!pin1||pins.length<2)return;let center2=pins.reduce((sum,{position:position22})=>({x:sum.x+position22.x/pins.length,y:sum.y+position22.y/pins.length}),{x:0,y:0}),offset3=vec3_exports.fromValues(pin1.x-center2.x,pin1.y-center2.y,0),axis=vec3_exports.normalize(vec3_exports.create(),[outward.x,outward.y,outward.z]);if(vec3_exports.scaleAndAdd(offset3,offset3,axis,-vec3_exports.dot(offset3,axis)),!(vec3_exports.length(offset3)<1e-6))return{x:matingCenter.x+offset3[0],y:matingCenter.y+offset3[1],z:matingCenter.z+offset3[2]}}function resolveAssemblyCableEndpoint(cable,selector2,cableConnector){let scoped=getComponentsInAssemblyScope(cable),motorReference=selector2.match(/^(.+)\.wireside$/);if(motorReference){let motors=scoped.filter(part=>part.componentName==="AssemblyMotor"&&part.name===motorReference[1]);if(motors.length!==1)throw new Error(`assembly.cable "${cable.name}" endpoint "${selector2}" must match exactly one motor in its assembly device`);let motor=motors[0],motorConnector=getJstMotorConnector2(motor.motorModel.wireConnection);if(!motorConnector)throw new Error(`assembly.cable "${cable.name}" requires motor "${motor.name}" to have a JST PH or SH wireConnection, e.g. "jst4_ph" or "jst4_sh", for its connector endpoint`);let faceMount=resolveMotorFaceMount(motor),placement=faceMount?{position:faceMount.position,pcbRotation:0,layer:"top"}:resolveAssemblyMotorPlacement(motor),offset3=faceMount?.rotation??resolveAssemblyMotorRotation(motor,placement),orientation32=mat4_exports.create(),bottom=placement.layer==="bottom";mat4_exports.rotateX(orientation32,orientation32,offset3.x*Math.PI/180),mat4_exports.rotateY(orientation32,orientation32,(offset3.y+(bottom?180:0))*Math.PI/180),mat4_exports.rotateZ(orientation32,orientation32,(bottom?-1:1)*(placement.pcbRotation+offset3.z)*Math.PI/180);let reference4=motor.motorReferencePoints.wireside,direction22=vec3_exports.transformMat4(vec3_exports.create(),[reference4.direction.x,reference4.direction.y,reference4.direction.z],orientation32),point12=vec3_exports.transformMat4(vec3_exports.create(),[reference4.position.x,reference4.position.y,reference4.position.z+motorConnector.contactOffsetZ],orientation32),halfPinSpan=(motorConnector.pinCount-1)*motorConnector.pitch/2,pin1Offset=vec3_exports.transformMat4(vec3_exports.create(),[reference4.direction.y*halfPinSpan,-reference4.direction.x*halfPinSpan,0],orientation32),tipDepth=motorConnector.matingDepth-motorConnector.plugInsertionDepth,board2;if(cable._parsedProps.waypoints?.length){let boardAncestor=motor.parent,subcircuitId=faceMount?.subcircuit_id??placement.subcircuit_id;if(subcircuitId){let mountedSubcircuit=scoped.find(part=>part.isSubcircuit&&part.getSubcircuit().subcircuit_id===subcircuitId);if(!mountedSubcircuit)throw new Error(`assembly.cable "${cable.name}" motor "${motor.name}" mounting subcircuit is not in its assembly device`);boardAncestor=mountedSubcircuit}for(;boardAncestor&&boardAncestor.componentName!=="Board"&&boardAncestor.componentName!=="MountedBoard";)boardAncestor=boardAncestor.parent;board2=boardAncestor?._getBoard()}return{sourceComponentId:motor.source_component_id,board:board2,position:{x:point12[0]+placement.position.x+direction22[0]*tipDepth,y:point12[1]+placement.position.y+direction22[1]*tipDepth,z:point12[2]+placement.position.z+direction22[2]*tipDepth},pin1Position:{x:point12[0]+placement.position.x+direction22[0]*tipDepth+pin1Offset[0],y:point12[1]+placement.position.y+direction22[1]*tipDepth+pin1Offset[1],z:point12[2]+placement.position.z+direction22[2]*tipDepth+pin1Offset[2]},direction:{x:direction22[0],y:direction22[1],z:direction22[2]},cableInput:{standard:motorConnector.standard,pinCount:motorConnector.pinCount}}}let scope=getAssemblyScope(cable),matches=selectAll(preprocessSelector(selector2,cable),scope,{adapter:cssSelectPrimitiveComponentAdapter}).filter(part=>scoped.includes(part));if(matches.length!==1)throw new Error(`assembly.cable "${cable.name}" endpoint "${selector2}" matched ${matches.length} components; expected exactly one in its assembly device`);let connector=matches[0];if(!(connector instanceof NormalComponent)||connector.componentName!=="Connector"||!connector.pcb_component_id||!connector.source_component_id)throw new Error(`assembly.cable "${cable.name}" endpoint "${selector2}" must name a PCB connector or MOTOR.wireside`);let props=connector._parsedProps;if(!cableConnector&&props.standard!=="usb_c"&&props.standard!=="jst_sh"&&props.standard!=="jst_ph")throw new Error(`assembly.cable "${cable.name}" cannot infer endpoint "${selector2}"; use a connector with standard="usb_c", "jst_sh", or "jst_ph"`);let pcb=cable.root.db.pcb_component.get(connector.pcb_component_id),board=connector._getBoard(),layer=pcb.layer==="bottom"?"bottom":"top",inferredCenter=pcb.cable_insertion_center??pcb.center,inferredDirection=vec3_exports.normalize(vec3_exports.create(),[inferredCenter.x-pcb.center.x,inferredCenter.y-pcb.center.y,0]),direction4=connector._getPcbComponentInsertionAxisDirection(layer,pcb.rotation)??(props.standard==="usb_c"&&vec3_exports.length(inferredDirection)>0?{x:inferredDirection[0],y:inferredDirection[1],z:0}:{x:0,y:0,z:layer==="bottom"?-1:1}),jstProfile=props.standard==="jst_ph"||props.standard==="jst_sh"?getJstMotorConnector2(`jst-${props.standard==="jst_ph"?"ph":"sh"}-${props.pinCount}`):void 0,center2=Math.abs(direction4.z)>.5?jstProfile&&resolveAssemblyCableContactRowCenter(cable,connector,direction4,jstProfile.pcbContactRowOffset)||pcb.center:inferredCenter,sign=layer==="bottom"?-1:1,height10=!props.standard&&cableConnector?Math.abs(direction4.z)>.5?cableConnector.bodyDepth:cableConnector.bodyHeight/2:Math.abs(direction4.z)>.5?jstProfile?jstProfile.matingDepth-jstProfile.plugInsertionDepth:1.5:props.standard==="usb_c"?1.5:props.standard==="jst_sh"?1.4:2.25,position22={x:center2.x,y:center2.y,z:sign*(board.boardThickness/2+height10)};return{sourceComponentId:connector.source_component_id,board,position:position22,pin1Position:resolveAssemblyCablePin1Position(cable,connector,position22,direction4),direction:direction4,cableInput:props.standard==="usb_c"?{standard:"usb_c"}:props.standard==="jst_sh"||props.standard==="jst_ph"?{standard:props.standard,pinCount:props.pinCount}:void 0}}function inferAssemblyCablePath({from,to:to3,fromDirection,toDirection}){let distance29=Math.hypot(to3.x-from.x,to3.y-from.y,to3.z-from.z);if(distance29<1e-6)throw new Error("Cable wire exits must be at different positions");let chord=vec3_exports.fromValues(to3.x-from.x,to3.y-from.y,to3.z-from.z),routeNormal=vec3_exports.cross(vec3_exports.create(),chord,[fromDirection.x,fromDirection.y,fromDirection.z]);vec3_exports.length(routeNormal)<1e-6&&vec3_exports.cross(routeNormal,chord,Math.abs(chord[2])/distance29>.95?[0,1,0]:[0,0,1]);let archDirection=vec3_exports.normalize(vec3_exports.create(),vec3_exports.cross(vec3_exports.create(),routeNormal,chord)),archSide=from.z<0&&to3.z<0?-1:1;archDirection[2]*archSide<0&&vec3_exports.scale(archDirection,archDirection,-1);let clearance=Math.min(25,Math.max(8,distance29/3)),controlA={x:from.x+fromDirection.x*clearance,y:from.y+fromDirection.y*clearance,z:from.z+fromDirection.z*clearance},controlB={x:to3.x+toDirection.x*clearance,y:to3.y+toDirection.y*clearance,z:to3.z+toDirection.z*clearance},path=[from,{x:from.x+fromDirection.x*.1,y:from.y+fromDirection.y*.1,z:from.z+fromDirection.z*.1}];for(let i23=1;i23<48;i23++){let t48=i23/48,u23=1-t48,arch=Math.sin(Math.PI*t48)**2*Math.min(12,distance29*.15);path.push({x:u23**3*from.x+3*u23**2*t48*controlA.x+3*u23*t48**2*controlB.x+t48**3*to3.x+archDirection[0]*arch,y:u23**3*from.y+3*u23**2*t48*controlA.y+3*u23*t48**2*controlB.y+t48**3*to3.y+archDirection[1]*arch,z:u23**3*from.z+3*u23**2*t48*controlA.z+3*u23*t48**2*controlB.z+t48**3*to3.z+archDirection[2]*arch})}return path.push({x:to3.x+toDirection.x*.1,y:to3.y+toDirection.y*.1,z:to3.z+toDirection.z*.1},to3),path}var CONNECTOR_TANGENT_LENGTH_MM=.1,MIN_SEGMENT_LENGTH_MM=1e-6,MIN_TANGENT_LENGTH=1e-6,BEZIER_HANDLE_LENGTH_RATIO=1/3,CURVE_SAMPLES_PER_SPAN=12;function resolveAuthoredAssemblyCablePath({cable,from,to:to3,fromExit,toExit,waypoints}){let{waypointAnchor,waypointAxisOrientation}=cable._parsedProps,anchor3=from.position;waypointAnchor==="end"&&(anchor3=to3.position);let board=from.board;if(waypointAxisOrientation==="board_at_end"&&(board=to3.board),!board){let endpoint=cable._parsedProps.from;throw waypointAxisOrientation==="board_at_end"&&(endpoint=cable._parsedProps.to),new Error(`assembly.cable "${cable.name}" endpoint "${endpoint}" has no board for waypointAxisOrientation="${waypointAxisOrientation}"`)}let boardToWorld={...board._computePcbGlobalTransformBeforeLayout(),e:0,f:0},fromTangent=vec3_exports.scaleAndAdd(vec3_exports.create(),[fromExit.x,fromExit.y,fromExit.z],[from.direction.x,from.direction.y,from.direction.z],CONNECTOR_TANGENT_LENGTH_MM),toTangent=vec3_exports.scaleAndAdd(vec3_exports.create(),[toExit.x,toExit.y,toExit.z],[to3.direction.x,to3.direction.y,to3.direction.z],CONNECTOR_TANGENT_LENGTH_MM),path=[fromExit,{x:fromTangent[0],y:fromTangent[1],z:fromTangent[2]},...waypoints.map(waypoint=>{let offset3=applyToPoint3(boardToWorld,waypoint);return{x:anchor3.x+offset3.x,y:anchor3.y+offset3.y,z:anchor3.z+waypoint.z}}),{x:toTangent[0],y:toTangent[1],z:toTangent[2]},toExit],directions22=[],segmentLengths=[],previousDirection;for(let vertex=1;vertex<path.length;vertex++){let previous=path[vertex-1],current23=path[vertex],direction4=vec3_exports.subtract([0,0,0],[current23.x,current23.y,current23.z],[previous.x,previous.y,previous.z]),segmentLength=vec3_exports.length(direction4);if(segmentLength<MIN_SEGMENT_LENGTH_MM)throw new Error(`assembly.cable "${cable.name}" waypoints must leave distinct consecutive path points, including connector exits`);if(vec3_exports.normalize(direction4,direction4),previousDirection&&vec3_exports.length(vec3_exports.add([0,0,0],previousDirection,direction4))<MIN_TANGENT_LENGTH)throw new Error(`assembly.cable "${cable.name}" waypoints must not reverse direction at a path point`);directions22.push(direction4),segmentLengths.push(segmentLength),previousDirection=direction4}let tangents=[directions22[0]];for(let vertex=2;vertex<path.length-2;vertex++){let tangent=vec3_exports.add([0,0,0],directions22[vertex-1],directions22[vertex]);vec3_exports.normalize(tangent,tangent),tangents.push(tangent)}tangents.push(directions22.at(-1));let smoothPath=[path[0],path[1]];for(let vertex=1;vertex<path.length-2;vertex++){let start=path[vertex],end=path[vertex+1],startPoint=[start.x,start.y,start.z],endPoint=[end.x,end.y,end.z],handleLength=segmentLengths[vertex]*BEZIER_HANDLE_LENGTH_RATIO,controlA=vec3_exports.scaleAndAdd([0,0,0],startPoint,tangents[vertex-1],handleLength),controlB=vec3_exports.scaleAndAdd([0,0,0],endPoint,tangents[vertex],-handleLength);for(let sample=1;sample<CURVE_SAMPLES_PER_SPAN;sample++){let point12=vec3_exports.bezier([0,0,0],startPoint,controlA,controlB,endPoint,sample/CURVE_SAMPLES_PER_SPAN);smoothPath.push({x:point12[0],y:point12[1],z:point12[2]})}smoothPath.push(end)}smoothPath.push(path.at(-1));let validatedPath=cad_cable.shape.path.safeParse(smoothPath);if(!validatedPath.success)throw new Error(`assembly.cable "${cable.name}" waypoints produce invalid curve points; adjust their positions or spacing`);previousDirection=void 0;for(let vertex=1;vertex<validatedPath.data.length;vertex++){let previous=validatedPath.data[vertex-1],current23=validatedPath.data[vertex],direction4=vec3_exports.subtract([0,0,0],[current23.x,current23.y,current23.z],[previous.x,previous.y,previous.z]);if(vec3_exports.normalize(direction4,direction4),previousDirection&&vec3_exports.length(vec3_exports.add([0,0,0],previousDirection,direction4))<MIN_TANGENT_LENGTH)throw new Error(`assembly.cable "${cable.name}" smooth curve must not reverse direction; adjust the nearby waypoints`);previousDirection=direction4}return validatedPath.data}var wireExitDepth=connector=>connector.bodyDepth+(connector.kind==="usb_c_plug"?connector.shellDepth:0);function resolveAssemblyCable(cable){let model110=cable._parsedProps.model,explicitDefinition=model110?parseCableString2(model110):void 0,from=resolveAssemblyCableEndpoint(cable,cable._parsedProps.from,explicitDefinition?.connectorA),to3=resolveAssemblyCableEndpoint(cable,cable._parsedProps.to,explicitDefinition?.connectorB),fromDefinition=explicitDefinition??getCableDefinition(from.cableInput),toDefinition=explicitDefinition??getCableDefinition(to3.cableInput);if(from.sourceComponentId===to3.sourceComponentId)throw new Error(`assembly.cable "${cable.name}" must connect two different endpoints`);if(!explicitDefinition&&(fromDefinition.standard!==toDefinition.standard||fromDefinition.connectorA.kind!==toDefinition.connectorA.kind||"pinCount"in fromDefinition.connectorA&&"pinCount"in toDefinition.connectorA&&fromDefinition.connectorA.pinCount!==toDefinition.connectorA.pinCount))throw new Error(`assembly.cable "${cable.name}" endpoints "${cable._parsedProps.from}" and "${cable._parsedProps.to}" have incompatible connector standards or pin counts`);if(cable._parsedProps.standard&&cable._parsedProps.standard!==fromDefinition.standard)throw new Error(`assembly.cable "${cable.name}" standard="${cable._parsedProps.standard}" conflicts with its endpoints`);let definition=fromDefinition,endpointExit=(position22,direction4,depth)=>{let exit=vec3_exports.scaleAndAdd(vec3_exports.create(),[position22.x,position22.y,position22.z],[direction4.x,direction4.y,direction4.z],depth);return{x:exit[0],y:exit[1],z:exit[2]}},fromExit=endpointExit(from.position,from.direction,wireExitDepth(definition.connectorA)),toExit=endpointExit(to3.position,to3.direction,wireExitDepth(definition.connectorB)),path,waypoints=cable._parsedProps.waypoints;return waypoints?.length?path=resolveAuthoredAssemblyCablePath({cable,from,to:to3,fromExit,toExit,waypoints}):path=inferAssemblyCablePath({from:fromExit,to:toExit,fromDirection:from.direction,toDirection:to3.direction}),{name:cable.name,from_source_component_id:from.sourceComponentId,to_source_component_id:to3.sourceComponentId,from_connector_pin1_position:from.pin1Position,to_connector_pin1_position:to3.pin1Position,cableprinter_string:model110??("pinCount"in definition.connectorA?`${definition.standard}_pins${definition.connectorA.pinCount}`:definition.standard),path}}var AssemblyCable=class extends AssemblyComponent{constructor(){super(...arguments);__publicField(this,"cadCableId")}get config(){return{componentName:"AssemblyCable",zodProps:assemblyCableProps}}doInitialCadModelRender(){if(!this.root||this.root.pcbDisabled)return;let cable=resolveAssemblyCable(this);this.cadCableId=this.root.db.cad_cable.insert(cable).cad_cable_id}onPropsChange(){super.onPropsChange(),this._markDirty("CadModelRender")}updateCadModelRender(){!this.root||this.root.pcbDisabled||!this.cadCableId||this.root.db.cad_cable.update(this.cadCableId,resolveAssemblyCable(this))}},AssemblyDrawingTitleBlock=class extends PrimitiveComponent{get config(){return{componentName:"AssemblyDrawingTitleBlock",zodProps:assemblyDrawingTitleBlockProps}}doInitialAssignNameToUnnamedComponents(){}doInitialSourceRender(){if(this.parent?.componentName!=="AssemblyDrawingPage")throw new Error("assembly.drawing.titleblock must belong to a drawing page");if(this.children.length)throw new Error("assembly.drawing.titleblock cannot contain children")}},AssemblyDrawingPartView=class extends PrimitiveComponent{get config(){return{componentName:"AssemblyDrawingPartView",zodProps:assemblyDrawingPartViewProps}}doInitialAssignNameToUnnamedComponents(){}doInitialSourceRender(){if(this.parent?.componentName!=="AssemblyDrawingPage")throw new Error("assembly.drawing.partview must belong to a drawing page");if(this.children.some(child=>child.componentName!=="AssemblyDrawingDimension"))throw new Error("assembly.drawing.partview can contain only dimensions")}};function resolveDrawingViewCenters(page){let views=page.children.filter(child=>child instanceof AssemblyDrawingPartView),centers={x:new Map,y:new Map},resolving={x:new Set,y:new Set},resolveAxis=(view,axis)=>{if(centers[axis].has(view))return centers[axis].get(view);if(resolving[axis].has(view))throw new Error(`Drawing placement cycle at part view "${view.name||"unnamed part view"}" on ${axis} axis`);resolving[axis].add(view);let props=view._parsedProps,negative=axis==="x"?props.leftOfRef:props.belowRef,positive12=axis==="x"?props.rightOfRef:props.aboveRef,selector2=negative??positive12,center2=(axis==="x"?props.centerX:props.centerY)??0;if(selector2){let matches=selectAll(preprocessSelector(selector2,view),page,{adapter:cssSelectPrimitiveComponentAdapter}).filter(child=>views.includes(child));if(matches.length!==1)throw new Error(`Part view "${view.name||"unnamed part view"}" placement selector "${selector2}" matched ${matches.length} sibling views; expected exactly one`);let reference4=matches[0];if(reference4===view)throw new Error(`Part view "${view.name||"unnamed part view"}" cannot reference itself for placement`);let size23=axis==="x"?props.width:props.height,referenceSize=axis==="x"?reference4._parsedProps.width:reference4._parsedProps.height;center2=resolveAxis(reference4,axis)+(negative?-1:1)*(size23+referenceSize)/2}return resolving[axis].delete(view),centers[axis].set(view,center2),center2};return views.map(view=>({view,center:{x:resolveAxis(view,"x"),y:resolveAxis(view,"y")}}))}function resolveDrawingPartSelection(view){let selector2=view._parsedProps.partRef,scope=getAssemblyScope(view),matches=selectAll(preprocessSelector(selector2,view),[scope],{adapter:cssSelectPrimitiveComponentAdapter});if(matches.length!==1)throw new Error(`Part view "${view.name||"unnamed part view"}" partRef "${selector2}" matched ${matches.length} parts; expected exactly one`);let target=matches[0];if(target.source_group_id)return{source_group_id:target.source_group_id};let sourceComponentIds=[...new Set([target,...target.getDescendants()].flatMap(part=>part.source_component_id?[part.source_component_id]:[]))];if(!sourceComponentIds.length)throw new Error(`Part view "${view.name||"unnamed part view"}" partRef "${selector2}" has no source geometry`);return{source_component_ids:sourceComponentIds}}var directions3={"x+":"x_positive","x-":"x_negative","y+":"y_positive","y-":"y_negative","z+":"z_positive","z-":"z_negative",isometric:"isometric"};function AssemblyDrawingPage_doInitialDrawingRender(page){let{db:db22}=page.root,props=page._parsedProps,views=resolveDrawingViewCenters(page).map(({view,center:center2})=>({view,center:center2,selection:resolveDrawingPartSelection(view)})),preparedViews=views.map(({view,center:center2,selection})=>{let viewProps=view._parsedProps,drawingView={...selection,name:viewProps.name,display_name:viewProps.displayName,direction:directions3[viewProps.direction],center:center2,width:viewProps.width,height:viewProps.height,show_hidden_edges:viewProps.showHiddenEdges,section:viewProps.section?{axis:viewProps.section.axis,offset:viewProps.section.offset,keep_side:viewProps.section.keepSide,hatch_spacing:viewProps.section.hatchSpacing}:void 0};return{view,drawingView,dimensions:[]}}),insertPage=()=>{let{drawing_page_id}=db22.drawing_page.insert({name:props.name,display_name:props.displayName,width:props.width,height:props.height,page_size:props.size,orientation:props.size?props.orientation??"landscape":void 0});for(let{drawingView,dimensions:dimensions6}of preparedViews){let{drawing_part_view_id}=db22.drawing_part_view.insert({drawing_page_id,...drawingView});for(let dimension22 of dimensions6)db22.drawing_dimension_line.insert({drawing_part_view_id,...dimension22})}let block=page.children.find(child=>child instanceof AssemblyDrawingTitleBlock)?._parsedProps;block&&db22.drawing_page_title_block.insert({drawing_page_id,title:block.title,legal_owner:block.legalOwner,identification_number:block.identificationNumber,revision_index:block.revisionIndex,date_of_issue:block.dateOfIssue,creator:block.creator,approval_person:block.approvalPerson,sheet_number:block.sheetNumber,number_of_sheets:block.numberOfSheets})};if(!views.some(({view})=>view.children.length)){insertPage();return}let circuitJson=db22.toArray();page._queueAsyncEffect("resolve-drawing-dimensions",async()=>{try{let{resolveDrawingDimensions:resolveDrawingDimensions2}=await Promise.resolve().then(()=>(init_resolve_drawing_dimensions_EUYVRY2N(),resolve_drawing_dimensions_EUYVRY2N_exports));for(let prepared of preparedViews)prepared.dimensions=await resolveDrawingDimensions2(prepared.view,prepared.drawingView,circuitJson);insertPage()}catch(error2){page.drawingRenderError=error2,page._markDirty("DrawingRender")}})}var AssemblyDrawingPage=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"drawingRenderError")}get config(){return{componentName:"AssemblyDrawingPage",zodProps:assemblyDrawingPageProps}}doInitialAssignNameToUnnamedComponents(){}doInitialSourceRender(){if(this.children.some(child=>child.componentName!=="AssemblyDrawingPartView"&&child.componentName!=="AssemblyDrawingTitleBlock"))throw new Error("Drawing pages can contain only part views and a title block");if(this.children.filter(child=>child.componentName==="AssemblyDrawingTitleBlock").length>1)throw new Error("A drawing page can contain at most one title block")}updateDrawingRender(){if(this.drawingRenderError)throw this.drawingRenderError}doInitialDrawingRender(){AssemblyDrawingPage_doInitialDrawingRender(this)}},AssemblyDrawingDimension=class extends PrimitiveComponent{get config(){return{componentName:"AssemblyDrawingDimension",zodProps:assemblyDrawingDimensionProps}}doInitialAssignNameToUnnamedComponents(){}doInitialSourceRender(){if(this.parent?.componentName!=="AssemblyDrawingPartView")throw new Error("assembly.drawing.dimension must belong to a drawing part view");if(this.children.length)throw new Error("assembly.drawing.dimension cannot contain children")}},resolveAssemblyBoltModel=bolt=>{let props=bolt._parsedProps;if(props.diameter===void 0)return resolveAssemblyModel(props);try{let head=props.headType??"socket",model110=`${{socket:"hexsocketbolt",hex:"hexbolt",pan:"panscrew",countersunk:"flatheadscrew"}[head]}_m${props.diameter}_l${props.length}mm`;if(props.threadPitch!==void 0)if(head==="socket"){let standard=hexSocketBoltDimensions2[`M${props.diameter}`];if(props.threadPitch!==standard?.threadPitch)throw new Error("Socket-head bolts require the standard coarse thread pitch; supply cadModel for a custom thread")}else model110+=`_threadpitch${props.threadPitch}mm`;return parseModelString(model110),resolveAssemblyModel({model:model110})}catch{throw new Error(`Bolt "${bolt.name}" has an unsupported model or dimensions; use a supported modelprinter bolt or supply cadModel`)}},AssemblyBolt=class extends AssemblyComponent{constructor(){super(...arguments);__publicField(this,"isAssemblyDeviceContainer",!0)}get config(){return{componentName:"AssemblyBolt",zodProps:assemblyBoltProps}}doInitialReactSubtreesRender(){(0,import_react14.isValidElement)(this.props.cadModel)&&this.add(createInstanceFromReactElement(this.props.cadModel))}doInitialSourceRender(){getPartReferenceSurfaces(this),this.source_component_id=this.root.db.source_component.insert({ftype:"subassembly",name:this.name,display_name:this._parsedProps.displayName}).source_component_id}doInitialCadModelRender(){if(!this.root||this.root.pcbDisabled||!this.source_component_id)return;renderPartReferenceSurfaces(this);let model110=resolveAssemblyBoltModel(this)??this._parsedProps.cadModel;model110&&!(typeof model110=="object"&&"type"in model110)&&(this.cad_component_id=renderAssemblyCadModel(this,model110,resolveAssemblyPlacement(this)))}},Toolingrail=class extends Group{get isGroup(){return!0}doInitialSchematicComponentRender(){}doInitialSchematicLayout(){}doInitialSchematicTraceRender(){}get config(){return{componentName:"Toolingrail",zodProps:toolingrailProps}}_getPcbLayoutMode(){return"none"}_getRailGeometry(){let panel=getOwningPanel(this);if(!panel)return;let panelSize=panel._getPanelSize();if(!panelSize)throw new Error('<toolingrail> needs a panel with a known size. Use layoutMode="grid" or set the panel width and height.');let{width:width10,height:height10}=panelSize,railWidth=this._parsedProps.width,side=this._parsedProps.panelSide,availablePadding=panel._getEdgePadding()[side];if(railWidth>availablePadding)throw new Error(`Tooling rail width ${railWidth} mm exceeds the ${side} edge padding of ${availablePadding} mm. Increase that panel edge padding.`);return{x:side==="left"?-width10/2+railWidth/2:side==="right"?width10/2-railWidth/2:0,y:side==="bottom"?-height10/2+railWidth/2:side==="top"?height10/2-railWidth/2:0,width:side==="left"||side==="right"?railWidth:width10,height:side==="top"||side==="bottom"?railWidth:height10}}_computePcbGlobalTransformBeforeLayout(){let railToWorldTransform=super._computePcbGlobalTransformBeforeLayout(),rail=this._getRailGeometry();if(!rail||!this.parent)return railToWorldTransform;let panelToWorldTransform=this.parent._computePcbGlobalTransformBeforeLayout(),worldToPanelTransform=inverse6(panelToWorldTransform);return compose3(panelToWorldTransform,translate8(rail.x,rail.y),worldToPanelTransform,railToWorldTransform)}getPcbSize(){let rail=this._getRailGeometry();return{width:rail?.width??0,height:rail?.height??0}}calculatePcbGroupBounds(){if(this.root?.pcbDisabled||!this.pcb_group_id)return;let rail=this._getRailGeometry();if(!rail)return;let center2=applyToPoint3(this._computePcbGlobalTransformBeforeLayout(),{x:0,y:0});this.root.db.pcb_group.update(this.pcb_group_id,{center:center2,width:rail.width,height:rail.height})}doInitialPcbComponentRender(){if(this.parent?.componentName!=="Panel")throw new Error("<toolingrail> must be a direct child of <panel>");this._getRailGeometry(),super.doInitialPcbComponentRender(),this.pcb_group_id&&this.root.db.pcb_group.update(this.pcb_group_id,{anchor_alignment:pcb_group.shape.anchor_alignment.parse(this._parsedProps.pcbAnchorAlignment??"center")})}},createNamespacedElement=hostType=>{let Component2=props=>(0,import_react15.createElement)(hostType,props);return Component2.displayName=hostType,Component2},analog={digitalstimulus:createNamespacedElement("analogdigitalstimulus"),eyediagram:createNamespacedElement("analogeyediagram"),transientsimulation:createNamespacedElement("analogtransientsimulation"),dcoperatingpointsimulation:createNamespacedElement("analogdcoperatingpointsimulation"),dcsweepsimulation:createNamespacedElement("analogdcsweepsimulation"),acsweepsimulation:createNamespacedElement("analogacsweepsimulation"),sweepparameter:createNamespacedElement("analogsweepparameter")},assembly={drawing:{dimension:createNamespacedElement("assembly.drawing.dimension"),page:createNamespacedElement("assembly.drawing.page"),partview:createNamespacedElement("assembly.drawing.partview"),titleblock:createNamespacedElement("assembly.drawing.titleblock")},explosion:{stage:createNamespacedElement("assembly.explosion.stage"),move:createNamespacedElement("assembly.explosion.move")},referencesurface:createNamespacedElement("assembly.referencesurface"),bolt:createNamespacedElement("assembly.bolt"),part:createNamespacedElement("assembly.part"),cable:createNamespacedElement("assembly.cable"),printedpart:createNamespacedElement("assembly.printedpart"),motor:createNamespacedElement("assembly.motor"),subassembly:createNamespacedElement("assembly.subassembly"),cadassembly:createNamespacedElement("assembly.cadassembly"),device:createNamespacedElement("assembly.device"),screen:createNamespacedElement("assembly.screen")},EnclosureFdmBoxElement=createNamespacedElement("enclosure.fdm.box"),enclosure={cutoutaperture:createNamespacedElement("enclosure.cutoutaperture"),fdm:{box:EnclosureFdmBoxElement,Box:EnclosureFdmBoxElement}},simulation={pcbreturncurrentsimulation:createNamespacedElement("pcbreturncurrentsimulation"),pcbreturncurrentexcitation:createNamespacedElement("pcbreturncurrentexcitation")},systemblock={page:createNamespacedElement("systemblockpage"),group:createNamespacedElement("systemblockgroup"),component:createNamespacedElement("systemblockcomponent"),connection:createNamespacedElement("systemblockconnection")},RootCircuit=class extends IsolatedCircuit{constructor({platform,projectUrl}={}){super({platform,projectUrl,cachedSubcircuits:new Map,pendingSubcircuitRenders:new Map});__publicField(this,"isRootCircuit",!0);this.root=this}},Project2=RootCircuit,Circuit=RootCircuit,useRenderedCircuit=reactElements=>{let[isLoading,setIsLoading]=import_react16.default.useState(!0),[error2,setError]=import_react16.default.useState(null),[circuit,setCircuit]=import_react16.default.useState(),[circuitJson,setCircuitJson]=import_react16.default.useState();return import_react16.default.useEffect(()=>{setIsLoading(!0),setError(null),reactElements&&setTimeout(()=>{try{let circuit2=new RootCircuit;circuit2.add(reactElements),setCircuit(circuit2),setCircuitJson(circuit2.toJson())}catch(error22){setError(error22)}setIsLoading(!1)},1)},[reactElements]),{isLoading,error:error2,circuit,circuitJson}},createUseComponent=(Component2,pins)=>(name,props)=>{let pinLabelsFlatArray=[];Array.isArray(pins)?pinLabelsFlatArray.push(...pins.flat()):typeof pins=="object"&&pinLabelsFlatArray.push(...Object.values(pins).flat(),...Object.keys(pins));let R23=props2=>{if(props2?.name&&props2.name!==name)throw new Error(`Component name mismatch. Hook name: ${name}, Component prop name: ${props2.name}`);let combinedProps={...props,...props2,name},tracesToCreate=[];for(let portLabel of pinLabelsFlatArray)if(combinedProps[portLabel]){let from=`.${name} > .${portLabel}`,to3=combinedProps[portLabel];tracesToCreate.push({from,to:to3}),delete combinedProps[portLabel]}return(0,import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment,{children:[(0,import_jsx_runtime32.jsx)(Component2,{...combinedProps}),tracesToCreate.map((trace,i23)=>(0,import_jsx_runtime32.jsx)("trace",{...trace},i23))]})};for(let port of pinLabelsFlatArray)R23[port]=`.${name} > .${port}`;return R23},useCapacitor=createUseComponent(props=>(0,import_jsx_runtime33.jsx)("capacitor",{...props}),capacitorPins),useChip=pinLabels=>createUseComponent(props=>(0,import_jsx_runtime34.jsx)("chip",{pinLabels,...props}),pinLabels),useDiode=createUseComponent(props=>(0,import_jsx_runtime35.jsx)("diode",{...props}),diodePins),useLed=createUseComponent(props=>(0,import_jsx_runtime36.jsx)("led",{...props}),ledPins),useResistor=createUseComponent(props=>(0,import_jsx_runtime37.jsx)("resistor",{...props}),resistorPins),sel=new Proxy(refdes=>new Proxy({},{get:(_23,pin)=>`.${refdes} > .${pin}`}),{get:(_23,prop1)=>{let fn3=(...args)=>{let chipFnOrPinType=args[0];return new Proxy({},{get:(_33,pinName)=>`.${prop1} > .${pinName}`})};return new Proxy(fn3,{get:(_33,prop2)=>prop1==="net"?`net.${prop2}`:prop1==="subcircuit"?new Proxy({},{get:(_42,prop3)=>new Proxy({},{get:(_52,prop4)=>`subcircuit.${prop2} > .${prop3} > .${prop4}`})}):`.${prop1} > .${prop2}`,apply:(target,_33,args)=>prop1==="net"?new Proxy({},{get:(_42,netName)=>`net.${netName}`}):new Proxy({},{get:(_42,pinOrSubComponentName)=>{let pinResult=`.${prop1} > .${pinOrSubComponentName}`;return["U","J","CN"].some(p23=>prop1.startsWith(p23))?pinResult:new Proxy(new String(pinResult),{get:(_52,nestedProp)=>typeof nestedProp=="symbol"||nestedProp==="toString"?()=>pinResult:`.${prop1} > .${pinOrSubComponentName} > .${nestedProp}`})}})})}});extendCatalogue(components_exports);extendCatalogue({"assembly.drawing.dimension":AssemblyDrawingDimension,"assembly.drawing.page":AssemblyDrawingPage,"assembly.drawing.partview":AssemblyDrawingPartView,"assembly.drawing.titleblock":AssemblyDrawingTitleBlock,"assembly.cable":AssemblyCable,"assembly.device":AssemblyDevice,"assembly.explosion.stage":AssemblyExplosionStage,"assembly.explosion.move":AssemblyExplosionMove,"assembly.motor":AssemblyMotor,"assembly.bolt":AssemblyBolt,"assembly.part":AssemblyPart,"assembly.referencesurface":AssemblyReferenceSurface,"assembly.printedpart":AssemblyPrintedPart,"assembly.screen":AssemblyScreen,"assembly.subassembly":AssemblySubassembly,"assembly.cadassembly":AssemblySubassembly,Bug:Chip,"enclosure.cutoutaperture":EnclosureCutoutAperture,"enclosure.fdm.box":EnclosureFdmBox,Fanout:Breakout,FanoutPoint:BreakoutPoint});function serializeAssemblyExplosion(roots,assembled){let nextStageId=0,records=resolveAssemblyExplosionRecords(roots,assembled,()=>`cad_explosion_stage_${nextStageId++}`),stageOrderById=new Map([...records.stages.values()].map(stage=>[stage.cad_explosion_stage_id,stage.order]));return[...records.stages.values(),...[...records.moves.values()].map(move=>({...move,cad_explosion_move_id:`cad_explosion_move_${stageOrderById.get(move.cad_explosion_stage_id)}_${move.order}`}))]}var React4=__toESM(require_react(),1),ReactJsxRuntime=__toESM(require_jsx_runtime(),1);init_dist2();var fabricatorPresets={jlcpcb_economy_20260912:{minimumViaHoleDiameterWithoutExtraCharge:.3},jlcpcb_standard_20260912:{minimumViaHoleDiameterWithoutExtraCharge:.3}},presetAliases={jlcpcb_economy:"jlcpcb_economy_20260912",jlcpcb_standard:"jlcpcb_standard_20260912"};function resolvePreset(name){let resolved=Object.hasOwn(presetAliases,name)?presetAliases[name]:name;return Object.hasOwn(fabricatorPresets,resolved)?fabricatorPresets[resolved]:void 0}function runDrcChecks({circuitJson,fabricatorPreset,pcbBoardId}){let preset=resolvePreset(fabricatorPreset);if(!preset)return[];let threshold=preset.minimumViaHoleDiameterWithoutExtraCharge,smallVias=circuitJson.filter(element2=>element2.type==="pcb_via").filter(via=>via.hole_diameter<threshold);return smallVias.length===0?[]:[pcb_fabricator_extra_charge_warning.parse({type:"pcb_fabricator_extra_charge_warning",fabricator_preset:fabricatorPreset,pcb_board_id:pcbBoardId,pcb_via_ids:smallVias.map(via=>via.pcb_via_id),message:`${fabricatorPreset}: ${smallVias.length} via(s) have a hole diameter below ${threshold} mm and incur an extra fabrication charge. Use a hole diameter of at least ${threshold} mm to avoid this charge.`})]}var fabricatorEngine2={runDrcChecks};var __create4=Object.create,__defProp8=Object.defineProperty,__getOwnPropDesc4=Object.getOwnPropertyDescriptor,__getOwnPropNames4=Object.getOwnPropertyNames,__getProtoOf4=Object.getPrototypeOf,__hasOwnProp5=Object.prototype.hasOwnProperty,__commonJS4=(cb3,mod)=>function(){return mod||(0,cb3[__getOwnPropNames4(cb3)[0]])((mod={exports:{}}).exports,mod),mod.exports},__export5=(target,all)=>{for(var name in all)__defProp8(target,name,{get:all[name],enumerable:!0})},__copyProps4=(to3,from,except,desc)=>{if(from&&typeof from=="object"||typeof from=="function")for(let key of __getOwnPropNames4(from))!__hasOwnProp5.call(to3,key)&&key!==except&&__defProp8(to3,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc4(from,key))||desc.enumerable});return to3},__toESM4=(mod,isNodeMode,target)=>(target=mod!=null?__create4(__getProtoOf4(mod)):{},__copyProps4(isNodeMode||!mod||!mod.__esModule?__defProp8(target,"default",{value:mod,enumerable:!0}):target,mod)),require_react_production=__commonJS4({"node_modules/react/cjs/react.production.js"(exports){"use strict";var REACT_ELEMENT_TYPE=Symbol.for("react.transitional.element"),REACT_PORTAL_TYPE=Symbol.for("react.portal"),REACT_FRAGMENT_TYPE=Symbol.for("react.fragment"),REACT_STRICT_MODE_TYPE=Symbol.for("react.strict_mode"),REACT_PROFILER_TYPE=Symbol.for("react.profiler"),REACT_CONSUMER_TYPE=Symbol.for("react.consumer"),REACT_CONTEXT_TYPE=Symbol.for("react.context"),REACT_FORWARD_REF_TYPE=Symbol.for("react.forward_ref"),REACT_SUSPENSE_TYPE=Symbol.for("react.suspense"),REACT_MEMO_TYPE=Symbol.for("react.memo"),REACT_LAZY_TYPE=Symbol.for("react.lazy"),MAYBE_ITERATOR_SYMBOL=Symbol.iterator;function getIteratorFn(maybeIterable){return maybeIterable===null||typeof maybeIterable!="object"?null:(maybeIterable=MAYBE_ITERATOR_SYMBOL&&maybeIterable[MAYBE_ITERATOR_SYMBOL]||maybeIterable["@@iterator"],typeof maybeIterable=="function"?maybeIterable:null)}var ReactNoopUpdateQueue={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},assign=Object.assign,emptyObject={};function Component(props,context,updater){this.props=props,this.context=context,this.refs=emptyObject,this.updater=updater||ReactNoopUpdateQueue}Component.prototype.isReactComponent={},Component.prototype.setState=function(partialState,callback){if(typeof partialState!="object"&&typeof partialState!="function"&&partialState!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,partialState,callback,"setState")},Component.prototype.forceUpdate=function(callback){this.updater.enqueueForceUpdate(this,callback,"forceUpdate")};function ComponentDummy(){}ComponentDummy.prototype=Component.prototype;function PureComponent(props,context,updater){this.props=props,this.context=context,this.refs=emptyObject,this.updater=updater||ReactNoopUpdateQueue}var pureComponentPrototype=PureComponent.prototype=new ComponentDummy;pureComponentPrototype.constructor=PureComponent,assign(pureComponentPrototype,Component.prototype),pureComponentPrototype.isPureReactComponent=!0;var isArrayImpl=Array.isArray,ReactSharedInternals={H:null,A:null,T:null,S:null,V:null},hasOwnProperty=Object.prototype.hasOwnProperty;function ReactElement(type,key,self2,source,owner,props){return self2=props.ref,{$$typeof:REACT_ELEMENT_TYPE,type,key,ref:self2!==void 0?self2:null,props}}function cloneAndReplaceKey(oldElement,newKey){return ReactElement(oldElement.type,newKey,void 0,void 0,void 0,oldElement.props)}function isValidElement33(object){return typeof object=="object"&&object!==null&&object.$$typeof===REACT_ELEMENT_TYPE}function escape2(key){var escaperLookup={"=":"=0",":":"=2"};return"$"+key.replace(/[=:]/g,function(match2){return escaperLookup[match2]})}var userProvidedKeyEscapeRegex=/\/+/g;function getElementKey(element2,index2){return typeof element2=="object"&&element2!==null&&element2.key!=null?escape2(""+element2.key):index2.toString(36)}function noop$1(){}function resolveThenable(thenable){switch(thenable.status){case"fulfilled":return thenable.value;case"rejected":throw thenable.reason;default:switch(typeof thenable.status=="string"?thenable.then(noop$1,noop$1):(thenable.status="pending",thenable.then(function(fulfilledValue){thenable.status==="pending"&&(thenable.status="fulfilled",thenable.value=fulfilledValue)},function(error2){thenable.status==="pending"&&(thenable.status="rejected",thenable.reason=error2)})),thenable.status){case"fulfilled":return thenable.value;case"rejected":throw thenable.reason}}throw thenable}function mapIntoArray(children,array2,escapedPrefix,nameSoFar,callback){var type=typeof children;(type==="undefined"||type==="boolean")&&(children=null);var invokeCallback=!1;if(children===null)invokeCallback=!0;else switch(type){case"bigint":case"string":case"number":invokeCallback=!0;break;case"object":switch(children.$$typeof){case REACT_ELEMENT_TYPE:case REACT_PORTAL_TYPE:invokeCallback=!0;break;case REACT_LAZY_TYPE:return invokeCallback=children._init,mapIntoArray(invokeCallback(children._payload),array2,escapedPrefix,nameSoFar,callback)}}if(invokeCallback)return callback=callback(children),invokeCallback=nameSoFar===""?"."+getElementKey(children,0):nameSoFar,isArrayImpl(callback)?(escapedPrefix="",invokeCallback!=null&&(escapedPrefix=invokeCallback.replace(userProvidedKeyEscapeRegex,"$&/")+"/"),mapIntoArray(callback,array2,escapedPrefix,"",function(c11){return c11})):callback!=null&&(isValidElement33(callback)&&(callback=cloneAndReplaceKey(callback,escapedPrefix+(callback.key==null||children&&children.key===callback.key?"":(""+callback.key).replace(userProvidedKeyEscapeRegex,"$&/")+"/")+invokeCallback)),array2.push(callback)),1;invokeCallback=0;var nextNamePrefix=nameSoFar===""?".":nameSoFar+":";if(isArrayImpl(children))for(var i10=0;i10<children.length;i10++)nameSoFar=children[i10],type=nextNamePrefix+getElementKey(nameSoFar,i10),invokeCallback+=mapIntoArray(nameSoFar,array2,escapedPrefix,type,callback);else if(i10=getIteratorFn(children),typeof i10=="function")for(children=i10.call(children),i10=0;!(nameSoFar=children.next()).done;)nameSoFar=nameSoFar.value,type=nextNamePrefix+getElementKey(nameSoFar,i10++),invokeCallback+=mapIntoArray(nameSoFar,array2,escapedPrefix,type,callback);else if(type==="object"){if(typeof children.then=="function")return mapIntoArray(resolveThenable(children),array2,escapedPrefix,nameSoFar,callback);throw array2=String(children),Error("Objects are not valid as a React child (found: "+(array2==="[object Object]"?"object with keys {"+Object.keys(children).join(", ")+"}":array2)+"). If you meant to render a collection of children, use an array instead.")}return invokeCallback}function mapChildren(children,func,context){if(children==null)return children;var result=[],count=0;return mapIntoArray(children,result,"","",function(child){return func.call(context,child,count++)}),result}function lazyInitializer(payload){if(payload._status===-1){var ctor=payload._result;ctor=ctor(),ctor.then(function(moduleObject){(payload._status===0||payload._status===-1)&&(payload._status=1,payload._result=moduleObject)},function(error2){(payload._status===0||payload._status===-1)&&(payload._status=2,payload._result=error2)}),payload._status===-1&&(payload._status=0,payload._result=ctor)}if(payload._status===1)return payload._result.default;throw payload._result}var reportGlobalError=typeof reportError=="function"?reportError:function(error2){if(typeof window=="object"&&typeof window.ErrorEvent=="function"){var event=new window.ErrorEvent("error",{bubbles:!0,cancelable:!0,message:typeof error2=="object"&&error2!==null&&typeof error2.message=="string"?String(error2.message):String(error2),error:error2});if(!window.dispatchEvent(event))return}else if(typeof process=="object"&&typeof process.emit=="function"){process.emit("uncaughtException",error2);return}console.error(error2)};function noop(){}exports.Children={map:mapChildren,forEach:function(children,forEachFunc,forEachContext){mapChildren(children,function(){forEachFunc.apply(this,arguments)},forEachContext)},count:function(children){var n10=0;return mapChildren(children,function(){n10++}),n10},toArray:function(children){return mapChildren(children,function(child){return child})||[]},only:function(children){if(!isValidElement33(children))throw Error("React.Children.only expected to receive a single React element child.");return children}},exports.Component=Component,exports.Fragment=REACT_FRAGMENT_TYPE,exports.Profiler=REACT_PROFILER_TYPE,exports.PureComponent=PureComponent,exports.StrictMode=REACT_STRICT_MODE_TYPE,exports.Suspense=REACT_SUSPENSE_TYPE,exports.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=ReactSharedInternals,exports.__COMPILER_RUNTIME={__proto__:null,c:function(size32){return ReactSharedInternals.H.useMemoCache(size32)}},exports.cache=function(fn3){return function(){return fn3.apply(null,arguments)}},exports.cloneElement=function(element2,config,children){if(element2==null)throw Error("The argument must be a React element, but you passed "+element2+".");var props=assign({},element2.props),key=element2.key,owner=void 0;if(config!=null)for(propName in config.ref!==void 0&&(owner=void 0),config.key!==void 0&&(key=""+config.key),config)!hasOwnProperty.call(config,propName)||propName==="key"||propName==="__self"||propName==="__source"||propName==="ref"&&config.ref===void 0||(props[propName]=config[propName]);var propName=arguments.length-2;if(propName===1)props.children=children;else if(1<propName){for(var childArray=Array(propName),i10=0;i10<propName;i10++)childArray[i10]=arguments[i10+2];props.children=childArray}return ReactElement(element2.type,key,void 0,void 0,owner,props)},exports.createContext=function(defaultValue){return defaultValue={$$typeof:REACT_CONTEXT_TYPE,_currentValue:defaultValue,_currentValue2:defaultValue,_threadCount:0,Provider:null,Consumer:null},defaultValue.Provider=defaultValue,defaultValue.Consumer={$$typeof:REACT_CONSUMER_TYPE,_context:defaultValue},defaultValue},exports.createElement=function(type,config,children){var propName,props={},key=null;if(config!=null)for(propName in config.key!==void 0&&(key=""+config.key),config)hasOwnProperty.call(config,propName)&&propName!=="key"&&propName!=="__self"&&propName!=="__source"&&(props[propName]=config[propName]);var childrenLength=arguments.length-2;if(childrenLength===1)props.children=children;else if(1<childrenLength){for(var childArray=Array(childrenLength),i10=0;i10<childrenLength;i10++)childArray[i10]=arguments[i10+2];props.children=childArray}if(type&&type.defaultProps)for(propName in childrenLength=type.defaultProps,childrenLength)props[propName]===void 0&&(props[propName]=childrenLength[propName]);return ReactElement(type,key,void 0,void 0,null,props)},exports.createRef=function(){return{current:null}},exports.forwardRef=function(render3){return{$$typeof:REACT_FORWARD_REF_TYPE,render:render3}},exports.isValidElement=isValidElement33,exports.lazy=function(ctor){return{$$typeof:REACT_LAZY_TYPE,_payload:{_status:-1,_result:ctor},_init:lazyInitializer}},exports.memo=function(type,compare2){return{$$typeof:REACT_MEMO_TYPE,type,compare:compare2===void 0?null:compare2}},exports.startTransition=function(scope){var prevTransition=ReactSharedInternals.T,currentTransition={};ReactSharedInternals.T=currentTransition;try{var returnValue=scope(),onStartTransitionFinish=ReactSharedInternals.S;onStartTransitionFinish!==null&&onStartTransitionFinish(currentTransition,returnValue),typeof returnValue=="object"&&returnValue!==null&&typeof returnValue.then=="function"&&returnValue.then(noop,reportGlobalError)}catch(error2){reportGlobalError(error2)}finally{ReactSharedInternals.T=prevTransition}},exports.unstable_useCacheRefresh=function(){return ReactSharedInternals.H.useCacheRefresh()},exports.use=function(usable){return ReactSharedInternals.H.use(usable)},exports.useActionState=function(action,initialState,permalink){return ReactSharedInternals.H.useActionState(action,initialState,permalink)},exports.useCallback=function(callback,deps){return ReactSharedInternals.H.useCallback(callback,deps)},exports.useContext=function(Context){return ReactSharedInternals.H.useContext(Context)},exports.useDebugValue=function(){},exports.useDeferredValue=function(value,initialValue){return ReactSharedInternals.H.useDeferredValue(value,initialValue)},exports.useEffect=function(create10,createDeps,update2){var dispatcher=ReactSharedInternals.H;if(typeof update2=="function")throw Error("useEffect CRUD overload is not enabled in this build of React.");return dispatcher.useEffect(create10,createDeps)},exports.useId=function(){return ReactSharedInternals.H.useId()},exports.useImperativeHandle=function(ref,create10,deps){return ReactSharedInternals.H.useImperativeHandle(ref,create10,deps)},exports.useInsertionEffect=function(create10,deps){return ReactSharedInternals.H.useInsertionEffect(create10,deps)},exports.useLayoutEffect=function(create10,deps){return ReactSharedInternals.H.useLayoutEffect(create10,deps)},exports.useMemo=function(create10,deps){return ReactSharedInternals.H.useMemo(create10,deps)},exports.useOptimistic=function(passthrough,reducer){return ReactSharedInternals.H.useOptimistic(passthrough,reducer)},exports.useReducer=function(reducer,initialArg,init){return ReactSharedInternals.H.useReducer(reducer,initialArg,init)},exports.useRef=function(initialValue){return ReactSharedInternals.H.useRef(initialValue)},exports.useState=function(initialState){return ReactSharedInternals.H.useState(initialState)},exports.useSyncExternalStore=function(subscribe,getSnapshot,getServerSnapshot){return ReactSharedInternals.H.useSyncExternalStore(subscribe,getSnapshot,getServerSnapshot)},exports.useTransition=function(){return ReactSharedInternals.H.useTransition()},exports.version="19.1.0"}}),require_react_development2=__commonJS4({"node_modules/react/cjs/react.development.js"(exports,module){"use strict";(function(){function defineDeprecationWarning(methodName,info){Object.defineProperty(Component.prototype,methodName,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",info[0],info[1])}})}function getIteratorFn(maybeIterable){return maybeIterable===null||typeof maybeIterable!="object"?null:(maybeIterable=MAYBE_ITERATOR_SYMBOL&&maybeIterable[MAYBE_ITERATOR_SYMBOL]||maybeIterable["@@iterator"],typeof maybeIterable=="function"?maybeIterable:null)}function warnNoop(publicInstance,callerName){publicInstance=(publicInstance=publicInstance.constructor)&&(publicInstance.displayName||publicInstance.name)||"ReactClass";var warningKey=publicInstance+"."+callerName;didWarnStateUpdateForUnmountedComponent[warningKey]||(console.error("Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.",callerName,publicInstance),didWarnStateUpdateForUnmountedComponent[warningKey]=!0)}function Component(props,context,updater){this.props=props,this.context=context,this.refs=emptyObject,this.updater=updater||ReactNoopUpdateQueue}function ComponentDummy(){}function PureComponent(props,context,updater){this.props=props,this.context=context,this.refs=emptyObject,this.updater=updater||ReactNoopUpdateQueue}function testStringCoercion(value){return""+value}function checkKeyStringCoercion(value){try{testStringCoercion(value);var JSCompiler_inline_result=!1}catch{JSCompiler_inline_result=!0}if(JSCompiler_inline_result){JSCompiler_inline_result=console;var JSCompiler_temp_const=JSCompiler_inline_result.error,JSCompiler_inline_result$jscomp$0=typeof Symbol=="function"&&Symbol.toStringTag&&value[Symbol.toStringTag]||value.constructor.name||"Object";return JSCompiler_temp_const.call(JSCompiler_inline_result,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",JSCompiler_inline_result$jscomp$0),testStringCoercion(value)}}function getComponentNameFromType(type){if(type==null)return null;if(typeof type=="function")return type.$$typeof===REACT_CLIENT_REFERENCE?null:type.displayName||type.name||null;if(typeof type=="string")return type;switch(type){case REACT_FRAGMENT_TYPE:return"Fragment";case REACT_PROFILER_TYPE:return"Profiler";case REACT_STRICT_MODE_TYPE:return"StrictMode";case REACT_SUSPENSE_TYPE:return"Suspense";case REACT_SUSPENSE_LIST_TYPE:return"SuspenseList";case REACT_ACTIVITY_TYPE:return"Activity"}if(typeof type=="object")switch(typeof type.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),type.$$typeof){case REACT_PORTAL_TYPE:return"Portal";case REACT_CONTEXT_TYPE:return(type.displayName||"Context")+".Provider";case REACT_CONSUMER_TYPE:return(type._context.displayName||"Context")+".Consumer";case REACT_FORWARD_REF_TYPE:var innerType=type.render;return type=type.displayName,type||(type=innerType.displayName||innerType.name||"",type=type!==""?"ForwardRef("+type+")":"ForwardRef"),type;case REACT_MEMO_TYPE:return innerType=type.displayName||null,innerType!==null?innerType:getComponentNameFromType(type.type)||"Memo";case REACT_LAZY_TYPE:innerType=type._payload,type=type._init;try{return getComponentNameFromType(type(innerType))}catch{}}return null}function getTaskName(type){if(type===REACT_FRAGMENT_TYPE)return"<>";if(typeof type=="object"&&type!==null&&type.$$typeof===REACT_LAZY_TYPE)return"<...>";try{var name=getComponentNameFromType(type);return name?"<"+name+">":"<...>"}catch{return"<...>"}}function getOwner(){var dispatcher=ReactSharedInternals.A;return dispatcher===null?null:dispatcher.getOwner()}function UnknownOwner(){return Error("react-stack-top-frame")}function hasValidKey(config){if(hasOwnProperty.call(config,"key")){var getter=Object.getOwnPropertyDescriptor(config,"key").get;if(getter&&getter.isReactWarning)return!1}return config.key!==void 0}function defineKeyPropWarningGetter(props,displayName){function warnAboutAccessingKey(){specialPropKeyWarningShown||(specialPropKeyWarningShown=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",displayName))}warnAboutAccessingKey.isReactWarning=!0,Object.defineProperty(props,"key",{get:warnAboutAccessingKey,configurable:!0})}function elementRefGetterWithDeprecationWarning(){var componentName=getComponentNameFromType(this.type);return didWarnAboutElementRef[componentName]||(didWarnAboutElementRef[componentName]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),componentName=this.props.ref,componentName!==void 0?componentName:null}function ReactElement(type,key,self2,source,owner,props,debugStack,debugTask){return self2=props.ref,type={$$typeof:REACT_ELEMENT_TYPE,type,key,props,_owner:owner},(self2!==void 0?self2:null)!==null?Object.defineProperty(type,"ref",{enumerable:!1,get:elementRefGetterWithDeprecationWarning}):Object.defineProperty(type,"ref",{enumerable:!1,value:null}),type._store={},Object.defineProperty(type._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(type,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(type,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:debugStack}),Object.defineProperty(type,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:debugTask}),Object.freeze&&(Object.freeze(type.props),Object.freeze(type)),type}function cloneAndReplaceKey(oldElement,newKey){return newKey=ReactElement(oldElement.type,newKey,void 0,void 0,oldElement._owner,oldElement.props,oldElement._debugStack,oldElement._debugTask),oldElement._store&&(newKey._store.validated=oldElement._store.validated),newKey}function isValidElement33(object){return typeof object=="object"&&object!==null&&object.$$typeof===REACT_ELEMENT_TYPE}function escape2(key){var escaperLookup={"=":"=0",":":"=2"};return"$"+key.replace(/[=:]/g,function(match2){return escaperLookup[match2]})}function getElementKey(element2,index2){return typeof element2=="object"&&element2!==null&&element2.key!=null?(checkKeyStringCoercion(element2.key),escape2(""+element2.key)):index2.toString(36)}function noop$1(){}function resolveThenable(thenable){switch(thenable.status){case"fulfilled":return thenable.value;case"rejected":throw thenable.reason;default:switch(typeof thenable.status=="string"?thenable.then(noop$1,noop$1):(thenable.status="pending",thenable.then(function(fulfilledValue){thenable.status==="pending"&&(thenable.status="fulfilled",thenable.value=fulfilledValue)},function(error2){thenable.status==="pending"&&(thenable.status="rejected",thenable.reason=error2)})),thenable.status){case"fulfilled":return thenable.value;case"rejected":throw thenable.reason}}throw thenable}function mapIntoArray(children,array2,escapedPrefix,nameSoFar,callback){var type=typeof children;(type==="undefined"||type==="boolean")&&(children=null);var invokeCallback=!1;if(children===null)invokeCallback=!0;else switch(type){case"bigint":case"string":case"number":invokeCallback=!0;break;case"object":switch(children.$$typeof){case REACT_ELEMENT_TYPE:case REACT_PORTAL_TYPE:invokeCallback=!0;break;case REACT_LAZY_TYPE:return invokeCallback=children._init,mapIntoArray(invokeCallback(children._payload),array2,escapedPrefix,nameSoFar,callback)}}if(invokeCallback){invokeCallback=children,callback=callback(invokeCallback);var childKey=nameSoFar===""?"."+getElementKey(invokeCallback,0):nameSoFar;return isArrayImpl(callback)?(escapedPrefix="",childKey!=null&&(escapedPrefix=childKey.replace(userProvidedKeyEscapeRegex,"$&/")+"/"),mapIntoArray(callback,array2,escapedPrefix,"",function(c11){return c11})):callback!=null&&(isValidElement33(callback)&&(callback.key!=null&&(invokeCallback&&invokeCallback.key===callback.key||checkKeyStringCoercion(callback.key)),escapedPrefix=cloneAndReplaceKey(callback,escapedPrefix+(callback.key==null||invokeCallback&&invokeCallback.key===callback.key?"":(""+callback.key).replace(userProvidedKeyEscapeRegex,"$&/")+"/")+childKey),nameSoFar!==""&&invokeCallback!=null&&isValidElement33(invokeCallback)&&invokeCallback.key==null&&invokeCallback._store&&!invokeCallback._store.validated&&(escapedPrefix._store.validated=2),callback=escapedPrefix),array2.push(callback)),1}if(invokeCallback=0,childKey=nameSoFar===""?".":nameSoFar+":",isArrayImpl(children))for(var i10=0;i10<children.length;i10++)nameSoFar=children[i10],type=childKey+getElementKey(nameSoFar,i10),invokeCallback+=mapIntoArray(nameSoFar,array2,escapedPrefix,type,callback);else if(i10=getIteratorFn(children),typeof i10=="function")for(i10===children.entries&&(didWarnAboutMaps||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),didWarnAboutMaps=!0),children=i10.call(children),i10=0;!(nameSoFar=children.next()).done;)nameSoFar=nameSoFar.value,type=childKey+getElementKey(nameSoFar,i10++),invokeCallback+=mapIntoArray(nameSoFar,array2,escapedPrefix,type,callback);else if(type==="object"){if(typeof children.then=="function")return mapIntoArray(resolveThenable(children),array2,escapedPrefix,nameSoFar,callback);throw array2=String(children),Error("Objects are not valid as a React child (found: "+(array2==="[object Object]"?"object with keys {"+Object.keys(children).join(", ")+"}":array2)+"). If you meant to render a collection of children, use an array instead.")}return invokeCallback}function mapChildren(children,func,context){if(children==null)return children;var result=[],count=0;return mapIntoArray(children,result,"","",function(child){return func.call(context,child,count++)}),result}function lazyInitializer(payload){if(payload._status===-1){var ctor=payload._result;ctor=ctor(),ctor.then(function(moduleObject){(payload._status===0||payload._status===-1)&&(payload._status=1,payload._result=moduleObject)},function(error2){(payload._status===0||payload._status===-1)&&(payload._status=2,payload._result=error2)}),payload._status===-1&&(payload._status=0,payload._result=ctor)}if(payload._status===1)return ctor=payload._result,ctor===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
1051
+ `),position22={x:pcbBoard.center.x+pcbBoard.width/2-.25,y:pcbBoard.center.y-pcbBoard.height/2+1};this.root.db.pcb_silkscreen_text.insert({pcb_component_id:this.pcb_board_id,layer:"top",font:"tscircuit2024",font_size:.45,text:text4,ccw_rotation:0,anchor_alignment:"bottom_right",anchor_position:position22})}doInitialSourceRender(){let nestedBoard=this.getDescendants().find(d23=>d23.lowercaseComponentName==="board");if(nestedBoard)throw new Error(`Nested boards are not supported: found board "${nestedBoard.name}" inside board "${this.name}"`);super.doInitialSourceRender();let{db:db22}=this.root,source_board23=db22.source_board.insert({source_group_id:this.source_group_id,title:this.props.title||this.props.name});this.source_board_id=source_board23.source_board_id}getSubcircuitPropHash(){return Subcircuit_getSubcircuitPropHash(this)}doInitialRenderIsolatedSubcircuits(){Subcircuit_doInitialRenderIsolatedSubcircuits(this)}doInitialInflateSubcircuitCircuitJson(){let isolatedJson=this._isolatedCircuitJson;if(isolatedJson){this._isInflatedFromCircuitJson=!0,this._isolatedCircuitJson=null,inflateCircuitJson(this,isolatedJson,[]);return}let{circuitJson,children}=this._parsedProps;circuitJson&&(this._isInflatedFromCircuitJson=!0),inflateCircuitJson(this,circuitJson,children)}doInitialPcbComponentRender(){if(this.root?.pcbDisabled)return;let{db:db22}=this.root,{_parsedProps:props}=this,pcbBoardFromCircuitJson=props.circuitJson?.find(elm=>elm.type==="pcb_board"),viaTenting=getViaTenting(props.defaultViaTenting),rawProps=this.props,resolvedIsViaInPadAllowed=rawProps.isViaInPadAllowed??pcbBoardFromCircuitJson?.is_via_in_pad_allowed,resolvedAllowBlindAndBuriedVias=rawProps.allowBlindAndBuriedVias??pcbBoardFromCircuitJson?.allow_blind_and_buried_vias,computedWidth=props.width??pcbBoardFromCircuitJson?.width??0,computedHeight=props.height??pcbBoardFromCircuitJson?.height??0,globalPos=this._getGlobalPcbPositionBeforeLayout(),center2={x:globalPos.x+(props.outlineOffsetX??0),y:globalPos.y+(props.outlineOffsetY??0)},{boardAnchorPosition,boardAnchorAlignment}=props;if(boardAnchorPosition&&(center2=getBoardCenterFromAnchor({boardAnchorPosition,boardAnchorAlignment:boardAnchorAlignment??"center",width:computedWidth,height:computedHeight})),props.outline){let xValues=props.outline.map(point12=>point12.x),yValues=props.outline.map(point12=>point12.y),minX=Math.min(...xValues),maxX=Math.max(...xValues),minY=Math.min(...yValues),maxY=Math.max(...yValues);computedWidth=maxX-minX,computedHeight=maxY-minY}let outline=props.outline;!outline&&props.borderRadius!=null&&computedWidth>0&&computedHeight>0&&(outline=getRoundedRectOutline(computedWidth,computedHeight,props.borderRadius).map(point12=>({x:point12.x+center2.x,y:point12.y+center2.y})));let outlineTranslation={x:0,y:0};if(props.outline&&outline&&outline.length>0&&(this.parent?.lowercaseComponentName==="panel"||this.parent?.lowercaseComponentName==="subpanel")){let outlineBounds=getBoundsFromPoints3(outline);if(outlineBounds){let outlineCenterX=(outlineBounds.minX+outlineBounds.maxX)/2,outlineCenterY=(outlineBounds.minY+outlineBounds.maxY)/2;outlineTranslation={x:center2.x-outlineCenterX,y:center2.y-outlineCenterY}}}let subcircuitProps2=this.getSubcircuit()._parsedProps,pcbStyle3=this.getInheritedMergedProperty("pcbStyle"),styledViaDimensions=getViaDiameterDefaults(pcbStyle3),configuredViaHoleDiameter=subcircuitProps2.minViaHoleDiameter??(pcbStyle3?.viaHoleDiameter!==void 0?styledViaDimensions.holeDiameter:void 0),resolvedMinViaHoleDiameter=configuredViaHoleDiameter??jlcMinTolerances2.min_via_hole_diameter,resolvedMinViaPadDiameter=subcircuitProps2.minViaPadDiameter??(pcbStyle3?.viaPadDiameter!==void 0?styledViaDimensions.padDiameter:configuredViaHoleDiameter!==void 0?configuredViaHoleDiameter+DEFAULT_VIA_PAD_DIAMETER_OVER_HOLE_DIAMETER_MM:jlcMinTolerances2.min_via_pad_diameter),pcb_board23=db22.pcb_board.insert({source_board_id:this.source_board_id,subcircuit_id:this.subcircuit_id??void 0,center:center2,default_via_tented_on_top:viaTenting.tented_on_top??pcbBoardFromCircuitJson?.default_via_tented_on_top,default_via_tented_on_bottom:viaTenting.tented_on_bottom??pcbBoardFromCircuitJson?.default_via_tented_on_bottom,thickness:this.boardThickness,num_layers:this.allLayers.length,width:computedWidth,height:computedHeight,outline:props.outline?outline?.map(point12=>({x:point12.x+(props.outlineOffsetX??0)+outlineTranslation.x,y:point12.y+(props.outlineOffsetY??0)+outlineTranslation.y})):outline,material:props.material,...resolvedIsViaInPadAllowed!==void 0&&{is_via_in_pad_allowed:resolvedIsViaInPadAllowed},...resolvedAllowBlindAndBuriedVias!==void 0&&{allow_blind_and_buried_vias:resolvedAllowBlindAndBuriedVias},...props.solderMaskColor!==void 0&&{solder_mask_color:props.solderMaskColor},...props.silkscreenColor!==void 0&&{silkscreen_color:props.silkscreenColor},min_trace_width:subcircuitProps2.minTraceWidth??jlcMinTolerances2.min_trace_width,min_via_hole_diameter:resolvedMinViaHoleDiameter,min_via_pad_diameter:resolvedMinViaPadDiameter,min_via_hole_edge_to_via_hole_edge_clearance:subcircuitProps2.minViaHoleEdgeToViaHoleEdgeClearance??jlcMinTolerances2.min_via_hole_edge_to_via_hole_edge_clearance,min_via_edge_to_pad_edge_clearance:subcircuitProps2.minViaEdgeToPadEdgeClearance??jlcMinTolerances2.min_via_edge_to_pad_edge_clearance,min_trace_to_hole_edge_clearance:subcircuitProps2.minTraceToHoleEdgeClearance??jlcMinTolerances2.min_trace_to_hole_edge_clearance,min_trace_to_pad_edge_clearance:subcircuitProps2.minTraceToPadEdgeClearance??jlcMinTolerances2.min_trace_to_pad_edge_clearance,min_pad_edge_to_pad_edge_clearance:subcircuitProps2.minPadEdgeToPadEdgeClearance??jlcMinTolerances2.min_pad_edge_to_pad_edge_clearance,min_plated_hole_drill_edge_to_drill_edge_clearance:subcircuitProps2.minPlatedHoleDrillEdgeToDrillEdgeClearance??jlcMinTolerances2.min_plated_hole_drill_edge_to_drill_edge_clearance,min_board_edge_clearance:subcircuitProps2.minBoardEdgeClearance??jlcMinTolerances2.min_board_edge_clearance});this.pcb_board_id=pcb_board23.pcb_board_id,Board_doInitialPcbStackupRender(this,pcbBoardFromCircuitJson),this._addBoardInformationToSilkscreen()}removePcbComponentRender(){let{db:db22}=this.root;this.pcb_board_id&&(db22.pcb_board.delete(this.pcb_board_id),this.pcb_board_id=null)}doInitialPcbDesignRuleChecks(){super.doInitialPcbDesignRuleChecks(),this.updatePcbDesignRuleChecks()}doInitialPcbPlacementDesignRuleChecks(){Board_doInitialPcbPlacementDesignRuleChecks(this)}doInitialPcbCopperPourCleanup(){Board_doInitialPcbCopperPourCleanup(this)}updatePcbDesignRuleChecks(){Board_updatePcbDesignRuleChecks(this)}runRenderPhaseForChildren(phase){this.root?.emit("board:renderPhaseStarted",{renderId:this._renderId,phase}),super.runRenderPhaseForChildren(phase)}_repositionOnPcb(position22){let{db:db22}=this.root,pcbBoard=this.pcb_board_id?db22.pcb_board.get(this.pcb_board_id):null,oldPos=pcbBoard?.center;if(!oldPos){this.pcb_board_id&&db22.pcb_board.update(this.pcb_board_id,{center:position22});return}let deltaX=position22.x-oldPos.x,deltaY=position22.y-oldPos.y;if(!(Math.abs(deltaX)<1e-6&&Math.abs(deltaY)<1e-6)&&this.pcb_board_id&&(db22.pcb_board.update(this.pcb_board_id,{center:position22}),pcbBoard?.outline)){let outlineBounds=getBoundsFromPoints3(pcbBoard.outline);if(outlineBounds){let oldOutlineCenter={x:(outlineBounds.minX+outlineBounds.maxX)/2,y:(outlineBounds.minY+outlineBounds.maxY)/2},outlineDeltaX=position22.x-oldOutlineCenter.x,outlineDeltaY=position22.y-oldOutlineCenter.y,newOutline=pcbBoard.outline.map(p23=>({x:p23.x+outlineDeltaX,y:p23.y+outlineDeltaY}));db22.pcb_board.update(this.pcb_board_id,{outline:newOutline});for(let castellatedHole of this._castellatedHoles)castellatedHole.syncPositionToBoardOutline()}}}_isExpectedCastellatedHoleDrcError(result){return this._castellatedHoles.some(castellatedHole=>castellatedHole.isExpectedBoardEdgeDrcError(result))}},Subcircuit=class extends Group{constructor(props){super({...props,subcircuit:!0})}getSubcircuitPropHash(){return Subcircuit_getSubcircuitPropHash(this)}doInitialRenderIsolatedSubcircuits(){Subcircuit_doInitialRenderIsolatedSubcircuits(this)}doInitialCreateNetsFromProps(){super.doInitialCreateNetsFromProps(),this._createTracesForExposedConnections()}_createTracesForExposedConnections(){let exposedNets=this._getNetNamesToExpose();if(!exposedNets?.length)return;let parentSubcircuit=this.parent?.getSubcircuit?.();if(parentSubcircuit&&this.name)for(let exposedNetName of exposedNets){let netName=normalizeExposedNetName(exposedNetName),parentNetSelector=`> net.${netName}`,childNetSelector=`.${this.name} > net.${netName}`;if(parentSubcircuit.children.find(child=>child instanceof Net&&child._parsedProps.name===netName)||parentSubcircuit.add(new Net({name:netName})),parentSubcircuit.children.find(child=>{if(!(child instanceof Trace)||!child._exposesSubcircuitConnection)return!1;let childProps=child._parsedProps;return childProps.from===childNetSelector&&childProps.to===parentNetSelector}))continue;let trace=new Trace({from:childNetSelector,to:parentNetSelector,displayName:netName});trace._exposesSubcircuitConnection=!0,parentSubcircuit.add(trace)}}_getNetNamesToExpose(){let explicitExposedNets=this._parsedProps.exposedNets??[];if(!this._parsedProps.exposeNets)return explicitExposedNets;let childNetNames=this.selectAll("net").filter(net=>net instanceof Net&&net.getSubcircuit()===this).map(net=>net._parsedProps.name);return Array.from(new Set([...explicitExposedNets,...childNetNames]))}doInitialInflateSubcircuitCircuitJson(){let isolatedJson=this._isolatedCircuitJson;if(isolatedJson){this._isInflatedFromCircuitJson=!0,this._isolatedCircuitJson=null,inflateCircuitJson(this,isolatedJson,[]);return}let{circuitJson,children}=this._parsedProps;circuitJson&&(this._isInflatedFromCircuitJson=!0),inflateCircuitJson(this,circuitJson,children)}},normalizeExposedNetName=netName=>netName.startsWith("net.")?netName.slice(4):netName,MountedBoard=class extends Subcircuit{constructor(){super(...arguments);__publicField(this,"pcb_board_id",null);__publicField(this,"_connectedSchematicPortPairs",new Set)}get config(){return{componentName:"MountedBoard",zodProps:mountedboardProps}}get boardThickness(){return 1.6}get allLayers(){return["top","bottom"]}_getBoardCalcVariables(){return this._findCarrierBoard()?._getBoardCalcVariables()??{}}_findCarrierBoard(){let current23=this.parent;for(;current23;){if(current23 instanceof Board)return current23;current23=current23.parent}return null}doInitialPcbComponentRender(){if(this.root?.pcbDisabled)return;let{db:db22}=this.root,{_parsedProps:props}=this,globalPos=this._getGlobalPcbPositionBeforeLayout(),pcb_board23=db22.pcb_board.insert({center:{x:globalPos.x,y:globalPos.y},width:props.width??0,height:props.height??0,is_mounted_to_carrier_board:!0});this.pcb_board_id=pcb_board23.pcb_board_id}doInitialPcbBoardAutoSize(){if(!this.pcb_board_id||!this.root)return;let carrierBoard=this._findCarrierBoard();carrierBoard?.pcb_board_id&&this.root.db.pcb_board.update(this.pcb_board_id,{carrier_pcb_board_id:carrierBoard.pcb_board_id})}},PanelTab=class extends PrimitiveComponent{get config(){return{componentName:"PanelTab",zodProps:panelTabProps}}doInitialPcbComponentRender(){if(!this.root?.pcbDisabled&&this.parent?.componentName!=="Panel"&&this.parent?.componentName!=="Subpanel")throw new Error("<paneltab> must be a direct child of <panel> or <subpanel>")}},PanelTabKeepout=class extends PrimitiveComponent{get config(){return{componentName:"PanelTabKeepout",zodProps:panelTabKeepoutProps}}doInitialPcbComponentRender(){if(!this.root?.pcbDisabled&&this.parent?.componentName!=="Panel"&&this.parent?.componentName!=="Subpanel")throw new Error("<paneltabkeepout> must be a direct child of <panel> or <subpanel>")}};function getPointAlongOutline(edges,{perimeterDistance,leftOffsetMm=0}){let perimeter=edges.at(-1).perimeterStart+edges.at(-1).length,wrappedDistance=(perimeterDistance%perimeter+perimeter)%perimeter,edge=edges.find(outlineEdge=>wrappedDistance<=outlineEdge.perimeterStart+outlineEdge.length)??edges.at(-1),ccwRotationDegrees=Math.atan2(edge.end.y-edge.start.y,edge.end.x-edge.start.x)*180/Math.PI;return applyToPoint3(compose3(translate8(edge.start.x,edge.start.y),rotateDEG3(ccwRotationDegrees)),{x:wrappedDistance-edge.perimeterStart,y:leftOffsetMm})}function getOutwardSlotBoundary(route2,options){let normals=route2.slice(1).map((end,routeIndex)=>{let start=route2[routeIndex],length93=Math.hypot(end.x-start.x,end.y-start.y);return{x:options.winding*(end.y-start.y)/length93,y:-options.winding*(end.x-start.x)/length93}});return route2.flatMap((position22,routeIndex)=>{let before=normals[Math.max(0,routeIndex-1)],after=normals[Math.min(normals.length-1,routeIndex)],denominator=1+before.x*after.x+before.y*after.y;return denominator<1e-8?[before,after].map(normal=>applyToPoint3(translate8(normal.x*options.width,normal.y*options.width),position22)):[applyToPoint3(translate8((before.x+after.x)*options.width/denominator,(before.y+after.y)*options.width/denominator),position22)]})}function getOutlineSpan({edges,startPerimeterDistance,endPerimeterDistance}){let perimeter=edges.at(-1).perimeterStart+edges.at(-1).length,route2=[getPointAlongOutline(edges,{perimeterDistance:startPerimeterDistance})];for(let lap of[0,1])for(let edge of edges){let vertexDistance=edge.perimeterStart+lap*perimeter;vertexDistance>startPerimeterDistance+1e-9&&vertexDistance<endPerimeterDistance-1e-9&&route2.push(edge.start)}return route2.push(getPointAlongOutline(edges,{perimeterDistance:endPerimeterDistance})),route2}function generateContinuousPanelRoutingSlots(outline,options){let edges=[],perimeter=0,twiceSignedArea=0;for(let outlineIndex=0;outlineIndex<outline.length;outlineIndex++){let start=outline[outlineIndex],end=outline[(outlineIndex+1)%outline.length],length93=Math.hypot(end.x-start.x,end.y-start.y);length93<1e-9||(edges.push({start,end,length:length93,perimeterStart:perimeter}),perimeter+=length93,twiceSignedArea+=start.x*end.y-end.x*start.y)}if(edges.length<3||Math.abs(twiceSignedArea)<1e-9)return{tabCutouts:[],mouseBites:[],tabBridges:[]};let requestedGapLength=options.gapLength,tabCenters=edges.filter(edge=>edge.length>=requestedGapLength+2*options.cutoutWidth).map(edge=>edge.perimeterStart+edge.length/2);tabCenters.length<2&&(tabCenters=[0,1,2,3].map(quarter=>(quarter+.5)*perimeter/4));let gapLength=Math.min(requestedGapLength,perimeter/(2*tabCenters.length)),tabCutouts=[],mouseBites=[],tabBridges=[];for(let tabIndex=0;tabIndex<tabCenters.length;tabIndex++){let tabCenter=tabCenters[tabIndex],nextTabCenter=tabCenters[(tabIndex+1)%tabCenters.length]+(tabIndex===tabCenters.length-1?perimeter:0),routeStart=tabCenter+gapLength/2,routeEnd=nextTabCenter-gapLength/2,route2=getOutlineSpan({edges,startPerimeterDistance:routeStart,endPerimeterDistance:routeEnd}),outerBoundary=getOutwardSlotBoundary(route2,{width:options.cutoutWidth,winding:Math.sign(twiceSignedArea)});if(tabCutouts.push({type:"pcb_cutout",pcb_cutout_id:`panel_continuous_slot_${tabIndex}`,shape:"polygon",points:[...route2,...outerBoundary.reverse()]}),gapLength>1e-6){let tabRoute=getOutlineSpan({edges,startPerimeterDistance:tabCenter-gapLength/2,endPerimeterDistance:tabCenter+gapLength/2}),tabOuterBoundary=getOutwardSlotBoundary(tabRoute,{width:2*options.cutoutWidth,winding:Math.sign(twiceSignedArea)}),bridgeOutline=[...tabRoute,...tabOuterBoundary.reverse()];if(tabBridges.push(bridgeOutline),options.mouseBites&&options.mouseBiteHoleDiameter>0&&gapLength>=options.mouseBiteHoleDiameter){let pitch=options.mouseBiteHoleDiameter+options.mouseBiteHoleSpacing,holeCount=Math.floor((gapLength-options.mouseBiteHoleDiameter)/pitch)+1;for(let holeIndex=0;holeIndex<holeCount;holeIndex++){let offset3=(holeIndex-(holeCount-1)/2)*pitch,perimeterDistance=tabCenter+offset3,boardEdge=getPointAlongOutline(edges,{perimeterDistance}),routingEdge=getPointAlongOutline(edges,{perimeterDistance,leftOffsetMm:-Math.sign(twiceSignedArea)*options.cutoutWidth});mouseBites.push({boardEdge,outwardNormal:vector$1(point2(boardEdge.x,boardEdge.y),point2(routingEdge.x,routingEdge.y)).normalize(),bridgeOutline})}}}}return{tabCutouts,mouseBites,tabBridges}}function getPanelRoutingSlotPolygon(cutout){if(cutout.shape==="polygon"){let polygon42=new Polygon$1(cutout.points.map(({x:x23,y:y23})=>point2(x23,y23)));return polygon42.orientation()===ORIENTATION.CW?polygon42.reverse():polygon42}let halfWidth=cutout.width/2,halfHeight=cutout.height/2,radius=Math.min(cutout.corner_radius??0,halfWidth,halfHeight),polygon32;if(radius<=0)polygon32=new Polygon$1(new Box(-halfWidth,-halfHeight,halfWidth,halfHeight));else{let arcs=[point2(halfWidth-radius,halfHeight-radius),point2(-halfWidth+radius,halfHeight-radius),point2(-halfWidth+radius,-halfHeight+radius),point2(halfWidth-radius,-halfHeight+radius)].map((center2,cornerIndex)=>new Arc(center2,radius,cornerIndex*Math.PI/2,(cornerIndex+1)*Math.PI/2,!0));polygon32=new Polygon$1(arcs.flatMap((arc32,cornerIndex)=>{let nextArc=arcs[(cornerIndex+1)%arcs.length];return arc32.end.equalTo(nextArc.start)?[arc32]:[arc32,segment(arc32.end,nextArc.start)]}))}let cutoutLocalToCircuitWorldTransform=compose3(translate8(cutout.center.x,cutout.center.y),rotateDEG3(cutout.rotation??0));return polygon32.transform(new Matrix(cutoutLocalToCircuitWorldTransform.a,cutoutLocalToCircuitWorldTransform.b,cutoutLocalToCircuitWorldTransform.c,cutoutLocalToCircuitWorldTransform.d,cutoutLocalToCircuitWorldTransform.e,cutoutLocalToCircuitWorldTransform.f))}var POSITION_TOLERANCE_MM=1e-6;function getRoutingIntervals({routingPolygon,boardEdge,outwardNormal}){let origin=point2(boardEdge.x,boardEdge.y),rayLine=line(origin,origin.translate(outwardNormal)),distances=routingPolygon.intersect(rayLine).map(position22=>vector$1(origin,position22).dot(outwardNormal)).sort((a23,b23)=>a23-b23),intervals=[];for(let boundaryIndex=0;boundaryIndex<distances.length-1;boundaryIndex++){let start=Math.max(0,distances[boundaryIndex]),end=distances[boundaryIndex+1];if(end-start<=POSITION_TOLERANCE_MM)continue;let midpoint32=origin.translate(outwardNormal.multiply((start+end)/2));routingPolygon.contains(midpoint32)&&intervals.push({start,end})}return intervals}function getConnectedIntervalEnd(intervals){let orderedIntervals=intervals.toSorted((a23,b23)=>a23.start-b23.start),end=0;for(let interval of orderedIntervals){if(interval.start>end+POSITION_TOLERANCE_MM)break;end=Math.max(end,interval.end)}return end}function getPanelMouseBitePositions({mouseBites,routingCutouts,minimumDrillPitch}){if(mouseBites.length===0)return[];let routingPolygons=routingCutouts.map(getPanelRoutingSlotPolygon),drillPositions=new Map;for(let{boardEdge}of mouseBites){let positionKey=`${Math.round(boardEdge.x/POSITION_TOLERANCE_MM)},${Math.round(boardEdge.y/POSITION_TOLERANCE_MM)}`;drillPositions.has(positionKey)||drillPositions.set(positionKey,boardEdge)}for(let{boardEdge,outwardNormal,bridgeOutline}of mouseBites){let channelEnd=getConnectedIntervalEnd(routingPolygons.flatMap(routingPolygon=>getRoutingIntervals({routingPolygon,boardEdge,outwardNormal}))),bridgeEnd=getConnectedIntervalEnd(getRoutingIntervals({routingPolygon:new Polygon$1(bridgeOutline.map(({x:x23,y:y23})=>point2(x23,y23))),boardEdge,outwardNormal})),oppositeEdgeDistance=Math.min(channelEnd,bridgeEnd);if(oppositeEdgeDistance<=POSITION_TOLERANCE_MM)throw new Error("Could not locate the routed channel beside a panel tab");let oppositeEdge=point2(boardEdge.x,boardEdge.y).translate(outwardNormal.multiply(oppositeEdgeDistance)),positionKey=`${Math.round(oppositeEdge.x/POSITION_TOLERANCE_MM)},${Math.round(oppositeEdge.y/POSITION_TOLERANCE_MM)}`;if(drillPositions.has(positionKey))continue;[...drillPositions.values()].some(position22=>Math.hypot(position22.x-oppositeEdge.x,position22.y-oppositeEdge.y)<minimumDrillPitch-POSITION_TOLERANCE_MM)||drillPositions.set(positionKey,{x:oppositeEdge.x,y:oppositeEdge.y})}return[...drillPositions.values()]}function getSlotPolygonsWithoutHoles(polygon32){let hole=[...polygon32.faces].find(face2=>face2.orientation()===ORIENTATION.CW);if(!hole)return polygon32.splitToIslands();let bounds=polygon32.box,splitX=hole.box.center.x;return[new Box(bounds.xmin-1,bounds.ymin-1,splitX,bounds.ymax+1),new Box(splitX,bounds.ymin-1,bounds.xmax+1,bounds.ymax+1)].flatMap(half=>getSlotPolygonsWithoutHoles(BooleanOperations.intersect(polygon32,new Polygon$1(half))))}function preservePanelTabBridges(cutouts,tabBridges){let bridges=tabBridges.map(vertices=>{let polygon32=new Polygon$1(vertices.map(({x:x23,y:y23})=>point2(x23,y23)));return polygon32.orientation()===ORIENTATION.CW?polygon32.reverse():polygon32});return cutouts.flatMap(cutout=>{let slot=getPanelRoutingSlotPolygon(cutout),changed=!1;for(let bridge of bridges)slot.box.not_intersect(bridge.box)||BooleanOperations.intersect(slot,bridge).area()<1e-8||(slot=BooleanOperations.subtract(slot,bridge),changed=!0);return changed?getSlotPolygonsWithoutHoles(slot).map(polygon32=>({type:"pcb_cutout",pcb_cutout_id:cutout.pcb_cutout_id,shape:"polygon",points:[...polygon32.faces].flatMap(face2=>face2.shapes.flatMap(shape50=>{if(shape50 instanceof Segment$1)return[{x:shape50.start.x,y:shape50.start.y}];let maxAngle=2*Math.acos(1-Math.min(.001/shape50.r,1)),steps=Math.max(1,Math.ceil(shape50.sweep/maxAngle));return Array.from({length:steps},(_23,arcIndex)=>{let position22=shape50.pointAtLength(shape50.length*arcIndex/steps);return{x:position22.x,y:position22.y}})}))})):[cutout]})}var DEFAULT_TAB_LENGTH=5,DEFAULT_TAB_WIDTH=2,TAB_SCALE_REFERENCE_BOARD_SIZE=20,MIN_TAB_SCALE=.3,MOUSE_BITE_DIAMETER_TO_TAB_WIDTH=.45,MOUSE_BITE_SPACING_TO_DIAMETER=.5;function getScaledPanelTabSize({minimumBoardDimension,tabWidth,tabLength}){let scale52=Math.max(minimumBoardDimension/TAB_SCALE_REFERENCE_BOARD_SIZE,MIN_TAB_SCALE);return{tabWidth:Math.min(tabWidth,DEFAULT_TAB_WIDTH*scale52),tabLength:Math.min(tabLength,DEFAULT_TAB_LENGTH*scale52)}}function getMouseBiteSize({tabWidth}){let diameter=tabWidth*MOUSE_BITE_DIAMETER_TO_TAB_WIDTH;return{diameter,spacing:diameter*MOUSE_BITE_SPACING_TO_DIAMETER}}var generateCutoutsAndMousebitesForOutline=(outline,options)=>{let{gapLength,cutoutWidth,mouseBites:useMouseBites,mouseBiteHoleDiameter,mouseBiteHoleSpacing,vScore}=options,tabCutouts=[],mouseBites=[],tabBridges=[],vScoreLines=[];if(outline.length<2)return{tabCutouts,mouseBites,tabBridges,vScoreLines};if(outline.some((position22,outlineIndex)=>{let previousPosition=outline[(outlineIndex-1+outline.length)%outline.length],nextPosition=outline[(outlineIndex+1)%outline.length],incomingLength=Math.hypot(position22.x-previousPosition.x,position22.y-previousPosition.y),segmentLength=Math.hypot(nextPosition.x-position22.x,nextPosition.y-position22.y),directionCosine=((position22.x-previousPosition.x)*(nextPosition.x-position22.x)+(position22.y-previousPosition.y)*(nextPosition.y-position22.y))/(incomingLength*segmentLength);return incomingLength>1e-9&&segmentLength>1e-9&&segmentLength<gapLength+2*cutoutWidth&&directionCosine>Math.cos(Math.PI/12)})){if(vScore)throw new Error("V-scored panel tabs require straight board edges; curved board outlines cannot be V-scored");return{...generateContinuousPanelRoutingSlots(outline,options),vScoreLines}}let outlinePolygon=new Polygon$1(outline.map(p23=>point2(p23.x,p23.y))),is_ccw;if(outline.length>2){let p03=point2(outline[0].x,outline[0].y),p13=point2(outline[1].x,outline[1].y),segmentDir=vector$1(p03,p13).normalize(),normalToLeft=segmentDir.rotate(Math.PI/2),testPoint=p03.translate(segmentDir.multiply(segment(p03,p13).length/2)).translate(normalToLeft.multiply(.01));is_ccw=outlinePolygon.contains(testPoint)}else is_ccw=outlinePolygon.area()>0;for(let i23=0;i23<outline.length;i23++){let p1_=outline[i23],p2_=outline[(i23+1)%outline.length];if(!p1_||!p2_)continue;let p13=point2(p1_.x,p1_.y),p23=point2(p2_.x,p2_.y),segment5=segment(p13,p23),segmentLength=segment5.length;if(segmentLength<1e-6)continue;let segmentVec=vector$1(p13,p23),segmentDir=segmentVec.normalize(),normalVec=segmentDir.rotate(Math.PI/2),testPoint=segment5.middle().translate(normalVec.multiply(.01));outlinePolygon.contains(testPoint)&&(normalVec=normalVec.multiply(-1));let effectiveGapLength=Math.min(gapLength,segmentLength*.9),holeAndSpacing=mouseBiteHoleDiameter+mouseBiteHoleSpacing,numBitesInGap=mouseBiteHoleDiameter>0&&holeAndSpacing>0?Math.max(0,Math.floor((effectiveGapLength-mouseBiteHoleDiameter)/holeAndSpacing)+1):0,totalBitesLength=numBitesInGap*mouseBiteHoleDiameter+(numBitesInGap-1)*mouseBiteHoleSpacing,gapStartDist=(segmentLength-effectiveGapLength)/2,gapEndDist=gapStartDist+effectiveGapLength,extrusion=normalVec.multiply(cutoutWidth),tabStart=p13.translate(segmentDir.multiply(gapStartDist)),tabEnd=p13.translate(segmentDir.multiply(gapEndDist)),bridgeOutline=[tabStart,tabEnd,tabEnd.translate(extrusion.multiply(2)),tabStart.translate(extrusion.multiply(2))].map(({x:x23,y:y23})=>({x:x23,y:y23}));if(effectiveGapLength>1e-6&&tabBridges.push(bridgeOutline),vScore&&effectiveGapLength>1e-6&&vScoreLines.push([{x:tabStart.x,y:tabStart.y},{x:tabEnd.x,y:tabEnd.y}]),useMouseBites&&numBitesInGap>0&&effectiveGapLength>=totalBitesLength){let firstBiteCenterOffsetInGap=(effectiveGapLength-totalBitesLength)/2+mouseBiteHoleDiameter/2,firstBiteDistFromP1=gapStartDist+firstBiteCenterOffsetInGap;for(let k23=0;k23<numBitesInGap;k23++){let biteDist=firstBiteDistFromP1+k23*holeAndSpacing,pos=p13.translate(segmentDir.multiply(biteDist));mouseBites.push({boardEdge:{x:pos.x,y:pos.y},outwardNormal:normalVec,bridgeOutline})}}let p_prev_=outline[(i23-1+outline.length)%outline.length],p_next_=outline[(i23+2)%outline.length],start_ext=0,end_ext=0;if(p_prev_&&p_next_){let vec_in_p1=vector$1(point2(p_prev_.x,p_prev_.y),p13),p1_cross=vec_in_p1.cross(segmentVec),is_p1_convex=is_ccw?p1_cross>1e-9:p1_cross<-1e-9,vec_out_p2=vector$1(p23,point2(p_next_.x,p_next_.y)),p2_cross=segmentVec.cross(vec_out_p2),is_p2_convex=is_ccw?p2_cross>1e-9:p2_cross<-1e-9;if(is_p1_convex){let angle3=vec_in_p1.angleTo(segmentVec);angle3>Math.PI&&(angle3=2*Math.PI-angle3),start_ext=cutoutWidth*Math.tan(angle3/2)}else start_ext=0;if(is_p2_convex){let angle3=segmentVec.angleTo(vec_out_p2);angle3>Math.PI&&(angle3=2*Math.PI-angle3),end_ext=cutoutWidth*Math.tan(angle3/2)}else end_ext=0}let cutoutParts=effectiveGapLength<1e-6?[{start:0-start_ext,end:segmentLength+end_ext}]:[{start:0-start_ext,end:gapStartDist},{start:gapEndDist,end:segmentLength+end_ext}];for(let part of cutoutParts){let partLength=part.end-part.start;if(partLength<1e-6)continue;let center2=p13.translate(segmentDir.multiply(part.start+partLength/2)).translate(extrusion.multiply(.5)),width10=partLength,height10=cutoutWidth,rotationDeg=segmentDir.slope*180/Math.PI;tabCutouts.push({type:"pcb_cutout",pcb_cutout_id:"panel_tab_slot",shape:"rect",center:{x:center2.x,y:center2.y},width:width10,height:height10,rotation:rotationDeg,corner_radius:cutoutWidth/2})}}return{tabCutouts,mouseBites,tabBridges,vScoreLines}};function generatePanelTabsAndMouseBites(boards,options){let finalTabCutouts=[],allMouseBites=[],tabBridges=[],vScoreLines=[],{tabWidth,tabLength,mouseBites:useMouseBites,vScore=!1}=options,boardDimensions=[];for(let board of boards)if(board.width&&board.height)boardDimensions.push(Math.min(board.width,board.height));else if(board.outline&&board.outline.length>0){let outlinePolygon=new Polygon$1(board.outline.map(p23=>point2(p23.x,p23.y))),area3=Math.abs(outlinePolygon.area());area3>0&&boardDimensions.push(Math.sqrt(area3))}boardDimensions.length>0&&({tabWidth,tabLength}=getScaledPanelTabSize({minimumBoardDimension:Math.min(...boardDimensions),tabWidth,tabLength}));let processedBoards=boards.map(board=>{if((!board.outline||board.outline.length===0)&&board.width&&board.height){let w23=board.width/2,h23=board.height/2;return{...board,outline:[{x:board.center.x-w23,y:board.center.y-h23},{x:board.center.x+w23,y:board.center.y-h23},{x:board.center.x+w23,y:board.center.y+h23},{x:board.center.x-w23,y:board.center.y+h23}]}}return board}),{diameter:mouseBiteDiameter,spacing:mouseBiteSpacing}=getMouseBiteSize({tabWidth});for(let board of processedBoards)if(board.outline&&board.outline.length>0){let generated=generateCutoutsAndMousebitesForOutline(board.outline,{gapLength:tabLength,cutoutWidth:tabWidth,mouseBites:useMouseBites,mouseBiteHoleDiameter:mouseBiteDiameter,mouseBiteHoleSpacing:mouseBiteSpacing,vScore});finalTabCutouts.push(...generated.tabCutouts),allMouseBites.push(...generated.mouseBites),tabBridges.push(...generated.tabBridges),vScoreLines.push(...generated.vScoreLines)}let tabCutouts=preservePanelTabBridges(finalTabCutouts,tabBridges).map((tab,index2)=>({...tab,pcb_cutout_id:`panel_tab_${index2}`})),mouseBitePositions=[];useMouseBites&&(mouseBitePositions=getPanelMouseBitePositions({mouseBites:allMouseBites,routingCutouts:generatePanelOutlineRoutingCutouts(processedBoards,{cutoutWidth:tabWidth}),minimumDrillPitch:mouseBiteDiameter+mouseBiteSpacing}));let mouseBiteHoles=mouseBitePositions.map((bite,index2)=>({type:"pcb_hole",pcb_hole_id:`panel_mouse_bite_${index2}`,hole_shape:"circle",hole_diameter:mouseBiteDiameter,x:bite.x,y:bite.y}));return{tabCutouts,mouseBiteHoles,vScoreLines}}function generatePanelOutlineRoutingCutouts(boards,options){return boards.map(board=>{if((!board.outline||board.outline.length===0)&&board.width&&board.height){let halfWidth=board.width/2,halfHeight=board.height/2;return{...board,outline:[{x:board.center.x-halfWidth,y:board.center.y-halfHeight},{x:board.center.x+halfWidth,y:board.center.y-halfHeight},{x:board.center.x+halfWidth,y:board.center.y+halfHeight},{x:board.center.x-halfWidth,y:board.center.y+halfHeight}]}}return board}).flatMap(board=>{if(!board.outline||board.outline.length===0)return[];let{tabCutouts}=generateCutoutsAndMousebitesForOutline(board.outline,{gapLength:0,cutoutWidth:options.cutoutWidth,mouseBites:!1,mouseBiteHoleDiameter:0,mouseBiteHoleSpacing:0,vScore:!1});return tabCutouts.map(cutout=>({...cutout,pcb_board_id:board.pcb_board_id}))}).map((cutout,outlineRoutingCutoutIndex)=>({...cutout,pcb_cutout_id:`panel_outline_routing_cutout_${outlineRoutingCutoutIndex}`}))}function getRectangularPanelBoardBounds(board){let firstCorner=board.outline?.[0],outline=board.outline?.filter((position22,outlineIndex)=>outlineIndex===0||position22.x!==firstCorner?.x||position22.y!==firstCorner?.y);if(outline?.length){let minX=Math.round(Math.min(...outline.map(position22=>position22.x))*1e6)/1e6,maxX=Math.round(Math.max(...outline.map(position22=>position22.x))*1e6)/1e6,minY=Math.round(Math.min(...outline.map(position22=>position22.y))*1e6)/1e6,maxY=Math.round(Math.max(...outline.map(position22=>position22.y))*1e6)/1e6;if(new Set(outline.map(position22=>`${Math.round(position22.x*1e6)}:${Math.round(position22.y*1e6)}`)).size!==4||outline.some(position22=>Math.abs(position22.x-minX)>1e-6&&Math.abs(position22.x-maxX)>1e-6||Math.abs(position22.y-minY)>1e-6&&Math.abs(position22.y-maxY)>1e-6))throw new Error("Panel tab controls require axis-aligned rectangular board outlines");return{minX,maxX,minY,maxY}}if(board.width===void 0||board.height===void 0||board.width<=0||board.height<=0)throw new Error("Panel tab controls require positive rectangular board dimensions");return{minX:board.center.x-board.width/2,maxX:board.center.x+board.width/2,minY:board.center.y-board.height/2,maxY:board.center.y+board.height/2}}var getPanelTabCentreAlongEdge=({tab,edgeLength})=>tab.boardEdge==="top"||tab.boardEdge==="bottom"?tab.centerOffsetFromBoardLeftEdge??edgeLength-tab.centerOffsetFromBoardRightEdge:tab.centerOffsetFromBoardBottomEdge??edgeLength-tab.centerOffsetFromBoardTopEdge;function generateControlledPanelTabs(boards,options){let tabCutouts=[],mouseBiteHoles=[],tabBridges=[],dimensions6=boards.map(({board})=>getRectangularPanelBoardBounds(board)),minimumBoardDimension=Math.min(...dimensions6.flatMap(bounds=>[bounds.maxX-bounds.minX,bounds.maxY-bounds.minY])),{tabWidth,tabLength}=getScaledPanelTabSize({minimumBoardDimension,tabWidth:options.tabWidth,tabLength:options.tabLength}),mouseBiteSize=getMouseBiteSize({tabWidth}),drillDiameter=mouseBiteSize.diameter,drillPitch=mouseBiteSize.diameter+mouseBiteSize.spacing;for(let control of[...options.tabs??[],...options.tabKeepouts??[]])if(control.boardName&&!boards.some(({boardName})=>boardName===control.boardName))throw new Error(`Unknown board name "${control.boardName}" in panel tabs`);for(let{board,boardName}of boards){let bounds=getRectangularPanelBoardBounds(board),edges=[{side:"top",origin:{x:bounds.minX,y:bounds.maxY},length:bounds.maxX-bounds.minX,ccwRotationDegrees:0,outwardSign:1},{side:"bottom",origin:{x:bounds.minX,y:bounds.minY},length:bounds.maxX-bounds.minX,ccwRotationDegrees:0,outwardSign:-1},{side:"left",origin:{x:bounds.minX,y:bounds.minY},length:bounds.maxY-bounds.minY,ccwRotationDegrees:90,outwardSign:1},{side:"right",origin:{x:bounds.maxX,y:bounds.minY},length:bounds.maxY-bounds.minY,ccwRotationDegrees:90,outwardSign:-1}],boardTabCount=0;for(let edge of edges){let explicitTabs=options.tabs,tabPlacements=explicitTabs===void 0?Array.from({length:options.tabCountPerEdge??1},(_23,tabIndex)=>({centre:(tabIndex+1)*edge.length/((options.tabCountPerEdge??1)+1),length:tabLength})):explicitTabs.filter(tab=>tab.boardEdge===edge.side&&(!tab.boardName||tab.boardName===boardName)).map(tab=>({centre:getPanelTabCentreAlongEdge({tab,edgeLength:edge.length}),length:tab.tabWidth??tabLength})),keepouts=options.tabKeepouts?.filter(keepout=>keepout.boardEdge===edge.side&&(!keepout.boardName||keepout.boardName===boardName))??[],intervals=[];for(let{centre,length:length93}of tabPlacements.sort((firstTab,secondTab)=>firstTab.centre-secondTab.centre)){let start=centre-length93/2,end=centre+length93/2;if(start<0||end>edge.length)throw new Error(`A ${edge.side} tab on ${boardName} extends beyond the board edge. Reduce tabLength or move the tab.`);if(keepouts.some(keepout=>end>=keepout.from&&start<=keepout.to)){if(explicitTabs)throw new Error(`An explicit ${edge.side} tab on ${boardName} overlaps a tab keepout`);continue}if(intervals.at(-1)&&start<intervals.at(-1).end)throw new Error(`The ${edge.side} tabs on ${boardName} overlap. Reduce their count or tabLength.`);let previousTab=intervals.at(-1);if(previousTab&&start-previousTab.end<tabWidth-1e-9)throw new Error(`The ${edge.side} tabs on ${boardName} leave insufficient router clearance. Reduce their count, tabLength, or tabWidth.`);intervals.push({start,end,centre})}boardTabCount+=intervals.length;let edgeToWorldTransform=compose3(translate8(edge.origin.x,edge.origin.y),rotateDEG3(edge.ccwRotationDegrees));for(let interval of intervals)tabBridges.push([{x:interval.start,y:0},{x:interval.end,y:0},{x:interval.end,y:edge.outwardSign*2*tabWidth},{x:interval.start,y:edge.outwardSign*2*tabWidth}].map(point12=>applyToPoint3(edgeToWorldTransform,point12)));let routeStart=-tabWidth;for(let interval of[...intervals,{start:edge.length+tabWidth,end:edge.length+tabWidth,centre:edge.length}]){let routeLength3=interval.start-routeStart;routeLength3>1e-9&&tabCutouts.push({pcb_cutout_id:`pcb_cutout_panel_tab_${board.pcb_board_id}_${tabCutouts.length}`,type:"pcb_cutout",shape:"rect",center:applyToPoint3(edgeToWorldTransform,{x:routeStart+routeLength3/2,y:edge.outwardSign*tabWidth/2}),width:routeLength3,height:tabWidth,rotation:edge.ccwRotationDegrees,corner_radius:Math.min(routeLength3,tabWidth)/2}),routeStart=interval.end}if(options.mouseBites&&drillDiameter>0)for(let interval of intervals){let intervalLength=interval.end-interval.start;if(intervalLength<drillDiameter)continue;let holeCount=Math.floor((intervalLength-drillDiameter)/drillPitch)+1;for(let holeIndex=0;holeIndex<holeCount;holeIndex++){let position22=applyToPoint3(edgeToWorldTransform,{x:interval.centre+(holeIndex-(holeCount-1)/2)*drillPitch,y:0});mouseBiteHoles.push({pcb_hole_id:`pcb_hole_panel_mouse_bite_${board.pcb_board_id}_${mouseBiteHoles.length}`,type:"pcb_hole",hole_shape:"circle",hole_diameter:drillDiameter,...position22})}}}if(boardTabCount===0)throw new Error(`${boardName} has no panel tabs and would be cut free of the panel. Add a <paneltab> for it or narrow its <paneltabkeepout>.`)}return{tabCutouts:preservePanelTabBridges(tabCutouts,tabBridges).map((cutout,cutoutIndex)=>({...cutout,pcb_cutout_id:`pcb_cutout_panel_tab_${cutoutIndex}`})),mouseBiteHoles}}var getBoardDimensionsFromProps=board=>{let props=board._parsedProps,width10=props.width!=null?distance4.parse(props.width):void 0,height10=props.height!=null?distance4.parse(props.height):void 0;if((width10===void 0||height10===void 0)&&props.outline?.length){let outlineBounds=getBoundsFromPoints3(props.outline);outlineBounds&&(width10??(width10=outlineBounds.maxX-outlineBounds.minX),height10??(height10=outlineBounds.maxY-outlineBounds.minY))}if((width10===void 0||height10===void 0)&&props.circuitJson?.length){let pcbBoardFromJson=props.circuitJson.find(elm=>elm.type==="pcb_board");pcbBoardFromJson&&(width10??(width10=pcbBoardFromJson.width),height10??(height10=pcbBoardFromJson.height))}return{width:width10??0,height:height10??0}};function packIntoGrid({items,db:db22,row,col,cellWidth,cellHeight,boardGap,availablePanelWidth,availablePanelHeight}){let itemsWithDims=items.map(item=>{let dims=getItemDimensions(item,db22);return{item,width:dims.width,height:dims.height}}).filter(item=>!(item.width===0&&item.height===0));if(itemsWithDims.length===0)return{positions:[],gridWidth:0,gridHeight:0};let cols,rows,minCellWidth=cellWidth?distance4.parse(cellWidth):0,minCellHeight=cellHeight?distance4.parse(cellHeight):0;if(col!==void 0)cols=col,rows=row??Math.ceil(itemsWithDims.length/cols);else if(row!==void 0)rows=row,cols=Math.ceil(itemsWithDims.length/rows);else if(availablePanelWidth!==void 0&&availablePanelHeight!==void 0){let maxItemWidth=Math.max(...itemsWithDims.map(b23=>b23.width),minCellWidth),maxItemHeight=Math.max(...itemsWithDims.map(b23=>b23.height),minCellHeight),maxCols=Math.max(1,Math.floor((availablePanelWidth+boardGap)/(maxItemWidth+boardGap))),maxRows=Math.max(1,Math.floor((availablePanelHeight+boardGap)/(maxItemHeight+boardGap)));cols=maxCols,rows=Math.ceil(itemsWithDims.length/cols),rows>maxRows&&(rows=maxRows,cols=Math.ceil(itemsWithDims.length/rows),cols>maxCols&&(cols=maxCols,rows=Math.ceil(itemsWithDims.length/cols))),cols=Math.max(1,cols),rows=Math.max(1,rows)}else cols=Math.ceil(Math.sqrt(itemsWithDims.length)),rows=Math.ceil(itemsWithDims.length/cols);let colWidths=Array(cols).fill(0),rowHeights=Array(rows).fill(0);itemsWithDims.forEach((item,i23)=>{let colIdx=i23%cols,rowIdx=Math.floor(i23/cols);rowIdx<rowHeights.length&&item.height>rowHeights[rowIdx]&&(rowHeights[rowIdx]=item.height),colIdx<colWidths.length&&item.width>colWidths[colIdx]&&(colWidths[colIdx]=item.width)});for(let i23=0;i23<colWidths.length;i23++)colWidths[i23]=Math.max(colWidths[i23],minCellWidth);for(let i23=0;i23<rowHeights.length;i23++)rowHeights[i23]=Math.max(rowHeights[i23],minCellHeight);let gridWidth=colWidths.reduce((a23,b23)=>a23+b23,0)+(cols>1?(cols-1)*boardGap:0),gridHeight=rowHeights.reduce((a23,b23)=>a23+b23,0)+(rows>1?(rows-1)*boardGap:0),startX=-gridWidth/2,startY=-gridHeight/2,colXOffsets=[startX];for(let i23=1;i23<cols;i23++)colXOffsets.push(colXOffsets[i23-1]+colWidths[i23-1]+boardGap);let rowYOffsets=[startY];for(let i23=1;i23<rows;i23++)rowYOffsets.push(rowYOffsets[i23-1]+rowHeights[i23-1]+boardGap);let positions=[];return itemsWithDims.forEach((itemWithDims,i23)=>{let colIdx=i23%cols,rowIdx=Math.floor(i23/cols);if(rowIdx>=rowYOffsets.length||colIdx>=colXOffsets.length)return;let x23=colXOffsets[colIdx]+colWidths[colIdx]/2,y23=rowYOffsets[rowIdx]+rowHeights[rowIdx]/2;positions.push({item:itemWithDims.item,pos:{x:x23,y:y23}})}),{positions,gridWidth,gridHeight}}function getItemDimensions(item,db22){if(item.componentName==="Board"){let board=item;if(db22&&board.pcb_board_id){let pcbBoard=db22.pcb_board.get(board.pcb_board_id);if(pcbBoard?.width!==void 0&&pcbBoard?.height!==void 0)return{width:pcbBoard.width,height:pcbBoard.height}}return getBoardDimensionsFromProps(board)}if(item.componentName==="Subpanel"){let subpanel=item,props=subpanel._parsedProps;if(props.width!==void 0&&props.height!==void 0)return{width:distance4.parse(props.width),height:distance4.parse(props.height)};let directBoards=subpanel._getDirectBoardChildren();if(directBoards.length===0){let allBoards=subpanel._getAllBoardInstances();if(allBoards.length===0)return{width:0,height:0};let minX=1/0,minY=1/0,maxX=-1/0,maxY=-1/0;for(let board of allBoards){let dims=getBoardDimensionsFromProps(board);if(dims.width===0||dims.height===0)continue;let offset3=board._panelPositionOffset??{x:0,y:0};minX=Math.min(minX,offset3.x-dims.width/2),maxX=Math.max(maxX,offset3.x+dims.width/2),minY=Math.min(minY,offset3.y-dims.height/2),maxY=Math.max(maxY,offset3.y+dims.height/2)}return minX===1/0?{width:0,height:0}:{width:maxX-minX,height:maxY-minY}}if(directBoards.length===1)return getBoardDimensionsFromProps(directBoards[0]);if(subpanel._cachedGridWidth>0&&subpanel._cachedGridHeight>0){let edgePadding=distance4.parse(props.edgePadding??5);return{width:subpanel._cachedGridWidth+edgePadding*2,height:subpanel._cachedGridHeight+edgePadding*2}}let totalWidth=0,totalHeight=0;for(let board of directBoards){let dims=getBoardDimensionsFromProps(board);totalWidth=Math.max(totalWidth,dims.width),totalHeight=Math.max(totalHeight,dims.height)}return{width:totalWidth,height:totalHeight}}return{width:0,height:0}}var V_SCORE_LINE_LAYER="top",V_SCORE_LINE_STROKE_WIDTH=.1,Subpanel=class _Subpanel extends Group{constructor(){super(...arguments);__publicField(this,"pcb_panel_id",null);__publicField(this,"_panelizationFeaturesGenerated",!1);__publicField(this,"_cachedGridWidth",0);__publicField(this,"_cachedGridHeight",0);__publicField(this,"_panelPositionOffset",null)}get config(){return{componentName:"Subpanel",zodProps:subpanelProps}}get _errorComponentName(){return this.componentName.toLowerCase()}get isGroup(){return!0}get isSubcircuit(){return!0}_getPcbLayoutMode(){return"none"}doInitialSchematicComponentRender(){}doInitialSchematicLayout(){}doInitialSchematicTraceRender(){}add(component){let acceptsToolingRail=this.componentName==="Panel";if(component.lowercaseComponentName!=="board"&&component.lowercaseComponentName!=="subpanel"&&component.lowercaseComponentName!=="trace"&&component.lowercaseComponentName!=="hole"&&component.lowercaseComponentName!=="fiducial"&&component.lowercaseComponentName!=="hole"&&component.lowercaseComponentName!=="fiducial"&&component.lowercaseComponentName!=="silkscreentext"&&component.lowercaseComponentName!=="paneltab"&&component.lowercaseComponentName!=="paneltabkeepout"&&!(acceptsToolingRail&&component.lowercaseComponentName==="toolingrail"))throw new Error(acceptsToolingRail?`<${this._errorComponentName}> can only contain <board>, <subpanel>, <trace>, <hole>, <fiducial>, <silkscreentext>, <paneltab>, <paneltabkeepout>, or <toolingrail> elements`:`<${this._errorComponentName}> can only contain <board>, <subpanel>, <trace>, <hole>, <fiducial>, <silkscreentext>, <paneltab>, or <paneltabkeepout> elements`);super.add(component)}_getMaxGridSize(){return{width:1/0,height:1/0}}_computePcbGlobalTransformBeforeLayout(){if(this._panelPositionOffset){let parentTransform=this.parent?._computePcbGlobalTransformBeforeLayout?.()??identity7();return compose3(parentTransform,translate8(this._panelPositionOffset.x,this._panelPositionOffset.y))}return super._computePcbGlobalTransformBeforeLayout()}_getAllBoardInstances(){let boards=[];for(let child of this.children)child instanceof Board?boards.push(child):child instanceof _Subpanel&&boards.push(...child._getAllBoardInstances());return boards}_containsBoards(){for(let child of this.children)if(child.componentName==="Board"||child.componentName==="Subpanel"&&"_containsBoards"in child&&child._containsBoards())return!0;return!1}_getDirectBoardChildren(){return this.children.filter(c23=>c23 instanceof Board)}doInitialPanelBoardLayout(){if(this.root?.pcbDisabled)return;let layoutMode=this._parsedProps.layoutMode??"none",gridItems=this.children.filter(c23=>c23 instanceof Board||c23 instanceof _Subpanel);if(layoutMode!=="none")for(let child of gridItems)child instanceof Board&&child._hasUserDefinedPcbPosition()&&this.root.db.source_property_ignored_warning.insert({source_component_id:child.source_component_id,property_name:"pcbX/pcbY",message:`Board has manual positioning but ${this._errorComponentName} layout mode is "${layoutMode}". Manual positioning will be ignored.`,error_type:"source_property_ignored_warning"});if(layoutMode==="none"&&gridItems.length>1&&gridItems.filter(c23=>!c23._hasUserDefinedPcbPosition()).length>1&&this.root.db.pcb_placement_error.insert({error_type:"pcb_placement_error",message:`Multiple boards/subpanels in ${this._errorComponentName} without positions. When layoutMode="none", each item must have explicit positioning. Use layoutMode="grid" for automatic positioning.`}),layoutMode!=="grid")return;let tabWidth=this._parsedProps.tabWidth??DEFAULT_TAB_WIDTH,boardGap=this._parsedProps.boardGap??tabWidth,availablePanelWidth,availablePanelHeight,hasExplicitRowOrCol=this._parsedProps.row!==void 0||this._parsedProps.col!==void 0,hasExplicitWidth=this._parsedProps.width!==void 0,hasExplicitHeight=this._parsedProps.height!==void 0;if(!hasExplicitRowOrCol&&hasExplicitWidth&&hasExplicitHeight){let{edgePadding:edgePaddingProp,edgePaddingLeft:edgePaddingLeftProp,edgePaddingRight:edgePaddingRightProp,edgePaddingTop:edgePaddingTopProp,edgePaddingBottom:edgePaddingBottomProp}=this._parsedProps,edgePadding=distance4.parse(edgePaddingProp??5),edgePaddingLeft=distance4.parse(edgePaddingLeftProp??edgePadding),edgePaddingRight=distance4.parse(edgePaddingRightProp??edgePadding),edgePaddingTop=distance4.parse(edgePaddingTopProp??edgePadding),edgePaddingBottom=distance4.parse(edgePaddingBottomProp??edgePadding),panelWidth=distance4.parse(this._parsedProps.width),panelHeight=distance4.parse(this._parsedProps.height);availablePanelWidth=panelWidth-edgePaddingLeft-edgePaddingRight,availablePanelHeight=panelHeight-edgePaddingTop-edgePaddingBottom}let packingOptions={items:gridItems,row:this._parsedProps.row,col:this._parsedProps.col,cellWidth:this._parsedProps.cellWidth,cellHeight:this._parsedProps.cellHeight,boardGap,availablePanelHeight,availablePanelWidth},packedGrid=packIntoGrid(packingOptions),maxGridSize=this._getMaxGridSize(),fitsMaxGridSize=grid22=>grid22.gridWidth<=maxGridSize.width&&grid22.gridHeight<=maxGridSize.height;if(!hasExplicitRowOrCol&&!hasExplicitWidth&&!hasExplicitHeight&&!fitsMaxGridSize(packedGrid)){let fittingGrids=gridItems.map((_23,columnIndex)=>packIntoGrid({...packingOptions,col:columnIndex+1})).filter(fitsMaxGridSize).sort((firstGrid,secondGrid)=>firstGrid.gridWidth*firstGrid.gridHeight-secondGrid.gridWidth*secondGrid.gridHeight);fittingGrids[0]&&(packedGrid=fittingGrids[0])}let{positions,gridWidth,gridHeight}=packedGrid;this._cachedGridWidth=gridWidth,this._cachedGridHeight=gridHeight;for(let{item,pos}of positions)item._panelPositionOffset=pos}doInitialPanelLayout(){if(this.root?.pcbDisabled)return;let{db:db22}=this.root;if((this._parsedProps.layoutMode??"none")==="grid"){for(let child of this.children)if(child instanceof Board){if(!child.pcb_board_id||!child._panelPositionOffset)continue;db22.pcb_board.update(child.pcb_board_id,{position_mode:"relative_to_panel_anchor",display_offset_x:`${child._panelPositionOffset.x}mm`,display_offset_y:`${child._panelPositionOffset.y}mm`})}else if(child instanceof _Subpanel&&child._panelPositionOffset)for(let board of child._getAllBoardInstances()){if(!board.pcb_board_id)continue;let boardOffset=board._panelPositionOffset??{x:0,y:0};db22.pcb_board.update(board.pcb_board_id,{position_mode:"relative_to_panel_anchor",display_offset_x:`${child._panelPositionOffset.x+boardOffset.x}mm`,display_offset_y:`${child._panelPositionOffset.y+boardOffset.y}mm`})}this._updatePanelDimensions()}else{let panelGlobalPos=this._getGlobalPcbPositionBeforeLayout();for(let board of this._getDirectBoardChildren()){if(!board.pcb_board_id)continue;let boardDb=db22.pcb_board.get(board.pcb_board_id);if(!boardDb)continue;let relativeX=boardDb.center.x-panelGlobalPos.x,relativeY=boardDb.center.y-panelGlobalPos.y;db22.pcb_board.update(board.pcb_board_id,{position_mode:"relative_to_panel_anchor",display_offset_x:`${relativeX}mm`,display_offset_y:`${relativeY}mm`})}}this._generatePanelizationFeatures()}_updatePanelDimensions(){let{db:db22}=this.root,hasExplicitWidth=this._parsedProps.width!==void 0,hasExplicitHeight=this._parsedProps.height!==void 0,gridWidth=this._cachedGridWidth,gridHeight=this._cachedGridHeight;if(this.pcb_group_id){if(hasExplicitWidth&&hasExplicitHeight)db22.pcb_group.update(this.pcb_group_id,{width:distance4.parse(this._parsedProps.width),height:distance4.parse(this._parsedProps.height)});else if(gridWidth>0||gridHeight>0){let{edgePadding:edgePaddingProp,edgePaddingLeft:edgePaddingLeftProp,edgePaddingRight:edgePaddingRightProp,edgePaddingTop:edgePaddingTopProp,edgePaddingBottom:edgePaddingBottomProp}=this._parsedProps,edgePadding=distance4.parse(edgePaddingProp??5),edgePaddingLeft=distance4.parse(edgePaddingLeftProp??edgePadding),edgePaddingRight=distance4.parse(edgePaddingRightProp??edgePadding),edgePaddingTop=distance4.parse(edgePaddingTopProp??edgePadding),edgePaddingBottom=distance4.parse(edgePaddingBottomProp??edgePadding);db22.pcb_group.update(this.pcb_group_id,{width:hasExplicitWidth?distance4.parse(this._parsedProps.width):gridWidth+edgePaddingLeft+edgePaddingRight,height:hasExplicitHeight?distance4.parse(this._parsedProps.height):gridHeight+edgePaddingTop+edgePaddingBottom})}}}_generatePanelizationFeatures(){if(this._panelizationFeaturesGenerated)return;let{db:db22}=this.root,props=this._parsedProps;if(this.componentName!=="Panel"&&(props.minWidth!==void 0||props.maxWidth!==void 0||props.minHeight!==void 0||props.maxHeight!==void 0))throw new Error("Panel size limits must be configured on the root <panel>");let panelizationMethod=props.panelizationMethod??"none",tabChildren=this.children.filter(child=>child instanceof PanelTab),keepoutChildren=this.children.filter(child=>child instanceof PanelTabKeepout),hasTabControls=props.tabCountPerEdge!==void 0||tabChildren.length>0||keepoutChildren.length>0;if(hasTabControls&&panelizationMethod!=="tab-routing")throw new Error('Panel tab controls require panelizationMethod="tab-routing"');if(props.tabCountPerEdge!==void 0&&tabChildren.length>0)throw new Error("Use either tabCountPerEdge or <paneltab> children");if(hasTabControls&&props.vScore)throw new Error("vScore is not supported with tabCountPerEdge, <paneltab> or <paneltabkeepout>");let childBoardInstances=this._getAllBoardInstances();if(panelizationMethod!=="none"){let childBoardIds=childBoardInstances.map(c23=>c23.pcb_board_id).filter(id3=>!!id3),boardsInPanel=db22.pcb_board.list().filter(b23=>childBoardIds.includes(b23.pcb_board_id));if(boardsInPanel.length===0)return;let tabWidth=props.tabWidth??DEFAULT_TAB_WIDTH;if(panelizationMethod==="outline_routing"){let outlineRoutingCutouts=generatePanelOutlineRoutingCutouts(boardsInPanel,{cutoutWidth:tabWidth});for(let outlineRoutingCutout of outlineRoutingCutouts)db22.pcb_cutout.insert({...outlineRoutingCutout,pcb_group_id:this.pcb_group_id??void 0,pcb_panel_id:getOwningPanel(this)?.pcb_panel_id??void 0,subcircuit_id:this.subcircuit_id??void 0})}else{let boardGap=props.boardGap??tabWidth,{tabCutouts,mouseBiteHoles,vScoreLines}=hasTabControls?{...generateControlledPanelTabs(boardsInPanel.map(board=>({board,boardName:childBoardInstances.find(childBoard=>childBoard.pcb_board_id===board.pcb_board_id)?.name??"unnamed board"})),{tabCountPerEdge:props.tabCountPerEdge,tabs:tabChildren.length?tabChildren.map(tab=>tab._parsedProps):void 0,tabKeepouts:keepoutChildren.map(keepout=>keepout._parsedProps),tabWidth,tabLength:props.tabLength??DEFAULT_TAB_LENGTH,mouseBites:props.mouseBites??!0}),vScoreLines:[]}:generatePanelTabsAndMouseBites(boardsInPanel,{boardGap,tabWidth,tabLength:props.tabLength??DEFAULT_TAB_LENGTH,mouseBites:props.mouseBites??!0,vScore:props.vScore??!1});for(let tabCutout of tabCutouts)db22.pcb_cutout.insert({...tabCutout,subcircuit_id:this.subcircuit_id??void 0,pcb_panel_id:getOwningPanel(this)?.pcb_panel_id??void 0});for(let mouseBiteHole of mouseBiteHoles)db22.pcb_hole.insert({...mouseBiteHole,subcircuit_id:this.subcircuit_id??void 0});for(let route2 of vScoreLines)db22.pcb_fabrication_note_path.insert({route:route2,layer:V_SCORE_LINE_LAYER,stroke_width:V_SCORE_LINE_STROKE_WIDTH,subcircuit_id:this.subcircuit_id??void 0,pcb_panel_id:getOwningPanel(this)?.pcb_panel_id??void 0})}}this._panelizationFeaturesGenerated=!0}doInitialPcbComponentRender(){if(!this.root?.pcbDisabled){if(!this._containsBoards())throw new Error(`<${this._errorComponentName}> must contain at least one <board>`);super.doInitialPcbComponentRender()}}},DEFAULT_PANEL_EDGE_PADDING=5,Panel=class extends Subpanel{get config(){return{componentName:"Panel",zodProps:panelProps}}doInitialPcbComponentRender(){if(this.root?.pcbDisabled)return;if(!this._containsBoards())throw new Error(`<${this._errorComponentName}> must contain at least one <board>`);let{db:db22}=this.root,props=this._parsedProps,inserted=db22.pcb_panel.insert({width:props.width!==void 0?distance4.parse(props.width):0,height:props.height!==void 0?distance4.parse(props.height):0,thickness:1.6,center:this._getGlobalPcbPositionBeforeLayout(),covered_with_solder_mask:!(props.noSolderMask??!1)});this.pcb_panel_id=inserted.pcb_panel_id}_getEdgePadding(){let{edgePadding=DEFAULT_PANEL_EDGE_PADDING,edgePaddingLeft=edgePadding,edgePaddingRight=edgePadding,edgePaddingTop=edgePadding,edgePaddingBottom=edgePadding}=this._parsedProps;return{left:edgePaddingLeft,right:edgePaddingRight,top:edgePaddingTop,bottom:edgePaddingBottom}}_getMaxGridSize(){let{maxWidth,maxHeight}=this._parsedProps,edgePadding=this._getEdgePadding();return{width:maxWidth===void 0?1/0:maxWidth-edgePadding.left-edgePadding.right,height:maxHeight===void 0?1/0:maxHeight-edgePadding.top-edgePadding.bottom}}doInitialPanelLayout(){if(super.doInitialPanelLayout(),this.root?.pcbDisabled||!this.pcb_panel_id)return;let panel=this.root.db.pcb_panel.get(this.pcb_panel_id),{minWidth,maxWidth,minHeight,maxHeight}=this._parsedProps,violations=[minWidth!==void 0&&panel.width<minWidth?`Panel width ${panel.width} mm is below the minimum width ${minWidth} mm`:void 0,maxWidth!==void 0&&panel.width>maxWidth?`Panel width ${panel.width} mm exceeds the maximum width ${maxWidth} mm`:void 0,minHeight!==void 0&&panel.height<minHeight?`Panel height ${panel.height} mm is below the minimum height ${minHeight} mm`:void 0,maxHeight!==void 0&&panel.height>maxHeight?`Panel height ${panel.height} mm exceeds the maximum height ${maxHeight} mm`:void 0];for(let message of violations)message&&this.root.db.pcb_panelization_placement_error.insert({message,pcb_panel_id:this.pcb_panel_id,error_type:"pcb_panelization_placement_error"})}_getPanelSize(){let{width:width10,height:height10,minWidth=0,minHeight=0}=this._parsedProps;if(width10!==void 0&&height10!==void 0)return{width:width10,height:height10};if(this._cachedGridWidth<=0&&this._cachedGridHeight<=0)return;let edgePadding=this._getEdgePadding();return{width:width10??Math.max(this._cachedGridWidth+edgePadding.left+edgePadding.right,minWidth),height:height10??Math.max(this._cachedGridHeight+edgePadding.top+edgePadding.bottom,minHeight)}}_updatePanelDimensions(){if(!this.pcb_panel_id)return;let panelSize=this._getPanelSize();panelSize&&this.root.db.pcb_panel.update(this.pcb_panel_id,panelSize)}updatePcbComponentRender(){if(this.root?.pcbDisabled||!this.pcb_panel_id)return;let{db:db22}=this.root,props=this._parsedProps,currentPanel=db22.pcb_panel.get(this.pcb_panel_id);db22.pcb_panel.update(this.pcb_panel_id,{width:props.width!==void 0?distance4.parse(props.width):currentPanel?.width,height:props.height!==void 0?distance4.parse(props.height):currentPanel?.height,center:this._getGlobalPcbPositionBeforeLayout(),covered_with_solder_mask:!(props.noSolderMask??!1)})}removePcbComponentRender(){this.pcb_panel_id&&(this.root?.db.pcb_panel.delete(this.pcb_panel_id),this.pcb_panel_id=null)}},GENERATED_ANTENNA_KEEPOUT_CLEARANCE_MM=1,GENERATED_ANTENNA_FEED_OPENING_CLEARANCE_MM=1,getGeneratedAntennaKeepouts=geometry=>{let xCoordinates=geometry.route.map(point12=>point12.x),yCoordinates=geometry.route.map(point12=>point12.y),edgeClearance=geometry.traceWidth/2+GENERATED_ANTENNA_KEEPOUT_CLEARANCE_MM,left=Math.min(...xCoordinates)-edgeClearance,right=Math.max(...xCoordinates)+edgeClearance,bottom=Math.min(...yCoordinates)-edgeClearance,top=Math.max(...yCoordinates)+edgeClearance,feedOpeningPoints=[geometry.feedPoint,...geometry.secondaryPort?[geometry.secondaryPort.point]:[]],openingLeft=Math.min(...feedOpeningPoints.map(point12=>point12.x))-GENERATED_ANTENNA_FEED_OPENING_CLEARANCE_MM,openingRight=Math.max(...feedOpeningPoints.map(point12=>point12.x))+GENERATED_ANTENNA_FEED_OPENING_CLEARANCE_MM,openingBottom=Math.min(...feedOpeningPoints.map(point12=>point12.y))-GENERATED_ANTENNA_FEED_OPENING_CLEARANCE_MM,openingTop=Math.max(...feedOpeningPoints.map(point12=>point12.y))+GENERATED_ANTENNA_FEED_OPENING_CLEARANCE_MM,rects=[],addRect=(rectLeft,rectRight,rectBottom,rectTop)=>{rectRight<=rectLeft||rectTop<=rectBottom||rects.push({center:{x:(rectLeft+rectRight)/2,y:(rectBottom+rectTop)/2},width:rectRight-rectLeft,height:rectTop-rectBottom})};return geometry.feedKeepoutOpeningDirection==="left"?(addRect(left,right,openingTop,top),addRect(left,right,bottom,openingBottom),addRect(openingRight,right,openingBottom,openingTop)):(addRect(left,openingLeft,bottom,openingTop),addRect(openingRight,right,bottom,openingTop),addRect(left,right,openingTop,top)),rects},getGeneratedAntennaGeometry=antennaShape3=>{switch(antennaShape3){case"2.4ghz_quarter_wave_monopole":return{traceWidth:.6,feedPoint:{x:0,y:0},feedKeepoutOpeningDirection:"left",route:[{x:0,y:0},{x:31,y:0}]};case"2.4ghz_meandered_monopole":return{traceWidth:.5,feedPoint:{x:0,y:0},feedKeepoutOpeningDirection:"bottom",route:[{x:0,y:0},{x:0,y:6},{x:3,y:6},{x:3,y:1.5},{x:6,y:1.5},{x:6,y:6},{x:9,y:6},{x:9,y:1.5},{x:12,y:1.5},{x:12,y:6},{x:15,y:6}]};case"2.4ghz_inverted_f":return{traceWidth:.8,feedPoint:{x:0,y:0},feedKeepoutOpeningDirection:"bottom",secondaryPort:{point:{x:-4,y:0},role:"ground"},groundViaPoint:{x:-4,y:0},route:[{x:-4,y:0},{x:-4,y:3},{x:0,y:3},{x:0,y:0},{x:0,y:3},{x:-4,y:3},{x:-4,y:8},{x:22,y:8}]};case"2.4ghz_meandered_inverted_f":return{traceWidth:.5,feedPoint:{x:0,y:0},feedKeepoutOpeningDirection:"bottom",secondaryPort:{point:{x:-1.7,y:0},role:"ground"},groundViaPoint:{x:-1.7,y:0},route:[{x:-1.7,y:0},{x:-1.7,y:4.9},{x:0,y:4.9},{x:0,y:0},{x:0,y:4.9},{x:-1.7,y:4.9},{x:2.3,y:4.9},{x:2.3,y:1.4},{x:5.3,y:1.4},{x:5.3,y:4.9},{x:8.3,y:4.9},{x:8.3,y:1.4},{x:11.3,y:1.4},{x:11.3,y:4.9},{x:13.3,y:4.9}]};case"2.4ghz_folded_dipole":return{traceWidth:.9,feedPoint:{x:0,y:0},feedKeepoutOpeningDirection:"bottom",secondaryPort:{point:{x:1.2,y:0},role:"feed2"},route:[{x:0,y:0},{x:-22.4,y:0},{x:-22.4,y:9},{x:23.6,y:9},{x:23.6,y:0},{x:1.2,y:0}]}}},Antenna=class extends NormalComponent{get config(){return{componentName:"Antenna",zodProps:antennaProps,sourceFtype:FTYPE.simple_chip,shouldRenderAsSchematicBox:!0}}getRefDesPrefixes(){return["ANT"]}initPorts(){let{antennaShape:antennaShape3,pcbPath:pcbPath3}=this._parsedProps,secondaryPortRole=pcbPath3?void 0:antennaShape3==="2.4ghz_inverted_f"||antennaShape3==="2.4ghz_meandered_inverted_f"?"ground":antennaShape3==="2.4ghz_folded_dipole"?"feed2":void 0;super.initPorts({pinCount:secondaryPortRole?2:1,additionalAliases:{pin1:secondaryPortRole==="feed2"?["feed","feed1"]:["feed"],...secondaryPortRole==="ground"?{pin2:["ground","gnd"]}:secondaryPortRole==="feed2"?{pin2:["feed2"]}:{}}})}doInitialReactSubtreesRender(){super.doInitialReactSubtreesRender();let{antennaShape:antennaShape3,pcbPath:pcbPath3}=this._parsedProps;if(!antennaShape3)return;let hasFootprint=this.children.some(child=>child.componentName==="Footprint");if(pcbPath3&&hasFootprint)return;let geometry=pcbPath3?void 0:getGeneratedAntennaGeometry(antennaShape3),generatedFootprint=new Footprint({name:`${this.name}_generated_antenna`});if(hasFootprint||generatedFootprint.add(new SmtPad({shape:"rect",width:.8,height:.8,pcbX:geometry?.feedPoint.x??0,pcbY:geometry?.feedPoint.y??0,layer:"top",portHints:["pin1"],coveredWithSolderMask:!0})),geometry){let keepouts=getGeneratedAntennaKeepouts(geometry);for(let keepout of keepouts)generatedFootprint.add(new Keepout({shape:"rect",pcbX:keepout.center.x,pcbY:keepout.center.y,width:keepout.width,height:keepout.height,layers:[...this.root?._getBoard()?.allLayers??["top","bottom"]],excludeRefs:[this.getSubcircuitSelector()]}));let antennaTrace=new PcbTrace({route:geometry.route.map(point12=>({route_type:"wire",...point12,width:geometry.traceWidth,layer:"top"}))});antennaTrace.isAntennaTrace=!0,generatedFootprint.add(antennaTrace),geometry.secondaryPort&&!geometry.groundViaPoint&&!hasFootprint&&generatedFootprint.add(new SmtPad({shape:"rect",width:.8,height:.8,pcbX:geometry.secondaryPort.point.x,pcbY:geometry.secondaryPort.point.y,layer:"top",portHints:["pin2"],coveredWithSolderMask:!0})),geometry.groundViaPoint&&generatedFootprint.add(new PlatedHole({shape:"circle",pcbX:geometry.groundViaPoint.x,pcbY:geometry.groundViaPoint.y,holeDiameter:.3,outerDiameter:.7,portHints:["pin2"],coveredWithSolderMask:!0}))}this.add(generatedFootprint)}doInitialCreateTracesFromProps(){super.doInitialCreateTracesFromProps();let{pcbPath:pcbPath3}=this._parsedProps;if(!pcbPath3)return;let antennaTrace=new Trace({name:`${this.name}_pcb_path`,path:[`${this.getSubcircuitSelector()} > port.pin1`],pcbPath:pcbPath3});antennaTrace.isAntennaTrace=!0,this.add(antennaTrace)}},Pinout=class extends Chip{constructor(props){super(props)}get config(){return{...super.config,componentName:"Pinout",zodProps:pinoutProps}}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({ftype:"simple_pinout",name:this.name,manufacturer_part_number:resolveManufacturerPartNumber(props),supplier_part_numbers:props.supplierPartNumbers,display_name:props.displayName});this.source_component_id=source_component.source_component_id}},Jumper=class extends NormalComponent{constructor(){super(...arguments);__publicField(this,"schematicDimensions",null)}get config(){return{schematicSymbolName:void 0,componentName:"Jumper",zodProps:jumperProps,shouldRenderAsSchematicBox:!0}}_getSchematicPortArrangement(){let arrangement=super._getSchematicPortArrangement();if(arrangement&&Object.keys(arrangement).length>0)return arrangement;let pinCount=this._parsedProps.pinCount??(Array.isArray(this._parsedProps.pinLabels)?this._parsedProps.pinLabels.length:this._parsedProps.pinLabels?Object.keys(this._parsedProps.pinLabels).length:this.getPortsFromFootprint().length),direction4=this._parsedProps.schDirection??"right";return{leftSize:direction4==="left"?pinCount:0,rightSize:direction4==="right"?pinCount:0}}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,{pcbX,pcbY}=this.getResolvedPcbPositionProp(),source_component=db22.source_component.insert({ftype:"simple_chip",name:this.name,manufacturer_part_number:resolveManufacturerPartNumber(props),supplier_part_numbers:props.supplierPartNumbers,are_pins_interchangeable:!0,display_name:props.displayName});this.source_component_id=source_component.source_component_id}doInitialPcbComponentRender(){if(this.root?.pcbDisabled)return;let{db:db22}=this.root,{_parsedProps:props}=this,{pcbX,pcbY}=this.getResolvedPcbPositionProp(),globalTransformRotation=this.getGlobalTransformRotation(),pcb_component23=db22.pcb_component.insert({footprint_origin:this._getGlobalPcbPositionBeforeLayout(),center:{x:pcbX,y:pcbY},width:2,height:3,layer:props.layer??"top",rotation:normalizeDegrees(globalTransformRotation),insertion_direction:this._getPcbComponentInsertionDirection(props.layer??"top",globalTransformRotation),source_component_id:this.source_component_id,subcircuit_id:this.getSubcircuit().subcircuit_id??void 0,do_not_place:props.doNotPlace??!1,obstructs_within_bounds:props.obstructsWithinBounds??!0,is_allowed_to_be_off_board:props.allowOffBoard??!1,metadata:props.kicadFootprintMetadata?{kicad_footprint:props.kicadFootprintMetadata}:void 0});this.pcb_component_id=pcb_component23.pcb_component_id}doInitialPcbPortAttachment(){let{db:db22}=this.root,pcb_ports=db22.pcb_port.list({pcb_component_id:this.pcb_component_id}),pinLabelToPortId={};for(let i23=0;i23<pcb_ports.length;i23++){let port=pcb_ports[i23],sourcePort=db22.source_port.get(port.source_port_id),pinLabel="";if(typeof sourcePort?.pin_number=="number")pinLabel=sourcePort.pin_number.toString();else if(Array.isArray(sourcePort?.port_hints)){let matchedHint=sourcePort.port_hints.find(h23=>/^(pin)?\d+$/.test(h23));matchedHint&&(/^pin\d+$/.test(matchedHint)?pinLabel=matchedHint.replace(/^pin/,""):pinLabel=matchedHint)}pinLabelToPortId[pinLabel]=port.pcb_port_id}let traces=db22.pcb_trace.list({pcb_component_id:this.pcb_component_id}),updatePortId=portId=>{if(portId&&typeof portId=="string"&&portId.startsWith("{PIN")){let pin=portId.replace("{PIN","").replace("}","");return pinLabelToPortId[pin]||portId}return portId};for(let trace of traces)if(trace.route)for(let segment5 of trace.route)segment5.route_type==="wire"&&(segment5.start_pcb_port_id=updatePortId(segment5.start_pcb_port_id),segment5.end_pcb_port_id=updatePortId(segment5.end_pcb_port_id))}},INTERCONNECT_STANDARD_FOOTPRINTS={"0402":"0402","0603":"0603","0805":"0805",1206:"1206"},Interconnect=class extends NormalComponent{get config(){return{componentName:"Interconnect",zodProps:interconnectProps,shouldRenderAsSchematicBox:!0,sourceFtype:"interconnect"}}get defaultInternallyConnectedPinNames(){let{standard}=this._parsedProps;return standard&&INTERCONNECT_STANDARD_FOOTPRINTS[standard]?[["pin1","pin2"]]:[]}_getImpliedFootprintString(){let{standard}=this._parsedProps;return standard?INTERCONNECT_STANDARD_FOOTPRINTS[standard]??null:null}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({ftype:"interconnect",name:this.name,manufacturer_part_number:resolveManufacturerPartNumber(props),supplier_part_numbers:props.supplierPartNumbers,are_pins_interchangeable:!0,display_name:props.displayName});this.source_component_id=source_component.source_component_id}doInitialSourceParentAttachment(){let{db:db22}=this.root,internallyConnectedPorts=this._getInternallyConnectedPins();for(let ports of internallyConnectedPorts){let sourcePortIds=ports.map(port=>port.source_port_id).filter(id3=>id3!==null);sourcePortIds.length>=2&&db22.source_component_internal_connection.insert({source_component_id:this.source_component_id,subcircuit_id:this.getSubcircuit()?.subcircuit_id,source_port_ids:sourcePortIds})}}},SolderJumper=class extends NormalComponent{constructor(){super(...arguments);__publicField(this,"schematicDimensions",null)}_getPinCountFromFootprintString(footprint){let match2=footprint.match(/^solderjumper([23])(?:_|$)/);return match2?Number(match2[1]):null}_getPinNumberFromBridgedPinsProp(pinName){let numericPinMatch=pinName.match(/^(?:pin)?(\d+)$/i);if(numericPinMatch)return Number(numericPinMatch[1]);let pinLabels=this._parsedProps.pinLabels??this.props.pinLabels;if(Array.isArray(pinLabels)){let labelIndex=pinLabels.findIndex(label=>label===pinName);return labelIndex>=0?labelIndex+1:null}if(pinLabels&&typeof pinLabels=="object")for(let[pinKey,labelOrLabels]of Object.entries(pinLabels)){if(!(Array.isArray(labelOrLabels)?labelOrLabels:[labelOrLabels]).includes(pinName))continue;let pinNumberMatch=pinKey.match(/^(?:pin)?(\d+)$/i);return pinNumberMatch?Number(pinNumberMatch[1]):null}return null}_getBridgedPinNumbersForFootprint(pinCount){let props=this._parsedProps??this.props;return Array.isArray(props.bridgedPins)&&props.bridgedPins.length>0?Array.from(new Set(props.bridgedPins.flat().map(pinName=>this._getPinNumberFromBridgedPinsProp(pinName)).filter(pinNumber2=>pinNumber2!==null&&pinNumber2>=1&&pinNumber2<=pinCount))).sort((a23,b23)=>a23-b23):props.bridged?Array.from({length:pinCount},(_23,index2)=>index2+1):[]}resolveFootprint(){let footprint=super.resolveFootprint();if(typeof footprint!="string")return footprint;let pinCount=this._getPinCountFromFootprintString(footprint);if(!pinCount||/_bridged\d+/.test(footprint))return footprint;let bridgedPinNumbers=this._getBridgedPinNumbersForFootprint(pinCount);return bridgedPinNumbers.length===0?footprint:footprint.replace(/^solderjumper[23]/,`solderjumper${pinCount}_bridged${bridgedPinNumbers.join("")}`)}_getPinNumberFromBridgedPinName(pinName){return this.selectOne(`port.${pinName}`,{type:"port"})?._parsedProps.pinNumber??null}get defaultInternallyConnectedPinNames(){if(this._parsedProps.bridged){let pins=this.children.filter(c23=>c23.componentName==="Port").map(p23=>p23.name);return pins.length>0?[pins]:[]}return this._parsedProps.bridgedPins??[]}get config(){let props=this._parsedProps??this.props,resolvedPinCount=props.pinCount;if(props.pinCount==null&&!props.footprint&&(resolvedPinCount=2),props.pinCount==null){let nums=(props.bridgedPins??[]).flat().map(p_str=>this._getPinNumberFromBridgedPinName(p_str)).filter(n23=>n23!==null),maxPinFromBridged=nums.length>0?Math.max(...nums):0,pinCountFromLabels=props.pinLabels?Object.keys(props.pinLabels).length:0,finalPinCount=Math.max(maxPinFromBridged,pinCountFromLabels);(finalPinCount===2||finalPinCount===3)&&(resolvedPinCount=finalPinCount),resolvedPinCount==null&&props.footprint&&[2,3].includes(this.getPortsFromFootprint().length)&&(resolvedPinCount=this.getPortsFromFootprint().length)}let symbolName="";resolvedPinCount?symbolName+=`solderjumper${resolvedPinCount}`:symbolName="solderjumper";let bridgedPinNumbers=[];return Array.isArray(props.bridgedPins)&&props.bridgedPins.length>0?bridgedPinNumbers=Array.from(new Set(props.bridgedPins.flat().map(pinName=>this._getPinNumberFromBridgedPinName(pinName)).filter(n23=>n23!==null))).sort((a23,b23)=>a23-b23):props.bridged&&resolvedPinCount&&(bridgedPinNumbers=Array.from({length:resolvedPinCount},(_23,i23)=>i23+1)),bridgedPinNumbers.length>0&&(symbolName+=`_bridged${bridgedPinNumbers.join("")}`),{schematicSymbolName:props.symbolName??symbolName,componentName:"SolderJumper",zodProps:solderjumperProps,shouldRenderAsSchematicBox:!0}}_getSchematicPortArrangement(){let arrangement=super._getSchematicPortArrangement();if(arrangement&&Object.keys(arrangement).length>0)return arrangement;let pinCount=this._parsedProps.pinCount??(Array.isArray(this._parsedProps.pinLabels)?this._parsedProps.pinLabels.length:this._parsedProps.pinLabels?Object.keys(this._parsedProps.pinLabels).length:this.getPortsFromFootprint().length);pinCount==null&&!this._parsedProps.footprint&&(pinCount=2);let direction4=this._parsedProps.schDirection??"right";return{leftSize:direction4==="left"?pinCount:0,rightSize:direction4==="right"?pinCount:0}}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,{pcbX,pcbY}=this.getResolvedPcbPositionProp(),source_component=db22.source_component.insert({ftype:"simple_chip",name:this.name,manufacturer_part_number:resolveManufacturerPartNumber(props),supplier_part_numbers:props.supplierPartNumbers,are_pins_interchangeable:!0,display_name:props.displayName});this.source_component_id=source_component.source_component_id}doInitialPcbComponentRender(){if(this.root?.pcbDisabled)return;let{db:db22}=this.root,{_parsedProps:props}=this,{pcbX,pcbY}=this.getResolvedPcbPositionProp(),globalTransformRotation=this.getGlobalTransformRotation(),pcb_component23=db22.pcb_component.insert({footprint_origin:this._getGlobalPcbPositionBeforeLayout(),center:{x:pcbX,y:pcbY},width:2,height:3,layer:props.layer??"top",rotation:normalizeDegrees(globalTransformRotation),insertion_direction:this._getPcbComponentInsertionDirection(props.layer??"top",globalTransformRotation),source_component_id:this.source_component_id,subcircuit_id:this.getSubcircuit().subcircuit_id??void 0,do_not_place:props.doNotPlace??!1,obstructs_within_bounds:props.obstructsWithinBounds??!0,is_allowed_to_be_off_board:props.allowOffBoard??!1,metadata:props.kicadFootprintMetadata?{kicad_footprint:props.kicadFootprintMetadata}:void 0});this.pcb_component_id=pcb_component23.pcb_component_id}doInitialPcbPortAttachment(){let{db:db22}=this.root,pcb_ports=db22.pcb_port.list({pcb_component_id:this.pcb_component_id}),pinLabelToPortId={};for(let i23=0;i23<pcb_ports.length;i23++){let port=pcb_ports[i23],sourcePort=db22.source_port.get(port.source_port_id),pinLabel="";if(typeof sourcePort?.pin_number=="number")pinLabel=sourcePort.pin_number.toString();else if(Array.isArray(sourcePort?.port_hints)){let matchedHint=sourcePort.port_hints.find(h23=>/^(pin)?\d+$/.test(h23));matchedHint&&(/^pin\d+$/.test(matchedHint)?pinLabel=matchedHint.replace(/^pin/,""):pinLabel=matchedHint)}pinLabelToPortId[pinLabel]=port.pcb_port_id}let traces=db22.pcb_trace.list({pcb_component_id:this.pcb_component_id}),updatePortId=portId=>{if(portId&&typeof portId=="string"&&portId.startsWith("{PIN")){let pin=portId.replace("{PIN","").replace("}","");return pinLabelToPortId[pin]||portId}return portId};for(let trace of traces)if(trace.route)for(let segment5 of trace.route)segment5.route_type==="wire"&&(segment5.start_pcb_port_id=updatePortId(segment5.start_pcb_port_id),segment5.end_pcb_port_id=updatePortId(segment5.end_pcb_port_id))}},PowerSource=class extends NormalComponent{constructor(){super(...arguments);__publicField(this,"pos",this.portMap.pin1);__publicField(this,"positive",this.portMap.pin1);__publicField(this,"neg",this.portMap.pin2);__publicField(this,"negative",this.portMap.pin2)}get config(){return{schematicSymbolName:this.props.symbolName??"power_factor_meter_horz",componentName:"PowerSource",zodProps:powerSourceProps,sourceFtype:"simple_power_source"}}initPorts(){this.add(new Port({name:"pin1",pinNumber:1,aliases:["positive","pos"]})),this.add(new Port({name:"pin2",pinNumber:2,aliases:["negative","neg"]}))}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({ftype:"simple_power_source",name:this.name,voltage:props.voltage,supplier_part_numbers:props.supplierPartNumbers,manufacturer_part_number:resolveManufacturerPartNumber(props),are_pins_interchangeable:!1,display_name:props.displayName});this.source_component_id=source_component.source_component_id}},VoltageSource2=class extends NormalComponent{constructor(){super(...arguments);__publicField(this,"simulation_voltage_source_id",null);__publicField(this,"terminal1",this.portMap.terminal1);__publicField(this,"terminal2",this.portMap.terminal2)}get config(){return{componentName:"VoltageSource",schematicSymbolName:this.props.waveShape==="square"?"square_wave":"ac_voltmeter",zodProps:voltageSourceProps,sourceFtype:"simple_voltage_source"}}runRenderPhaseForChildren(phase){if(!phase.startsWith("Pcb"))for(let child of this.children)child.runRenderPhaseForChildren(phase),child.runRenderPhase(phase)}doInitialPcbComponentRender(){let hasExplicitPcbPosition=this._hasUserDefinedPcbPosition();if(!this._parsedProps.footprint){if(!hasExplicitPcbPosition)return;throw new Error("VoltageSource requires a footprint when pcbX/pcbY or pcb edge position props are used")}super.doInitialPcbComponentRender()}initPorts(){super.initPorts({additionalAliases:{pin1:["terminal1"],pin2:["terminal2"]}})}_getSchematicSymbolDisplayValue(){let{voltage:voltage32,frequency:frequency32}=this._parsedProps,parts=[];return voltage32!==void 0&&parts.push(`${formatSiUnit(voltage32)}V`),frequency32!==void 0&&parts.push(`${formatSiUnit(frequency32)}Hz`),parts.length>0?parts.join(" "):void 0}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({ftype:"simple_voltage_source",name:this.name,voltage:props.voltage,frequency:props.frequency,peak_to_peak_voltage:props.peakToPeakVoltage,wave_shape:props.waveShape,phase:props.phase,duty_cycle:props.dutyCycle,pulse_delay:props.pulseDelay,rise_time:props.riseTime,fall_time:props.fallTime,pulse_width:props.pulseWidth,period:props.period,supplier_part_numbers:props.supplierPartNumbers,manufacturer_part_number:resolveManufacturerPartNumber(props),are_pins_interchangeable:!0,display_name:props.displayName});this.source_component_id=source_component.source_component_id}doInitialSimulationRender(){let{db:db22}=this.root,{_parsedProps:props}=this,terminal1Port=this.portMap.terminal1,terminal2Port=this.portMap.terminal2,simulationVoltageSource=db22.simulation_voltage_source.insert({is_dc_source:!1,terminal1_source_port_id:terminal1Port.source_port_id??void 0,terminal2_source_port_id:terminal2Port.source_port_id??void 0,voltage:props.voltage,frequency:props.frequency,peak_to_peak_voltage:props.peakToPeakVoltage,wave_shape:props.waveShape,phase:props.phase,duty_cycle:props.dutyCycle,pulse_delay:props.pulseDelay,rise_time:props.riseTime,fall_time:props.fallTime,pulse_width:props.pulseWidth,period:props.period,ac_magnitude:props.acMagnitude,ac_phase:props.acPhase});this.simulation_voltage_source_id=simulationVoltageSource.simulation_voltage_source_id}},CurrentSource2=class extends NormalComponent{constructor(){super(...arguments);__publicField(this,"simulation_current_source_id",null);__publicField(this,"pos",this.portMap.pos);__publicField(this,"neg",this.portMap.neg)}get config(){return{componentName:"CurrentSource",schematicSymbolName:"current_source",zodProps:currentSourceProps,sourceFtype:"simple_current_source"}}runRenderPhaseForChildren(phase){if(!phase.startsWith("Pcb"))for(let child of this.children)child.runRenderPhaseForChildren(phase),child.runRenderPhase(phase)}doInitialPcbComponentRender(){let hasExplicitPcbPosition=this._hasUserDefinedPcbPosition();if(!this._parsedProps.footprint){if(!hasExplicitPcbPosition)return;throw new Error("CurrentSource requires a footprint when pcbX/pcbY or pcb edge position props are used")}super.doInitialPcbComponentRender()}initPorts(){super.initPorts({additionalAliases:{pin1:["pos"],pin2:["neg"]}})}_getSchematicSymbolDisplayValue(){let{current:current23,frequency:frequency32,peakToPeakCurrent}=this._parsedProps,parts=[];return current23!==void 0&&parts.push(`${formatSiUnit(current23)}A`),peakToPeakCurrent!==void 0&&parts.push(`${formatSiUnit(peakToPeakCurrent)}A p-p`),frequency32!==void 0&&parts.push(`${formatSiUnit(frequency32)}Hz`),parts.length>0?parts.join(" "):void 0}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({ftype:"simple_current_source",name:this.name,current:props.current,frequency:props.frequency,peak_to_peak_current:props.peakToPeakCurrent,wave_shape:props.waveShape,phase:props.phase,duty_cycle:props.dutyCycle,supplier_part_numbers:props.supplierPartNumbers,manufacturer_part_number:resolveManufacturerPartNumber(props),are_pins_interchangeable:!0,display_name:props.displayName});this.source_component_id=source_component.source_component_id}doInitialSimulationRender(){let{db:db22}=this.root,{_parsedProps:props}=this,isAc=props.frequency!==void 0||props.peakToPeakCurrent!==void 0||props.waveShape!==void 0||props.acMagnitude!==void 0||props.acPhase!==void 0,posPort=this.portMap.pos,negPort=this.portMap.neg;if(isAc){let simulationCurrentSource=db22.simulation_current_source.insert({is_dc_source:!1,terminal1_source_port_id:posPort.source_port_id??void 0,terminal2_source_port_id:negPort.source_port_id??void 0,current:props.current,frequency:props.frequency,peak_to_peak_current:props.peakToPeakCurrent,wave_shape:props.waveShape,phase:props.phase,duty_cycle:props.dutyCycle,ac_magnitude:props.acMagnitude,ac_phase:props.acPhase});this.simulation_current_source_id=simulationCurrentSource.simulation_current_source_id}else{if(props.current===void 0)return;let simulationCurrentSource=db22.simulation_current_source.insert({is_dc_source:!0,positive_source_port_id:posPort.source_port_id??void 0,negative_source_port_id:negPort.source_port_id??void 0,current:props.current,ac_magnitude:props.acMagnitude,ac_phase:props.acPhase});this.simulation_current_source_id=simulationCurrentSource.simulation_current_source_id}}},PLACEMENT_MARGIN=.25,rectForComponent=(component,margin)=>({left:component.center.x-component.size.width/2-margin,right:component.center.x+component.size.width/2+margin,bottom:component.center.y-component.size.height/2-margin,top:component.center.y+component.size.height/2+margin}),rectsOverlap4=(a23,b23)=>a23.left<b23.right&&a23.right>b23.left&&a23.bottom<b23.top&&a23.top>b23.bottom,getCandidateCenters=({baseCenter,size:size23})=>{let xStep=size23.width+PLACEMENT_MARGIN*2,yStep=size23.height+PLACEMENT_MARGIN*2;return[baseCenter,{x:baseCenter.x,y:baseCenter.y+yStep},{x:baseCenter.x,y:baseCenter.y-yStep},{x:baseCenter.x+xStep,y:baseCenter.y},{x:baseCenter.x-xStep,y:baseCenter.y},{x:baseCenter.x+xStep,y:baseCenter.y+yStep},{x:baseCenter.x-xStep,y:baseCenter.y+yStep},{x:baseCenter.x+xStep,y:baseCenter.y-yStep},{x:baseCenter.x-xStep,y:baseCenter.y-yStep},{x:baseCenter.x,y:baseCenter.y+yStep*2},{x:baseCenter.x,y:baseCenter.y-yStep*2}]},getConnectedSchematicPort=({ammeterSourcePortId,schematicPorts,sourceTraces})=>{for(let sourceTrace of sourceTraces){if(!sourceTrace.connected_source_port_ids.includes(ammeterSourcePortId))continue;let connectedSourcePortId=sourceTrace.connected_source_port_ids.find(sourcePortId=>sourcePortId!==ammeterSourcePortId);if(connectedSourcePortId===void 0)continue;let schematicPort=schematicPorts.find(port=>port.source_port_id===connectedSourcePortId);if(schematicPort)return schematicPort}return null},midpoint22=ports=>({x:ports.reduce((sum,port)=>sum+port.center.x,0)/ports.length,y:ports.reduce((sum,port)=>sum+port.center.y,0)/ports.length}),shiftAmmeterSchematicElements=({ammeter,db:db22,oldCenter,newCenter})=>{let schematicComponentId=ammeter.schematic_component_id;if(!schematicComponentId)return;let deltaX=newCenter.x-oldCenter.x,deltaY=newCenter.y-oldCenter.y;if(!(deltaX===0&&deltaY===0)){db22.schematic_component.update(schematicComponentId,{center:newCenter});for(let port of db22.schematic_port.list({schematic_component_id:schematicComponentId}))db22.schematic_port.update(port.schematic_port_id,{center:{x:port.center.x+deltaX,y:port.center.y+deltaY}});for(let text4 of db22.schematic_text.list({schematic_component_id:schematicComponentId}))db22.schematic_text.update(text4.schematic_text_id,{position:{x:text4.position.x+deltaX,y:text4.position.y+deltaY}});updateSchematicPrimitivesForLayoutShift({db:db22,schematicComponentId,deltaX,deltaY})}},Ammeter_doInitialSchematicLayout=ammeter=>{let{root}=ammeter;if(!root||root.schematicDisabled||!ammeter.schematic_component_id||ammeter._parsedProps.schX!==void 0||ammeter._parsedProps.schY!==void 0||ammeter.getGroup()?._getSchematicLayoutMode()!=="relative")return;let{db:db22}=root,schematicComponent=db22.schematic_component.get(ammeter.schematic_component_id);if(!schematicComponent)return;let ammeterSourcePortIds=[ammeter.portMap.pos.source_port_id,ammeter.portMap.neg.source_port_id].filter(sourcePortId=>typeof sourcePortId=="string");if(ammeterSourcePortIds.length===0)return;let schematicPorts=db22.schematic_port.list(),sourceTraces=db22.source_trace.list(),connectedSchematicPorts=ammeterSourcePortIds.map(ammeterSourcePortId=>getConnectedSchematicPort({ammeterSourcePortId,schematicPorts,sourceTraces})).filter(port=>port!==null);if(connectedSchematicPorts.length===0)return;let baseCenter=midpoint22(connectedSchematicPorts),obstacles=db22.schematic_component.list().filter(component=>component.schematic_component_id!==schematicComponent.schematic_component_id&&!component.is_schematic_group&&component.schematic_sheet_id===schematicComponent.schematic_sheet_id).map(component=>rectForComponent(component,PLACEMENT_MARGIN)),bestCenter=getCandidateCenters({baseCenter,size:schematicComponent.size}).find(candidateCenter=>{let candidateRect=rectForComponent({...schematicComponent,center:candidateCenter},PLACEMENT_MARGIN);return!obstacles.some(obstacle=>rectsOverlap4(candidateRect,obstacle))})??baseCenter;shiftAmmeterSchematicElements({ammeter,db:db22,oldCenter:schematicComponent.center,newCenter:bestCenter})},Ammeter=class extends NormalComponent{constructor(){super(...arguments);__publicField(this,"simulation_current_probe_id",null);__publicField(this,"pos",this.portMap.pos);__publicField(this,"neg",this.portMap.neg)}get config(){return{componentName:"Ammeter",schematicSymbolName:"dc_ammeter",zodProps:ammeterProps,sourceFtype:"simple_ammeter"}}runRenderPhaseForChildren(phase){if(!phase.startsWith("Pcb"))for(let child of this.children)child.runRenderPhaseForChildren(phase),child.runRenderPhase(phase)}doInitialPcbComponentRender(){let hasExplicitPcbPosition=this._hasUserDefinedPcbPosition();if(!this._parsedProps.footprint){if(!hasExplicitPcbPosition)return;throw new Error("Ammeter requires a footprint when pcbX/pcbY or pcb edge position props are used")}super.doInitialPcbComponentRender()}initPorts(){super.initPorts({ignoreSymbolPorts:!0,pinCount:2,additionalAliases:{pin1:["pos"],pin2:["neg"]}});let symbol=cc[this._getSchematicSymbolNameOrThrow()];this.portMap.pos.schematicSymbolPortDef=symbol.ports.find(port=>port.labels.includes("1"))??null,this.portMap.neg.schematicSymbolPortDef=symbol.ports.find(port=>port.labels.includes("2"))??null}doInitialSourceRender(){let{db:db22}=this.root,{supplierPartNumbers,displayName}=this._parsedProps,source_component=db22.source_component.insert({ftype:"simple_ammeter",name:this.name,supplier_part_numbers:supplierPartNumbers,manufacturer_part_number:resolveManufacturerPartNumber(this._parsedProps),display_name:displayName});this.source_component_id=source_component.source_component_id}doInitialSimulationRender(){let{db:db22}=this.root,{color:color32,graphDisplayName,graphCenter,graphVerticalOffset,graphCurrentPerDiv}=this._parsedProps,posPort=this.portMap.pos,negPort=this.portMap.neg,{simulation_current_probe_id}=db22.simulation_current_probe.insert({type:"simulation_current_probe",name:this.name,source_component_id:this.source_component_id,positive_source_port_id:posPort.source_port_id,negative_source_port_id:negPort.source_port_id,subcircuit_id:this.getSubcircuit()?.subcircuit_id??void 0,color:color32});if(this.simulation_current_probe_id=simulation_current_probe_id,graphDisplayName!==void 0||graphCenter!==void 0||graphVerticalOffset!==void 0||graphCurrentPerDiv!==void 0){let graphCurrentPerDivValue=parseSimulationGraphValue(graphCurrentPerDiv),graphVerticalOffsetValue=parseSimulationGraphValue(graphVerticalOffset);db22.simulation_oscilloscope_trace.insert({simulation_current_probe_id,display_name:graphDisplayName,color:color32,display_center_value:graphCenter,amps_per_div:graphCurrentPerDivValue,display_center_offset_divs:graphVerticalOffsetValue!==void 0&&graphCurrentPerDivValue!==void 0&&graphCurrentPerDivValue!==0?graphVerticalOffsetValue/graphCurrentPerDivValue:void 0})}}doInitialSchematicLayout(){Ammeter_doInitialSchematicLayout(this)}},edgeSpecifiers=["leftedge","rightedge","topedge","bottomedge","center"],Constraint3=class extends PrimitiveComponent{get config(){return{componentName:"Constraint",zodProps:constraintProps}}constructor(props){if(super(props),("xdist"in props||"ydist"in props)&&!("edgeToEdge"in props)&&!("centerToCenter"in props))throw new Error(`edgeToEdge, centerToCenter must be set for xDist or yDist for ${this}`);if("for"in props&&props.for.length<2)throw new Error(`"for" must have at least two selectors for ${this}`)}_getAllReferencedComponents(){let componentsWithSelectors=[],container=this.getPrimitiveContainer();function addComponentFromSelector(selector2){let maybeEdge=selector2.split(" ").pop(),edge=edgeSpecifiers.includes(maybeEdge)?maybeEdge:void 0,componentSelector=edge?selector2.replace(` ${edge}`,""):selector2,component=container.selectOne(componentSelector,{pcbPrimitive:!0});component&&componentsWithSelectors.push({selector:selector2,component,componentSelector,edge})}for(let key of["left","right","top","bottom"])key in this._parsedProps&&addComponentFromSelector(this._parsedProps[key]);if("for"in this._parsedProps)for(let selector2 of this._parsedProps.for)addComponentFromSelector(selector2);return{componentsWithSelectors}}},isSelectionResultPort=connectable=>!connectable||typeof connectable!="object"?!1:typeof connectable.getSourcePort=="function",isSelectionResultNet=connectable=>!connectable||typeof connectable!="object"?!1:typeof connectable.getSourceNet=="function",isSelectionResultComponent=connectable=>!connectable||typeof connectable!="object"?!1:typeof connectable.getPorts=="function",isCircuitJsonElement=connectable=>!connectable||typeof connectable!="object"?!1:typeof connectable.type=="string",isNonEmptyString=value=>typeof value=="string"&&value.length>0,SelectionResultPortImpl=class{constructor(port){__publicField(this,"port");this.port=port}getPcbPort(){let pcbPortId=this.port.pcb_port_id;return pcbPortId?this.port.root?.db.pcb_port.get(pcbPortId)??null:null}getSourcePort(){let sourcePortId=this.port.source_port_id;return sourcePortId?this.port.root?.db.source_port.get(sourcePortId)??null:null}},SelectionResultNetImpl=class{constructor(net){__publicField(this,"net");this.net=net}getSourceNet(){let sourceNetId=this.net.source_net_id;return sourceNetId?this.net.root?.db.source_net.get(sourceNetId)??null:null}},SelectionResultComponentImpl=class{constructor(component){__publicField(this,"component");this.component=component}getPort(name){let port=this.component.selectOne(`port.${name}`,{type:"port"})??this.component.selectOne(`.${name}`,{type:"port"});return port?new SelectionResultPortImpl(port):null}getPorts(){return this.component.selectAll("port").map(port=>new SelectionResultPortImpl(port))}getPcbComponent(){let pcbComponentId=this.component.pcb_component_id;return pcbComponentId?this.component.root?.db.pcb_component.get(pcbComponentId)??null:null}getSourceComponent(){let sourceComponentId=this.component.source_component_id;return sourceComponentId?this.component.root?.db.source_component.get(sourceComponentId)??null:null}},DrcCheck=class extends PrimitiveComponent{get config(){return{componentName:"DrcCheck",zodProps:drcCheckProps}}constructor(props){super(props)}async runCustomDrcCheck(circuitJson){let result=await this._parsedProps.checkFn(this.createCustomDrcCheckContext(circuitJson)),diagnostics=[];return Array.isArray(result)?diagnostics=result:result&&(diagnostics=[result]),diagnostics.map((diagnostic,index2)=>this.createCircuitJsonDiagnostic(diagnostic,index2)).filter(diagnostic=>!!diagnostic)}createCustomDrcCheckContext(circuitJson){return{select:this.selectCustomDrcElement.bind(this),selectAll:this.selectAllCustomDrcElements.bind(this),isConnected:(a23,b23)=>this.isConnected(a23,b23,circuitJson),isPulledUp:a23=>this.isConnected(a23,"net.VCC",circuitJson)||this.isConnected(a23,"net.VDD",circuitJson)||this.getResistanceBetween(a23,"net.VCC",circuitJson)!==null||this.getResistanceBetween(a23,"net.VDD",circuitJson)!==null,isPulledDown:a23=>this.isConnected(a23,"net.GND",circuitJson)||this.getResistanceBetween(a23,"net.GND",circuitJson)!==null,getResistanceBetween:(a23,b23)=>this.getResistanceBetween(a23,b23,circuitJson)}}selectCustomDrcElement(selector2){return this.wrapSelectionResult(this.getSubcircuit().selectOne(selector2))}selectAllCustomDrcElements(selector2){let selectionResults=[];for(let component of this.getSubcircuit().selectAll(selector2)){let selectionResult=this.wrapSelectionResult(component);selectionResult&&selectionResults.push(selectionResult)}return selectionResults}wrapSelectionResult(component){return component?component instanceof Port?new SelectionResultPortImpl(component):component instanceof Net?new SelectionResultNetImpl(component):new SelectionResultComponentImpl(component):null}createCircuitJsonDiagnostic(diagnostic,index2){let diagnosticRecord=diagnostic,diagnosticType="source_component_misconfigured_error";typeof diagnosticRecord.error_type=="string"?diagnosticType=diagnosticRecord.error_type:typeof diagnosticRecord.warning_type=="string"&&(diagnosticType=diagnosticRecord.warning_type);let diagnosticWithCircuitJsonDefaults={...diagnostic};typeof diagnosticRecord.type=="string"?diagnosticWithCircuitJsonDefaults.type=diagnosticRecord.type:diagnosticWithCircuitJsonDefaults.type=diagnosticType,typeof diagnosticRecord.warning_type!="string"&&(typeof diagnosticRecord.error_type=="string"?diagnosticWithCircuitJsonDefaults.error_type=diagnosticRecord.error_type:diagnosticWithCircuitJsonDefaults.error_type=diagnosticType);let diagnosticIdField=`${diagnosticType}_id`;return diagnosticRecord[diagnosticIdField]?diagnosticWithCircuitJsonDefaults[diagnosticIdField]=diagnosticRecord[diagnosticIdField]:diagnosticWithCircuitJsonDefaults[diagnosticIdField]=`${diagnosticType}_${this._renderId}_${index2}`,any_circuit_element.parse(diagnosticWithCircuitJsonDefaults)}isConnected(a23,b23,circuitJson){let aKeys=this.getConnectivityKeys(a23,circuitJson),bKeys=this.getConnectivityKeys(b23,circuitJson);return aKeys.some(key=>bKeys.includes(key))}getResistanceBetween(a23,b23,circuitJson){if(this.isConnected(a23,b23,circuitJson))return 0;let aKeys=this.getConnectivityKeys(a23,circuitJson),bKeys=this.getConnectivityKeys(b23,circuitJson);if(aKeys.length===0||bKeys.length===0)return null;let sourceResistors=circuitJson.filter(elm=>elm.type==="source_component"&&elm.ftype==="simple_resistor"),root=this.root;if(!root)return null;for(let resistor of sourceResistors){let resistorPorts=root.db.source_port.list({source_component_id:resistor.source_component_id});if(resistorPorts.length!==2)continue;let resistorKeys=resistorPorts.map(port=>port.subcircuit_connectivity_map_key),connectsA=resistorKeys.some(key=>key&&aKeys.includes(key)),connectsB=resistorKeys.some(key=>key&&bKeys.includes(key));if(connectsA&&connectsB)return resistor.resistance}return null}getConnectivityKeys(connectable,circuitJson){if(!connectable)return[];if(typeof connectable=="string"){let selected=this.selectCustomDrcElement(connectable);return selected?this.getConnectivityKeys(selected,circuitJson):[]}return isSelectionResultPort(connectable)?[connectable.getSourcePort()?.subcircuit_connectivity_map_key].filter(isNonEmptyString):isSelectionResultNet(connectable)?[connectable.getSourceNet()?.subcircuit_connectivity_map_key].filter(isNonEmptyString):isSelectionResultComponent(connectable)?connectable.getPorts().flatMap(port=>this.getConnectivityKeys(port,circuitJson)):isCircuitJsonElement(connectable)?this.getCircuitJsonElementConnectivityKeys(connectable,circuitJson):[]}getCircuitJsonElementConnectivityKeys(element2,circuitJson){if(!element2)return[];if(element2.type==="source_port")return[element2.subcircuit_connectivity_map_key].filter(isNonEmptyString);if(element2.type==="source_net")return[element2.subcircuit_connectivity_map_key].filter(isNonEmptyString);if(element2.type==="pcb_port")return this.getConnectivityKeys(element2.source_port_id,circuitJson);if(element2.type==="source_component"){let root=this.root;return root?root.db.source_port.list({source_component_id:element2.source_component_id}).map(port=>port.subcircuit_connectivity_map_key).filter(isNonEmptyString):[]}return[]}},AutoroutingPhase=class extends PrimitiveComponent{get config(){return{componentName:"AutoroutingPhase",zodProps:autoroutingPhaseProps}}add(_component){throw new Error("<autoroutingphase> cannot contain children")}},AutoplacedBreakoutPoint=class extends BaseBreakoutPoint{get config(){return{componentName:"AutoplacedBreakoutPoint",zodProps:baseBreakoutPointProps}}_applySolvedBreakoutPoint({sourceTraceId,layer,position:position22}){this.matchedSourceTraceId=sourceTraceId,this._renderPcbBreakoutPoint({layer:layer_ref.parse(layer)}),this._setPositionFromLayout(position22)}},DDR_BYTE0_PORTS=[{id:"DQ0",layer:"inner3",soc:{x:-6,y:-3},ram:{x:3.941917,y:-3.650917}},{id:"DQ1",layer:"inner6",fullLayer:"inner2",soc:{x:-5.5,y:-3},ram:{x:4.591917,y:-3.650917}},{id:"DQ2",layer:"inner5",fullLayer:"inner4",soc:{x:-4.5,y:-3},ram:{x:5.891917,y:-3.650917}},{id:"DQ3",layer:"inner2",fullLayer:"inner6",soc:{x:-4.5,y:-3.5},ram:{x:6.541917,y:-3.650917}},{id:"DQ4",layer:"inner3",fullLayer:"inner2",soc:{x:-6,y:-2.5},ram:{x:6.541917,y:-2.050917}},{id:"DQ5",layer:"inner2",fullLayer:"inner5",soc:{x:-6,y:-2},ram:{x:5.891917,y:-2.050917}},{id:"DQ6",layer:"inner5",fullLayer:"inner4",soc:{x:-5,y:-2},ram:{x:4.591917,y:-2.050917}},{id:"DQ7",layer:"inner4",fullLayer:"inner6",soc:{x:-5.5,y:-2},ram:{x:3.941917,y:-2.050917}},{id:"DM0",layer:"inner4",fullLayer:"inner5",soc:{x:-5,y:-3},ram:{x:4.591917,y:-2.850917}},{id:"DQS0",layer:"inner1",differentialPairId:"DQS0",soc:{x:-4.5,y:-2.5},ram:{x:5.241917,y:-2.850917}},{id:"DQS0_n",layer:"inner1",differentialPairId:"DQS0",soc:{x:-5,y:-2.5},ram:{x:5.891917,y:-2.850917}}],DDR_BYTE1_PORTS=[{id:"DQ8",layer:"inner6",fullLayer:"inner4",soc:{x:-6,y:3},ram:{x:3.941917,y:3.549083}},{id:"DQ9",layer:"inner3",fullLayer:"inner4",soc:{x:-5.5,y:2},ram:{x:4.591917,y:3.549083}},{id:"DQ10",layer:"inner3",fullLayer:"inner2",soc:{x:-4.5,y:2},ram:{x:5.891917,y:3.549083}},{id:"DQ11",layer:"inner6",fullLayer:"inner5",soc:{x:-4.5,y:2.5},ram:{x:6.541917,y:3.549083}},{id:"DQ12",layer:"inner5",fullLayer:"inner1",soc:{x:-6,y:2.5},ram:{x:6.541917,y:1.949083}},{id:"DQ13",layer:"inner2",fullLayer:"inner3",soc:{x:-6.5,y:3},ram:{x:5.891917,y:1.949083}},{id:"DQ14",layer:"inner5",fullLayer:"inner6",soc:{x:-5,y:2.5},ram:{x:4.591917,y:1.949083}},{id:"DQ15",layer:"inner4",fullLayer:"inner1",soc:{x:-4.5,y:3.5},ram:{x:3.941917,y:1.949083}},{id:"DM1",layer:"inner4",fullLayer:"inner5",soc:{x:-5,y:3.5},ram:{x:4.591917,y:2.749083}},{id:"DQS1",layer:"inner1",fullLayer:"bottom",differentialPairId:"DQS1",soc:{x:-4.5,y:3},ram:{x:5.241917,y:2.749083}},{id:"DQS1_n",layer:"inner1",fullLayer:"bottom",differentialPairId:"DQS1",soc:{x:-5,y:3},ram:{x:5.891917,y:2.749083}}],DDR_ADDR_CTRL_PORTS=[{id:"A0",layer:"bottom",soc:{x:-6.5,y:-.5},ram:{x:7.841917,y:-3.650917}},{id:"A1",layer:"inner3",soc:{x:-7,y:-2},ram:{x:8.491917,y:-3.650917}},{id:"A2",layer:"inner3",soc:{x:-7,y:-.5},ram:{x:7.841917,y:1.949083}},{id:"A3",layer:"inner6",soc:{x:-5,y:-1},ram:{x:7.841917,y:2.749083}},{id:"A4",layer:"inner4",soc:{x:-4.5,y:-1.5},ram:{x:7.841917,y:3.549083}},{id:"A5",layer:"inner2",soc:{x:-6.5,y:-2},ram:{x:8.491917,y:3.549083}},{id:"CS0_n",layer:"inner5",soc:{x:-5.5,y:-.5},ram:{x:7.841917,y:-2.050917}},{id:"CKE0",layer:"inner1",soc:{x:-4.5,y:-1},ram:{x:8.491917,y:-2.050917}},{id:"CK0",layer:"bottom",differentialPairId:"CK0",soc:{x:-4.5,y:1},ram:{x:8.491917,y:1.149083}},{id:"CK0_n",layer:"bottom",differentialPairId:"CK0",soc:{x:-5,y:1},ram:{x:8.491917,y:1.949083}},{id:"DDR_LINK_RESET0_n",layer:"inner6",soc:{x:-5,y:-1.5},ram:{x:13.041917,y:3.549083}}],createAm62lExample=options=>{let ports=options.buses.flatMap(bus=>bus.ports),addedPairIds=new Set,makeEndpoints=port=>[{regionId:"soc",position:port.soc},{regionId:"ram",position:port.ram}],connections=[];for(let port of ports){if(!port.differentialPairId){connections.push({id:port.id,endpoints:makeEndpoints(port)});continue}if(addedPairIds.has(port.differentialPairId))continue;addedPairIds.add(port.differentialPairId);let pair=ports.filter(candidate=>candidate.differentialPairId===port.differentialPairId);if(pair.length!==2)throw new Error(`Differential pair ${port.differentialPairId} must have two members`);let[first,second]=pair;connections.push({type:"differential",connections:[{id:first.id,endpoints:makeEndpoints(first)},{id:second.id,endpoints:makeEndpoints(second)}]})}let buses=options.buses.map(bus=>{let solverBus={id:bus.id,connectionIds:bus.ports.map(port=>port.id)};return bus.preferredLayer!==void 0&&(solverBus={...solverBus,preferredLayer:bus.preferredLayer}),bus.preferredLayers!==void 0&&(solverBus={...solverBus,preferredLayers:bus.preferredLayers}),solverBus});return{regions:[{id:"soc",bounds:{minX:-16.62808,maxX:-2.37192,minY:-10.62808,maxY:10.62808},edge:"right"},{id:"ram",bounds:{minX:1.091917,maxX:18.141917,minY:-9.650917,maxY:9.549083},edge:"left"}],connections,buses,boundaryPointSpacing:.48}},ddrByte0Example=createAm62lExample({buses:[{id:"DDR_BYTE0",ports:DDR_BYTE0_PORTS,preferredLayers:["inner1","inner4"]}]}),ddrByte1Example=createAm62lExample({buses:[{id:"DDR_BYTE1",ports:DDR_BYTE1_PORTS,preferredLayers:["inner2","inner5"]}]}),fullDdrExample=createAm62lExample({buses:[{id:"DDR_BYTE0",ports:DDR_BYTE0_PORTS,preferredLayers:["inner1","inner4"]},{id:"DDR_BYTE1",ports:DDR_BYTE1_PORTS,preferredLayers:["inner2","inner5"]},{id:"DDR_ADDR_CTRL",ports:DDR_ADDR_CTRL_PORTS,preferredLayers:["inner3","inner6"]}]}),controlBusExample=createAm62lExample({buses:[{id:"DDR_ADDR_CTRL",ports:DDR_ADDR_CTRL_PORTS,preferredLayers:["inner3","inner6"]}]}),WindingBreakoutInputError=class extends Error{constructor(){super(...arguments);__publicField(this,"name","WindingBreakoutInputError")}},WindingBreakoutInfeasibleError=class extends Error{constructor(){super(...arguments);__publicField(this,"name","WindingBreakoutInfeasibleError")}},WindingBreakoutInvariantError=class extends Error{constructor(){super(...arguments);__publicField(this,"name","WindingBreakoutInvariantError")}},WindingBreakoutOutputUnavailableError=class extends Error{constructor(){super(...arguments);__publicField(this,"name","WindingBreakoutOutputUnavailableError")}},getCanonicalConnections=input2=>{let connections=[];for(let entry of input2.connections)"type"in entry?connections.push(...entry.connections):connections.push(entry);return connections},getBusLayerCandidates=bus=>bus.preferredLayer!==void 0?[bus.preferredLayer]:bus.preferredLayers!==void 0?[...new Set(bus.preferredLayers)]:["top"],getLayerCandidatesByConnection=input2=>{let candidatesByConnection=new Map;for(let bus of input2.buses){let candidates=getBusLayerCandidates(bus);for(let connectionId of bus.connectionIds)candidatesByConnection.set(connectionId,candidates)}return Object.fromEntries(getCanonicalConnections(input2).map(connection=>[connection.id,candidatesByConnection.get(connection.id)??["top"]]))},fail=message=>{throw new WindingBreakoutInputError(`WindingBreakoutSolver: ${message}`)},isRecord=value=>typeof value=="object"&&value!==null&&!Array.isArray(value),requireRecord=(value,label)=>{isRecord(value)||fail(`${label} must be an object`)},requireId=(value,label)=>{(typeof value!="string"||value.trim().length===0)&&fail(`${label} must be a non-empty string`)},requireFinite=(value,label)=>{(typeof value!="number"||!Number.isFinite(value))&&fail(`${label} must be finite`)},requirePositive=(value,label)=>{requireFinite(value,label),value<=0&&fail(`${label} must be positive`)},requireArray=(value,message)=>Array.isArray(value)?value:fail(message),validatePoint=(value,label)=>(requireRecord(value,label),requireFinite(value.x,`${label}.x`),requireFinite(value.y,`${label}.y`),value),validateBounds=(value,label)=>(requireRecord(value,label),requireFinite(value.minX,`${label}.minX`),requireFinite(value.maxX,`${label}.maxX`),requireFinite(value.minY,`${label}.minY`),requireFinite(value.maxY,`${label}.maxY`),(value.minX>=value.maxX||value.minY>=value.maxY)&&fail(`${label} must have positive width and height`),{minX:value.minX,maxX:value.maxX,minY:value.minY,maxY:value.maxY}),pointIsInsideBounds4=(point12,bounds)=>point12.x>=bounds.minX&&point12.x<=bounds.maxX&&point12.y>=bounds.minY&&point12.y<=bounds.maxY,validateWindingBreakoutInput=input2=>{(!Array.isArray(input2.regions)||input2.regions.length===0)&&fail("at least one region is required"),requirePositive(input2.boundaryPointSpacing,"boundaryPointSpacing");let regionIds=new Set,regions=input2.regions.map((value,index2)=>{requireRecord(value,`regions[${index2}]`),requireId(value.id,`regions[${index2}].id`),regionIds.has(value.id)&&fail(`duplicate region id "${value.id}"`),regionIds.add(value.id);let bounds=validateBounds(value.bounds,`region "${value.id}" bounds`);return(typeof value.edge!="string"||!new Set(["left","right","bottom","top"]).has(value.edge))&&fail(`region "${value.id}" has invalid edge`),{id:value.id,bounds,edge:value.edge,center:{x:(bounds.minX+bounds.maxX)/2,y:(bounds.minY+bounds.maxY)/2}}}),vertical=regions.every(region=>region.edge==="left"||region.edge==="right"),horizontal=regions.every(region=>region.edge==="bottom"||region.edge==="top");!vertical&&!horizontal&&fail("all coordinated region edges must be parallel"),(!Array.isArray(input2.connections)||input2.connections.length===0)&&fail("at least one connection is required");let connections=[],connectionIds=new Set,atomicConnectionGroups=[],validateConnection=(value,label)=>{requireRecord(value,label),requireId(value.id,`${label}.id`),connectionIds.has(value.id)&&fail(`duplicate connection id "${value.id}"`),"layer"in value&&fail(`${label}.layer is not accepted; declare layer preferences on a bus`);let endpointValues=requireArray(value.endpoints,`${label}.endpoints must be an array`),endpointRegionIds=new Set,endpoints=endpointValues.map((endpointValue,endpointIndex)=>{let endpointLabel=`${label}.endpoints[${endpointIndex}]`;requireRecord(endpointValue,endpointLabel),requireId(endpointValue.regionId,`${endpointLabel}.regionId`),regionIds.has(endpointValue.regionId)||fail(`${endpointLabel} references unknown region "${endpointValue.regionId}"`),endpointRegionIds.has(endpointValue.regionId)&&fail(`${label} has duplicate endpoint for region "${endpointValue.regionId}"`),endpointRegionIds.add(endpointValue.regionId);let position22=validatePoint(endpointValue.position,`${endpointLabel}.position`),region=regions.find(candidate=>candidate.id===endpointValue.regionId);return pointIsInsideBounds4(position22,region.bounds)||fail(`${label} endpoint for region "${region.id}" is outside its bounds`),{regionId:endpointValue.regionId,position:position22}});for(let region of regions)endpointRegionIds.has(region.id)||fail(`${label} is missing endpoint for region "${region.id}"`);return endpoints.length!==regions.length&&fail(`${label} must contain exactly one endpoint for every region`),connectionIds.add(value.id),{id:value.id,endpoints}};for(let[index2,value]of input2.connections.entries()){let label=`connections[${index2}]`;if(requireRecord(value,label),"type"in value||"connections"in value){value.type!=="differential"&&fail(`${label} has invalid differential-pair type`),"layer"in value&&fail(`${label}.layer is not accepted; declare layer preferences on a bus`);let pairConnections=requireArray(value.connections,`${label}.connections must contain exactly two members`);pairConnections.length!==2&&fail(`${label}.connections must contain exactly two members`);let first=validateConnection(pairConnections[0],`${label}.connections[0]`),second=validateConnection(pairConnections[1],`${label}.connections[1]`);first.id===second.id&&fail(`${label} members must have distinct connection ids`),connections.push(first,second),atomicConnectionGroups.push([first.id,second.id])}else connections.push(validateConnection(value,label))}let busValues=requireArray(input2.buses,"buses must be an array"),busIds=new Set,busByConnection=new Map,buses=busValues.map((value,busIndex)=>{let label=`buses[${busIndex}]`;requireRecord(value,label),requireId(value.id,`${label}.id`);let busId=value.id;busIds.has(busId)&&fail(`duplicate bus id "${busId}"`),busIds.add(busId);let connectionIdValues=requireArray(value.connectionIds,`${label}.connectionIds must be a non-empty array`);connectionIdValues.length===0&&fail(`${label}.connectionIds must be a non-empty array`);let localConnectionIds=new Set,busConnectionIds=connectionIdValues.map((connectionId,connectionIndex)=>{requireId(connectionId,`${label}.connectionIds[${connectionIndex}]`),connectionIds.has(connectionId)||fail(`${label} references unknown connection "${connectionId}"`),localConnectionIds.has(connectionId)&&fail(`${label} contains duplicate connection "${connectionId}"`),localConnectionIds.add(connectionId);let previousBusId=busByConnection.get(connectionId);return previousBusId!==void 0&&fail(`connection "${connectionId}" belongs to multiple buses "${previousBusId}" and "${value.id}"`),busByConnection.set(connectionId,busId),connectionId}),preferredLayer;value.preferredLayer!==void 0&&(requireId(value.preferredLayer,`${label}.preferredLayer`),preferredLayer=value.preferredLayer);let preferredLayers;if(value.preferredLayers!==void 0){let preferredLayerValues=requireArray(value.preferredLayers,`${label}.preferredLayers must be a non-empty array`);preferredLayerValues.length===0&&fail(`${label}.preferredLayers must be a non-empty array`);let uniquePreferredLayers=new Set;preferredLayers=preferredLayerValues.map((layer,layerIndex)=>(requireId(layer,`${label}.preferredLayers[${layerIndex}]`),uniquePreferredLayers.has(layer)&&fail(`${label}.preferredLayers contains duplicate layer "${layer}"`),uniquePreferredLayers.add(layer),layer))}let validatedBus={id:busId,connectionIds:busConnectionIds};return preferredLayer!==void 0&&(validatedBus={...validatedBus,preferredLayer}),preferredLayers!==void 0&&(validatedBus={...validatedBus,preferredLayers}),validatedBus});for(let[firstConnectionId,secondConnectionId]of atomicConnectionGroups){let firstBusId=busByConnection.get(firstConnectionId),secondBusId=busByConnection.get(secondConnectionId);firstBusId!==secondBusId&&fail(`differential pair "${firstConnectionId}/${secondConnectionId}" must belong to the same bus`)}let layerNames=[...new Set([...buses.flatMap(bus=>getBusLayerCandidates(bus)),...connections.filter(connection=>!busByConnection.has(connection.id)).map(()=>"top")])].sort((first,second)=>first.localeCompare(second));return{regions,connections,buses,layerNames,atomicConnectionGroups}},GEOMETRY_EPSILON22=1e-9,isVerticalEdge=edge=>edge==="left"||edge==="right",getAxisMinimum=(region,vertical)=>vertical?region.bounds.minY:region.bounds.minX,getAxisMaximum=(region,vertical)=>vertical?region.bounds.maxY:region.bounds.maxX,getAxisPosition=(position22,vertical)=>vertical?position22.y:position22.x,deriveLayerOffsets=(layerNames,boundaryPointSpacing)=>{let staggerOffset=boundaryPointSpacing/2;return Object.fromEntries(layerNames.map((layer,index2)=>[layer,(index2-(layerNames.length-1)/2)*staggerOffset]))},makeAtomicLayerOrder=({referenceOrder,layer,layerByConnection,atomicGroups})=>{let candidates=referenceOrder.filter(connectionId=>layerByConnection[connectionId]===layer),groupByConnection=new Map(atomicGroups.flatMap(group2=>group2.map(connectionId=>[connectionId,group2]))),addedGroups=new Set,result=[];for(let connectionId of candidates){let group2=groupByConnection.get(connectionId);if(!group2){result.push(connectionId);continue}addedGroups.has(group2)||(addedGroups.add(group2),result.push(...candidates.filter(candidate=>group2.includes(candidate))))}return result},makeGateAxes=({regions,connections,spacing,count,layerOffsets})=>{let vertical=regions.every(region=>isVerticalEdge(region.edge)),minAxis=Math.max(...regions.map(region=>getAxisMinimum(region,vertical))),maxAxis=Math.min(...regions.map(region=>getAxisMaximum(region,vertical))),minimumOffset=Math.min(...Object.values(layerOffsets)),maximumOffset=Math.max(...Object.values(layerOffsets)),span=spacing*Math.max(0,count-1)+maximumOffset-minimumOffset;if(maxAxis-minAxis+GEOMETRY_EPSILON22<span)throw new WindingBreakoutInfeasibleError(`WindingBreakoutSolver: declared breakout edges need ${span.toFixed(2)}mm but expose only ${(maxAxis-minAxis).toFixed(2)}mm`);let meanAxis=regions.reduce((regionSum,region)=>{let positions=connections.map(connection=>connection.endpoints.find(endpoint=>endpoint.regionId===region.id).position);return regionSum+positions.reduce((sum,position22)=>sum+getAxisPosition(position22,vertical),0)/positions.length},0)/regions.length,start=Math.max(minAxis-minimumOffset,Math.min(maxAxis-spacing*Math.max(0,count-1)-maximumOffset,meanAxis-spacing*Math.max(0,count-1)/2));return{vertical,axes:Array.from({length:count},(_23,index2)=>start+index2*spacing)}},pointOnEdge=(region,axis,vertical)=>{if(vertical){let x23=region.bounds.maxX;return region.edge==="left"&&(x23=region.bounds.minX),{x:x23,y:axis}}let y23=region.bounds.maxY;return region.edge==="bottom"&&(y23=region.bounds.minY),{x:axis,y:y23}},placeBreakoutGates=({regions,connections,referenceOrder,layerNames,layerByConnection,boundaryPointSpacing,atomicGroups})=>{let layerOffsets=deriveLayerOffsets(layerNames,boundaryPointSpacing),gateOrderByLayer=Object.fromEntries(layerNames.map(layer=>[layer,makeAtomicLayerOrder({referenceOrder,layer,layerByConnection,atomicGroups})])),maxLayerNetCount=Math.max(...layerNames.map(layer=>connections.filter(connection=>layerByConnection[connection.id]===layer).length)),{vertical,axes:axes2}=makeGateAxes({regions,connections,spacing:boundaryPointSpacing,count:maxLayerNetCount,layerOffsets});return{breakoutPoints:regions.flatMap(region=>layerNames.flatMap(layer=>gateOrderByLayer[layer].map((connectionId,slotIndex)=>({regionId:region.id,connectionId,layer,...pointOnEdge(region,axes2[slotIndex]+layerOffsets[layer],vertical)}))))}},getAtomicUnits=(connectionIds,atomicGroups)=>{let connectionSet=new Set(connectionIds),groupByConnection=new Map(atomicGroups.flatMap(group2=>group2.map(connectionId=>[connectionId,group2]))),addedGroups=new Set,units=[];for(let connectionId of connectionIds){let group2=groupByConnection.get(connectionId);if(!group2){units.push([connectionId]);continue}addedGroups.has(group2)||(addedGroups.add(group2),units.push(group2.filter(memberId=>connectionSet.has(memberId))))}return units},assignConnectionLayers=({validated,referenceOrder})=>{let assignments=new Map;for(let bus of validated.buses){let busConnectionSet=new Set(bus.connectionIds),orderedBusConnections=referenceOrder.filter(connectionId=>busConnectionSet.has(connectionId)),candidates=getBusLayerCandidates(bus),units=getAtomicUnits(orderedBusConnections,validated.atomicConnectionGroups);for(let[unitIndex,unit2]of units.entries()){let layer=candidates[unitIndex%candidates.length];for(let connectionId of unit2)assignments.set(connectionId,layer)}}for(let connectionId of referenceOrder)assignments.has(connectionId)||assignments.set(connectionId,"top");let layerByConnection=Object.fromEntries(referenceOrder.map(connectionId=>[connectionId,assignments.get(connectionId)])),layerNames=[...new Set(Object.values(layerByConnection))].sort((first,second)=>first.localeCompare(second));return{layerByConnection,layerNames}},getLayerNames=input2=>[...new Set(Object.values(getLayerCandidatesByConnection(input2)).flat())].sort((first,second)=>first.localeCompare(second)),CONNECTION_COLORS=["#2563eb","#dc2626","#059669","#7c3aed","#d97706","#0891b2","#db2777","#4f46e5","#65a30d","#c2410c","#0f766e","#9333ea"],getConnectionColor=connectionId=>{let hash=2166136261;for(let character of connectionId)hash^=character.charCodeAt(0),hash=Math.imul(hash,16777619);return CONNECTION_COLORS[(hash>>>0)%CONNECTION_COLORS.length]},getGraphicsLayer3=(input2,layerIds)=>{let signalLayerIds=getLayerNames(input2),indexes=[...new Set(layerIds)].map(layerId=>{let index2=signalLayerIds.indexOf(layerId);if(index2<0)throw new Error(`Cannot visualize unknown signal layer "${layerId}"`);return index2});if(indexes.length===0)throw new Error("Cannot create graphics metadata without a signal layer");return indexes.sort((first,second)=>first-second),`z${indexes.join(",")}`},createInputGraphics=(input2,activeLayer)=>{let graphics={circles:[],rects:[],texts:[]},displayedLayers=getLayerNames(input2);activeLayer&&(displayedLayers=[activeLayer]);let visibleLayers=getGraphicsLayer3(input2,displayedLayers),connections=getCanonicalConnections(input2),layerCandidatesByConnection=getLayerCandidatesByConnection(input2),endpointRadius=Math.min(.12,input2.boundaryPointSpacing/4);for(let region of input2.regions){let center2={x:(region.bounds.minX+region.bounds.maxX)/2,y:(region.bounds.minY+region.bounds.maxY)/2};graphics.rects.push({center:center2,width:region.bounds.maxX-region.bounds.minX,height:region.bounds.maxY-region.bounds.minY,fill:"rgba(226, 232, 240, 0.035)",stroke:"rgba(71, 85, 105, 0.55)",layer:visibleLayers});for(let connection of connections){let layerCandidates=layerCandidatesByConnection[connection.id];if(activeLayer&&!layerCandidates.includes(activeLayer))continue;let endpoint=connection.endpoints.find(candidate=>candidate.regionId===region.id);if(!endpoint)continue;let color32=getConnectionColor(connection.id);graphics.circles.push({center:endpoint.position,radius:endpointRadius,fill:`${color32}70`,stroke:color32,layer:getGraphicsLayer3(input2,layerCandidates)})}graphics.texts.push({x:center2.x,y:region.bounds.maxY+.35,text:region.id,anchorSide:"bottom_center",color:"#334155",fontSize:.34,layer:visibleLayers})}return graphics},createStateGraphics=(input2,state2,activeLayer)=>{let connections=getCanonicalConnections(input2),breakoutPoints=state2.breakoutPoints.filter(point12=>!activeLayer||point12.layer===activeLayer),sharedGateSlots=new Map;for(let point12 of state2.breakoutPoints){let key=`${point12.regionId}:${point12.x.toFixed(9)}:${point12.y.toFixed(9)}`,slot=sharedGateSlots.get(key)??{x:point12.x,y:point12.y,layers:new Set};slot.layers.add(point12.layer),sharedGateSlots.set(key,slot)}return{lines:state2.referenceOrder.flatMap(connectionId=>{let connection=connections.find(candidate=>candidate.id===connectionId);if(!connection)return[];let connectionBreakouts=breakoutPoints.filter(point12=>point12.connectionId===connectionId),layer=connectionBreakouts[0]?.layer;if(!layer||activeLayer&&layer!==activeLayer)return[];if(connectionBreakouts.length!==input2.regions.length)return[];let points=input2.regions.flatMap((region,regionIndex)=>{let endpoint=connection.endpoints.find(candidate=>candidate.regionId===region.id),breakout=connectionBreakouts.find(candidate=>candidate.regionId===region.id);return!endpoint||!breakout?[]:regionIndex===0?[endpoint.position,breakout]:[breakout,endpoint.position]});return points.length<2?[]:[{points,strokeColor:`${getConnectionColor(connectionId)}55`,strokeWidth:.012,strokeDash:[.025,.07],layer:getGraphicsLayer3(input2,[layer])}]}),circles:[...sharedGateSlots.values()].flatMap(slot=>{let layers=[...slot.layers].filter(layer=>!activeLayer||layer===activeLayer);return layers.length===0?[]:[{center:slot,radius:.11,fill:"rgba(15, 23, 42, 0.06)",stroke:"#475569",layer:getGraphicsLayer3(input2,layers)}]}),points:breakoutPoints.map(point12=>({x:point12.x,y:point12.y,color:getConnectionColor(point12.connectionId),label:`${point12.connectionId} \xB7 ${point12.layer}`,layer:getGraphicsLayer3(input2,[point12.layer])}))}},createSolverPhaseVisualization=({input:input2,phase,detail,activeLayer,referenceOrder,referenceRegionId,showReferenceNumbers=!1,state:state2})=>{let inputGraphics=createInputGraphics(input2,activeLayer),stateGraphics;state2&&(stateGraphics=createStateGraphics(input2,state2,activeLayer));let displayedLayers=getLayerNames(input2);activeLayer&&(displayedLayers=[activeLayer]);let textLayer=getGraphicsLayer3(input2,displayedLayers),maxY=Math.max(...input2.regions.map(region=>region.bounds.maxY)),minX=Math.min(...input2.regions.map(region=>region.bounds.minX)),texts=[...inputGraphics.texts??[],...stateGraphics?.texts??[],{x:minX,y:maxY+1.05,text:phase,anchorSide:"bottom_left",color:"#0f172a",fontSize:.42,layer:textLayer},{x:minX,y:maxY+.68,text:detail,anchorSide:"bottom_left",color:"#475569",fontSize:.25,layer:textLayer}],referenceLines=[],referenceCircles=[];if(showReferenceNumbers&&referenceOrder){let referenceRegion=input2.regions.find(region=>region.id===referenceRegionId)??input2.regions[0],connections=getCanonicalConnections(input2),layerCandidatesByConnection=getLayerCandidatesByConnection(input2),orderedPositions=[];for(let[index2,connectionId]of referenceOrder.entries()){let connection=connections.find(candidate=>candidate.id===connectionId),layerCandidates=layerCandidatesByConnection[connectionId];if(!connection||!layerCandidates||activeLayer&&!layerCandidates.includes(activeLayer))continue;let endpoint=connection.endpoints.find(candidate=>candidate.regionId===referenceRegion.id);endpoint&&(orderedPositions.push(endpoint.position),texts.push({x:endpoint.position.x+.18,y:endpoint.position.y+.18,text:`${index2+1} \xB7 ${connectionId}`,anchorSide:"bottom_left",color:getConnectionColor(connectionId),fontSize:.21,layer:getGraphicsLayer3(input2,layerCandidates)}))}let center2={x:(referenceRegion.bounds.minX+referenceRegion.bounds.maxX)/2,y:(referenceRegion.bounds.minY+referenceRegion.bounds.maxY)/2};referenceLines.push(...orderedPositions.map(position22=>({points:[center2,position22],strokeColor:"rgba(100, 116, 139, 0.35)",strokeWidth:.01,strokeDash:[.03,.05],layer:textLayer}))),orderedPositions.length>1&&referenceLines.push({points:orderedPositions,strokeColor:"rgba(15, 23, 42, 0.65)",strokeWidth:.018,strokeDash:[.04,.04],label:`${referenceRegion.id} angular winding order`,layer:textLayer}),referenceCircles.push({center:center2,radius:.07,fill:"#0f172a",stroke:"#ffffff",label:`${referenceRegion.id} angular reference center`,layer:textLayer})}return{title:phase,coordinateSystem:"cartesian",rects:inputGraphics.rects,polygons:inputGraphics.polygons,lines:[...stateGraphics?.lines??[],...referenceLines],circles:[...inputGraphics.circles??[],...stateGraphics?.circles??[],...referenceCircles],points:stateGraphics?.points,texts}},getSharedGateSlotCount=points=>new Set(points.map(point12=>`${point12.regionId}:${point12.x.toFixed(9)}:${point12.y.toFixed(9)}`)).size,GatePlacementSolver=class extends BaseSolver{constructor(params){super();__publicField(this,"params");__publicField(this,"batchIndex",0);__publicField(this,"output");__publicField(this,"plannedPlacement");__publicField(this,"placementBatches");__publicField(this,"visibleBreakoutPoints",[]);__publicField(this,"layerByConnection");__publicField(this,"visualizationLayer");this.params=params,this.visualizationLayer=params.visualizationLayer;let assignment=assignConnectionLayers({validated:params.validated,referenceOrder:params.ordering.referenceOrder});this.layerByConnection=assignment.layerByConnection,this.placementBatches=params.validated.regions.flatMap(region=>assignment.layerNames.map(layer=>({regionId:region.id,layer}))),this.MAX_ITERATIONS=this.placementBatches.length+2}setVisualizationLayer(layer){this.visualizationLayer=layer}_step(){if(!this.plannedPlacement){this.plannedPlacement=placeBreakoutGates({regions:this.params.validated.regions,connections:this.params.validated.connections,referenceOrder:this.params.ordering.referenceOrder,layerNames:[...new Set(Object.values(this.layerByConnection))].sort((first,second)=>first.localeCompare(second)),layerByConnection:this.layerByConnection,boundaryPointSpacing:this.params.input.boundaryPointSpacing,atomicGroups:this.params.validated.atomicConnectionGroups}),this.stats={phase:"plan-gate-grid",regionLayerBatches:this.placementBatches.length,placedBreakpoints:0};return}let batch=this.placementBatches[this.batchIndex];if(batch){this.visibleBreakoutPoints.push(...this.plannedPlacement.breakoutPoints.filter(point12=>point12.regionId===batch.regionId&&point12.layer===batch.layer)),this.batchIndex+=1,this.stats={phase:"place-region-layer-batch",regionId:batch.regionId,layer:batch.layer,completedBatches:this.batchIndex,totalBatches:this.placementBatches.length,placedBreakpoints:this.visibleBreakoutPoints.length};return}this.output=this.plannedPlacement,this.stats={phase:"finalize-shared-gate-slots",placedBreakpoints:this.output.breakoutPoints.length,sharedGateSlots:getSharedGateSlotCount(this.output.breakoutPoints)},this.solved=!0}computeProgress(){let completedMicrosteps=this.batchIndex;return this.plannedPlacement&&(completedMicrosteps+=1),this.output&&(completedMicrosteps+=1),completedMicrosteps/this.MAX_ITERATIONS}getConstructorParams(){return[this.params]}getOutput(){if(!this.solved||!this.output)throw new WindingBreakoutInvariantError("WindingBreakoutSolver: gate placement requested before placement completed");return this.output}visualize(){let detail="Next microstep: derive layer offsets, atomic gate orders, and the common boundary slot grid";if(this.plannedPlacement&&this.batchIndex===0)detail=`Gate grid planned \xB7 ${this.placementBatches.length} region/layer batches remain`;else if(this.plannedPlacement&&!this.output){let latestBatch=this.placementBatches[this.batchIndex-1];detail=`Placed region \u201C${latestBatch.regionId}\u201D on layer \u201C${latestBatch.layer}\u201D \xB7 ${this.batchIndex}/${this.placementBatches.length} batches`}else if(this.output){let sharedGateSlotCount=getSharedGateSlotCount(this.output.breakoutPoints);detail=`${this.output.breakoutPoints.length} gates placed; coincident layer positions form ${sharedGateSlotCount} shared slots`}let visualizationState;if(this.plannedPlacement){let breakoutPoints=this.visibleBreakoutPoints;this.output&&(breakoutPoints=this.output.breakoutPoints),visualizationState={referenceOrder:this.params.ordering.referenceOrder,breakoutPoints}}let graphics=createSolverPhaseVisualization({input:this.params.input,activeLayer:this.visualizationLayer,phase:"Step 2 \xB7 Place boundary gates",detail,state:visualizationState}),plannedSlotGuides=(this.plannedPlacement?.breakoutPoints??[]).filter(point12=>!this.visualizationLayer||point12.layer===this.visualizationLayer).map(point12=>({center:point12,radius:.065,fill:"rgba(255, 255, 255, 0.75)",stroke:"rgba(100, 116, 139, 0.5)",label:`planned slot ${point12.regionId} \xB7 ${point12.layer}`,layer:getGraphicsLayer3(this.params.input,[point12.layer])}));return{...graphics,circles:[...graphics.circles??[],...plannedSlotGuides]}}},getNaturalWindingOrder=(region,connections)=>connections.map(connection=>{let position22=connection.endpoints.find(endpoint=>endpoint.regionId===region.id).position;return{id:connection.id,angle:Math.atan2(position22.y-region.center.y,position22.x-region.center.x),radius:Math.hypot(position22.x-region.center.x,position22.y-region.center.y)}}).sort((first,second)=>first.angle-second.angle||second.radius-first.radius||first.id.localeCompare(second.id)).map(connection=>connection.id),getReferenceWindingOrder=(naturalOrder,atomicGroups,buses)=>{let groupByConnection=new Map(atomicGroups.flatMap(group2=>group2.map(connectionId=>[connectionId,group2]))),addedGroups=new Set,result=[];for(let connectionId of naturalOrder){let group2=groupByConnection.get(connectionId);if(!group2){result.push(connectionId);continue}addedGroups.has(group2)||(addedGroups.add(group2),result.push(...naturalOrder.filter(candidate=>group2.includes(candidate))))}let busByConnection=new Map(buses.flatMap(bus=>bus.connectionIds.map(connectionId=>[connectionId,bus]))),addedBuses=new Set,busContiguousResult=[];for(let connectionId of result){let bus=busByConnection.get(connectionId);if(!bus){busContiguousResult.push(connectionId);continue}if(addedBuses.has(bus))continue;addedBuses.add(bus);let busConnectionIds=new Set(bus.connectionIds);busContiguousResult.push(...result.filter(candidate=>busConnectionIds.has(candidate)))}return busContiguousResult},ReferenceOrderingSolver=class extends BaseSolver{constructor(params){super();__publicField(this,"params");__publicField(this,"naturalOrderByRegion",{});__publicField(this,"currentRegionIndex",0);__publicField(this,"output");__publicField(this,"visualizedOrder");__publicField(this,"visualizedRegionId");__publicField(this,"visualizationLayer");this.params=params,this.visualizationLayer=params.visualizationLayer,this.MAX_ITERATIONS=params.validated.regions.length+1}setVisualizationLayer(layer){this.visualizationLayer=layer}_step(){let region=this.params.validated.regions[this.currentRegionIndex];if(region){let naturalOrder=getNaturalWindingOrder(region,this.params.validated.connections);this.naturalOrderByRegion[region.id]=naturalOrder,this.visualizedRegionId=region.id,this.visualizedOrder=naturalOrder,this.currentRegionIndex+=1,this.stats={phase:"derive-natural-order",regionId:region.id,completedRegions:this.currentRegionIndex,totalRegions:this.params.validated.regions.length,naturalOrder};return}let firstRegion=this.params.validated.regions[0],referenceOrder=getReferenceWindingOrder(this.naturalOrderByRegion[firstRegion.id],this.params.validated.atomicConnectionGroups,this.params.validated.buses);this.output={naturalOrderByRegion:this.naturalOrderByRegion,referenceOrder},this.visualizedRegionId=firstRegion.id,this.visualizedOrder=referenceOrder,this.stats={phase:"atomicize-reference-order",referenceRegion:firstRegion.id,referenceOrder},this.solved=!0}computeProgress(){let completedMicrosteps=this.currentRegionIndex;return this.output&&(completedMicrosteps+=1),completedMicrosteps/this.MAX_ITERATIONS}getConstructorParams(){return[this.params]}getOutput(){if(!this.solved||!this.output)throw new WindingBreakoutInvariantError("WindingBreakoutSolver: reference order requested before ordering completed");return this.output}visualize(){let firstRegionId=this.params.validated.regions[0].id,detail=`Next microstep: derive natural order for region \u201C${firstRegionId}\u201D`;return this.visualizedRegionId&&!this.output&&(detail=`Natural order for region \u201C${this.visualizedRegionId}\u201D \xB7 ${this.currentRegionIndex}/${this.params.validated.regions.length} regions processed`),this.output&&(detail=`Reference region \u201C${firstRegionId}\u201D finalized; buses are contiguous and differential pairs are atomic`),createSolverPhaseVisualization({input:this.params.input,activeLayer:this.visualizationLayer,phase:"Step 1 \xB7 Derive reference order",detail,referenceOrder:this.visualizedOrder,referenceRegionId:this.visualizedRegionId,showReferenceNumbers:!0})}},validateBreakoutPoints=({points,connectionIds,regions,atomicGroups})=>{let regionIds=regions.map(region=>region.id),endpointCounts=new Map,layerByConnection=new Map,connectionLayersAreValid=!0;for(let point12 of points){let key=`${point12.regionId}:${point12.connectionId}`;endpointCounts.set(key,(endpointCounts.get(key)??0)+1);let previousLayer=layerByConnection.get(point12.connectionId);previousLayer!==void 0&&previousLayer!==point12.layer&&(connectionLayersAreValid=!1),layerByConnection.set(point12.connectionId,point12.layer)}let expected=regionIds.flatMap(regionId=>connectionIds.map(connectionId=>`${regionId}:${connectionId}`)),endpointsAreValid=endpointCounts.size===expected.length&&expected.every(endpoint=>endpointCounts.get(endpoint)===1),atomicGroupsAreValid=atomicGroups.every(group2=>{let layer=layerByConnection.get(group2[0]);return!layer||group2.some(connectionId=>layerByConnection.get(connectionId)!==layer)?!1:regions.every(region=>{let layerPoints=points.filter(point12=>point12.regionId===region.id&&point12.layer===layer),vertical=region.edge==="left"||region.edge==="right",orderedConnectionIds=[...layerPoints].sort((first,second)=>vertical?first.y-second.y:first.x-second.x).map(point12=>point12.connectionId),firstIndex=orderedConnectionIds.indexOf(group2[0]),secondIndex=orderedConnectionIds.indexOf(group2[1]);return firstIndex!==-1&&secondIndex!==-1&&Math.abs(firstIndex-secondIndex)===1})});return endpointsAreValid&&connectionLayersAreValid&&atomicGroupsAreValid},finalizeWindingBreakoutOutput=({validated,placement})=>{if(!validateBreakoutPoints({points:placement.breakoutPoints,connectionIds:validated.connections.map(connection=>connection.id),regions:validated.regions,atomicGroups:validated.atomicConnectionGroups}))throw new WindingBreakoutInvariantError("WindingBreakoutSolver: generated invalid breakout points");return{breakoutPoints:placement.breakoutPoints}},PIPELINE_STAGE_NAMES=["referenceOrdering","gatePlacement"],WindingBreakoutSolver=class extends BasePipelineSolver{constructor(input2){super(input2);__publicField(this,"validatedInput");__publicField(this,"output");__publicField(this,"visualizationLayer");__publicField(this,"pipelineDef",[definePipelineStep("referenceOrdering",ReferenceOrderingSolver,pipeline=>[{input:pipeline.inputProblem,validated:pipeline.getValidatedInput(),visualizationLayer:pipeline.visualizationLayer}]),definePipelineStep("gatePlacement",GatePlacementSolver,pipeline=>[{input:pipeline.inputProblem,validated:pipeline.getValidatedInput(),ordering:pipeline.getRequiredStageOutput("referenceOrdering"),visualizationLayer:pipeline.visualizationLayer}])])}_setup(){this.validatedInput=validateWindingBreakoutInput(this.inputProblem),this.stats={phase:"setup-input-validation",regionCount:this.validatedInput.regions.length,connectionCount:this.validatedInput.connections.length,layerCount:this.validatedInput.layerNames.length}}getValidatedInput(){if(!this.validatedInput)throw new Error("WindingBreakoutSolver: input has not been validated");return this.validatedInput}_step(){super._step(),!this.output&&!this.activeSubSolver&&this.currentPipelineStageIndex>=this.pipelineDef.length&&(this.output=finalizeWindingBreakoutOutput({validated:this.getValidatedInput(),placement:this.getRequiredStageOutput("gatePlacement")}),this.solved=!0),this.stats={phase:this.getCurrentStageName(),completedStages:this.currentPipelineStageIndex,totalStages:this.pipelineDef.length},this.solved&&(this.stats.phase="finalize-output-validation"),this.output&&(this.stats.valid=!0,this.stats.breakoutPointCount=this.output.breakoutPoints.length)}getRequiredStageOutput(stageName){let output=this.getStageOutput(stageName);if(output===void 0)throw new Error(`WindingBreakoutSolver: pipeline stage \u201C${stageName}\u201D has no output`);return output}setVisualizationLayer(layer){this.visualizationLayer=layer;for(let stageName of PIPELINE_STAGE_NAMES){let solver=this.getSolver(stageName);solver&&"setVisualizationLayer"in solver&&solver.setVisualizationLayer(layer)}}getConstructorParams(){return[this.inputProblem]}getOutput(){if(!this.solved||!this.output)throw new WindingBreakoutOutputUnavailableError("WindingBreakoutSolver: getOutput() called before successful completion");return this.output}initialVisualize(){return createSolverPhaseVisualization({input:this.inputProblem,activeLayer:this.visualizationLayer,phase:"Input \xB7 Validated during setup",detail:"Region bounds, breakout edges, bus layer preferences, and canonical endpoints"})}finalVisualize(){if(!this.output)return null;let ordering=this.getRequiredStageOutput("referenceOrdering");return createSolverPhaseVisualization({input:this.inputProblem,activeLayer:this.visualizationLayer,phase:"Output \xB7 Validated after gate placement",detail:"Valid: one bus-constrained breakout point per connection and region; pairs are adjacent",state:{referenceOrder:ordering.referenceOrder,breakoutPoints:this.output.breakoutPoints}})}visualize(){return{...super.visualize(),title:"Winding breakout solver \xB7 step-by-step pipeline",coordinateSystem:"cartesian"}}},toWindingConnection=connection=>({id:connection.connectionId,endpoints:connection.endpoints}),defaultImplicitBreakoutPointSolverFn=input2=>{let windingInput={regions:input2.regions.map(region=>({id:region.regionId,bounds:region.bounds,edge:region.edge})),connections:input2.connections.map(connection=>"type"in connection?{type:"differential",connections:connection.connections.map(toWindingConnection)}:toWindingConnection(connection)),buses:input2.buses.map(bus=>({id:bus.busId,connectionIds:bus.connectionIds,preferredLayers:bus.targetLayers})),boundaryPointSpacing:input2.boundaryPointSpacing},solver=new WindingBreakoutSolver(windingInput);return solver.solve(),solver.getOutput()},getFanoutBounds=pcbGroup=>{let outlineBounds=pcbGroup.outline?getBoundsFromPoints3(pcbGroup.outline):null,width10=pcbGroup.width??(outlineBounds?outlineBounds.maxX-outlineBounds.minX:void 0),height10=pcbGroup.height??(outlineBounds?outlineBounds.maxY-outlineBounds.minY:void 0);return width10===void 0||height10===void 0?null:{minX:pcbGroup.center.x-width10/2,maxX:pcbGroup.center.x+width10/2,minY:pcbGroup.center.y-height10/2,maxY:pcbGroup.center.y+height10/2}},getAxisGap2=(firstMin,firstMax,secondMin,secondMax)=>Math.max(firstMin-secondMax,secondMin-firstMax,0),Breakout_doInitialPcbPlacementDesignRuleChecks=breakout=>{if(breakout.root?.pcbDisabled||!breakout.pcb_group_id)return;let root=breakout.root;if(!root)return;let siblingFanouts=breakout.parent?.children.filter(sibling=>sibling instanceof breakout.constructor);if(!siblingFanouts)return;let breakoutIndex=siblingFanouts.indexOf(breakout);if(breakoutIndex<0)return;let{db:db22}=root,pcbGroup=db22.pcb_group.get(breakout.pcb_group_id);if(!pcbGroup)return;let bounds=getFanoutBounds(pcbGroup);if(bounds)for(let otherFanout of siblingFanouts.slice(breakoutIndex+1)){if(!otherFanout.pcb_group_id)continue;let otherPcbGroup=db22.pcb_group.get(otherFanout.pcb_group_id);if(!otherPcbGroup)continue;let otherBounds=getFanoutBounds(otherPcbGroup);if(!otherBounds)continue;let breakoutMargin=breakout._parsedProps.fanoutMargin,otherFanoutMargin=otherFanout._parsedProps.fanoutMargin,requiredMargin=Math.max(typeof breakoutMargin=="number"?breakoutMargin:0,typeof otherFanoutMargin=="number"?otherFanoutMargin:0),horizontalGap=getAxisGap2(bounds.minX,bounds.maxX,otherBounds.minX,otherBounds.maxX),verticalGap=getAxisGap2(bounds.minY,bounds.maxY,otherBounds.minY,otherBounds.maxY),horizontalOverlap=Math.min(bounds.maxX,otherBounds.maxX)-Math.max(bounds.minX,otherBounds.minX),verticalOverlap=Math.min(bounds.maxY,otherBounds.maxY)-Math.max(bounds.minY,otherBounds.minY),boundariesOverlap=horizontalOverlap>0&&verticalOverlap>0,violatesMargin=requiredMargin>0&&horizontalGap<requiredMargin&&verticalGap<requiredMargin;if(!boundariesOverlap&&!violatesMargin)continue;let message=boundariesOverlap?`Fanout boundaries "${breakout.name}" and "${otherFanout.name}" overlap. Fanout boundaries may not overlap.`:`Fanout boundaries "${breakout.name}" and "${otherFanout.name}" do not maintain the required ${requiredMargin}mm fanoutMargin.`;db22.pcb_placement_error.list().some(error2=>error2.message===message)||db22.pcb_placement_error.insert({error_type:"pcb_placement_error",message,subcircuit_id:breakout.subcircuit_id??void 0})}},reportWindingBreakoutInfeasibleError=(breakout,error2)=>{if(!(error2 instanceof WindingBreakoutInfeasibleError)||!breakout.root||!breakout.pcb_group_id)return!1;let componentNames=breakout.root.db.pcb_component.list().filter(pcbComponent=>pcbComponent.pcb_group_id===breakout.pcb_group_id).map(pcbComponent=>pcbComponent.source_component_id?breakout.root.db.source_component.get(pcbComponent.source_component_id)?.name:void 0).filter(name=>!!name);return breakout.root.db.pcb_autorouting_error.insert({pcb_error_id:`pcb_autorouting_error_winding_breakout_${breakout.pcb_group_id}`,error_type:"pcb_autorouting_error",message:`Winding fanout failed for ${componentNames.join(", ")||breakout.name}: ${error2.message}. The connections could not escape to the breakout boundary. Give the fanout more room by increasing the breakout's padding, or by extending the breakout to include the parts crowding it (decoupling capacitors, series resistors).`}),!0},EDGES=["right","left","top","bottom"],isVerticalBreakoutEdge=edge=>edge==="left"||edge==="right",getBreakoutEdgeLength=(bounds,edge)=>isVerticalBreakoutEdge(edge)?bounds.maxY-bounds.minY:bounds.maxX-bounds.minX,canonicalBusFanoutDirections2=new Set(canonicalBusFanoutDirectionValues),getBreakoutEdgeForFanoutDirection=fanoutDirection=>{let direction4=typeof fanoutDirection=="string"?fanoutDirection:fanoutDirection.direction;if(direction4==="center"||!canonicalBusFanoutDirections2.has(direction4))return;let[side,position22]=direction4.split("side_");if(position22==="center")return{edge:side,band:"center"};let startPosition=isVerticalBreakoutEdge(side)?"bottom":"left";return{edge:side,band:position22===startPosition?"start":"end"}},distanceFromPointToEdge=(bounds,target,edge)=>{let edgePoint=isVerticalBreakoutEdge(edge)?{x:edge==="left"?bounds.minX:bounds.maxX,y:Math.max(bounds.minY,Math.min(bounds.maxY,target.y))}:{x:Math.max(bounds.minX,Math.min(bounds.maxX,target.x)),y:edge==="bottom"?bounds.minY:bounds.maxY};return Math.hypot(target.x-edgePoint.x,target.y-edgePoint.y)},assignSingleRegionBreakoutEdges=({bounds,connectionIds,pinPositionByConnectionId,externalPositionsByConnectionId,atomicGroups,buses,busFanoutDirections,fallbackEdge,boundaryPointSpacing,layerCount})=>{let parent=new Map(connectionIds.map(id3=>[id3,id3])),find2=id3=>{let root=id3;for(;parent.get(root)!==root;)root=parent.get(root);return parent.set(id3,root),root},union3=ids=>{let members=ids.filter(id3=>parent.has(id3));for(let id3 of members.slice(1)){let firstRoot=find2(members[0]),root=find2(id3);firstRoot!==root&&parent.set(root,firstRoot)}};for(let group2 of atomicGroups)union3(group2);for(let bus of buses)union3(bus.connectionIds);let unitsByRoot=new Map;for(let id3 of connectionIds){let root=find2(id3),unit2=unitsByRoot.get(root)??[];unit2.push(id3),unitsByRoot.set(root,unit2)}let forcedPlacementByRoot=new Map;for(let bus of[...buses].sort((a23,b23)=>a23.busId.localeCompare(b23.busId))){let fanoutDirection=busFanoutDirections?.[bus.busId],firstMember=bus.connectionIds.find(id3=>parent.has(id3));if(!fanoutDirection||!firstMember)continue;let placement=getBreakoutEdgeForFanoutDirection(fanoutDirection),root=find2(firstMember);placement&&!forcedPlacementByRoot.has(root)&&forcedPlacementByRoot.set(root,placement)}let regionDiagonal=Math.hypot(bounds.maxX-bounds.minX,bounds.maxY-bounds.minY),getConnectionCost=(id3,edge)=>{let externalPositions=externalPositionsByConnectionId.get(id3)??[];if(externalPositions.length===0)return edge===fallbackEdge?0:regionDiagonal;let pin=pinPositionByConnectionId.get(id3);if(!pin)return Math.min(...externalPositions.map(position22=>distanceFromPointToEdge(bounds,position22,edge)));let exit=isVerticalBreakoutEdge(edge)?{x:edge==="left"?bounds.minX:bounds.maxX,y:pin.y}:{x:pin.x,y:edge==="bottom"?bounds.minY:bounds.maxY};return Math.hypot(exit.x-pin.x,exit.y-pin.y)+Math.min(...externalPositions.map(position22=>Math.hypot(position22.x-exit.x,position22.y-exit.y)))},units=[...unitsByRoot.entries()].map(([root,ids])=>{let costByEdge=new Map(EDGES.map(edge2=>[edge2,ids.reduce((sum,id3)=>sum+getConnectionCost(id3,edge2),0)])),forcedPlacement=forcedPlacementByRoot.get(root),edge=forcedPlacement?.edge??EDGES.reduce((bestEdge,candidate)=>costByEdge.get(candidate)<costByEdge.get(bestEdge)?candidate:bestEdge);return{key:ids[0],connectionIds:ids,costByEdge,edge,band:forcedPlacement?.band,forced:!!forcedPlacement}}),getEdgeCapacity=edge=>(Math.floor(getBreakoutEdgeLength(bounds,edge)/boundaryPointSpacing)+1)*Math.max(1,layerCount),getEdgeLoad=edge=>units.filter(unit2=>unit2.edge===edge).reduce((sum,unit2)=>sum+unit2.connectionIds.length,0);for(let edge of EDGES)for(;getEdgeLoad(edge)>getEdgeCapacity(edge);){let bestMove;for(let unit2 of units)if(!(unit2.edge!==edge||unit2.forced))for(let targetEdge of EDGES){if(targetEdge===edge||getEdgeLoad(targetEdge)+unit2.connectionIds.length>getEdgeCapacity(targetEdge))continue;let penalty=unit2.costByEdge.get(targetEdge)-unit2.costByEdge.get(edge);(!bestMove||penalty<bestMove.penalty||penalty===bestMove.penalty&&unit2.key.localeCompare(bestMove.unit.key)<0)&&(bestMove={unit:unit2,targetEdge,penalty})}if(!bestMove)break;bestMove.unit.edge=bestMove.targetEdge}let connectionOrder=new Map(connectionIds.map((id3,index2)=>[id3,index2])),groups=[];for(let edge of EDGES)for(let band of[void 0,"start","center","end"]){let groupConnectionIds=units.filter(unit2=>unit2.edge===edge&&unit2.band===band).flatMap(unit2=>unit2.connectionIds).sort((a23,b23)=>connectionOrder.get(a23)-connectionOrder.get(b23));groupConnectionIds.length!==0&&groups.push({edge,...band?{band}:{},connectionIds:groupConnectionIds})}return groups},getRoutingScopeOrThrow=breakout=>{let routingScope=breakout.parent;if(!routingScope?.selectAll)throw new Error(`Automatic breakout "${breakout.name}" has no coordinated routing scope`);return routingScope},getAutomaticBreakouts=(routingScope,breakoutToSolve)=>{let automaticBreakouts=[];for(let group2 of routingScope.selectAll("group")){if(!group2.isRoutingDirective||group2.parent!==routingScope)continue;let breakout=group2;breakout.children.some(child=>child instanceof AutoplacedBreakoutPoint)&&automaticBreakouts.push(breakout)}let getSourceTraceIds=breakout=>new Set(collectBreakoutRegionGeometry(breakout).endpointBySourceTraceId.keys()),sourceTraceIdsToSolve=getSourceTraceIds(breakoutToSolve);return automaticBreakouts.filter(automaticBreakout=>{let automaticBreakoutSourceTraceIds=getSourceTraceIds(automaticBreakout);return automaticBreakoutSourceTraceIds.size===sourceTraceIdsToSolve.size&&[...sourceTraceIdsToSolve].every(sourceTraceId=>automaticBreakoutSourceTraceIds.has(sourceTraceId))})},collectBreakoutRegionGeometry=breakout=>{if(!breakout.root||!breakout.pcb_group_id)throw new Error(`Automatic breakout "${breakout.name}" has no PCB region`);let pcbGroup=breakout.root.db.pcb_group.get(breakout.pcb_group_id);if(!pcbGroup||!pcbGroup.width||!pcbGroup.height)throw new Error(`Automatic breakout "${breakout.name}" has invalid PCB region bounds`);let bounds={minX:pcbGroup.center.x-pcbGroup.width/2,maxX:pcbGroup.center.x+pcbGroup.width/2,minY:pcbGroup.center.y-pcbGroup.height/2,maxY:pcbGroup.center.y+pcbGroup.height/2},center2={x:(bounds.minX+bounds.maxX)/2,y:(bounds.minY+bounds.maxY)/2},endpointBySourceTraceId=new Map,sourcePortIdBySourceTraceId=new Map;for(let breakoutPoint of breakout.children.filter(child=>child instanceof AutoplacedBreakoutPoint)){let matchedPort=breakoutPoint.matchedPort;if(!matchedPort?.pcb_port_id||!matchedPort.source_port_id)throw new Error(`Automatic breakout "${breakout.name}" is missing a PCB endpoint`);let sourceTraceId=breakoutPoint.matchedSourceTraceId;if(!sourceTraceId){let matchingSourceTraces=breakout.root.db.source_trace.list().filter(sourceTrace=>sourceTrace.connected_source_port_ids.includes(matchedPort.source_port_id));if(matchingSourceTraces.length===0)throw new Error(`Automatic breakout "${breakout.name}" has a point without a source trace identity`);let boundaryCrossingSourceTraces=matchingSourceTraces.filter(sourceTrace=>sourceTrace.connected_source_port_ids.some(sourcePortId=>{if(sourcePortId===matchedPort.source_port_id)return!1;let pcbPort2=breakout.root.db.pcb_port.getWhere({source_port_id:sourcePortId});return!pcbPort2||pcbPort2.pcb_group_id===breakout.pcb_group_id?!1:!(pcbPort2.x>=bounds.minX&&pcbPort2.x<=bounds.maxX&&pcbPort2.y>=bounds.minY&&pcbPort2.y<=bounds.maxY)}));sourceTraceId=(boundaryCrossingSourceTraces.length>0?boundaryCrossingSourceTraces:matchingSourceTraces).slice().sort((first,second)=>first.source_trace_id.localeCompare(second.source_trace_id))[0].source_trace_id,breakoutPoint.matchedSourceTraceId=sourceTraceId}if(endpointBySourceTraceId.has(sourceTraceId))throw new Error(`Connection "${sourceTraceId}" has duplicate endpoint for region "${breakout.pcb_group_id}"`);let pcbPort=breakout.root.db.pcb_port.get(matchedPort.pcb_port_id);if(!pcbPort)throw new Error(`Connection "${sourceTraceId}" references unknown PCB endpoint "${matchedPort.pcb_port_id}"`);if(pcbPort.pcb_group_id!==breakout.pcb_group_id)throw new Error(`Connection "${sourceTraceId}" endpoint references unknown region "${pcbPort.pcb_group_id??"unassigned"}" instead of "${breakout.pcb_group_id}"`);if(pcbPort.x===void 0||pcbPort.y===void 0)throw new Error(`Connection "${sourceTraceId}" is missing endpoint coordinates for region "${breakout.pcb_group_id}"`);endpointBySourceTraceId.set(sourceTraceId,{regionId:breakout.pcb_group_id,position:{x:pcbPort.x,y:pcbPort.y}}),sourcePortIdBySourceTraceId.set(sourceTraceId,matchedPort.source_port_id)}return{breakout,pcbGroupId:breakout.pcb_group_id,bounds,center:center2,endpointBySourceTraceId,sourcePortIdBySourceTraceId}},sortRegionsByPlacement=regions=>{let xCoordinates=regions.map(region=>region.center.x),yCoordinates=regions.map(region=>region.center.y),xSpan=Math.max(...xCoordinates)-Math.min(...xCoordinates),ySpan=Math.max(...yCoordinates)-Math.min(...yCoordinates),horizontalPlacement=xSpan>=ySpan;return regions.sort((firstRegion,secondRegion)=>{if(horizontalPlacement){let xDifference=firstRegion.center.x-secondRegion.center.x;if(xDifference!==0)return xDifference;let yDifference=firstRegion.center.y-secondRegion.center.y;if(yDifference!==0)return yDifference}else{let yDifference=firstRegion.center.y-secondRegion.center.y;if(yDifference!==0)return yDifference;let xDifference=firstRegion.center.x-secondRegion.center.x;if(xDifference!==0)return xDifference}return firstRegion.breakout.name.localeCompare(secondRegion.breakout.name)}),{regions,horizontalPlacement}},getFacingEdge=({region,regionIndex,regions,horizontalPlacement,singleRegionPreferredEdge})=>{if(regions.length===1&&singleRegionPreferredEdge)return singleRegionPreferredEdge;let otherRegions=regions.filter(candidate=>candidate!==region),otherCenter=otherRegions.reduce((sum,candidate)=>({x:sum.x+candidate.center.x/otherRegions.length,y:sum.y+candidate.center.y/otherRegions.length}),{x:0,y:0});return horizontalPlacement?otherCenter.x>region.center.x?"right":otherCenter.x<region.center.x?"left":regionIndex<regions.length/2?"right":"left":otherCenter.y>region.center.y?"top":otherCenter.y<region.center.y?"bottom":regionIndex<regions.length/2?"top":"bottom"},getExternalPositionsBySourceTraceId=({region,sourceTraces})=>{let externalPositionsBySourceTraceId=new Map,root=region.breakout.root;if(!root)return externalPositionsBySourceTraceId;let internalSourcePortIds=new Set(region.sourcePortIdBySourceTraceId.values());for(let sourceTrace of sourceTraces)if(sourceTrace.connected_source_port_ids.some(sourcePortId=>internalSourcePortIds.has(sourcePortId)))for(let sourcePortId of sourceTrace.connected_source_port_ids){if(internalSourcePortIds.has(sourcePortId))continue;let pcbPort=root.db.pcb_port.getWhere({source_port_id:sourcePortId});if(!pcbPort?.pcb_port_id||pcbPort.x===void 0||pcbPort.y===void 0||pcbPort.pcb_group_id===region.pcbGroupId)continue;let externalPositions=externalPositionsBySourceTraceId.get(sourceTrace.source_trace_id)??new Map;externalPositions.set(pcbPort.pcb_port_id,{x:pcbPort.x,y:pcbPort.y}),externalPositionsBySourceTraceId.set(sourceTrace.source_trace_id,externalPositions)}return externalPositionsBySourceTraceId},getSingleRegionPreferredEdge=({region,externalPositionsBySourceTraceId})=>{let externalPcbPorts=new Map;for(let externalPositions of externalPositionsBySourceTraceId.values())for(let[pcbPortId,position22]of externalPositions)position22.x>=region.bounds.minX&&position22.x<=region.bounds.maxX&&position22.y>=region.bounds.minY&&position22.y<=region.bounds.maxY||externalPcbPorts.set(pcbPortId,position22);if(externalPcbPorts.size===0)return;let distanceToEdge=(target,edge)=>{let edgePoint=edge==="left"||edge==="right"?{x:edge==="left"?region.bounds.minX:region.bounds.maxX,y:Math.max(region.bounds.minY,Math.min(region.bounds.maxY,target.y))}:{x:Math.max(region.bounds.minX,Math.min(region.bounds.maxX,target.x)),y:edge==="bottom"?region.bounds.minY:region.bounds.maxY};return Math.hypot(target.x-edgePoint.x,target.y-edgePoint.y)},edges=["right","left","top","bottom"];return edges.reduce((bestEdge,edge)=>{let bestCost=[...externalPcbPorts.values()].reduce((sum,target)=>sum+distanceToEdge(target,bestEdge),0);return[...externalPcbPorts.values()].reduce((sum,target)=>sum+distanceToEdge(target,edge),0)<bestCost?edge:bestEdge},edges[0])},getSourceTraceForConnectionOrThrow=({connectionOwner,connectionOwnerLabel,connectionSelector,sourceTraces})=>{let matchingSourceTraces=sourceTraces.filter(sourceTrace=>sourceTrace.name===connectionSelector);if(matchingSourceTraces.length===0){let selectedPort=connectionOwner.getSubcircuit().selectOne(connectionSelector,{type:"port"});selectedPort?.source_port_id&&(matchingSourceTraces=sourceTraces.filter(sourceTrace=>sourceTrace.connected_source_port_ids.includes(selectedPort.source_port_id)))}if(matchingSourceTraces.length===0)throw new Error(`Could not resolve "${connectionSelector}" in ${connectionOwnerLabel}`);if(matchingSourceTraces.length>1)throw new Error(`Connection "${connectionSelector}" resolves to multiple source traces in ${connectionOwnerLabel}`);return matchingSourceTraces[0]},getImplicitBreakoutSolverBuses=({routingScope,sourceTraces,coordinatedSourceTraceIds,availableLayers})=>{let solverBuses=[],subcircuitId=routingScope.getSubcircuit().subcircuit_id;for(let bus of routingScope.selectAll("bus")){if(bus.getSubcircuit().subcircuit_id!==subcircuitId)continue;let connectionIds=[];for(let connectionSelector of bus._parsedProps.connections){let sourceTrace=getSourceTraceForConnectionOrThrow({connectionOwner:bus,connectionOwnerLabel:`bus "${bus.name}"`,connectionSelector,sourceTraces});coordinatedSourceTraceIds.has(sourceTrace.source_trace_id)&&connectionIds.push(sourceTrace.source_trace_id)}if(connectionIds.length===0)continue;let solverBus={busId:bus.name,connectionIds};if(bus._parsedProps.preferredLayer!==void 0)solverBus={...solverBus,targetLayers:[bus._parsedProps.preferredLayer]};else if(bus._parsedProps.preferredLayers!==void 0)solverBus={...solverBus,targetLayers:bus._parsedProps.preferredLayers};else{let targetLayers=bus._parsedProps.pcbAllowedLayers??availableLayers;solverBus={...solverBus,targetLayers:[...new Set(targetLayers)]}}solverBuses.push(solverBus)}return solverBuses},getDifferentialPairSourceTraces=({routingScope,sourceTraces})=>{let subcircuitId=routingScope.getSubcircuit().subcircuit_id,pairs32=[];for(let differentialPair of routingScope.selectAll("differentialpair")){if(differentialPair.getSubcircuit().subcircuit_id!==subcircuitId)continue;let positiveSourceTrace=getSourceTraceForConnectionOrThrow({connectionOwner:differentialPair,connectionOwnerLabel:`differential pair "${differentialPair.name}"`,connectionSelector:differentialPair._parsedProps.positiveConnection,sourceTraces}),negativeSourceTrace=getSourceTraceForConnectionOrThrow({connectionOwner:differentialPair,connectionOwnerLabel:`differential pair "${differentialPair.name}"`,connectionSelector:differentialPair._parsedProps.negativeConnection,sourceTraces});pairs32.push({differentialPair,positiveSourceTraceId:positiveSourceTrace.source_trace_id,negativeSourceTraceId:negativeSourceTrace.source_trace_id})}return pairs32},getBoundaryPointSpacing=breakout=>{let board=breakout.root?.db.pcb_board.list()[0],traceWidth=board?.min_trace_width??.15,traceToPadClearance=board?.min_trace_to_pad_edge_clearance??.2,viaPadDiameter=board?.min_via_pad_diameter??.3;return getFanoutBoundaryPointSpacing({traceWidth,traceToPadClearance,viaPadDiameter})},getCoordinatedFanoutLayers=({routingScope,automaticBreakouts})=>{let coordinatedLayers=getBoardAvailableLayers(routingScope._getSubcircuitLayerCount());for(let automaticBreakout of automaticBreakouts){let fanoutRoutingLayers=automaticBreakout._parsedProps.fanoutRoutingLayers?.map(String);if(!fanoutRoutingLayers)continue;let fanoutLayerSet=new Set(fanoutRoutingLayers);coordinatedLayers=coordinatedLayers.filter(layer=>fanoutLayerSet.has(layer))}if(coordinatedLayers.length===0)throw new Error(`Automatic breakouts in routing scope "${routingScope.name}" have no shared fanout routing layer`);return coordinatedLayers},warnAboutUnknownFanoutDirectionBuses=({breakout,routingScope,busFanoutDirections})=>{if(!busFanoutDirections||!breakout.root)return;let sourceComponentId=breakout.root.db.pcb_component.list().find(pcbComponent=>pcbComponent.pcb_group_id===breakout.pcb_group_id)?.source_component_id;if(!sourceComponentId)return;let subcircuitId=routingScope.getSubcircuit().subcircuit_id,busNames=new Set(routingScope.selectAll("bus").filter(bus=>bus.getSubcircuit().subcircuit_id===subcircuitId).map(bus=>bus.name));for(let busName of Object.keys(busFanoutDirections))busNames.has(busName)||breakout.root.db.source_property_ignored_warning.insert({source_component_id:sourceComponentId,property_name:"busFanoutDirections",error_type:"source_property_ignored_warning",message:`Breakout "${breakout.name}" busFanoutDirections names unknown bus "${busName}"; the entry is ignored`,subcircuit_id:subcircuitId??void 0})},createImplicitBreakoutPointSolverContext=breakout=>{if(!breakout.root)throw new Error(`Automatic breakout "${breakout.name}" has no circuit root`);let routingScope=getRoutingScopeOrThrow(breakout),automaticBreakouts=getAutomaticBreakouts(routingScope,breakout),regionIds=new Set,collectedRegions=automaticBreakouts.map(automaticBreakout=>{let region=collectBreakoutRegionGeometry(automaticBreakout);if(regionIds.has(region.pcbGroupId))throw new Error(`Duplicate automatic breakout region "${region.pcbGroupId}"`);return regionIds.add(region.pcbGroupId),region}),{regions,horizontalPlacement}=sortRegionsByPlacement(collectedRegions),sourceTraceIds=new Set;for(let region of regions)for(let sourceTraceId of region.endpointBySourceTraceId.keys())sourceTraceIds.add(sourceTraceId);let sourceTraces=breakout.root.db.source_trace.list().filter(sourceTrace=>sourceTrace.subcircuit_id===routingScope.getSubcircuit().subcircuit_id),sourceTraceById=new Map;for(let sourceTrace of sourceTraces){if(sourceTraceById.has(sourceTrace.source_trace_id))throw new Error(`Duplicate connection identity "${sourceTrace.source_trace_id}"`);sourceTraceById.set(sourceTrace.source_trace_id,sourceTrace)}let sortedSourceTraceIds=[...sourceTraceIds].sort((firstSourceTraceId,secondSourceTraceId)=>{let firstName=sourceTraceById.get(firstSourceTraceId)?.name??firstSourceTraceId,secondName=sourceTraceById.get(secondSourceTraceId)?.name??secondSourceTraceId,nameDifference=firstName.localeCompare(secondName);return nameDifference!==0?nameDifference:firstSourceTraceId.localeCompare(secondSourceTraceId)});for(let sourceTraceId of sortedSourceTraceIds){if(!sourceTraceById.has(sourceTraceId))throw new Error(`Unknown connection identity "${sourceTraceId}"`);for(let region of regions)if(!region.endpointBySourceTraceId.has(sourceTraceId))throw new Error(`Connection "${sourceTraceId}" is missing endpoint for region "${region.pcbGroupId}"`)}let buses=getImplicitBreakoutSolverBuses({routingScope,sourceTraces,coordinatedSourceTraceIds:sourceTraceIds,availableLayers:getCoordinatedFanoutLayers({routingScope,automaticBreakouts})}),endpointsBySourceTraceId=new Map;for(let sourceTraceId of sortedSourceTraceIds)endpointsBySourceTraceId.set(sourceTraceId,regions.map(region=>region.endpointBySourceTraceId.get(sourceTraceId)));let differentialPairBySourceTraceId=new Map;for(let pair of getDifferentialPairSourceTraces({routingScope,sourceTraces})){let positiveIsCoordinated=sourceTraceIds.has(pair.positiveSourceTraceId),negativeIsCoordinated=sourceTraceIds.has(pair.negativeSourceTraceId);if(positiveIsCoordinated!==negativeIsCoordinated)throw new Error(`Differential pair "${pair.differentialPair.name}" is missing one coordinated member`);if(positiveIsCoordinated){if(differentialPairBySourceTraceId.has(pair.positiveSourceTraceId)||differentialPairBySourceTraceId.has(pair.negativeSourceTraceId))throw new Error("A connection belongs to multiple differential pairs");differentialPairBySourceTraceId.set(pair.positiveSourceTraceId,pair),differentialPairBySourceTraceId.set(pair.negativeSourceTraceId,pair)}}let connections=[],addedDifferentialPairs=new Set;for(let sourceTraceId of sortedSourceTraceIds){let differentialPair=differentialPairBySourceTraceId.get(sourceTraceId);if(!differentialPair){connections.push({connectionId:sourceTraceId,endpoints:endpointsBySourceTraceId.get(sourceTraceId)});continue}addedDifferentialPairs.has(differentialPair.differentialPair)||(addedDifferentialPairs.add(differentialPair.differentialPair),connections.push({type:"differential",connections:[{connectionId:differentialPair.positiveSourceTraceId,endpoints:endpointsBySourceTraceId.get(differentialPair.positiveSourceTraceId)},{connectionId:differentialPair.negativeSourceTraceId,endpoints:endpointsBySourceTraceId.get(differentialPair.negativeSourceTraceId)}]}))}let sourcePortIdByConnectionIdByRegionId=new Map,externalPositionsBySourceTraceId=regions.length===1?getExternalPositionsBySourceTraceId({region:regions[0],sourceTraces}):void 0,singleRegionPreferredEdge=externalPositionsBySourceTraceId?getSingleRegionPreferredEdge({region:regions[0],externalPositionsBySourceTraceId}):void 0,solverRegions=regions.map((region,regionIndex)=>(sourcePortIdByConnectionIdByRegionId.set(region.pcbGroupId,region.sourcePortIdBySourceTraceId),{regionId:region.pcbGroupId,bounds:region.bounds,edge:getFacingEdge({region,regionIndex,regions,horizontalPlacement,singleRegionPreferredEdge})})),boundaryPointSpacing=getBoundaryPointSpacing(breakout),singleRegionEdgeGroups;if(externalPositionsBySourceTraceId){let region=regions[0],busFanoutDirections=region.breakout._parsedProps.busFanoutDirections;warnAboutUnknownFanoutDirectionBuses({breakout:region.breakout,routingScope,busFanoutDirections}),singleRegionEdgeGroups=assignSingleRegionBreakoutEdges({bounds:region.bounds,connectionIds:sortedSourceTraceIds,pinPositionByConnectionId:new Map([...region.endpointBySourceTraceId].map(([sourceTraceId,endpoint])=>[sourceTraceId,endpoint.position])),externalPositionsByConnectionId:new Map([...externalPositionsBySourceTraceId].map(([sourceTraceId,positions])=>[sourceTraceId,[...positions.values()]])),atomicGroups:[...new Set(differentialPairBySourceTraceId.values())].map(pair=>[pair.positiveSourceTraceId,pair.negativeSourceTraceId]),buses,busFanoutDirections,fallbackEdge:solverRegions[0].edge,boundaryPointSpacing,layerCount:getCoordinatedFanoutLayers({routingScope,automaticBreakouts}).length})}return{input:{regions:solverRegions,connections,buses,boundaryPointSpacing},sourcePortIdByConnectionIdByRegionId,...singleRegionEdgeGroups?{singleRegionEdgeGroups}:{}}},GEOMETRY_EPSILON32=1e-9,packBreakoutEdgeGroups=({bounds,edge,blocks,boundaryPointSpacing})=>{let vertical=isVerticalBreakoutEdge(edge),edgeMin=vertical?bounds.minY:bounds.minX,edgeMax=vertical?bounds.maxY:bounds.maxX,edgeLength=getBreakoutEdgeLength(bounds,edge),getAxis3=point12=>vertical?point12.y:point12.x,placedBlocks=blocks.filter(block=>block.points.length>0).map(block=>{let axes2=block.points.map(getAxis3),low=Math.min(...axes2),length93=Math.max(...axes2)-low,targetLow=low;return block.band==="start"?targetLow=edgeMin+edgeLength/6-length93/2:block.band==="end"?targetLow=edgeMax-edgeLength/6-length93/2:block.band==="center"&&(targetLow=(edgeMin+edgeMax-length93)/2),targetLow=Math.max(edgeMin,Math.min(edgeMax-length93,targetLow)),{...block,low,length:length93,placedLow:targetLow}}).sort((first,second)=>first.placedLow-second.placedLow),cursor=edgeMin;for(let block of placedBlocks)block.placedLow=Math.max(block.placedLow,cursor),cursor=block.placedLow+block.length+boundaryPointSpacing;let limit=edgeMax;for(let block of[...placedBlocks].reverse())block.placedLow=Math.min(block.placedLow,limit-block.length),limit=block.placedLow-boundaryPointSpacing;let firstBlock=placedBlocks[0];if(firstBlock&&firstBlock.placedLow<edgeMin-GEOMETRY_EPSILON32){let neededLength=placedBlocks.reduce((sum,block)=>sum+block.length,0)+boundaryPointSpacing*(placedBlocks.length-1);throw new WindingBreakoutInfeasibleError(`WindingBreakoutSolver: ${edge} breakout edge needs ${neededLength.toFixed(2)}mm but exposes only ${edgeLength.toFixed(2)}mm`)}return placedBlocks.flatMap(block=>{let shift=block.placedLow-block.low;return block.points.map(point12=>vertical?{...point12,y:point12.y+shift}:{...point12,x:point12.x+shift})})},cachedSolutionsByRoutingScope=new WeakMap,runSolverSynchronously=(solverFn,input2)=>{let output=solverFn(input2);if(output instanceof Promise)throw new Error("Implicit breakout point solvers must return synchronously during PCB layout");return output.breakoutPoints},solveSingleRegionEdgeGroups=(context,solverFn)=>{let{input:input2,singleRegionEdgeGroups}=context,region=input2.regions[0],blocksByEdge=new Map;for(let group2 of singleRegionEdgeGroups){let groupConnectionIds=new Set(group2.connectionIds),points=runSolverSynchronously(solverFn,{...input2,regions:[{...region,edge:group2.edge}],connections:input2.connections.filter(connection=>"type"in connection?groupConnectionIds.has(connection.connections[0].connectionId):groupConnectionIds.has(connection.connectionId)),buses:input2.buses.map(bus=>({...bus,connectionIds:bus.connectionIds.filter(connectionId=>groupConnectionIds.has(connectionId))})).filter(bus=>bus.connectionIds.length>0)}),blocks=blocksByEdge.get(group2.edge)??[];blocks.push({band:group2.band,points}),blocksByEdge.set(group2.edge,blocks)}return[...blocksByEdge].flatMap(([edge,blocks])=>packBreakoutEdgeGroups({bounds:region.bounds,edge,blocks,boundaryPointSpacing:input2.boundaryPointSpacing}))},solveScope=(breakout,solverFn)=>{let context=createImplicitBreakoutPointSolverContext(breakout),singleRegionEdgeGroups=context.singleRegionEdgeGroups,outputBreakoutPoints=singleRegionEdgeGroups!==void 0&&(singleRegionEdgeGroups.length>1||singleRegionEdgeGroups[0]?.band!==void 0)?solveSingleRegionEdgeGroups(context,solverFn):runSolverSynchronously(solverFn,context.input),expectedConnectionCount=0;for(let connection of context.input.connections){if("type"in connection){expectedConnectionCount+=connection.connections.length;continue}expectedConnectionCount+=1}let breakoutPointsByRegionId=new Map,outputPointKeys=new Set;for(let region of context.input.regions)breakoutPointsByRegionId.set(region.regionId,[]);for(let breakoutPoint of outputBreakoutPoints){let regionBreakoutPoints=breakoutPointsByRegionId.get(breakoutPoint.regionId);if(!regionBreakoutPoints)throw new Error(`Implicit breakout point solver returned unknown region "${breakoutPoint.regionId}"`);let outputPointKey=`${breakoutPoint.regionId}:${breakoutPoint.connectionId}`;if(outputPointKeys.has(outputPointKey))throw new Error(`Implicit breakout point solver returned duplicate endpoint for connection "${breakoutPoint.connectionId}" in region "${breakoutPoint.regionId}"`);outputPointKeys.add(outputPointKey);let sourcePortId=context.sourcePortIdByConnectionIdByRegionId.get(breakoutPoint.regionId)?.get(breakoutPoint.connectionId);if(!sourcePortId)throw new Error(`Implicit breakout point solver returned unknown connection "${breakoutPoint.connectionId}" for region "${breakoutPoint.regionId}"`);regionBreakoutPoints.push({sourcePortId,sourceTraceId:breakoutPoint.connectionId,layer:breakoutPoint.layer,x:breakoutPoint.x,y:breakoutPoint.y})}for(let[regionId,regionBreakoutPoints]of breakoutPointsByRegionId)if(regionBreakoutPoints.length!==expectedConnectionCount)throw new Error(`Implicit breakout point solver output is missing endpoints for region "${regionId}"`);return{breakoutPointsByRegionId}},solveImplicitBreakoutPoints=(breakout,solverFn)=>{let routingScope=breakout.parent;if(!routingScope||!breakout.pcb_group_id)throw new Error(`Automatic breakout "${breakout.name}" has no coordinated PCB region`);let cachedSolutions=cachedSolutionsByRoutingScope.get(routingScope);(!cachedSolutions||cachedSolutions.solverFn!==solverFn)&&(cachedSolutions={solverFn,solutions:[]},cachedSolutionsByRoutingScope.set(routingScope,cachedSolutions));let solution2=cachedSolutions.solutions.find(candidateSolution=>candidateSolution.breakoutPointsByRegionId.has(breakout.pcb_group_id));solution2||(solution2=solveScope(breakout,solverFn),cachedSolutions.solutions.push(solution2));let breakoutPoints=solution2.breakoutPointsByRegionId.get(breakout.pcb_group_id);if(!breakoutPoints)throw new Error(`Automatic breakout "${breakout.name}" references unknown implicit-breakout region "${breakout.pcb_group_id}"`);return breakoutPoints},Breakout=class extends Group{get isDogboneFanout(){let autorouter=this._parsedProps.autorouter;return(typeof autorouter=="string"?autorouter:autorouter?.preset)==="dogbone"}get isRoutingDirective(){return!0}get config(){return{...super.config,zodProps:breakoutProps}}doInitialCreateAutoplacedBreakoutPoints(){for(let path of this._parsedProps.pcbTracePaths??[]){let exit=path.route.at(-1),point12=new SavedFanoutPoint({connection:path.connection,pcbX:exit.x,pcbY:exit.y});if(point12.exitLayer=exit.route_type==="wire"?exit.layer:exit.to_layer,this.add(point12),point12._matchConnection(),!point12.matchedPort||!this.selectAll("port").includes(point12.matchedPort))throw new Error(`Fanout trace path "${path.connection}" must select a port inside the fanout`);if(this.children.some(child=>!(child instanceof BreakoutPoint)||child===point12?!1:(child._matchConnection(),child.matchedPort===point12.matchedPort)))throw new Error(`Duplicate fanout exit for "${path.connection}"`)}let portsInBreakout=this.selectAll("port"),breakoutPortSet=new Set(portsInBreakout),manualBreakoutPoints=this.children.filter(c23=>c23 instanceof BreakoutPoint),manuallyMappedPorts=new Set(manualBreakoutPoints.map(bp22=>(bp22._matchConnection(),bp22.matchedPort)).filter(Boolean)),allTraces=this.getSubcircuit().selectAll("trace"),autoPlacedPorts=new Set;for(let trace of allTraces){let result=trace._findConnectedPorts();if(!(!result.allPortsFound||!result.ports))for(let port of result.ports){let isInside2=breakoutPortSet.has(port),hasOutsidePort=result.ports.some(p23=>!breakoutPortSet.has(p23));if(!isInside2||!hasOutsidePort&&!this.isDogboneFanout||manuallyMappedPorts.has(port)||autoPlacedPorts.has(port))continue;autoPlacedPorts.add(port);let breakoutPoint=new AutoplacedBreakoutPoint({});breakoutPoint.matchedPort=port,breakoutPoint.matchedSourceTraceId=trace.source_trace_id,this.add(breakoutPoint)}}}doInitialPcbAutoplaceBreakoutPoints(){if(this.root?.pcbDisabled)return;if(this.isDogboneFanout&&this._parsedProps.pcbTracePaths===void 0){for(let point12 of this.children){if(!(point12 instanceof AutoplacedBreakoutPoint))continue;let port=this.root.db.pcb_port.get(point12.matchedPort.pcb_port_id);point12._applySolvedBreakoutPoint({sourceTraceId:point12.matchedSourceTraceId,layer:port.layers[0],position:port})}return}let ownAutorouter=this.props.autorouter,inheritedAutorouter=ownAutorouter===void 0?this.parent?.getInheritedProperty("autorouter"):void 0,implicitBreakoutPointSolverFn=typeof ownAutorouter=="object"?ownAutorouter.implicitBreakoutPointSolverFn:typeof inheritedAutorouter=="object"?inheritedAutorouter.implicitBreakoutPointSolverFn:void 0,autoBreakoutPoints=this.children.filter(child=>child instanceof AutoplacedBreakoutPoint);if(autoBreakoutPoints.length===0||!this.root||!this.pcb_group_id)return;let pcbGroup=this.root.db.pcb_group.get(this.pcb_group_id);if(!pcbGroup?.width||!pcbGroup.height)return;let bounds={minX:pcbGroup.center.x-pcbGroup.width/2,maxX:pcbGroup.center.x+pcbGroup.width/2,minY:pcbGroup.center.y-pcbGroup.height/2,maxY:pcbGroup.center.y+pcbGroup.height/2},solvedBreakoutPoints;try{solvedBreakoutPoints=solveImplicitBreakoutPoints(this,implicitBreakoutPointSolverFn??defaultImplicitBreakoutPointSolverFn)}catch(error2){if(implicitBreakoutPointSolverFn||!reportWindingBreakoutInfeasibleError(this,error2))throw error2;return}let BOUNDARY_INSET_MM=1e-4,insetWithinBounds=(x23,y23)=>({x:Math.max(bounds.minX+BOUNDARY_INSET_MM,Math.min(bounds.maxX-BOUNDARY_INSET_MM,x23)),y:Math.max(bounds.minY+BOUNDARY_INSET_MM,Math.min(bounds.maxY-BOUNDARY_INSET_MM,y23))});for(let solvedPoint of solvedBreakoutPoints){let matchingBreakoutPoint=autoBreakoutPoints.find(child=>child.matchedPort?.source_port_id===solvedPoint.sourcePortId);if(matchingBreakoutPoint){let insetPoint=insetWithinBounds(solvedPoint.x,solvedPoint.y);matchingBreakoutPoint._applySolvedBreakoutPoint({sourceTraceId:solvedPoint.sourceTraceId,layer:solvedPoint.layer,position:insetPoint})}}}doInitialPcbPrimitiveRender(){super.doInitialPcbPrimitiveRender()}doInitialPcbPlacementDesignRuleChecks(){Breakout_doInitialPcbPlacementDesignRuleChecks(this)}},SilkscreenGraphic=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"pcb_silkscreen_graphic_id",null);__publicField(this,"pcb_silkscreen_graphic_ids",[]);__publicField(this,"pcb_silkscreen_path_ids",[]);__publicField(this,"isPcbPrimitive",!0)}get config(){return{componentName:"SilkscreenGraphic",zodProps:silkscreenGraphicProps}}doInitialPcbPrimitiveRender(){this.root?.pcbDisabled||this._queueAsyncEffect("SilkscreenGraphicRender",async()=>{if(this.root?.pcbDisabled)return;let{db:db22}=this.root,{_parsedProps:props}=this,{maybeFlipLayer}=this._getPcbPrimitiveFlippedHelpers(),layer=maybeFlipLayer(props.layer??"top");if(layer!=="top"&&layer!=="bottom")throw new Error(`Invalid layer "${layer}" for SilkscreenGraphic. Must be "top" or "bottom".`);let sourceImage=await loadImageSource(props.imageUrl);if(sourceImage.mimetype!==SVG_MIMETYPE2&&sourceImage.mimetype!==PNG_MIMETYPE)throw new Error(`Unsupported imageUrl for SilkscreenGraphic: "${props.imageUrl}". Expected an SVG or PNG image.`);let imageAsset={project_relative_path:sourceImage.projectRelativePath,url:sourceImage.dataUrl,mimetype:sourceImage.mimetype},brepShapes=sourceImage.mimetype===SVG_MIMETYPE2?getSvgBRepShapes({svg:sourceImage.text,width:props.width,height:props.height,transform:this._computePcbGlobalTransformBeforeLayout()}):[this.getPlacementBoxBRepShape()],pcbComponentId=this.parent?.pcb_component_id??this.getPrimitiveContainer()?.pcb_component_id??"";for(let brepShape of brepShapes){let graphic=db22.insert({type:"pcb_silkscreen_graphic",pcb_component_id:pcbComponentId,pcb_group_id:this.getGroup()?.pcb_group_id??void 0,subcircuit_id:this.getSubcircuit()?.subcircuit_id??void 0,layer,shape:"brep",brep_shape:brepShape,image_asset:imageAsset});this.pcb_silkscreen_graphic_ids.push(graphic.pcb_silkscreen_graphic_id)}this.pcb_silkscreen_graphic_id=this.pcb_silkscreen_graphic_ids[0]??null,sourceImage.mimetype===SVG_MIMETYPE2&&this.insertRenderableSilkscreenPaths(sourceImage.text,layer)})}insertRenderableSilkscreenPaths(svg,layer){let{db:db22}=this.root,{_parsedProps:props}=this,transform22=this._computePcbGlobalTransformBeforeLayout(),pcb_component_id=this.parent?.pcb_component_id??this.getPrimitiveContainer()?.pcb_component_id??"";for(let route2 of getTransformedSvgPathRoutes({svg,width:props.width,height:props.height,transform:transform22})){if(route2.length<2)continue;let path=db22.pcb_silkscreen_path.insert({pcb_component_id,layer,route:route2,stroke_width:Math.max(Math.min(props.width,props.height)/60,.05),subcircuit_id:this.getSubcircuit()?.subcircuit_id??void 0,pcb_group_id:this.getGroup()?.pcb_group_id??void 0});this.pcb_silkscreen_path_ids.push(path.pcb_silkscreen_path_id)}}getPcbSize(){let{_parsedProps:props}=this;return{width:props.width,height:props.height}}getPlacementBoxBRepShape(){let{_parsedProps:props}=this,halfWidth=props.width/2,halfHeight=props.height/2,transform22=this._computePcbGlobalTransformBeforeLayout();return{outer_ring:{vertices:ensureClockwise([{x:-halfWidth,y:halfHeight},{x:halfWidth,y:halfHeight},{x:halfWidth,y:-halfHeight},{x:-halfWidth,y:-halfHeight}]).map(point12=>applyToPoint3(transform22,point12))},inner_rings:[]}}_moveCircuitJsonElements({deltaX,deltaY}){if(this.root?.pcbDisabled)return;let{db:db22}=this.root,moveVertex=vertex=>({...vertex,x:vertex.x+deltaX,y:vertex.y+deltaY});for(let graphicId of this.pcb_silkscreen_graphic_ids){let graphic=db22.pcb_silkscreen_graphic.get(graphicId);graphic&&db22.pcb_silkscreen_graphic.update(graphicId,{brep_shape:{outer_ring:{vertices:graphic.brep_shape.outer_ring.vertices.map(moveVertex)},inner_rings:graphic.brep_shape.inner_rings.map(ring23=>({vertices:ring23.vertices.map(moveVertex)}))}})}for(let pathId of this.pcb_silkscreen_path_ids){let path=db22.pcb_silkscreen_path.get(pathId);path&&db22.pcb_silkscreen_path.update(pathId,{route:path.route.map(point12=>({...point12,x:point12.x+deltaX,y:point12.y+deltaY}))})}}},Fiducial=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"pcb_smtpad_id",null);__publicField(this,"isPcbPrimitive",!0)}get config(){return{componentName:"Fiducial",zodProps:fiducialProps,sourceFtype:"simple_fiducial"}}doInitialPcbPrimitiveRender(){if(this.root?.pcbDisabled)return;let{db:db22}=this.root,{_parsedProps:props}=this,position22=this._getGlobalPcbPositionBeforeLayout(),{maybeFlipLayer}=this._getPcbPrimitiveFlippedHelpers(),pcb_component_id=this.parent?.pcb_component_id??this.getPrimitiveContainer()?.pcb_component_id??void 0,pcb_smtpad23=db22.pcb_smtpad.insert({pcb_component_id,subcircuit_id:this.getSubcircuit()?.subcircuit_id??void 0,pcb_group_id:this.getGroup()?.pcb_group_id??void 0,layer:maybeFlipLayer(props.layer||"top"),shape:"circle",x:position22.x,y:position22.y,radius:distance4.parse(props.padDiameter)/2,soldermask_margin:props.soldermaskPullback?distance4.parse(props.soldermaskPullback):distance4.parse(props.padDiameter)/2,is_covered_with_solder_mask:!0});this.pcb_smtpad_id=pcb_smtpad23.pcb_smtpad_id}getPcbSize(){let{_parsedProps:props}=this,d23=distance4.parse(props.padDiameter);return{width:d23,height:d23}}_setPositionFromLayout(newCenter){if(!this.pcb_smtpad_id)return;let{db:db22}=this.root;db22.pcb_smtpad.update(this.pcb_smtpad_id,{x:newCenter.x,y:newCenter.y})}_moveCircuitJsonElements({deltaX,deltaY}){if(this.root?.pcbDisabled)return;let{db:db22}=this.root;if(!this.pcb_smtpad_id)return;let pad2=db22.pcb_smtpad.get(this.pcb_smtpad_id);pad2&&(pad2.shape==="rect"||pad2.shape==="circle"||pad2.shape==="rotated_rect"||pad2.shape==="pill"?this._setPositionFromLayout({x:pad2.x+deltaX,y:pad2.y+deltaY}):pad2.shape==="polygon"&&db22.pcb_smtpad.update(this.pcb_smtpad_id,{points:pad2.points.map(p23=>({x:p23.x+deltaX,y:p23.y+deltaY}))}))}},EPSILON30=1e-9,isWireRoutePoint=routePoint3=>routePoint3.route_type==="wire",getWirePointKey=point12=>`${point12.layer}:${point12.x}:${point12.y}`,isPointOnSegment42=(p23,a23,b23)=>{if(Math.hypot(b23.x-a23.x,b23.y-a23.y)<=EPSILON30)return Math.hypot(p23.x-a23.x,p23.y-a23.y)<=EPSILON30;let cross52=(p23.y-a23.y)*(b23.x-a23.x)-(p23.x-a23.x)*(b23.y-a23.y);if(Math.abs(cross52)>EPSILON30)return!1;let dot23=(p23.x-a23.x)*(b23.x-a23.x)+(p23.y-a23.y)*(b23.y-a23.y);if(dot23<-EPSILON30)return!1;let squaredLength6=(b23.x-a23.x)**2+(b23.y-a23.y)**2;return!(dot23-squaredLength6>EPSILON30)},isPointInRing2=(point12,ring23)=>{if(ring23.length<3)return!1;let inside42=!1,previous=ring23[ring23.length-1];for(let current23 of ring23){if(isPointOnSegment42(point12,previous,current23))return!0;current23.y>point12.y!=previous.y>point12.y&&point12.x<(previous.x-current23.x)*(point12.y-current23.y)/(previous.y-current23.y)+current23.x&&(inside42=!inside42),previous=current23}return inside42},isPointInRectPour=(p23,pour)=>{let{center:center2,width:width10,height:height10}=pour,rotationRad=(pour.rotation??0)*Math.PI/180,cosR=Math.cos(-rotationRad),sinR=Math.sin(-rotationRad),dx22=p23.x-center2.x,dy22=p23.y-center2.y,localX=dx22*cosR-dy22*sinR,localY=dx22*sinR+dy22*cosR;return Math.abs(localX)<=width10/2+EPSILON30&&Math.abs(localY)<=height10/2+EPSILON30},isPointInBrepPour=(p23,pour)=>isPointInRing2(p23,pour.brep_shape.outer_ring.vertices)&&!pour.brep_shape.inner_rings.some(ring23=>isPointInRing2(p23,ring23.vertices)),isPointInCopperPour=(point12,pour)=>pour.shape==="rect"?isPointInRectPour(point12,pour):pour.shape==="brep"?isPointInBrepPour(point12,pour):!1,isTraceConnectedToSourceNet=(trace,sourceNetId,sourceTraceById)=>{if(trace.source_trace_id===sourceNetId)return!0;if(!trace.source_trace_id)return!1;let sourceTrace=sourceTraceById.get(trace.source_trace_id);return sourceTrace?sourceTrace.connected_source_net_ids.includes(sourceNetId):!1},isSegmentFullyInsideCopperPour=(start,end,pour)=>{let dx22=end.x-start.x,dy22=end.y-start.y;if(Math.hypot(dx22,dy22)<=EPSILON30||!isPointInCopperPour(start,pour)||!isPointInCopperPour(end,pour))return!1;if(pour.shape==="rect")return!0;if(pour.shape!=="brep")return!1;for(let ring23 of[pour.brep_shape.outer_ring,...pour.brep_shape.inner_rings]){let vertices=ring23.vertices;for(let edgeIndex=0;edgeIndex<vertices.length;edgeIndex++)if(doesTraceSegmentTouchPourBoundaryEdge(start,end,vertices[edgeIndex],vertices[(edgeIndex+1)%vertices.length]))return!1}return!0},doesTraceSegmentTouchPourBoundaryEdge=(traceStart,traceEnd,boundaryStart,boundaryEnd)=>{if(isPointOnSegment42(traceStart,boundaryStart,boundaryEnd)||isPointOnSegment42(traceEnd,boundaryStart,boundaryEnd)||isPointOnSegment42(boundaryStart,traceStart,traceEnd)||isPointOnSegment42(boundaryEnd,traceStart,traceEnd))return!0;let side=(start,end,point12)=>(end.x-start.x)*(point12.y-start.y)-(end.y-start.y)*(point12.x-start.x),oppositeSides=(first,second)=>first>EPSILON30&&second<-EPSILON30||first<-EPSILON30&&second>EPSILON30;return oppositeSides(side(traceStart,traceEnd,boundaryStart),side(traceStart,traceEnd,boundaryEnd))&&oppositeSides(side(boundaryStart,boundaryEnd,traceStart),side(boundaryStart,boundaryEnd,traceEnd))},markTraceSegmentsInsideCopperPour=({db:db22,copperPour})=>{let sourceNetId=copperPour.source_net_id;if(!sourceNetId)return;let sourceTraceById=new Map(db22.source_trace.list().map(sourceTrace=>[sourceTrace.source_trace_id,sourceTrace])),traceCoverage=db22.pcb_trace.list().filter(trace=>isTraceConnectedToSourceNet(trace,sourceNetId,sourceTraceById)).map(trace=>({trace,coveredSegments:trace.route.slice(0,-1).map((from,segmentIndex)=>{let to3=trace.route[segmentIndex+1];return isWireRoutePoint(from)&&isWireRoutePoint(to3)&&from.layer===copperPour.layer&&to3.layer===copperPour.layer&&isSegmentFullyInsideCopperPour(from,to3,copperPour)})})),exposedPoints=new Set;for(let{trace,coveredSegments}of traceCoverage)for(let[routeIndex,point12]of trace.route.entries()){let coveredBefore=routeIndex===0||coveredSegments[routeIndex-1],coveredAfter=routeIndex===trace.route.length-1||coveredSegments[routeIndex];isWireRoutePoint(point12)&&(!coveredBefore||!coveredAfter)&&exposedPoints.add(getWirePointKey(point12))}for(let{trace,coveredSegments}of traceCoverage){let routeChanged=!1,nextRoute=trace.route.map(routePoint3=>{let point12={...routePoint3};return isWireRoutePoint(point12)&&coveredSegments.length>0&&!exposedPoints.has(getWirePointKey(point12))&&(point12.is_inside_copper_pour=!0,point12.copper_pour_id=copperPour.pcb_copper_pour_id,routeChanged=!0),point12});routeChanged&&db22.pcb_trace.update(trace.pcb_trace_id,{route:nextRoute})}},pendingCopperPourRenders=new WeakMap,DEFAULT_THERMAL_RELIEF_SPOKE_WIDTH_MM=.3,renderAllCopperPoursForSubcircuit=async subcircuit=>{if(!subcircuit.root)return;let{db:db22}=subcircuit.root,copperPours=subcircuit.selectAll("copperpour").filter(copperPour=>copperPour.getSubcircuit()===subcircuit),resolvedCopperPours=[];for(let copperPour of copperPours){let{_parsedProps:props}=copperPour,sourceNetId=subcircuit.selectOne(props.connectsTo)?.source_net_id;if(!sourceNetId){copperPour.renderError(`Net "${props.connectsTo}" not found for copper pour`);continue}resolvedCopperPours.push({copperPour,sourceNetId})}if(resolvedCopperPours.length===0)return;let circuitJson=db22.toArray(),boardComponent=subcircuit._getBoard(),pcbBoard=boardComponent?.pcb_board_id?db22.pcb_board.get(boardComponent.pcb_board_id):void 0,resolvedPcbBoardOutline=pcbBoard?.outline?.length?pcbBoard.outline:void 0;if(!resolvedPcbBoardOutline&&pcbBoard?.width!==void 0&&pcbBoard.height!==void 0){let{center:center2,width:width10,height:height10}=pcbBoard;resolvedPcbBoardOutline=[{x:center2.x-width10/2,y:center2.y-height10/2},{x:center2.x+width10/2,y:center2.y-height10/2},{x:center2.x+width10/2,y:center2.y+height10/2},{x:center2.x-width10/2,y:center2.y+height10/2}]}let inputProblem=convertCircuitJsonToInputProblem(circuitJson,resolvedCopperPours.map(({copperPour,sourceNetId})=>{let{_parsedProps:props}=copperPour,clearance=props.clearance??.2;return{pcb_board_id:pcbBoard?.pcb_board_id,layer:props.layer,crosshatch:props.crosshatch,crosshatchPitch:props.crosshatchPitch,crosshatchWidth:props.crosshatchWidth,subcircuit_id:subcircuit.subcircuit_id??void 0,source_net_id:sourceNetId,pad_margin:props.padMargin??clearance,trace_margin:props.traceMargin??clearance,pour_margin:clearance,board_edge_margin:props.boardEdgeMargin??clearance,board_edge_outline:copperPour._isImplicitCopperPour?resolvedPcbBoardOutline:void 0,cutout_margin:props.cutoutMargin??clearance,...props.useThermalReliefs?{use_thermal_reliefs:!0,thermal_relief_spoke_width:DEFAULT_THERMAL_RELIEF_SPOKE_WIDTH_MM}:{},outline:props.outline??resolvedPcbBoardOutline}}));await initializeManifoldGeometry();let solver=new CopperPourPipelineSolver(inputProblem);subcircuit.root.emit("solver:started",{type:"solver:started",solverName:"CopperPourPipelineSolver",solverParams:inputProblem,solverConstructorArgs:[inputProblem],componentName:subcircuit.getString()});let{brep_shapes_by_region}=solver.getOutput();for(let[regionIndex,{copperPour,sourceNetId}]of resolvedCopperPours.entries()){let{_parsedProps:props}=copperPour,coveredWithSolderMask=props.coveredWithSolderMask??!1;for(let brepShape of brep_shapes_by_region[regionIndex]??[]){let insertedPour=db22.pcb_copper_pour.insert({shape:"brep",layer:props.layer,brep_shape:brepShape,source_net_id:sourceNetId,subcircuit_id:subcircuit.subcircuit_id??void 0,covered_with_solder_mask:coveredWithSolderMask});markTraceSegmentsInsideCopperPour({db:db22,copperPour:insertedPour})}}};function CopperPour_doInitialPcbCopperPourRender(copperPour){copperPour.root?.pcbDisabled||copperPour._queueAsyncEffect("PcbCopperPourRender",async()=>{let subcircuit=copperPour.getSubcircuit(),pendingRender=pendingCopperPourRenders.get(subcircuit);if(pendingRender){await pendingRender;return}let renderPromise=renderAllCopperPoursForSubcircuit(subcircuit);pendingCopperPourRenders.set(subcircuit,renderPromise);try{await renderPromise}finally{pendingCopperPourRenders.delete(subcircuit)}})}var renderViaStitchingForCopperPours=copperPour=>{let subcircuit=copperPour.getSubcircuit();if(!subcircuit.root)return;let copperPours=subcircuit.selectAll("copperpour").filter(candidateCopperPour=>candidateCopperPour.getSubcircuit()===subcircuit);if(copperPours[0]!==copperPour)return;let sourceNetIds=copperPours.flatMap(candidateCopperPour=>{let net=subcircuit.selectOne(candidateCopperPour._parsedProps.connectsTo);return net?.source_net_id?[net.source_net_id]:[]});if(sourceNetIds.length===0)return;let{db:db22}=subcircuit.root,pcbStyle3=copperPour.getInheritedMergedProperty("pcbStyle"),{holeDiameter,padDiameter}=getViaDiameterDefaults(pcbStyle3),boardComponent=copperPour._getBoard(),pcbBoard=boardComponent?.pcb_board_id?db22.pcb_board.get(boardComponent.pcb_board_id):void 0,solverInput={circuitJson:db22.toArray(),options:{sourceNetIds:[...new Set(sourceNetIds)],viaHoleDiameter:pcbBoard?.min_via_hole_diameter??holeDiameter,viaOuterDiameter:pcbBoard?.min_via_pad_diameter??padDiameter,viaStitchPitch:boardComponent?._parsedProps.viaStitchPitch}},solver=new ViaStitchSolver(solverInput);if(subcircuit.root.emit("solver:started",{type:"solver:started",solverName:"ViaStitchSolver",solverParams:solverInput,solverConstructorArgs:[solverInput],componentName:subcircuit.getString()}),solver.solve(),solver.failed)throw new Error(solver.error??"Via stitching solver failed");for(let pcbVia of solver.getOutput().pcbVias){let{pcb_via_id:_solverViaId,...pcbViaInput}=pcb_via.parse(pcbVia),insertedVia=db22.pcb_via.insert({...pcbViaInput,tented_on_top:void 0,tented_on_bottom:void 0});boardComponent?._generatedStitchingViaIds?.add(insertedVia.pcb_via_id)}};function CopperPour_doInitialPcbViaStitchRender(copperPour){copperPour.root?.pcbDisabled||!copperPour.root?._featurePcbViaStitching||copperPour._getBoard()?._parsedProps.enableViaStitching&&copperPour._queueAsyncEffect("PcbViaStitchRender",async()=>{renderViaStitchingForCopperPours(copperPour)})}var CopperPour=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"isPcbPrimitive",!0);__publicField(this,"_isImplicitCopperPour",!1)}get config(){return{componentName:"CopperPour",zodProps:copperPourProps}}getPcbSize(){return{width:0,height:0}}doInitialCreateNetsFromProps(){let{_parsedProps:props}=this;createNetsFromProps(this,[props.connectsTo])}doInitialPcbCopperPourRender(){CopperPour_doInitialPcbCopperPourRender(this)}doInitialPcbViaStitchRender(){CopperPour_doInitialPcbViaStitchRender(this)}},AssemblyComponent=class _AssemblyComponent extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"cadAssemblyBomItemId")}get shouldRenderAssemblyBom(){return!0}getParentAssemblyBomId(){let ancestor=this.parent;for(;ancestor;){if(ancestor instanceof _AssemblyComponent&&ancestor.shouldRenderAssemblyBom)return ancestor.ensureAssemblyBomItem();ancestor=ancestor.parent}}ensureAssemblyBomItem(){if(!(!this.root||!this.shouldRenderAssemblyBom))return this.cadAssemblyBomItemId||(this.cadAssemblyBomItemId=this.root.db.cad_assembly_bom_item.insert({name:this._parsedProps.displayName||this.name||"Unnamed assembly",quantity:1,parent_cad_assembly_bom_item_id:this.getParentAssemblyBomId()}).cad_assembly_bom_item_id),this.cadAssemblyBomItemId}doInitialCadAssemblyBomRender(){if(!this.root)return;if(!this.shouldRenderAssemblyBom){this.cadAssemblyBomItemId&&this.root.db.cad_assembly_bom_item.delete(this.cadAssemblyBomItemId),this.cadAssemblyBomItemId=void 0;return}let cadAssemblyBomItemId=this.ensureAssemblyBomItem(),cadComponentIds=this.source_component_id?this.root.db.cad_component.list().filter(cad=>cad.source_component_id===this.source_component_id).map(cad=>cad.cad_component_id):[];this.root.db.cad_assembly_bom_item.update(cadAssemblyBomItemId,{name:this._parsedProps.displayName||this.name||"Unnamed assembly",quantity:1,parent_cad_assembly_bom_item_id:this.getParentAssemblyBomId(),source_component_id:this.source_component_id??void 0,cad_component_ids:cadComponentIds.length?cadComponentIds:void 0,supplier_part_numbers:this._parsedProps.supplierPartNumbers,purchase_urls:this._parsedProps.purchaseUrls})}updateCadAssemblyBomRender(){this.doInitialCadAssemblyBomRender()}removeCadAssemblyBomRender(){super.removeCadAssemblyBomRender(),this.root&&this.cadAssemblyBomItemId&&this.root.db.cad_assembly_bom_item.delete(this.cadAssemblyBomItemId),this.cadAssemblyBomItemId=void 0}onPropsChange(){this._markDirty("CadAssemblyBomRender");let markDescendants=parent=>{for(let child of parent.children)child._markDirty("CadAssemblyBomRender"),markDescendants(child)};markDescendants(this)}},resolveAssemblyModel=props=>{if(props.model!==void 0)return/^https?:\/\//i.test(props.model)?resolveAssemblyModelUrl(props.model):{glbUrl:`https://modelcdn.tscircuit.com/jscad_models/${encodeURIComponent(props.model)}.glb`};if(props.modelUrl!==void 0)return resolveAssemblyModelUrl(props.modelUrl)},AssemblyDevice=class extends AssemblyComponent{constructor(){super(...arguments);__publicField(this,"isAssemblyDeviceContainer",!0)}get config(){return{componentName:"AssemblyDevice",zodProps:assemblyDeviceProps}}doInitialAssignNameToUnnamedComponents(){}computeSchematicGlobalTransform(){return identity7()}_computePcbGlobalTransformBeforeLayout(){return identity7()}get shouldRenderAssemblyBom(){let props=this._parsedProps;return props.model!==void 0||props.modelUrl!==void 0||props.purchaseUrls!==void 0||props.supplierPartNumbers!==void 0}doInitialSourceRender(){this._parsedProps.modelUrl===void 0&&this._parsedProps.model===void 0||!this.root||(this.source_component_id=this.root.db.source_component.insert({ftype:"subassembly",name:this.name}).source_component_id)}doInitialCadModelRender(){let model110=resolveAssemblyModel(this._parsedProps);!this.root||this.root.pcbDisabled||!this.source_component_id||!model110||(this.cad_component_id=renderAssemblyCadModel(this,model110,{position:{x:0,y:0,z:0},pcbRotation:0,layer:"top"}))}},resolveBoardMountRotationAnchor=board=>{let anchor3=board._parsedProps.mountRotationAnchor??"rightedge",transform22=board._computePcbGlobalTransformBeforeLayout();switch(anchor3){case"rightedge":return[transform22.a,transform22.b,0];case"leftedge":return[-transform22.a,-transform22.b,0];case"topedge":return[transform22.c,transform22.d,0];case"bottomedge":return[-transform22.c,-transform22.d,0]}let components=board.getDescendants().filter(component2=>matchesAssemblyIdentity(component2,anchor3));if(components.length!==1)throw new Error(`board "${board.name}" mountRotationAnchor "${anchor3}" matched ${components.length} components; expected exactly one on this board`);let component=components[0],pcbComponent=component.pcb_component_id&&board.root.db.pcb_component.get(component.pcb_component_id);if(!pcbComponent)throw new Error(`board "${board.name}" mountRotationAnchor "${anchor3}" has no PCB component geometry`);let pcbBoard=board.root.db.pcb_board.get(board.pcb_board_id),x23=pcbComponent.center.x-pcbBoard.center.x,y23=pcbComponent.center.y-pcbBoard.center.y;if(Math.hypot(x23,y23)<1e-6)throw new Error(`board "${board.name}" mountRotationAnchor "${anchor3}" is on the mounting axis and has no direction`);return[x23,y23,0]},radians2=degrees22=>degrees22*Math.PI/180,degrees3=angle3=>normalizeDegrees(angle3*180/Math.PI),shaftRotation=direction4=>{switch(direction4){case"x+":return{x:0,y:90,z:0};case"x-":return{x:0,y:270,z:0};case"y+":return{x:270,y:0,z:0};case"y-":return{x:90,y:0,z:0};default:return{x:0,y:0,z:0}}},resolveAssemblyMotorRotation=(motor,placement)=>{let alignment=shaftRotation(motor._parsedProps.shaftFacingDirection),board=resolveMotorMountedBoard(motor),input2=board?._parsedProps.mountRotation;if(!board||!input2)return alignment;let bottom=placement.layer==="bottom",sign=bottom?-1:1,orientation32=mat4_exports.create();mat4_exports.rotateX(orientation32,orientation32,radians2(alignment.x)),mat4_exports.rotateY(orientation32,orientation32,radians2(alignment.y+(bottom?180:0))),mat4_exports.rotateZ(orientation32,orientation32,radians2(sign*placement.pcbRotation));let expression3=input2.startsWith("calc(")?input2.match(/^calc\(\s*(.*?)\s*(?:([+-])\s*((?:\d+(?:\.\d*)?|\.\d+))\s*(degcw|degccw))?\s*\)$/):[input2,input2],path=expression3[1],separator=path.lastIndexOf("."),motorIdentity=path.slice(0,separator),directionName=path.slice(separator+1);if(!matchesAssemblyIdentity(motor,motorIdentity))throw new Error(`board "${board.name}" mountRotation "${input2}" must reference its mounted motor "${motor.name}"`);let direction4=Object.entries(motor.motorReferencePoints).find(([name])=>name===directionName)?.[1];if(!direction4)throw new Error(`assembly.motor "${motor.name}" has no ${directionName} reference`);if(Math.abs(direction4.direction.z)>1e-6)throw new Error(`board "${board.name}" mountRotation "${input2}" must reference a direction in the mounting face, e.g. "${motorIdentity}.wireside"`);let clockwiseAngle=radians2((expression3[2]==="-"?-1:1)*Number(expression3[3]??0)*(expression3[4]==="degccw"?-1:1)),anchor3=vec3_exports.normalize(vec3_exports.create(),resolveBoardMountRotationAnchor(board)),shaft=vec3_exports.transformMat4(vec3_exports.create(),[0,0,1],orientation32),turn=mat4_exports.fromRotation(mat4_exports.create(),-clockwiseAngle,shaft),target=vec3_exports.transformMat4(vec3_exports.create(),anchor3,turn),motorDirection=vec3_exports.transformMat4(vec3_exports.create(),[direction4.direction.x,direction4.direction.y,direction4.direction.z],orientation32),spin=Math.atan2(vec3_exports.dot(shaft,vec3_exports.cross(vec3_exports.create(),motorDirection,target)),vec3_exports.dot(motorDirection,target));mat4_exports.rotateZ(orientation32,orientation32,spin);let pitch=Math.asin(Math.max(-1,Math.min(1,orientation32[8]))),nonsingular=Math.abs(orientation32[8])<.999999,roll=nonsingular?Math.atan2(-orientation32[9],orientation32[10]):Math.atan2(orientation32[6],orientation32[5]),yaw=nonsingular?Math.atan2(-orientation32[4],orientation32[0]):0;return{x:degrees3(roll),y:degrees3(pitch)-(bottom?180:0),z:sign*degrees3(yaw)-placement.pcbRotation}},resolveAssemblyMotorPlacement=motor=>{let printedPartPlacement=resolveMotorPrintedPartPlacement(motor);if(printedPartPlacement)return printedPartPlacement;let board=resolveMotorMountedBoard(motor),orientation32=board?._parsedProps.mountOrientation,layer=orientation32?orientation32==="bottom_layer_toward_mount_face"?"bottom":"top":motor._parsedProps.shaftFacingDirection==="z-"?"bottom":"top";if(!board)return{position:{x:0,y:0,z:0},pcbRotation:0,layer};let pcbBoard=board.root.db.pcb_board.get(board.pcb_board_id);if(!pcbBoard)throw new Error(`Mounted board "${board.name}" has no PCB geometry`);let sign=layer==="bottom"?-1:1,boardTransform=board._computePcbGlobalTransformBeforeLayout();return{position:{...pcbBoard.center,z:sign*(-motor.motorReferencePoints.backface.position.z+(board._parsedProps.mountGap??0)+pcbBoard.thickness/2)},pcbRotation:normalizeDegrees(Math.atan2(boardTransform.b,boardTransform.a)*180/Math.PI),layer,subcircuit_id:pcbBoard.subcircuit_id}},resolveMotorFaceMount=motor=>{let parent=findParentAssembly(motor);if(!parent&&!getComponentsInAssemblyScope(motor).some(part=>part.componentName==="AssemblyMotor"&&part._parsedProps.mountedTo))return;let{transforms:transforms3,roots,motorMountRoots,subcircuitId}=resolvePrintedPartMounts(motor);if(!parent&&!motorMountRoots.has(roots.get(motor)))return;let world=transforms3.get(motor);return{position:{x:world[12],y:world[13],z:world[14]},rotation:getAssemblyCadRotation(world),subcircuit_id:subcircuitId}},AssemblyMotor=class extends AssemblyComponent{get config(){return{componentName:"AssemblyMotor",zodProps:assemblyMotorProps}}get motorModelString(){let base=this._parsedProps.model??this._parsedProps.standard,wireConnection=this._parsedProps.wireConnection;return wireConnection===void 0?base:`${base}_${wireConnection}`}get motorModel(){let model110=(()=>{try{return parseModelString(this.motorModelString)}catch(cause){throw new Error(`assembly.motor "${this.name}" requires a NEMA modelprinter model: ${cause instanceof Error?cause.message:cause}`,{cause})}})();if(model110.fn!=="nema")throw new Error(`assembly.motor "${this.name}" requires a NEMA modelprinter model`);return model110}get motorReferencePoints(){let{fn:fn3,...parameters}=this.motorModel;return getNemaMotorReferencePoints2(parameters)}doInitialSourceRender(){this.motorModel,this.source_component_id=this.root.db.source_component.insert({ftype:"motor",name:this.name}).source_component_id}doInitialCadModelRender(){if(!this.root||this.root.pcbDisabled||!this.source_component_id)return;let model110=resolveAssemblyModel({model:this.motorModelString}),faceMount=resolveMotorFaceMount(this);if(faceMount){this.cad_component_id=renderAssemblyCadModel(this,{...model110,rotationOffset:faceMount.rotation},{...faceMount,pcbRotation:0,layer:"top"});return}let placement=resolveAssemblyMotorPlacement(this);this.cad_component_id=renderAssemblyCadModel(this,{...model110,rotationOffset:resolveAssemblyMotorRotation(this,placement)},placement)}},formatMillimetersForModelprinter=millimeters=>Number(millimeters.toFixed(6)).toString(),getDefaultFlexScreenModel=component=>{let{width:width10,height:height10}=component._parsedProps;if(width10===void 0||height10===void 0)throw new Error(`assembly.screen "${component.name}" requires both width and height when cadModel is omitted`);return`flexscreen_w${formatMillimetersForModelprinter(width10)}mm_h${formatMillimetersForModelprinter(height10)}mm`},AssemblyScreen_doInitialCadModelRender=component=>{if(!component.root||component.root.pcbDisabled||!component.source_component_id)return;let placement=resolveAssemblyPlacement(component);component.cad_component_id=renderAssemblyCadModel(component,resolveAssemblyModel(component._parsedProps)??component._parsedProps.cadModel??getDefaultFlexScreenModel(component),placement)},AssemblyScreen=class extends AssemblyComponent{constructor(){super(...arguments);__publicField(this,"isAssemblyDeviceContainer",!0)}get config(){return{componentName:"AssemblyScreen",zodProps:assemblyScreenProps}}doInitialAssignNameToUnnamedComponents(){if(!this._parsedProps.name)throw new Error("assembly.screen requires a non-empty name")}doInitialSourceRender(){let sourceComponent=this.root.db.source_component.insert({ftype:"subassembly",name:this.name});this.source_component_id=sourceComponent.source_component_id}doInitialCadModelRender(){AssemblyScreen_doInitialCadModelRender(this)}},renderPartReferenceSurfaces=part=>{let surfaces=getPartReferenceSurfaces(part);if(!surfaces.length)return;let{transforms:transforms3,subcircuitId}=resolvePrintedPartMounts(part),world=transforms3.get(part),rotation6=mat3_exports.fromMat4(mat3_exports.create(),world),toPoint=vector7=>({x:vector7[0],y:vector7[1],z:vector7[2]});for(let surface6 of surfaces){let child=part.children.find(child2=>child2.componentName==="AssemblyReferenceSurface"&&child2.name===surface6.name);part.root.db.cad_reference_surface.insert({source_component_id:part.source_component_id,name:surface6.name,shape:"rect",center:toPoint(vec3_exports.transformMat4(vec3_exports.create(),surface6.origin,world)),normal:toPoint(vec3_exports.normalize(vec3_exports.create(),vec3_exports.transformMat3(vec3_exports.create(),surface6.normal,rotation6))),x_axis:toPoint(vec3_exports.normalize(vec3_exports.create(),vec3_exports.transformMat3(vec3_exports.create(),surface6.xAxis,rotation6))),width:child?._parsedProps.width,height:child?._parsedProps.height,subcircuit_id:subcircuitId})}},AssemblySubassembly=class extends AssemblyComponent{constructor(){super(...arguments);__publicField(this,"isAssemblyDeviceContainer",!0)}get config(){return{componentName:"AssemblySubassembly",zodProps:assemblySubassemblyProps}}doInitialAssignNameToUnnamedComponents(){if(!this._parsedProps.name)throw new Error("assembly.subassembly requires a non-empty name")}doInitialReactSubtreesRender(){(0,import_react11.isValidElement)(this.props.cadModel)&&this.add(createInstanceFromReactElement(this.props.cadModel))}doInitialSourceRender(){getPartReferenceSurfaces(this);let sourceComponent=this.root.db.source_component.insert({ftype:"subassembly",name:this.name});this.source_component_id=sourceComponent.source_component_id}doInitialCadModelRender(){if(!this.root||this.root.pcbDisabled||!this.source_component_id)return;renderPartReferenceSurfaces(this);let placement=resolveAssemblyPlacement(this),model110=resolveAssemblyModel(this._parsedProps)??this._parsedProps.cadModel;model110&&!(typeof model110=="object"&&"type"in model110)&&(this.cad_component_id=renderAssemblyCadModel(this,model110,placement))}},assemblyPath=assembly2=>{let names=[],ancestor=assembly2;for(;ancestor;)["AssemblyDevice","AssemblySubassembly","AssemblyBolt","AssemblyPart","AssemblyPrintedPart","AssemblyScreen","AssemblyMotor"].includes(ancestor.componentName)&&names.unshift(ancestor.name||"unnamed assembly"),ancestor=ancestor.parent;return names.join(".")},hasRemovedAncestor=part=>{let parent=part.parent;for(;parent;){if(parent.shouldBeRemoved)return!0;parent=parent.parent}return!1},resolveAssemblyExplosionStages=roots=>{let stages=roots.flatMap(root=>[root,...root.getDescendants()]).filter(part=>part.componentName==="AssemblyExplosionStage"&&!part.shouldBeRemoved&&!hasRemovedAncestor(part)),stageRef=stage=>`${assemblyPath(stage.parent)}.${stage.name}`,byRef=new Map;for(let stage of stages){let ref=stageRef(stage);if(byRef.has(ref))throw new Error(`Duplicate explosion stage "${ref}"`);byRef.set(ref,stage)}let edges=new Map,indegrees=new Map(stages.map(stage=>[stage,0]));for(let stage of stages)for(let direction4 of["prevStageRef","nextStageRef"]){let ref=stage._parsedProps[direction4];if(!ref)continue;let ownerPath=assemblyPath(stage.parent),resolved=byRef.get(`${ownerPath}.${ref}`)??(ref.startsWith(`${ownerPath.split(".")[0]}.`)?byRef.get(ref):void 0);if(!resolved)throw new Error(`Explosion stage "${stageRef(stage)}" references unknown stage "${ref}"`);let before=direction4==="nextStageRef"?stage:resolved,after=direction4==="nextStageRef"?resolved:stage,successors=edges.get(before)??new Set;successors.has(after)||(successors.add(after),edges.set(before,successors),indegrees.set(after,indegrees.get(after)+1))}let remaining=new Set(stages),ordered=[];for(;remaining.size;){let eligible=stages.find(stage=>remaining.has(stage)&&indegrees.get(stage)===0);if(!eligible)throw new Error(`Explosion stage ordering cycle: ${[...remaining].map(stageRef).join(", ")}`);remaining.delete(eligible),ordered.push(eligible);for(let successor of edges.get(eligible)??[])indegrees.set(successor,indegrees.get(successor)-1)}return ordered},pointPlus=(point12,offset3)=>({x:point12.x+offset3.x,y:point12.y+offset3.y,z:point12.z+offset3.z}),zero5=()=>({x:0,y:0,z:0});function getAssemblyExplosion(circuit,options={}){if(!circuit.firstChild?.renderPhaseStates.CadModelRender.initialized)throw new Error("Render the assembly before evaluating explosion stages");let progress=options.stageProgress??1;if(!Number.isFinite(progress)||progress<0||progress>1)throw new Error("Explosion stage progress must be between 0 and 1");let ordered=resolveAssemblyExplosionStages(circuit.children),stages=ordered.map(stage=>`${assemblyPath(stage.parent)}.${stage.name}`),stop=options.throughStageRef===void 0?ordered.length-1:stages.indexOf(options.throughStageRef);if(options.throughStageRef!==void 0&&stop<0)throw new Error(`Unknown explosion stage "${options.throughStageRef}"`);let assembled=circuit.getCircuitJson();if(assembled.some(record=>record.type==="cad_explosion_move"&&record.targets.some(target=>target.type==="cad_explosion_stage")))return{...getCircuitJsonAssemblyExplosion(assembled,options),collisionCheckStatus:getRenderedExplosionCollisionCheckStatus(circuit.firstChild)};let sourceOffsets=new Map,partOffsets=new Map,lines=[];for(let[stageIndex,stage]of ordered.entries()){let owner=stage.parent,instructions=stage.children.filter(move=>!move.shouldBeRemoved);for(let[moveIndex,instruction]of instructions.entries()){let move=instruction,targets=new Map;for(let targetRef of move._parsedProps.targetRefs){let target=owner;for(let segment5 of targetRef.split(".")){let matches=target.children.filter(part=>!part.shouldBeRemoved&&part.name===segment5&&["AssemblyBolt","AssemblyPart","AssemblyPrintedPart","AssemblySubassembly","AssemblyScreen","AssemblyMotor"].includes(part.componentName));if(matches.length!==1)throw new Error(`Explosion stage "${stages[stageIndex]}" target "${targetRef}" matched ${matches.length} assembly parts; expected one`);target=matches[0]}if([target,...target.getDescendants()].some(part=>part.pcb_component_id||part.componentName==="Board"||part.componentName==="AssemblyCable"))throw new Error(`Explosion target "${targetRef}" includes PCB or cable geometry; this prototype moves mechanical CAD parts only`);targets.has(target)||targets.set(target,targetRef)}if(stageIndex>stop)continue;let fraction=stageIndex===stop?Math.max(0,Math.min(1,progress*instructions.length-moveIndex)):1;if(!fraction)continue;let placement=isPositionedAssembly(owner)?resolveAssemblyPlacement(owner):void 0,frame=placement?.worldTransform?mat4_exports.clone(placement.worldTransform):mat4_exports.create();placement&&!placement.worldTransform&&(mat4_exports.rotateZ(frame,frame,placement.pcbRotation*Math.PI/180),placement.layer==="bottom"&&mat4_exports.rotateY(frame,frame,Math.PI));let displacement=vec3_exports.transformMat3(vec3_exports.create(),[(move._parsedProps.offX??0)*fraction,(move._parsedProps.offY??0)*fraction,(move._parsedProps.offZ??0)*fraction],mat3_exports.fromMat4(mat3_exports.create(),frame)),offset3={x:displacement[0],y:displacement[1],z:displacement[2]},movedParts=new Set;for(let[target,targetRef]of targets){let descendants2=[target,...target.getDescendants()],targetCad=assembled.find(cad=>cad.type==="cad_component"&&cad.source_component_id===target.source_component_id),targetSources=new Set(descendants2.map(part=>part.source_component_id)),currentCadPositions=assembled.filter(cad=>cad.type==="cad_component"&&targetSources.has(cad.source_component_id)).map(cad=>pointPlus(cad.position,sourceOffsets.get(cad.source_component_id)??zero5())),centroid=currentCadPositions.length?{x:currentCadPositions.reduce((sum,position22)=>sum+position22.x,0)/currentCadPositions.length,y:currentCadPositions.reduce((sum,position22)=>sum+position22.y,0)/currentCadPositions.length,z:currentCadPositions.reduce((sum,position22)=>sum+position22.z,0)/currentCadPositions.length}:void 0,anchor3=(targetCad?pointPlus(targetCad.position,sourceOffsets.get(targetCad.source_component_id)??zero5()):void 0)??centroid??(isPositionedAssembly(target)?pointPlus(resolveAssemblyPlacement(target).position,partOffsets.get(target)??zero5()):void 0);if(!anchor3)throw new Error(`Explosion target "${targetRef}" has no resolved assembly pose`);let from=anchor3;Math.hypot(offset3.x,offset3.y,offset3.z)>0&&lines.push({stageRef:stages[stageIndex],targetRef,points:[from,pointPlus(from,offset3)]});for(let part of descendants2)movedParts.add(part)}let movedSources=new Set;for(let part of movedParts)partOffsets.set(part,pointPlus(partOffsets.get(part)??zero5(),offset3)),part.source_component_id&&movedSources.add(part.source_component_id);for(let sourceId of movedSources)sourceOffsets.set(sourceId,pointPlus(sourceOffsets.get(sourceId)??zero5(),offset3))}}return{circuitJson:structuredClone(assembled).filter(record=>record.type!=="cad_explosion_stage"&&record.type!=="cad_explosion_move").map(record=>{if(record.type!=="cad_component"&&record.type!=="cad_reference_surface")return record;let offset3=sourceOffsets.get(record.source_component_id);return offset3?record.type==="cad_component"?{...record,position:pointPlus(record.position,offset3)}:{...record,center:pointPlus(record.center,offset3)}:record}),stages,lines,collisionCheckStatus:getRenderedExplosionCollisionCheckStatus(circuit.firstChild)}}function resolveAssemblyExplosionRecords(roots,assembled,getStageId){let ordered=resolveAssemblyExplosionStages(roots),stages=ordered.map((stage,order)=>({type:"cad_explosion_stage",cad_explosion_stage_id:getStageId(stage),name:`${assemblyPath(stage.parent)}.${stage.name}`,order,cad_component_ids:[],cad_reference_surface_ids:[]})),moves=[],moveComponents=[];for(let[stageIndex,stage]of ordered.entries()){let owner=stage.parent,placement=isPositionedAssembly(owner)?resolveAssemblyPlacement(owner):void 0,frame=placement?.worldTransform?mat4_exports.clone(placement.worldTransform):mat4_exports.create();placement&&!placement.worldTransform&&(mat4_exports.rotateZ(frame,frame,placement.pcbRotation*Math.PI/180),placement.layer==="bottom"&&mat4_exports.rotateY(frame,frame,Math.PI));for(let[order,instruction]of stage.children.filter(child=>!child.shouldBeRemoved).entries()){let move=instruction,targets=[];for(let targetRef of move._parsedProps.targetRefs){let qualified=`${assemblyPath(owner)}.${targetRef}`,targetStage=stages.find(candidate=>candidate.name===qualified||targetRef.startsWith(`${assemblyPath(owner).split(".")[0]}.`)&&candidate.name===targetRef),target=owner,matchedPart=!0,matchCount=0;for(let segment5 of targetRef.split(".")){let matches=target.children.filter(part=>!part.shouldBeRemoved&&part.name===segment5&&["AssemblyBolt","AssemblyPart","AssemblyPrintedPart","AssemblySubassembly","AssemblyScreen","AssemblyMotor"].includes(part.componentName));if(matchCount=matches.length,matches.length!==1){matchedPart=!1;break}target=matches[0]}if(targetStage&&matchedPart)throw new Error(`Ambiguous explosion target "${targetRef}" names both a part and a stage`);if(targetStage){targets.push({type:"cad_explosion_stage",cad_explosion_stage_id:targetStage.cad_explosion_stage_id});continue}if(!matchedPart)throw new Error(`Explosion stage "${stages[stageIndex].name}" target "${targetRef}" matched ${matchCount} assembly parts; expected one or a matching stage`);let descendants2=[target,...target.getDescendants()];if(descendants2.some(part=>part.pcb_component_id||part.componentName==="Board"||part.componentName==="AssemblyCable"))throw new Error(`Explosion target "${targetRef}" includes unsupported PCB or cable geometry`);let sources=new Set(descendants2.map(part=>part.source_component_id).filter(Boolean)),geometry=assembled.filter(record=>(record.type==="cad_component"||record.type==="cad_reference_surface")&&sources.has(record.source_component_id));if(!geometry.length)throw new Error(`Explosion target "${targetRef}" has no emitted geometry`);for(let record of geometry)record.type==="cad_component"&&targets.push({type:"cad_component",cad_component_id:record.cad_component_id}),record.type==="cad_reference_surface"&&targets.push({type:"cad_reference_surface",cad_reference_surface_id:record.cad_reference_surface_id})}let displacement=vec3_exports.transformMat3(vec3_exports.create(),[move._parsedProps.offX??0,move._parsedProps.offY??0,move._parsedProps.offZ??0],mat3_exports.fromMat4(mat3_exports.create(),frame));moveComponents.push(move),moves.push({type:"cad_explosion_move",cad_explosion_stage_id:stages[stageIndex].cad_explosion_stage_id,order,targets,translation:{x:displacement[0],y:displacement[1],z:displacement[2]}})}}let resolved=new Set,visiting=new Set,resolveMembership=stage=>{if(resolved.has(stage.cad_explosion_stage_id))return;if(visiting.has(stage.cad_explosion_stage_id))throw new Error(`Explosion stage membership cycle at "${stage.name}"`);visiting.add(stage.cad_explosion_stage_id);let cad=new Set(stage.cad_component_ids),surfaces=new Set(stage.cad_reference_surface_ids);for(let move of moves.filter(move2=>move2.cad_explosion_stage_id===stage.cad_explosion_stage_id))for(let target of move.targets)if(target.type==="cad_component")cad.add(target.cad_component_id);else if(target.type==="cad_reference_surface")surfaces.add(target.cad_reference_surface_id);else{let memberStage=stages.find(candidate=>candidate.cad_explosion_stage_id===target.cad_explosion_stage_id);resolveMembership(memberStage);for(let id3 of memberStage.cad_component_ids)cad.add(id3);for(let id3 of memberStage.cad_reference_surface_ids??[])surfaces.add(id3)}stage.cad_component_ids=[...cad],stage.cad_reference_surface_ids=[...surfaces],visiting.delete(stage.cad_explosion_stage_id),resolved.add(stage.cad_explosion_stage_id)};for(let stage of stages)resolveMembership(stage);return{stages:new Map(ordered.map((stage,i23)=>[stage,stages[i23]])),moves:new Map(moveComponents.map((move,i23)=>[move,moves[i23]]))}}function getRenderedAssemblyExplosionRecords(component){let root=component.root;return resolveAssemblyExplosionRecords(root.children,root.db.toArray(),stage=>{if(!stage.cad_explosion_stage_id)throw new Error(`Explosion stage "${stage.name}" has not rendered its identity`);return stage.cad_explosion_stage_id})}function markAssemblyExplosionDirty(component){for(let root of component.root?.children??[])for(let part of[root,...root.getDescendants()])(part.componentName==="AssemblyExplosionStage"||part.componentName==="AssemblyExplosionMove")&&part._markDirty("CadExplosionRender")}var AssemblyExplosionStage=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"cad_explosion_stage_id",null)}get config(){return{componentName:"AssemblyExplosionStage",zodProps:assemblyExplosionStageProps}}doInitialSourceRender(){if(this.parent?.componentName!=="AssemblyDevice"&&this.parent?.componentName!=="AssemblySubassembly")throw new Error(`Explosion stage "${this.name}" must belong to an assembly device or subassembly`);if(this.children.some(child=>child.componentName!=="AssemblyExplosionMove"))throw new Error(`Explosion stage "${this.name}" can contain only explosion moves`)}onPropsChange(){markAssemblyExplosionDirty(this)}doInitialCadExplosionStageRender(){!this.root||this.root.pcbDisabled||(this.cad_explosion_stage_id=this.root.db.cad_explosion_stage.insert({name:`${assemblyPath(this.parent)}.${this.name}`,order:0,cad_component_ids:[],cad_reference_surface_ids:[]}).cad_explosion_stage_id,markAssemblyExplosionDirty(this))}doInitialCadExplosionRender(){if(!this.root||this.root.pcbDisabled||!this.cad_explosion_stage_id)return;let stage=getRenderedAssemblyExplosionRecords(this).stages.get(this);this.root.db.cad_explosion_stage.update(this.cad_explosion_stage_id,stage)}updateCadExplosionRender(){this.doInitialCadExplosionRender()}removeCadExplosionStageRender(){if(!(!this.root||!this.cad_explosion_stage_id)){for(let move of this.children)move.removeCadExplosionStageRender();this.root.db.cad_explosion_stage.delete(this.cad_explosion_stage_id),this.cad_explosion_stage_id=null,markAssemblyExplosionDirty(this)}}},AssemblyExplosionMove=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"cad_explosion_move_id",null)}get config(){return{componentName:"AssemblyExplosionMove",zodProps:assemblyExplosionMoveProps}}doInitialAssignNameToUnnamedComponents(){}doInitialSourceRender(){if(this.parent?.componentName!=="AssemblyExplosionStage")throw new Error("An explosion move must belong to an explosion stage")}onPropsChange(){markAssemblyExplosionDirty(this)}doInitialCadExplosionStageRender(){markAssemblyExplosionDirty(this)}doInitialCadExplosionRender(){if(!this.root||this.root.pcbDisabled||this.parent?.shouldBeRemoved)return;let move=getRenderedAssemblyExplosionRecords(this).moves.get(this);this.cad_explosion_move_id=this.root.db.cad_explosion_move.insert(move).cad_explosion_move_id}updateCadExplosionRender(){if(!this.root||this.root.pcbDisabled||this.parent?.shouldBeRemoved)return;if(!this.cad_explosion_move_id){this.doInitialCadExplosionRender();return}let move=getRenderedAssemblyExplosionRecords(this).moves.get(this);this.root.db.cad_explosion_move.update(this.cad_explosion_move_id,move)}removeCadExplosionStageRender(){this.root&&this.cad_explosion_move_id&&this.root.db.cad_explosion_move.delete(this.cad_explosion_move_id),this.cad_explosion_move_id=null,markAssemblyExplosionDirty(this)}},AssemblyPart=class extends AssemblyComponent{constructor(){super(...arguments);__publicField(this,"isAssemblyDeviceContainer",!0)}get config(){return{componentName:"AssemblyPart",zodProps:assemblyPartProps}}doInitialReactSubtreesRender(){(0,import_react12.isValidElement)(this.props.cadModel)&&this.add(createInstanceFromReactElement(this.props.cadModel))}doInitialSourceRender(){getPartReferenceSurfaces(this),this.source_component_id=this.root.db.source_component.insert({ftype:"subassembly",name:this.name,display_name:this._parsedProps.displayName}).source_component_id}doInitialCadModelRender(){if(!this.root||this.root.pcbDisabled||!this.source_component_id)return;renderPartReferenceSurfaces(this);let model110=resolveAssemblyModel(this._parsedProps)??this._parsedProps.cadModel;model110&&!(typeof model110=="object"&&"type"in model110)&&(this.cad_component_id=renderAssemblyCadModel(this,model110,resolveAssemblyPlacement(this)))}},AssemblyReferenceSurface=class extends PrimitiveComponent{get config(){return{componentName:"AssemblyReferenceSurface",zodProps:assemblyReferenceSurfaceProps}}doInitialSourceRender(){if(this.parent?.componentName!=="AssemblyBolt"&&this.parent?.componentName!=="AssemblyPart"&&this.parent?.componentName!=="AssemblyPrintedPart"&&this.parent?.componentName!=="AssemblySubassembly")throw new Error(`Reference surface "${this.name}" must be a child of assembly.part, assembly.printedpart, assembly.bolt, or assembly.subassembly`)}get referenceFrame(){let{name,plane,normalDirection,centerXOffset,centerYOffset,centerZOffset}=this._parsedProps,sign=normalDirection.endsWith("-")?-1:1;return{name,origin:[centerXOffset,centerYOffset,centerZOffset],normal:plane==="xy"?[0,0,sign]:plane==="xz"?[0,sign,0]:[sign,0,0],xAxis:plane==="yz"?[0,1,0]:[1,0,0]}}},getModelReachAboveOrigin=({cad,authoredModel})=>{let bounds=cad.model_bounds??authoredModel?.modelBounds,origin=cad.model_origin_position??authoredModel?.modelOriginPosition;if(!bounds?.min||!bounds?.max||!origin)return;let normal=cad.model_board_normal_direction??authoredModel?.modelBoardNormalDirection??"z+",axis=normal[0];if(axis!=="x"&&axis!=="y"&&axis!=="z")return;let min4=bounds.min[axis],max5=bounds.max[axis],at22=origin[axis];if(min4===void 0||max5===void 0||at22===void 0)return;let reach=normal.endsWith("-")?at22-min4:max5-at22;return Number.isFinite(reach)&&reach>=0?reach:void 0},getComponentBody=({owner,pcbComponent,cadComponent,boardSurfaceZ})=>{let cadModelProp22=owner?._parsedProps?.cadModel,authoredModel=cadModelProp22&&typeof cadModelProp22=="object"?cadModelProp22:void 0,size23=cadComponent?.size??authoredModel?.size,x23=size23?.x,y23=size23?.y,z20=size23?.z,reach=cadComponent?getModelReachAboveOrigin({cad:cadComponent,authoredModel}):void 0,originZ=cadComponent?.position?.z,aboveBoardHeight=reach!==void 0&&originZ!==void 0?reach+Math.abs(originZ-boardSurfaceZ):void 0;return{size:x23!==void 0&&y23!==void 0?{x:x23,y:y23,z:z20}:void 0,aboveBoardHeight,rotation:cadComponent?.rotation?.z??pcbComponent.rotation??0,footprint:{width:pcbComponent.width,height:pcbComponent.height}}},getNearestBoardWall=({point:point12,board})=>{let halfWidth=(board.width??0)/2,halfHeight=(board.height??0)/2,distances=[["x_neg",Math.abs(point12.x-(board.center.x-halfWidth))],["x_pos",Math.abs(point12.x-(board.center.x+halfWidth))],["y_neg",Math.abs(point12.y-(board.center.y-halfHeight))],["y_pos",Math.abs(point12.y-(board.center.y+halfHeight))]];return distances.sort((a23,b23)=>a23[1]-b23[1]),distances[0][0]},getSolverWall=boardWall=>boardWall,INSERTION_DIRECTION_TO_BOARD_WALL={from_top:"y_pos",from_bottom:"y_neg",from_left:"x_neg",from_right:"x_pos"},getFdmEnclosureSolverInput=(apertureComponent,{board,pcbBoard})=>{let owner=apertureComponent.parent;for(;owner&&owner!==board&&!owner.pcb_component_id;)owner=owner.parent;let pcbComponent=owner?.pcb_component_id?apertureComponent.root?.db.pcb_component.get(owner.pcb_component_id):null;if(!pcbComponent)throw new Error("<enclosure.cutoutaperture /> must be nested inside a component with a PCB footprint");let aperture=apertureComponent._parsedProps,apertureAxisDirection=owner?._getEnclosureApertureAxisDirection?.(pcbComponent.layer,pcbComponent.rotation??0),apertureDirection=apertureAxisDirection?apertureAxisDirection.z!==0?apertureAxisDirection.z>0?"from_above":"from_below":Math.abs(apertureAxisDirection.x)>=Math.abs(apertureAxisDirection.y)?apertureAxisDirection.x>=0?"from_right":"from_left":apertureAxisDirection.y>=0?"from_top":"from_bottom":pcbComponent.insertion_direction,verticalFace=apertureDirection==="from_above"?"z_pos":apertureDirection==="from_below"?"z_neg":void 0,boardSide=pcbComponent.layer==="bottom"?"bottom":"top",face2,center2;if(verticalFace)face2=verticalFace,center2={x:pcbComponent.center.x-pcbBoard.center.x,y:pcbComponent.center.y-pcbBoard.center.y};else{let point12=pcbComponent.cable_insertion_center??pcbComponent.center,boardWall=INSERTION_DIRECTION_TO_BOARD_WALL[apertureDirection]??getNearestBoardWall({point:point12,board:pcbBoard}),cableDelta=pcbComponent.cable_insertion_center?{x:pcbComponent.cable_insertion_center.x-pcbComponent.center.x,y:pcbComponent.cable_insertion_center.y-pcbComponent.center.y}:null,cableProjectionMatchesWall=cableDelta!=null&&(boardWall==="x_neg"||boardWall==="x_pos"?Math.abs(cableDelta.x)>=Math.abs(cableDelta.y):Math.abs(cableDelta.y)>=Math.abs(cableDelta.x)),tangentPoint=apertureAxisDirection?pcbComponent.center:cableProjectionMatchesWall?point12:pcbComponent.center;face2=getSolverWall(boardWall),center2={x:tangentPoint.x-pcbBoard.center.x,y:tangentPoint.y-pcbBoard.center.y}}let cadComponent=apertureComponent.root?.db.cad_component.getWhere({pcb_component_id:pcbComponent.pcb_component_id})??null,boardSurfaceZ=(boardSide==="bottom"?-1:1)*((pcbBoard.thickness??board.boardThickness)/2),componentBody=getComponentBody({owner,pcbComponent,cadComponent,boardSurfaceZ}),commonInput={face:face2,center:center2,boardSide,apertureAxisDirection,rotation:pcbComponent.rotation??void 0,depth:aperture.depth,componentBody,widthDimensionOffset:aperture.widthDimensionOffset,heightDimensionOffset:aperture.heightDimensionOffset,margin:aperture.margin};switch(aperture.shape){case"pill":case"rect":return{...commonInput,shape:aperture.shape,width:aperture.width,height:aperture.height};case"circle":return{...commonInput,shape:"circle",radius:aperture.radius}}},EnclosureCutoutAperture=class extends PrimitiveComponent{get config(){return{componentName:"EnclosureCutoutAperture",zodProps:enclosureCutoutApertureProps}}getFdmEnclosureSolverInput(params){return getFdmEnclosureSolverInput(this,params)}},getReferencedEnclosureBoard=(component,boardRef)=>{let rootComponent=component.root?.firstChild,selectedComponent=rootComponent?selectOne(boardRef,rootComponent,{adapter:cssSelectPrimitiveComponentAdapter}):null,board=selectedComponent instanceof Board?selectedComponent:[rootComponent,...rootComponent?.getDescendants()??[]].find(descendant=>descendant instanceof Board&&descendant.isMatchingNameOrAlias(boardRef));if(!(board instanceof Board))throw new Error(`Could not find a <board /> matching enclosure boardRef "${boardRef}"`);return board},EnclosureFdmBox_doInitialCadModelRender=component=>{let root=component.root;if(!root||root.pcbDisabled||!component.source_component_id||!component.pcb_component_id)return;let{db:db22}=root,props=component._parsedProps,board=getReferencedEnclosureBoard(component,props.boardRef),pcbBoard=board.pcb_board_id?db22.pcb_board.get(board.pcb_board_id):null;if(!pcbBoard?.width||!pcbBoard.height)throw new Error(`Could not resolve dimensions for boardRef "${props.boardRef}"`);let boardThickness=pcbBoard.thickness??board.boardThickness,inputProblem={board:{width:pcbBoard.width,height:pcbBoard.height,thickness:boardThickness},width:props.width,height:props.height,depth:props.depth,wallThickness:props.wallThickness,floorThickness:props.floorThickness,lidThickness:props.lidThickness,boardClearance:props.boardClearance,standoffHeight:props.standoffHeight,topHeadroom:props.topHeadroom,lidLipDepth:props.lidLipDepth,apertures:props.disableCutouts?[]:board.getDescendants().filter(descendant=>descendant instanceof EnclosureCutoutAperture).map(aperture=>aperture.getFdmEnclosureSolverInput({board,pcbBoard}))},solver=new CreateFdmEnclosureSolver(inputProblem),solverConstructorArgs=solver.getConstructorParams();if(root.emit("solver:started",{type:"solver:started",solverName:"CreateFdmEnclosureSolver",solverParams:solverConstructorArgs[0],solverConstructorArgs,componentName:component.getString()}),solver.solve(),solver.failed)throw new Error(solver.error??"Failed to create FDM enclosure");let output=solver.getOutput();db22.pcb_component.update(component.pcb_component_id,{center:pcbBoard.center,width:output.dimensions.width,height:output.dimensions.height});let position22={x:pcbBoard.center.x,y:pcbBoard.center.y,z:-boardThickness/2-output.dimensions.floorThickness-output.dimensions.standoffHeight},cadComponents=output.parts.map(part=>db22.cad_component.insert({position:position22,rotation:{x:0,y:0,z:0},pcb_component_id:component.pcb_component_id,source_component_id:component.source_component_id,model_jscad:part.jscadPlan,model_unit_to_mm_scale_factor:1,model_object_fit:"contain_within_bounds",model_origin_alignment:"bottom_center_of_component",anchor_alignment:"center",show_as_translucent_model:!1,show_hidden_edges:props.showHiddenEdges}));component.cad_component_id=cadComponents[0]?.cad_component_id??null},EnclosureFdmBox=class _EnclosureFdmBox extends PrimitiveComponent{get config(){return{componentName:"EnclosureFdmBox",zodProps:enclosureFdmBoxProps}}doInitialAssignNameToUnnamedComponents(){if(this._parsedProps.name)return;let top=this;for(;top.parent instanceof PrimitiveComponent;)top=top.parent;let index2=[top,...top.getDescendants()].filter(component=>component instanceof _EnclosureFdmBox).indexOf(this);this.fallbackUnassignedName=`unnamed_enclosure_fdm_box_${index2===-1?0:index2+1}`}doInitialSourceRender(){let sourceComponent=this.root.db.source_component.insert({ftype:"simple_chip",name:this.name});this.source_component_id=sourceComponent.source_component_id}doInitialPcbComponentRender(){let root=this.root;if(!root||root.pcbDisabled||!this.source_component_id)return;let board=getReferencedEnclosureBoard(this,this._parsedProps.boardRef),center2=(board.pcb_board_id?root.db.pcb_board.get(board.pcb_board_id):null)?.center??board._getGlobalPcbPositionBeforeLayout(),pcbComponent=root.db.pcb_component.insert({center:center2,width:0,height:0,layer:"top",rotation:0,source_component_id:this.source_component_id,obstructs_within_bounds:!1,do_not_place:!0,is_allowed_to_be_off_board:!0});this.pcb_component_id=pcbComponent.pcb_component_id}doInitialCadModelRender(){EnclosureFdmBox_doInitialCadModelRender(this)}},Battery=class extends NormalComponent{get config(){return{componentName:"Battery",schematicSymbolName:this.props.symbolName??"battery",zodProps:batteryProps,sourceFtype:"simple_power_source"}}initPorts(){super.initPorts({additionalAliases:{pin1:["anode","pos","left"],pin2:["cathode","neg","right"]}})}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({name:this.name,ftype:"simple_power_source",capacity:props.capacity,supplier_part_numbers:props.supplierPartNumbers,manufacturer_part_number:resolveManufacturerPartNumber(props),are_pins_interchangeable:!1,display_name:props.displayName});this.source_component_id=source_component.source_component_id}},PinHeader2=class extends NormalComponent{_getPcbRotationBeforeLayout(){let orientationRotation=this.props.pcbOrientation==="vertical"?-90:0;return(super._getPcbRotationBeforeLayout()??0)+orientationRotation}get config(){return{componentName:"PinHeader",zodProps:pinHeaderProps,shouldRenderAsSchematicBox:!0}}_getImpliedFootprintString(){let pinCount=this._parsedProps.pinCount??(Array.isArray(this._parsedProps.pinLabels)?this._parsedProps.pinLabels.length:this._parsedProps.pinLabels?Object.keys(this._parsedProps.pinLabels).length:0),holeDiameter=this._parsedProps.holeDiameter,platedDiameter=this._parsedProps.platedDiameter,pitch=this._parsedProps.pitch,showSilkscreenPinLabels=this._parsedProps.showSilkscreenPinLabels,rows=this._parsedProps.doubleRow?2:1,gender=this._parsedProps.gender;if(pinCount>0){let footprintString;if(pitch)!holeDiameter&&!platedDiameter?footprintString=`pinrow${pinCount}_p${pitch}`:footprintString=`pinrow${pinCount}_p${pitch}_id${holeDiameter}_od${platedDiameter}`;else if(!holeDiameter&&!platedDiameter)footprintString=`pinrow${pinCount}`;else return null;return showSilkscreenPinLabels!==!0&&(footprintString+="_nopinlabels"),gender==="female"&&(footprintString+="_female"),rows>1&&(footprintString+=`_rows${rows}`),footprintString}return null}initPorts(){let pinCount=this._parsedProps.pinCount??(Array.isArray(this._parsedProps.pinLabels)?this._parsedProps.pinLabels.length:this._parsedProps.pinLabels?Object.keys(this._parsedProps.pinLabels).length:1);for(let i23=1;i23<=pinCount;i23++){let rawLabel=Array.isArray(this._parsedProps.pinLabels)?this._parsedProps.pinLabels[i23-1]:this._parsedProps.pinLabels?.[`pin${i23}`];if(rawLabel){let primaryLabel=Array.isArray(rawLabel)?rawLabel[0]:rawLabel,otherLabels=Array.isArray(rawLabel)?rawLabel.slice(1):[];this.add(new Port({pinNumber:i23,name:primaryLabel,aliases:[`pin${i23}`,...otherLabels]}))}else this.add(new Port({pinNumber:i23,name:`pin${i23}`}))}}_getSchematicPortArrangement(){let pinCount=this._parsedProps.pinCount??1,facingDirection=this._parsedProps.schFacingDirection??this._parsedProps.facingDirection??"right",schPinArrangement=this._parsedProps.schPinArrangement,pins=Array.from({length:pinCount},(_23,i23)=>`pin${i23+1}`);return facingDirection==="left"?{leftSide:{direction:schPinArrangement?.leftSide?.direction??"top-to-bottom",pins:schPinArrangement?.leftSide?.pins??pins}}:facingDirection==="up"?{topSide:{direction:schPinArrangement?.topSide?.direction??"left-to-right",pins:schPinArrangement?.topSide?.pins??pins}}:facingDirection==="down"?{bottomSide:{direction:schPinArrangement?.bottomSide?.direction??"left-to-right",pins:schPinArrangement?.bottomSide?.pins??pins}}:{rightSide:{direction:schPinArrangement?.rightSide?.direction??"top-to-bottom",pins:schPinArrangement?.rightSide?.pins??pins}}}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({ftype:"simple_pin_header",name:this.name,supplier_part_numbers:props.supplierPartNumbers,manufacturer_part_number:resolveManufacturerPartNumber(props),pin_count:props.pinCount,gender:props.gender,are_pins_interchangeable:!0,display_name:props.displayName});this.source_component_id=source_component.source_component_id}};function getResonatorSymbolName(variant){switch(variant){case"two_ground_pins":return"crystal_4pin";case"ground_pin":return"resonator";case"no_ground":return"crystal";default:return"crystal"}}var Resonator=class extends NormalComponent{get config(){return{componentName:"Resonator",schematicSymbolName:this.props.symbolName??getResonatorSymbolName(this.props.pinVariant),zodProps:resonatorProps,shouldRenderAsSchematicBox:!1}}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,pinVariant=props.pinVariant||"no_ground",source_component=db22.source_component.insert({ftype:"simple_resonator",name:this.name,manufacturer_part_number:resolveManufacturerPartNumber(props),frequency:props.frequency,load_capacitance:props.loadCapacitance,supplier_part_numbers:props.supplierPartNumbers,pin_variant:pinVariant,are_pins_interchangeable:pinVariant==="no_ground"||pinVariant==="ground_pin",display_name:props.displayName});this.source_component_id=source_component.source_component_id}_getSchematicSymbolDisplayValue(){let freqDisplay=`${formatSiUnit(this._parsedProps.frequency)}Hz`;return this._parsedProps.loadCapacitance?`${freqDisplay} / ${formatSiUnit(this._parsedProps.loadCapacitance)}F`:freqDisplay}};function getPotentiometerSymbolName(variant){switch(variant){case"three_pin":return"potentiometer3";case"two_pin":return"potentiometer2";default:return"potentiometer2"}}var Potentiometer2=class extends NormalComponent{get config(){return{componentName:"Potentiometer",schematicSymbolName:this.props.symbolName??getPotentiometerSymbolName(this.props.pinVariant),zodProps:potentiometerProps,shouldRenderAsSchematicBox:!1}}_getSchematicSymbolDisplayValue(){return`${formatSiUnit(this._parsedProps.maxResistance)}\u03A9`}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,pinVariant=props.pinVariant||"two_pin",source_component=db22.source_component.insert({ftype:"simple_potentiometer",name:this.name,manufacturer_part_number:resolveManufacturerPartNumber(props),supplier_part_numbers:props.supplierPartNumbers,max_resistance:props.maxResistance,pin_variant:pinVariant,are_pins_interchangeable:pinVariant==="two_pin",display_name:props.displayName,display_max_resistance:this._getSchematicSymbolDisplayValue()});this.source_component_id=source_component.source_component_id}},DEFAULT_CRYSTAL_MAX_TRACE_LENGTH_MM=10,DEFAULT_CRYSTAL_MAX_VIA_COUNT=0,Crystal2=class extends NormalComponent{get config(){return{schematicSymbolName:this.props.symbolName??(this.props.pinVariant==="four_pin"?"crystal_4pin":"crystal"),componentName:"Crystal",zodProps:crystalProps,sourceFtype:"simple_crystal"}}initPorts(){let additionalAliases=this.props.pinVariant==="four_pin"?{pin1:["left1","1","X1"],pin2:["top1","2","gnd1"],pin3:["right1","3","X2"],pin4:["bottom1","4","gnd2"]}:{pin1:["pos","left","X1"],pin2:["neg","right","X2"]};super.initPorts({additionalAliases})}_getSchematicSymbolDisplayValue(){let freqDisplay=`${formatSiUnit(this._parsedProps.frequency)}Hz`;return this._parsedProps.loadCapacitance?`${freqDisplay} / ${formatSiUnit(this._parsedProps.loadCapacitance)}F`:freqDisplay}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({name:this.name,ftype:"simple_crystal",manufacturer_part_number:resolveManufacturerPartNumber(props),supplier_part_numbers:props.supplierPartNumbers,frequency:props.frequency,load_capacitance:props.loadCapacitance,display_frequency:`${formatSiUnit(props.frequency)}Hz`,display_load_capacitance:`${formatSiUnit(props.loadCapacitance)}F`,pin_variant:props.pinVariant||"two_pin",are_pins_interchangeable:(props.pinVariant||"two_pin")==="two_pin",display_name:props.displayName});this.source_component_id=source_component.source_component_id}doInitialSourceDesignRuleChecks(){if(super.doInitialSourceDesignRuleChecks(),!this.source_component_id)return;let{db:db22}=this.root,maximumTraceLength=this._parsedProps.maxTraceLength??DEFAULT_CRYSTAL_MAX_TRACE_LENGTH_MM,crystalSignalSourcePortIds=new Set,crystalSignalConnectivityMapKeys=new Set;for(let signalPort of[this.portMap.X1,this.portMap.X2]){if(!signalPort.source_port_id)continue;let sourcePort=db22.source_port.get(signalPort.source_port_id);sourcePort&&(crystalSignalSourcePortIds.add(signalPort.source_port_id),sourcePort.subcircuit_connectivity_map_key&&crystalSignalConnectivityMapKeys.add(sourcePort.subcircuit_connectivity_map_key))}for(let sourceTrace of db22.source_trace.list()){let isDirectlyConnectedToCrystal=sourceTrace.connected_source_port_ids.some(sourcePortId=>crystalSignalSourcePortIds.has(sourcePortId)),isOnCrystalNet=sourceTrace.subcircuit_connectivity_map_key!==void 0&&crystalSignalConnectivityMapKeys.has(sourceTrace.subcircuit_connectivity_map_key);if(!isDirectlyConnectedToCrystal&&!isOnCrystalNet)continue;let needsMaximumTraceLength=typeof sourceTrace.max_length!="number"||sourceTrace.max_length>maximumTraceLength,needsMaximumViaCount=sourceTrace.max_via_count!==DEFAULT_CRYSTAL_MAX_VIA_COUNT;!needsMaximumTraceLength&&!needsMaximumViaCount||db22.source_trace.update(sourceTrace.source_trace_id,{...needsMaximumTraceLength?{max_length:maximumTraceLength}:{},...needsMaximumViaCount?{max_via_count:DEFAULT_CRYSTAL_MAX_VIA_COUNT}:{}})}}},OpAmp=class extends NormalComponent{constructor(){super(...arguments);__publicField(this,"inverting_input",this.portMap.inverting_input);__publicField(this,"non_inverting_input",this.portMap.non_inverting_input);__publicField(this,"output",this.portMap.output);__publicField(this,"positive_supply",this.portMap.positive_supply);__publicField(this,"negative_supply",this.portMap.negative_supply)}getSchematicSymbolName(){return this.props.symbolName?this.props.symbolName:this.props.connections?.positive_supply||this.props.connections?.negative_supply?"opamp_with_power":"opamp_no_power"}get config(){return{componentName:"OpAmp",schematicSymbolName:this.getSchematicSymbolName(),zodProps:opampProps,sourceFtype:"simple_op_amp"}}initPorts(){let additionalAliases={pin1:["non_inverting_input"],pin2:["inverting_input"]};this.getSchematicSymbolName()==="opamp_with_power"?Object.assign(additionalAliases,{pin4:["output"],pin5:["positive_supply","vcc","vdd"],pin3:["negative_supply","vee","vss","gnd"]}):Object.assign(additionalAliases,{pin3:["output"],pin4:["positive_supply","vcc","vdd"],pin5:["negative_supply","vee","vss","gnd"]}),super.initPorts({pinCount:5,additionalAliases})}doInitialSourceRender(){let{db:db22}=this.root,{_parsedProps:props}=this,source_component=db22.source_component.insert({ftype:"simple_op_amp",name:this.name,supplier_part_numbers:props.supplierPartNumbers,manufacturer_part_number:resolveManufacturerPartNumber(props),display_name:props.displayName});this.source_component_id=source_component.source_component_id}doInitialSimulationRender(){let{db:db22}=this.root,invertingInputPort=this.portMap.inverting_input,nonInvertingInputPort=this.portMap.non_inverting_input,outputPort=this.portMap.output,positiveSupplyPort=this.portMap.positive_supply,negativeSupplyPort=this.portMap.negative_supply;!invertingInputPort?.source_port_id||!nonInvertingInputPort?.source_port_id||!outputPort?.source_port_id||!positiveSupplyPort?.source_port_id||!negativeSupplyPort?.source_port_id||db22.simulation_op_amp.insert({type:"simulation_op_amp",source_component_id:this.source_component_id,inverting_input_source_port_id:invertingInputPort.source_port_id,non_inverting_input_source_port_id:nonInvertingInputPort.source_port_id,output_source_port_id:outputPort.source_port_id,positive_supply_source_port_id:positiveSupplyPort.source_port_id,negative_supply_source_port_id:negativeSupplyPort.source_port_id})}},SchematicSymbol_doInitialSchematicComponentRender=schematicSymbol=>{if(schematicSymbol.root?.schematicDisabled||schematicSymbol.getCollapsedSchematicBoxAncestor())return;let{db:db22}=schematicSymbol.root,symbolName=schematicSymbol._getSchematicSymbolNameOrThrow(),symbol=cc[symbolName];if(!symbol)throw new Error(`No schematic symbol found for "${symbolName}"`);let center2=schematicSymbol._getGlobalSchematicPositionBeforeLayout(),schematicSheetId=schematicSymbol._resolveSchematicSheetId(),subcircuitId=schematicSymbol.getSubcircuit().subcircuit_id??void 0,schematicComponent=db22.schematic_component.insert({center:center2,size:{...symbol.size},is_box_with_pins:!0,symbol_name:symbolName,source_component_id:schematicSymbol.source_component_id??void 0,schematic_sheet_id:schematicSheetId});schematicSymbol.schematic_component_id=schematicComponent.schematic_component_id;for(let symbolPort of symbol.ports){let port=schematicSymbol.getPortForSymbolPort(symbolPort);if(!port?.source_port_id)throw new Error(`Missing source port for schematic symbol port "${symbolPort.labels.join("/")}" on ${schematicSymbol.getString()}`);let portCenter={x:center2.x+symbolPort.x-symbol.center.x,y:center2.y+symbolPort.y-symbol.center.y},schematicPort=db22.schematic_port.insert({schematic_component_id:schematicComponent.schematic_component_id,center:portCenter,source_port_id:port.source_port_id,facing_direction:getRelativeDirection(center2,portCenter),distance_from_component_edge:.4,pin_number:port._parsedProps.pinNumber,display_pin_label:port._parsedProps.aliases?.[0],is_connected:!1,schematic_sheet_id:schematicSheetId,subcircuit_id:subcircuitId});port.schematic_port_id=schematicPort.schematic_port_id}},getSingleConnectionTarget=(connectionName,target)=>{let targets=Array.isArray(target)?target:[target];if(targets.length!==1)throw new Error(`SchematicSymbol connection "${connectionName}" must select exactly one physical port`);return targets[0]},SchematicSymbol_doInitialPortMatching=schematicSymbol=>{let{db:db22}=schematicSymbol.root,{chipRef,connections}=schematicSymbol._parsedProps;if(chipRef&&!connections){db22.source_property_ignored_warning.insert({source_component_id:schematicSymbol.source_component_id,property_name:"chipRef",message:`${schematicSymbol.getString()} has chipRef "${chipRef}" without connections. chipRef will be ignored.`,error_type:"source_property_ignored_warning",subcircuit_id:schematicSymbol.getSubcircuit().subcircuit_id??void 0});return}if(connections&&!chipRef){db22.source_property_ignored_warning.insert({source_component_id:schematicSymbol.source_component_id,property_name:"connections",message:`${schematicSymbol.getString()} has connections without chipRef. connections will be ignored.`,error_type:"source_property_ignored_warning",subcircuit_id:schematicSymbol.getSubcircuit().subcircuit_id??void 0});return}if(!chipRef||!connections)return;let referencedChip=schematicSymbol.getSubcircuit().selectOne(chipRef);if(!referencedChip?.source_component_id)throw new Error(`Could not resolve chipRef "${chipRef}" for ${schematicSymbol.getString()}`);let usedConnectionNames=new Set;for(let schematicPort of schematicSymbol.ports){let symbolPort=schematicPort.schematicSymbolPortDef,matchingConnections=Object.entries(connections).filter(([connectionName2])=>schematicPort.isMatchingAnyOf([connectionName2]));if(matchingConnections.length===0)throw new Error(`${schematicSymbol.getString()} is missing an explicit connection for symbol port "${symbolPort.labels.join("/")}"`);if(matchingConnections.length>1)throw new Error(`${schematicSymbol.getString()} has multiple connections for symbol port "${symbolPort.labels.join("/")}"`);let[connectionName,connectionTarget5]=matchingConnections[0];usedConnectionNames.add(connectionName);let targetSelector=getSingleConnectionTarget(connectionName,connectionTarget5),physicalPort=schematicSymbol.getSubcircuit().selectOne(targetSelector,{type:"port"});if(!physicalPort?.source_port_id)throw new Error(`Could not resolve connection "${connectionName}" target "${targetSelector}" for ${schematicSymbol.getString()}`);if(db22.source_port.get(physicalPort.source_port_id)?.source_component_id!==referencedChip.source_component_id)throw new Error(`Connection "${connectionName}" target "${targetSelector}" does not belong to chipRef "${chipRef}"`);schematicPort.source_port_id=physicalPort.source_port_id,schematicPort.source_component_id=physicalPort.source_component_id}let unusedConnectionNames=Object.keys(connections).filter(connectionName=>!usedConnectionNames.has(connectionName));if(unusedConnectionNames.length>0)throw new Error(`${schematicSymbol.getString()} has connections that do not match symbol ports: ${unusedConnectionNames.join(", ")}`)},SchematicSymbol=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"isSchematicPrimitive",!0);__publicField(this,"isPrimitiveContainer",!0)}get config(){return{componentName:"SchematicSymbol",schematicSymbolName:this.props.symbolName,zodProps:schematicSymbolProps}}initPorts(){let symbol=cc[this._getSchematicSymbolNameOrThrow()],shouldCreateSourcePort=!(this._parsedProps.chipRef&&this._parsedProps.connections);for(let symbolPort of symbol.ports){let pinNumber2=getPinNumberFromLabels(symbolPort.labels);if(!pinNumber2)throw new Error(`Schematic symbol port must have a numeric pin label: ${symbolPort.labels.join("/")}`);let existingPort=this.ports.find(port2=>port2._parsedProps.pinNumber===pinNumber2);if(existingPort){existingPort.schematicSymbolPortDef=symbolPort;continue}let aliases23=symbolPort.labels.filter(label=>label!==pinNumber2.toString()&&label!==`pin${pinNumber2}`),port=new Port({pinNumber:pinNumber2,aliases:aliases23},{shouldCreateSourcePort});port.schematicSymbolPortDef=symbolPort,this.add(port)}}doInitialInitializePortsFromChildren(){this.initPorts()}updateInitializePortsFromChildren(){this.initPorts()}get ports(){return this.children.filter(child=>child instanceof Port)}getPortForSymbolPort(symbolPort){return this.ports.find(port=>port.schematicSymbolPortDef===symbolPort)??null}doInitialSourceRender(){let sourceComponent=this.root.db.source_component.insert({ftype:"simple_chip",name:this.name,display_name:this._parsedProps.displayName,are_pins_interchangeable:!1});this.source_component_id=sourceComponent.source_component_id}doInitialPortMatching(){SchematicSymbol_doInitialPortMatching(this)}doInitialSchematicComponentRender(){SchematicSymbol_doInitialSchematicComponentRender(this)}},SchematicSection=class _SchematicSection extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"isSchematicPrimitive",!0)}get config(){return{componentName:"SchematicSection",zodProps:schematicSectionProps}}_computeSectionBounds(board,sectionName,schematicSheetId){let{db:db22}=this.root,members=board.getDescendants().filter(c23=>c23.getSchematicSectionName()===sectionName);if(members.length===0)return null;let positions=[];for(let member of members){let schematicComponentId=member.schematic_component_id;if(!schematicComponentId)continue;let schComp=db22.schematic_component.get(schematicComponentId);if(!schComp||schComp.schematic_sheet_id!==schematicSheetId)continue;let hw22=schComp.size.width/2,hh22=schComp.size.height/2;positions.push({minX:schComp.center.x-hw22,maxX:schComp.center.x+hw22,minY:schComp.center.y-hh22,maxY:schComp.center.y+hh22});for(let text4 of db22.schematic_text.list({schematic_component_id:schematicComponentId}))positions.push(getSchematicTextBounds2({text:text4.text,position:text4.position,anchor:text4.anchor,fontSize:text4.font_size}))}return positions.length===0?null:computeBoundsFromCellContents(positions)}doInitialSchematicSectionRender(){if(this.root?.schematicDisabled)return;let board=this.root?._getBoard();if(!board)return;let schematicSheetId=this._resolveSchematicSheetId(),allSections=board.getDescendants().filter(component=>component instanceof _SchematicSection&&component._resolveSchematicSheetId()===schematicSheetId);if(allSections[0]!==this)return;let{db:db22}=this.root,PADDING=.5,LABEL_PADDING=.2,STROKE_WIDTH=.02,TOL42=.001,namedSectionsWithBounds=allSections.map(section=>{let bounds=section._computeSectionBounds(board,section._parsedProps.name,schematicSheetId);return bounds?{displayName:section._parsedProps.displayName,sectionTitleFontSize:section._parsedProps.sectionTitleFontSize,rawBounds:bounds,cell:{minX:bounds.minX-PADDING,maxX:bounds.maxX+PADDING,minY:bounds.minY-PADDING,maxY:bounds.maxY+PADDING}}:null}).filter(s23=>s23!==null),unsectionedBounds=this._computeSectionBounds(board,null,schematicSheetId),allSectionsWithBounds=[...namedSectionsWithBounds];if(unsectionedBounds&&allSectionsWithBounds.push({displayName:void 0,sectionTitleFontSize:void 0,rawBounds:unsectionedBounds,cell:{minX:unsectionedBounds.minX-PADDING,maxX:unsectionedBounds.maxX+PADDING,minY:unsectionedBounds.minY-PADDING,maxY:unsectionedBounds.maxY+PADDING}}),allSectionsWithBounds.length===0)return;let allCells=allSectionsWithBounds.map(s23=>s23.cell),outer=computeBoundsFromCellContents(allCells),dividers=calculateCellBoundaries2(allSectionsWithBounds.map(s23=>s23.rawBounds),{cellMargin:1});for(let line4 of dividers)db22.schematic_line.insert({x1:line4.start.x,y1:line4.start.y,x2:line4.end.x,y2:line4.end.y,stroke_width:STROKE_WIDTH,color:"#000000",is_dashed:!0,schematic_sheet_id:schematicSheetId});let hDividers=dividers.filter(l23=>Math.abs(l23.start.y-l23.end.y)<TOL42),vDividers=dividers.filter(l23=>Math.abs(l23.start.x-l23.end.x)<TOL42);for(let sectionWithBounds of allSectionsWithBounds){let{displayName,sectionTitleFontSize,rawBounds,cell}=sectionWithBounds;if(!displayName)continue;let overlapsAnotherSection=allSectionsWithBounds.some(section=>section!==sectionWithBounds&&doBoundsOverlap(section.rawBounds,rawBounds)),dividersAbove=hDividers.map(l23=>l23.start.y).filter(y23=>y23>rawBounds.maxY),topBoundary=dividersAbove.length>0?Math.min(...dividersAbove):outer.maxY,dividersToLeft=vDividers.map(l23=>l23.start.x).filter(x23=>x23<rawBounds.minX),leftBoundary=outer.minX;overlapsAnotherSection&&(leftBoundary=cell.minX),dividersToLeft.length>0&&(leftBoundary=Math.max(...dividersToLeft));let fontSize=sectionTitleFontSize??.18;db22.schematic_text.insert({anchor:"top_left",text:displayName,font_size:fontSize,color:"#000000",position:{x:leftBoundary+LABEL_PADDING,y:Math.max(topBoundary-LABEL_PADDING,rawBounds.maxY+LABEL_PADDING+fontSize)},rotation:0,schematic_sheet_id:schematicSheetId})}}},getCircuitJsonSchematicSheetSize=sheetSize=>schematic_sheet_size.parse(sheetSize.toLowerCase()),SCHEMATIC_SHEET_DIMENSIONS_MM={a4:{width:297,height:210},ansi_b:{width:431.8,height:279.4}},resolveCircuitJsonSchematicSheetProperties=({sheetSize,sheetWidth,sheetHeight})=>{let circuitJsonSheetSize=getCircuitJsonSchematicSheetSize(sheetSize),defaultDimensions=SCHEMATIC_SHEET_DIMENSIONS_MM[circuitJsonSheetSize];return{sheetSize:circuitJsonSheetSize,sheetWidth:sheetWidth??defaultDimensions.width,sheetHeight:sheetHeight??defaultDimensions.height}},SCHEMATIC_UNIT_TO_MM2=10.16/1.1,SCHEMATIC_SHEET_INNER_MARGIN2=5/SCHEMATIC_UNIT_TO_MM2,BOUNDS_EPSILON=1e-6,getSchematicElementId=schematicElement=>{switch(schematicElement.type){case"schematic_component":return schematicElement.schematic_component_id;case"schematic_net_label":return schematicElement.schematic_net_label_id;case"schematic_trace":return schematicElement.schematic_trace_id}},warnIfSchematicElementsOutsideSheet=({db:db22,schematicSheetId,schematicSheetName,schematicSheetCenter,sheetWidth,sheetHeight})=>{let sheetWidthInSchematicUnits=sheetWidth/SCHEMATIC_UNIT_TO_MM2,sheetHeightInSchematicUnits=sheetHeight/SCHEMATIC_UNIT_TO_MM2,sheetContentBounds={minX:schematicSheetCenter.x-sheetWidthInSchematicUnits/2+SCHEMATIC_SHEET_INNER_MARGIN2,maxX:schematicSheetCenter.x+sheetWidthInSchematicUnits/2-SCHEMATIC_SHEET_INNER_MARGIN2,minY:schematicSheetCenter.y-sheetHeightInSchematicUnits/2+SCHEMATIC_SHEET_INNER_MARGIN2,maxY:schematicSheetCenter.y+sheetHeightInSchematicUnits/2-SCHEMATIC_SHEET_INNER_MARGIN2},checkedElements=[...db22.schematic_component.list(),...db22.schematic_net_label.list(),...db22.schematic_trace.list()].filter(schematicElement=>schematicElement.schematic_sheet_id===schematicSheetId);for(let schematicElement of checkedElements){let elementBounds=getSchematicElementBounds(schematicElement);if(!elementBounds||!(elementBounds.minX<sheetContentBounds.minX-BOUNDS_EPSILON||elementBounds.maxX>sheetContentBounds.maxX+BOUNDS_EPSILON||elementBounds.minY<sheetContentBounds.minY-BOUNDS_EPSILON||elementBounds.maxY>sheetContentBounds.maxY+BOUNDS_EPSILON))continue;let schematicElementId=getSchematicElementId(schematicElement);db22.schematic_element_outside_sheet_warning.insert({warning_type:"schematic_element_outside_sheet_warning",message:`${schematicElement.type} ${schematicElementId} extends outside the drawing area of schematic sheet "${schematicSheetName}"`,schematic_sheet_id:schematicSheetId,schematic_element_type:schematicElement.type,schematic_element_id:schematicElementId})}},SchematicSheet=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"isSchematicPrimitive",!0);__publicField(this,"resolvedSchematicSheetDisplayName","Schematic Sheet")}get config(){return{componentName:"SchematicSheet",zodProps:schematicSheetProps}}doInitialSourceGroupRender(){if(this.root?.schematicDisabled)return;let{db:db22}=this.root,{_parsedProps:props}=this,explicitlyReservedSheetIndices=new Set(this.root.children.flatMap(component=>[component,...component.getDescendants()]).filter(component=>component.componentName==="SchematicSheet").map(component=>component._parsedProps.sheetIndex).filter(sheetIndex2=>sheetIndex2!==void 0)),occupiedSheetIndices=new Set([...explicitlyReservedSheetIndices,...db22.schematic_sheet.list().map(schematicSheet2=>schematicSheet2.sheet_index).filter(sheetIndex2=>sheetIndex2!==void 0)]),nextAvailableSheetIndex=0;for(;occupiedSheetIndices.has(nextAvailableSheetIndex);)nextAvailableSheetIndex+=1;let sheetIndex=props.sheetIndex??nextAvailableSheetIndex,name=props.name??props.displayName??`Sheet ${sheetIndex+1}`,displayName=props.displayName??name;this.resolvedSchematicSheetDisplayName=displayName;let resolvedSheetProperties=resolveCircuitJsonSchematicSheetProperties(props),schematicSheet=db22.schematic_sheet.insert({name,display_name:displayName,sheet_index:sheetIndex,sheet_size:resolvedSheetProperties.sheetSize,sheet_width:resolvedSheetProperties.sheetWidth,sheet_height:resolvedSheetProperties.sheetHeight,subcircuit_id:this.getSubcircuit().subcircuit_id??void 0});this.schematic_sheet_id=schematicSheet.schematic_sheet_id;let defaultSheetProperties=resolveCircuitJsonSchematicSheetProperties({sheetSize:"A4"});(resolvedSheetProperties.sheetSize!==defaultSheetProperties.sheetSize||resolvedSheetProperties.sheetWidth!==defaultSheetProperties.sheetWidth||resolvedSheetProperties.sheetHeight!==defaultSheetProperties.sheetHeight)&&db22.schematic_sheet_styling_warning.insert({warning_type:"schematic_sheet_styling_warning",styling_issue_type:"non_default_sheet_size",schematic_sheet_id:this.schematic_sheet_id,subcircuit_id:schematicSheet.subcircuit_id,message:`Schematic sheet "${displayName}" uses a non-default size (${resolvedSheetProperties.sheetWidth} \xD7 ${resolvedSheetProperties.sheetHeight} mm). Prefer the default A4 sheet size (297 \xD7 210 mm) for consistent schematic styling.`})}doInitialSchematicSheetRender(){if(this.root?.schematicDisabled||!this.schematic_sheet_id)return;let{db:db22}=this.root,resolvedSheetProperties=resolveCircuitJsonSchematicSheetProperties(this._parsedProps);if(this._parsedProps.sheetWidth!==void 0||this._parsedProps.sheetHeight!==void 0){warnIfSchematicElementsOutsideSheet({db:db22,schematicSheetId:this.schematic_sheet_id,schematicSheetName:this.resolvedSchematicSheetDisplayName,schematicSheetCenter:{x:0,y:0},sheetWidth:resolvedSheetProperties.sheetWidth,sheetHeight:resolvedSheetProperties.sheetHeight});return}let schematicElements=[...db22.schematic_component.list(),...db22.schematic_port.list(),...db22.schematic_text.list(),...db22.schematic_line.list(),...db22.schematic_rect.list(),...db22.schematic_circle.list(),...db22.schematic_arc.list(),...db22.schematic_path.list()].filter(element2=>element2.schematic_sheet_id===this.schematic_sheet_id),schematicSheetCenter={x:0,y:0};if(schematicElements.length>0){let bounds=getBoundsForSchematic(schematicElements);Number.isFinite(bounds.minX)&&Number.isFinite(bounds.maxX)&&Number.isFinite(bounds.minY)&&Number.isFinite(bounds.maxY)&&(schematicSheetCenter={x:(bounds.minX+bounds.maxX)/2,y:(bounds.minY+bounds.maxY)/2},db22.schematic_sheet.update(this.schematic_sheet_id,{center:schematicSheetCenter}))}warnIfSchematicElementsOutsideSheet({db:db22,schematicSheetId:this.schematic_sheet_id,schematicSheetName:this.resolvedSchematicSheetDisplayName,schematicSheetCenter,sheetWidth:resolvedSheetProperties.sheetWidth,sheetHeight:resolvedSheetProperties.sheetHeight})}},SchematicGraphic=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"isSchematicPrimitive",!0);__publicField(this,"schematic_graphic_id")}get config(){return{componentName:"SchematicGraphic",zodProps:schematicGraphicProps}}doInitialSchematicPrimitiveRender(){if(this.root?.schematicDisabled||this.getCollapsedSchematicBoxAncestor())return;let{db:db22}=this.root,{imageUrl,svgContent,width:width10,height:height10}=this._parsedProps;if(imageUrl!==void 0){this._queueAsyncEffect("SchematicGraphicRender",async()=>{if(this.root?.schematicDisabled)return;let resolvedImageUrl=await resolveStaticFileImport(imageUrl,this.root?.platform),sourceImage=await loadImageSource(resolvedImageUrl).catch(error2=>{if(svgContent===void 0||resolvedImageUrl.startsWith("data:"))throw error2;return null});if(sourceImage===null){let asset32={project_relative_path:imageUrl.startsWith("data:")?"inline":imageUrl,url:resolvedImageUrl,mimetype:SVG_MIMETYPE2},schematicGraphic2=this.root.db.schematic_graphic.insert({asset:asset32,schematic_sheet_id:this._resolveSchematicSheetId(),svg_content:svgContent,...width10===void 0?{}:{width:width10},...height10===void 0?{}:{height:height10}});this.schematic_graphic_id=schematicGraphic2.schematic_graphic_id;return}if(sourceImage.mimetype!==SVG_MIMETYPE2)throw new Error(`Unsupported imageUrl for SchematicGraphic: "${imageUrl}". Expected an SVG image.`);let asset23={project_relative_path:imageUrl.startsWith("data:")?sourceImage.projectRelativePath:imageUrl,url:sourceImage.dataUrl,mimetype:sourceImage.mimetype},fallbackSvgContent=sourceImage.dataUrl.startsWith("data:")?svgContent:sourceImage.text,schematicGraphic=this.root.db.schematic_graphic.insert({asset:asset23,schematic_sheet_id:this._resolveSchematicSheetId(),...fallbackSvgContent===void 0?{}:{svg_content:fallbackSvgContent},...width10===void 0?{}:{width:width10},...height10===void 0?{}:{height:height10}});this.schematic_graphic_id=schematicGraphic.schematic_graphic_id});return}if(svgContent!==void 0){let asset23={project_relative_path:"inline",url:`data:image/svg+xml,${encodeURIComponent(svgContent)}`,mimetype:SVG_MIMETYPE2},schematicGraphic=db22.schematic_graphic.insert({asset:asset23,schematic_sheet_id:this._resolveSchematicSheetId(),...width10===void 0?{}:{width:width10},...height10===void 0?{}:{height:height10}});this.schematic_graphic_id=schematicGraphic.schematic_graphic_id}}},SchematicTable=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"isSchematicPrimitive",!0);__publicField(this,"schematic_table_id",null)}get config(){return{componentName:"SchematicTable",zodProps:schematicTableProps}}doInitialSchematicPrimitiveRender(){if(this.root?.schematicDisabled||this.getCollapsedSchematicBoxAncestor())return;let{db:db22}=this.root,{_parsedProps:props}=this,rows=this.children.filter(c23=>c23.componentName==="SchematicRow");if(rows.length===0)return;let grid22=[],maxCols=0;for(let row of rows){let cells=row.children.filter(c23=>c23.componentName==="SchematicCell");maxCols=Math.max(maxCols,cells.length)}for(let i23=0;i23<rows.length;i23++)grid22[i23]=[];for(let i23=0;i23<rows.length;i23++){let cells=rows[i23].children.filter(c23=>c23.componentName==="SchematicCell"),k23=0;for(let j23=0;j23<cells.length;j23++){for(;grid22[i23][k23];)k23++;let cell=cells[j23],colSpan=cell._parsedProps.colSpan??1,rowSpan=cell._parsedProps.rowSpan??1;for(let r23=0;r23<rowSpan;r23++)for(let c23=0;c23<colSpan;c23++)grid22[i23+r23]||(grid22[i23+r23]=[]),grid22[i23+r23][k23+c23]=cell;k23+=colSpan}}maxCols=Math.max(0,...grid22.map(r23=>r23.length));let rowHeights=rows.map((row,i23)=>row._parsedProps.height??1),colWidths=Array.from({length:maxCols},(_23,j23)=>{let maxWidth=0;for(let i23=0;i23<rows.length;i23++){let cell=grid22[i23]?.[j23];if(cell){let text4=cell._parsedProps.text??cell._parsedProps.children,cellWidth=cell._parsedProps.width??(text4?.length??2)*.5;cellWidth>maxWidth&&(maxWidth=cellWidth)}}return maxWidth||10}),anchorPos=this._getGlobalSchematicPositionBeforeLayout(),table=db22.schematic_table.insert({anchor_position:anchorPos,column_widths:colWidths,row_heights:rowHeights,cell_padding:props.cellPadding,border_width:props.borderWidth,anchor:props.anchor,subcircuit_id:this.getSubcircuit()?.subcircuit_id||"",schematic_component_id:this.parent?.schematic_component_id||"",schematic_sheet_id:this._resolveSchematicSheetId()});this.schematic_table_id=table.schematic_table_id;let processedCells=new Set,yOffset=0;for(let i23=0;i23<rows.length;i23++){let xOffset=0;for(let j23=0;j23<maxCols;j23++){let cell=grid22[i23]?.[j23];if(cell&&!processedCells.has(cell)){processedCells.add(cell);let cellProps=cell._parsedProps,rowSpan=cellProps.rowSpan??1,colSpan=cellProps.colSpan??1,cellWidth=0;for(let c23=0;c23<colSpan;c23++)cellWidth+=colWidths[j23+c23];let cellHeight=0;for(let r23=0;r23<rowSpan;r23++)cellHeight+=rowHeights[i23+r23];db22.schematic_table_cell.insert({schematic_table_id:this.schematic_table_id,start_row_index:i23,end_row_index:i23+rowSpan-1,start_column_index:j23,end_column_index:j23+colSpan-1,text:cellProps.text??cellProps.children,center:{x:anchorPos.x+xOffset+cellWidth/2,y:anchorPos.y-yOffset-cellHeight/2},width:cellWidth,height:cellHeight,horizontal_align:cellProps.horizontalAlign,vertical_align:cellProps.verticalAlign,font_size:cellProps.fontSize??props.fontSize,subcircuit_id:this.getSubcircuit()?.subcircuit_id||""})}colWidths[j23]&&(xOffset+=colWidths[j23])}yOffset+=rowHeights[i23]}}},SchematicRow=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"isSchematicPrimitive",!0)}get config(){return{componentName:"SchematicRow",zodProps:schematicRowProps}}},SchematicCell=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"isSchematicPrimitive",!0);__publicField(this,"canHaveTextChildren",!0)}get config(){return{componentName:"SchematicCell",zodProps:schematicCellProps}}},AnalogSimulation=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"simulation_experiment_id",null)}get config(){return{componentName:"AnalogSimulation",zodProps:analogSimulationProps}}getSpiceEngineName(){return this._parsedProps.spiceEngine}usesIndependentGraphAxes(){return this._parsedProps.graphIndependentAxes===!0}doInitialSimulationRender(){let{db:db22}=this.root,{duration,name,startTime,timePerStep,spiceOptions:spiceOptions3}=this._parsedProps,durationMs=duration||10,timePerStepMs=timePerStep||.01,simulationExperiment=db22.simulation_experiment.insert({name:name??"spice_transient_analysis",experiment_type:"spice_transient_analysis",end_time_ms:durationMs,start_time_ms:startTime,time_per_step:timePerStepMs,spice_options:spiceOptions3});this.simulation_experiment_id=simulationExperiment.simulation_experiment_id}},AnalogAnalysisSimulation=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"simulation_experiment_id",null)}getSpiceEngineName(){return typeof this.props.spiceEngine=="string"?this.props.spiceEngine:void 0}usesIndependentGraphAxes(){return this.props.graphIndependentAxes===!0}getOrCreateSimulationExperiment(){if(this.simulation_experiment_id)return this.root?.db.simulation_experiment.get(this.simulation_experiment_id)??null;if(this.children.filter(child=>child.componentName==="AnalogSweepParameter").length>1)return this.renderError("An analog simulation can contain at most one sweep parameter."),null;let simulationExperiment=this.insertSimulationExperiment();return this.simulation_experiment_id=simulationExperiment?.simulation_experiment_id??null,simulationExperiment}doInitialSimulationRender(){this.getOrCreateSimulationExperiment()}};function resolveExternalSimulationPort({declaration,selector:selector2}){let ports=declaration.getSubcircuit().selectAll(selector2).filter(port=>port.componentName==="Port");if(ports.length!==1||!ports[0].source_port_id)throw new Error(`Simulation pin selector "${selector2}" must identify exactly one physical source pin.`);return ports[0]}function resolveExternalTransientSimulation({declaration,selector:selector2}){let simulations=declaration.getSubcircuit().selectAll(selector2).filter(simulation3=>simulation3.componentName==="AnalogTransientSimulation");if(simulations.length!==1)throw new Error(`Simulation selector "${selector2}" must identify one transient in this subcircuit.`);let simulation2=simulations[0];if(simulation2.getSpiceEngineName()!=="pcb_spice")throw new Error(`Simulation "${selector2}" requires spiceEngine="pcb_spice" for IBIS declarations.`);return simulation2.getOrCreateSimulationExperiment(),simulation2}function AnalogTransientSimulation_validateIbisBindings(simulation2){if(simulation2.getSpiceEngineName()!=="pcb_spice")return;let models2=simulation2.getSubcircuit().selectAll("ibismodel").filter(model110=>!model110.shouldBeRemoved).map(model110=>simulation2.root.db.simulation_ibis_model.get(model110.simulation_ibis_model_id));for(let selector2 of Object.keys(simulation2._parsedProps.ibisPinStates??{})){let port=resolveExternalSimulationPort({declaration:simulation2,selector:selector2});if(models2.filter(model110=>Object.values(model110.ibis_pin_name_to_source_port_id).includes(port.source_port_id)).length!==1)throw new Error(`Simulation "${simulation2._parsedProps.name??"transient"}" pin "${selector2}" requires exactly one IBIS model binding in this subcircuit.`)}}function AnalogTransientSimulation_getPcbSpiceChannel(declaration){if(declaration.getInheritedProperty("analogSimulationDisabled"))return;let channel23=declaration._parsedProps.pcbSpiceChannel;if(!channel23)return;let resolvePort=selector2=>resolveExternalSimulationPort({declaration,selector:selector2}).source_port_id,extraction=channel23.extraction;return{reduction:channel23.reduction,sections:channel23.sections,lanes:channel23.lanes.map(lane=>({name:lane.name,driver_source_port_id:resolvePort(lane.from),receiver_source_port_id:resolvePort(lane.to)})),reference_source_port_id:resolvePort(channel23.referencePinRef),passive_source_component_ids:channel23.passiveComponentRefs?.map(selector2=>{let components=declaration.getSubcircuit().selectAll(selector2).filter(component=>component.source_component_id);if(components.length!==1)throw new Error(`PCB SPICE passive component selector "${selector2}" must identify one component in this subcircuit.`);return components[0].source_component_id}),extraction:{minimum_frequency_hz:extraction.minimumFrequency,maximum_frequency_hz:extraction.maximumFrequency,model_frequency_hz:extraction.modelFrequency,filaments:extraction.filaments,refinement_filaments:extraction.refinementFilaments,convergence_tolerance:extraction.convergenceTolerance,capacitance_tolerance:extraction.capacitanceTolerance,reciprocity_tolerance:extraction.reciprocityTolerance,dc_resistance_tolerance:extraction.dcResistanceTolerance,max_panel_length_mm:extraction.maxPanelLength,ground_mesh_size_mm:extraction.groundMeshSize},relative_permittivity:channel23.relativePermittivity,via_plating_thickness_mm:channel23.via?.platingThickness,via_equivalent_width_mm:channel23.via?.equivalentWidth,omit_through_via_stubs:channel23.via?.omitThroughViaStubs,straightened_stage_profiles:channel23.straightenedStageProfiles&&Object.fromEntries(Object.entries(channel23.straightenedStageProfiles).map(([layer,profile5])=>[layer,{spacing_mm:profile5.spacing,relative_permittivity:profile5.relativePermittivity,return:{width_mm:profile5.return.width,thickness_mm:profile5.return.thickness,length_factor:profile5.return.lengthFactor,center_y_mm:profile5.return.centerY,center_z_mm:profile5.return.centerZ}}]))}}var AnalogTransientSimulation=class extends AnalogAnalysisSimulation{get config(){return{componentName:"AnalogTransientSimulation",zodProps:analogTransientSimulationProps}}doInitialSimulationSpiceEngineRender(){this.getInheritedProperty("analogSimulationDisabled")||AnalogTransientSimulation_validateIbisBindings(this)}updateSimulationSpiceEngineRender(){this.doInitialSimulationSpiceEngineRender()}onPropsChange(){if(this._markDirty("SimulationRender"),!this.simulation_experiment_id)return;let subcircuit=this.getSubcircuit();for(let declaration of[...subcircuit.selectAll("analogdigitalstimulus"),...subcircuit.selectAll("analogeyediagram")])declaration.getSubcircuit()===subcircuit&&declaration._markDirty("SimulationSpiceEngineRender")}updateSimulationRender(){this.insertSimulationExperiment()}removeIbisPinStates(){for(let state2 of this.root.db.simulation_ibis_pin_state.list({simulation_experiment_id:this.simulation_experiment_id}))this.root.db.simulation_ibis_pin_state.delete(state2.simulation_ibis_pin_state_id)}removeSimulationRender(){this.simulation_experiment_id&&(this.removeIbisPinStates(),this.root.db.simulation_experiment.delete(this.simulation_experiment_id),this.simulation_experiment_id=null)}insertSimulationExperiment(){let{db:db22}=this.root,{duration,name,startTime,timePerStep,spiceOptions:spiceOptions3}=this._parsedProps,ibisPinStates=this.getInheritedProperty("analogSimulationDisabled")?{}:this._parsedProps.ibisPinStates,pins=Object.entries(ibisPinStates??{}).map(([selector2,state2])=>{let pin={source_port_id:resolveExternalSimulationPort({declaration:this,selector:selector2}).source_port_id,is_output:state2.isOutput};return state2.isOutput?{...pin,is_output_enabled:state2.isOutputEnabled}:pin});if(new Set(pins.map(pin=>pin.source_port_id)).size!==pins.length)throw new Error(`Simulation "${name??"transient"}" assigns multiple states to the same physical pin.`);let experimentProps={name:name??"spice_transient_analysis",experiment_type:"spice_transient_analysis",end_time_ms:duration,start_time_ms:startTime,time_per_step:timePerStep,spice_options:spiceOptions3,spice_engine:this.getSpiceEngineName(),pcb_spice_channel:AnalogTransientSimulation_getPcbSpiceChannel(this),subcircuit_id:this.getSubcircuit().subcircuit_id},experiment=this.simulation_experiment_id?db22.simulation_experiment.update(this.simulation_experiment_id,experimentProps):db22.simulation_experiment.insert(experimentProps);this.simulation_experiment_id&&this.removeIbisPinStates();for(let pin of pins)db22.simulation_ibis_pin_state.insert({simulation_experiment_id:experiment.simulation_experiment_id,...pin});return experiment}};function AnalogDigitalStimulus_getSimulationDigitalStimulus(declaration){let props=declaration._parsedProps,simulation2=resolveExternalTransientSimulation({declaration,selector:props.simulationRef}),port=resolveExternalSimulationPort({declaration,selector:props.sourcePinRef}),experiment=simulation2.getOrCreateSimulationExperiment();if(props.startTime>=experiment.end_time_ms)throw new Error(`Stimulus "${props.name}" starts outside its simulation.`);let pinState=declaration.root.db.simulation_ibis_pin_state.list({simulation_experiment_id:experiment.simulation_experiment_id}).find(state2=>state2.source_port_id===port.source_port_id);if(pinState?.is_output!==!0||pinState.is_output_enabled!==!0)throw new Error(`Stimulus "${props.name}" must drive a pin declared as an enabled output in its simulation.`);if(declaration.root.db.simulation_digital_stimulus.list({simulation_experiment_id:experiment.simulation_experiment_id}).some(stimulus=>stimulus.simulation_digital_stimulus_id!==declaration.simulation_digital_stimulus_id&&(stimulus.source_port_id===port.source_port_id||stimulus.name===props.name)))throw new Error(`Stimulus "${props.name}" duplicates a driven pin or stimulus name in this simulation.`);return{type:"simulation_digital_stimulus",name:props.name,simulation_experiment_id:experiment.simulation_experiment_id,source_port_id:port.source_port_id,bit_duration_ms:props.bitDuration,start_time_ms:props.startTime,initial_state:props.initialState,inverted:props.inverted,transmission_pattern:{transmission_type:props.transmittedData.transmissionType,bits:props.transmittedData.bits,repeat:props.transmittedData.repeat}}}var AnalogDigitalStimulus=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"simulation_digital_stimulus_id",null)}get config(){return{componentName:"AnalogDigitalStimulus",zodProps:analogDigitalStimulusProps}}doInitialSimulationRender(){if(this.getInheritedProperty("analogSimulationDisabled"))return;let stimulus=AnalogDigitalStimulus_getSimulationDigitalStimulus(this);this.simulation_digital_stimulus_id?this.root.db.simulation_digital_stimulus.update(this.simulation_digital_stimulus_id,stimulus):this.simulation_digital_stimulus_id=this.root.db.simulation_digital_stimulus.insert(stimulus).simulation_digital_stimulus_id}onPropsChange(){this._markDirty("SimulationSpiceEngineRender")}updateSimulationSpiceEngineRender(){this.doInitialSimulationRender()}removeSimulationRender(){this.simulation_digital_stimulus_id&&this.root.db.simulation_digital_stimulus.delete(this.simulation_digital_stimulus_id),this.simulation_digital_stimulus_id=null}};function AnalogEyeDiagram_getSimulationEyeDiagram(declaration){let props=declaration._parsedProps,experiment=resolveExternalTransientSimulation({declaration,selector:props.simulationRef}).getOrCreateSimulationExperiment(),probes=declaration.getSubcircuit().selectAll(props.probeRef).filter(probe2=>probe2.componentName==="VoltageProbe");if(probes.length!==1)throw new Error(`Eye probe selector "${props.probeRef}" must identify one voltage probe in this subcircuit.`);let probe=probes[0];if(!probe.simulation_voltage_probe_id)throw new Error(`Eye probe "${props.probeRef}" did not render a voltage probe.`);let start=props.startTime??experiment.start_time_ms??0,end=props.endTime??experiment.end_time_ms,firstBoundary=(start-props.timeOrigin)/props.unitInterval+.5,lastBoundary=(end-props.timeOrigin)/props.unitInterval-1.5,roundingTolerance=8*Number.EPSILON*Math.max(1,Math.abs(firstBoundary),Math.abs(lastBoundary));if(start<(experiment.start_time_ms??0)||end>experiment.end_time_ms||end<=start||Math.ceil(firstBoundary-roundingTolerance)>Math.floor(lastBoundary+roundingTolerance))throw new Error(`Eye "${props.name}" needs a gate within its simulation containing at least two bit intervals forming a complete two-UI eye window aligned to timeOrigin after recording starts.`);return{type:"simulation_eye_diagram",name:props.name,simulation_experiment_id:experiment.simulation_experiment_id,simulation_voltage_probe_id:probe.simulation_voltage_probe_id,unit_interval_ms:props.unitInterval,time_origin_ms:props.timeOrigin,start_time_ms:start,end_time_ms:end}}var AnalogEyeDiagram=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"simulation_eye_diagram_id",null)}get config(){return{componentName:"AnalogEyeDiagram",zodProps:analogEyeDiagramProps}}doInitialSimulationSpiceEngineRender(){if(this.getInheritedProperty("analogSimulationDisabled"))return;let eye=AnalogEyeDiagram_getSimulationEyeDiagram(this);this.simulation_eye_diagram_id?this.root.db.simulation_eye_diagram.update(this.simulation_eye_diagram_id,eye):this.simulation_eye_diagram_id=this.root.db.simulation_eye_diagram.insert(eye).simulation_eye_diagram_id}onPropsChange(){this._markDirty("SimulationSpiceEngineRender")}updateSimulationSpiceEngineRender(){this.doInitialSimulationSpiceEngineRender()}removeSimulationSpiceEngineRender(){this.simulation_eye_diagram_id&&this.root.db.simulation_eye_diagram.delete(this.simulation_eye_diagram_id),this.simulation_eye_diagram_id=null}};function IbisModel_getSimulationIbisModel(declaration){let props=declaration._parsedProps,chips=declaration.getSubcircuit().selectAll(props.componentRef).filter(chip2=>chip2.source_component_id);if(chips.length!==1)throw new Error(`IBIS component selector "${props.componentRef}" must identify one component in this subcircuit.`);let chip=chips[0];if(declaration.root.db.simulation_ibis_model.list({source_component_id:chip.source_component_id}).some(model110=>model110.simulation_ibis_model_id!==declaration.simulation_ibis_model_id))throw new Error(`Component "${props.componentRef}" already has an IBIS model.`);let pinMap=Object.fromEntries(Object.entries(props.ibisPinNameToPortLabel).map(([pin,label])=>[pin,resolveExternalSimulationPort({declaration,selector:`${props.componentRef} > .${label}`}).source_port_id])),ibisPinNameBySourcePortId=new Map;for(let[pin,sourcePortId]of Object.entries(pinMap)){let previousPin=ibisPinNameBySourcePortId.get(sourcePortId);if(previousPin!==void 0)throw new Error(`IBIS pins "${previousPin}" and "${pin}" on "${props.componentRef}" resolve to the same physical pin.`);ibisPinNameBySourcePortId.set(sourcePortId,pin)}for(let pin of[...Object.keys(props.ibisPinNameToReferencePortLabels??{}),...Object.keys(props.ibisPinNameToModelName??{})])if(!Object.hasOwn(props.ibisPinNameToPortLabel,pin))throw new Error(`IBIS pin "${pin}" is referenced but not present in ibisPinNameToPortLabel.`);let references4;if(props.ibisPinNameToReferencePortLabels){references4={};for(let[pin,pinReferences]of Object.entries(props.ibisPinNameToReferencePortLabels)){references4[pin]={};for(let[role,sourcePortIdField]of[["pullup","pullup_reference_source_port_id"],["pulldown","pulldown_reference_source_port_id"],["powerClamp","power_clamp_reference_source_port_id"],["groundClamp","ground_clamp_reference_source_port_id"],["external","external_reference_source_port_id"]]){let label=pinReferences[role];label!==void 0&&(references4[pin][sourcePortIdField]=resolveExternalSimulationPort({declaration,selector:`${props.componentRef} > .${label}`}).source_port_id)}}}return{type:"simulation_ibis_model",source_component_id:chip.source_component_id,ibis_model_asset:props.ibisModelAsset,ibis_component_name:props.ibisComponentName,model_value_corner:props.modelValueCorner,include_package_parasitics:props.includePackageParasitics,ibis_pin_name_to_model_name:props.ibisPinNameToModelName,ibis_pin_name_to_source_port_id:pinMap,ibis_pin_name_to_reference_source_port_ids:references4}}var IbisModel=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"simulation_ibis_model_id",null)}get config(){return{componentName:"IbisModel",zodProps:ibisModelProps}}onPropsChange(){this._markDirty("SimulationRender")}markIbisBindingsDirty(){for(let node2=this.parent;node2;node2=node2.parent){if(!node2.isSubcircuit)continue;let subcircuit=node2.getSubcircuit();for(let simulation2 of subcircuit.selectAll("analogtransientsimulation"))simulation2.getSubcircuit()===subcircuit&&simulation2._markDirty("SimulationSpiceEngineRender")}}doInitialSimulationRender(){if(this.getInheritedProperty("analogSimulationDisabled"))return;let model110=IbisModel_getSimulationIbisModel(this);this.simulation_ibis_model_id?this.root.db.simulation_ibis_model.update(this.simulation_ibis_model_id,model110):this.simulation_ibis_model_id=this.root.db.simulation_ibis_model.insert(model110).simulation_ibis_model_id,this.markIbisBindingsDirty()}updateSimulationRender(){this.doInitialSimulationRender()}removeSimulationRender(){this.simulation_ibis_model_id&&this.root.db.simulation_ibis_model.delete(this.simulation_ibis_model_id),this.simulation_ibis_model_id=null,this.markIbisBindingsDirty()}},AnalogDcOperatingPointSimulation=class extends AnalogAnalysisSimulation{get config(){return{componentName:"AnalogDcOperatingPointSimulation",zodProps:analogDcOperatingPointSimulationProps}}insertSimulationExperiment(){let{name,spiceOptions:spiceOptions3}=this._parsedProps;return this.root.db.simulation_experiment.insert({name:name??"spice_dc_operating_point",experiment_type:"spice_dc_operating_point",spice_options:spiceOptions3})}},AnalogDcSweepSimulation=class extends AnalogAnalysisSimulation{get config(){return{componentName:"AnalogDcSweepSimulation",zodProps:analogDcSweepSimulationProps}}insertSimulationExperiment(){let{name,spiceOptions:spiceOptions3,sweepSource,sweepStart,sweepStop,sweepStep}=this._parsedProps,sweepSourceComponent=(this.getGroup()??this.getSubcircuit())?.selectOne(sweepSource),dcSweepSourceFields;if(sweepSourceComponent instanceof VoltageSource2){sweepSourceComponent.runRenderPhase("SimulationRender");let simulationVoltageSourceId=sweepSourceComponent.simulation_voltage_source_id;if(!simulationVoltageSourceId)return this.renderError(`DC sweep source "${sweepSource}" must resolve to one voltage or current source.`),null;dcSweepSourceFields={dc_sweep_voltage_source_id:simulationVoltageSourceId,dc_sweep_unit:"V"}}else if(sweepSourceComponent instanceof CurrentSource2){sweepSourceComponent.runRenderPhase("SimulationRender");let simulationCurrentSourceId=sweepSourceComponent.simulation_current_source_id;if(!simulationCurrentSourceId)return this.renderError(`DC sweep source "${sweepSource}" must resolve to one voltage or current source.`),null;dcSweepSourceFields={dc_sweep_current_source_id:simulationCurrentSourceId,dc_sweep_unit:"A"}}else return this.renderError(`DC sweep source "${sweepSource}" must resolve to one voltage or current source.`),null;return this.root.db.simulation_experiment.insert({name:name??"spice_dc_sweep",experiment_type:"spice_dc_sweep",spice_options:spiceOptions3,...dcSweepSourceFields,dc_sweep_start:sweepStart,dc_sweep_stop:sweepStop,dc_sweep_step:sweepStep})}},AnalogAcSweepSimulation=class extends AnalogAnalysisSimulation{get config(){return{componentName:"AnalogAcSweepSimulation",zodProps:analogAcSweepSimulationProps}}insertSimulationExperiment(){let{name,spiceOptions:spiceOptions3,sweepType,samplesPerInterval,sampleCount,startFrequency,stopFrequency}=this._parsedProps;return this.root.db.simulation_experiment.insert({name:name??"spice_ac_analysis",experiment_type:"spice_ac_analysis",spice_options:spiceOptions3,ac_sweep_type:sweepType,ac_samples_per_interval:samplesPerInterval,ac_sample_count:sampleCount,ac_start_frequency_hz:startFrequency,ac_stop_frequency_hz:stopFrequency})}},parameterUnits={resistance:"\u03A9",capacitance:"F",inductance:"H",voltage:"V",current:"A"},isParameterSweepCoordinateInRange=({parameterSweepCoordinate,stop,step})=>{let tolerance=Math.abs(step)*1e-9;return step>0?parameterSweepCoordinate<=stop+tolerance:parameterSweepCoordinate>=stop-tolerance},getGeneratedParameterSweepCoordinates=({start,stop,step})=>{let parameterSweepCoordinates=[];for(let parameterSweepCoordinate=start;isParameterSweepCoordinateInRange({parameterSweepCoordinate,stop,step});parameterSweepCoordinate=start+parameterSweepCoordinates.length*step)if(parameterSweepCoordinates.push(parameterSweepCoordinate),parameterSweepCoordinates.length>1e6)throw new Error("Parameter sweep exceeds 1,000,000 points");return parameterSweepCoordinates},getParameterSweepTargetSelector=props=>props.parameterType==="resistance"?props.resistorRef:props.parameterType==="capacitance"?props.capacitorRef:props.parameterType==="inductance"?props.inductorRef:props.parameterType==="voltage"?props.net:props.currentSourceRef,AnalogSweepParameter_doInitialSimulationRender=analogSweepParameter=>{if(!(analogSweepParameter.parent instanceof AnalogAnalysisSimulation)){analogSweepParameter.renderError("analog.sweepparameter must be nested directly in an analog simulation.");return}let simulationExperiment=analogSweepParameter.parent.getOrCreateSimulationExperiment();if(!simulationExperiment)return;let props=analogSweepParameter._parsedProps,parameterSweepCoordinates=props.values??getGeneratedParameterSweepCoordinates({start:props.start,stop:props.stop,step:props.step}),simulationScope=analogSweepParameter.parent.getGroup()??analogSweepParameter.parent.getSubcircuit(),targetSelector=getParameterSweepTargetSelector(props),parameterUnit=parameterUnits[props.parameterType],simulationParameterSweepTable=analogSweepParameter.root.db.simulation_parameter_sweep,simulationParameterSweepFields={simulation_experiment_id:simulationExperiment.simulation_experiment_id,name:props.name,parameter_type:props.parameterType,parameter_values:parameterSweepCoordinates,parameter_unit:parameterUnit},simulationParameterSweepId;if(props.parameterType==="voltage"){let sweepNet=simulationScope?.selectOne(targetSelector,{type:"net"});if(!sweepNet?.source_net_id){analogSweepParameter.renderError(`Voltage sweep net "${targetSelector}" could not be resolved.`);return}simulationParameterSweepId=simulationParameterSweepTable.insert({...simulationParameterSweepFields,parameter_type:"voltage",source_net_id:sweepNet.source_net_id}).simulation_parameter_sweep_id}else{let sourceComponentId=simulationScope?.selectOne(targetSelector)?.source_component_id;if(!sourceComponentId){analogSweepParameter.renderError(`Parameter sweep target "${targetSelector}" could not be resolved.`);return}props.parameterType==="resistance"?simulationParameterSweepId=simulationParameterSweepTable.insert({...simulationParameterSweepFields,parameter_type:"resistance",resistor_source_component_id:sourceComponentId}).simulation_parameter_sweep_id:props.parameterType==="capacitance"?simulationParameterSweepId=simulationParameterSweepTable.insert({...simulationParameterSweepFields,parameter_type:"capacitance",capacitor_source_component_id:sourceComponentId}).simulation_parameter_sweep_id:props.parameterType==="inductance"?simulationParameterSweepId=simulationParameterSweepTable.insert({...simulationParameterSweepFields,parameter_type:"inductance",inductor_source_component_id:sourceComponentId}).simulation_parameter_sweep_id:simulationParameterSweepId=simulationParameterSweepTable.insert({...simulationParameterSweepFields,parameter_type:"current",current_source_component_id:sourceComponentId}).simulation_parameter_sweep_id}analogSweepParameter.simulation_parameter_sweep_id=simulationParameterSweepId},AnalogSweepParameter=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"simulation_parameter_sweep_id",null)}get config(){return{componentName:"AnalogSweepParameter",zodProps:analogSweepParameterProps}}doInitialSimulationRender(){AnalogSweepParameter_doInitialSimulationRender(this)}},PcbReturnCurrentSimulation=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"simulation_experiment_id",null)}get config(){return{componentName:"PcbReturnCurrentSimulation",zodProps:pcbReturnCurrentSimulationProps}}doInitialSimulationRender(){if(this.root?.pcbDisabled)return;this.parent?.componentName==="PcbReturnCurrentSimulation"&&this.renderError("A PCB return-current simulation cannot contain another simulation."),this.children.some(child=>child.componentName!=="PcbReturnCurrentExcitation")&&this.renderError("A PCB return-current simulation can contain only return-current excitations.");let experiment=this.root.db.simulation_experiment.insert({name:this._parsedProps.name??"PCB return current",experiment_type:"pcb_return_current"});this.simulation_experiment_id=experiment.simulation_experiment_id}updateSimulationRender(){this.simulation_experiment_id&&this.root.db.simulation_experiment.update(this.simulation_experiment_id,{name:this._parsedProps.name??"PCB return current"})}removeSimulationRender(){this.simulation_experiment_id&&(this.root.db.simulation_experiment.delete(this.simulation_experiment_id),this.simulation_experiment_id=null)}},positionToleranceMm=1e-6;function PcbReturnCurrentExcitation_doInitialPcbSimulationRender(excitation){if(excitation.root?.pcbDisabled)return;let{db:db22}=excitation.root,props=excitation._parsedProps,simulation2=excitation.parent;if(simulation2?.componentName!=="PcbReturnCurrentSimulation"){excitation.renderError("A PCB return-current excitation must be directly inside a PCB return-current simulation.");return}if(!simulation2.simulation_experiment_id){excitation.renderError("The PCB return-current simulation has not been declared.");return}let subcircuit=excitation.getSubcircuit(),resolvePcbPort=(selector2,role)=>{let ports=subcircuit.selectAll(selector2).filter(component=>component.componentName==="Port");ports.length!==1&&excitation.renderError(`${role} selector "${selector2}" must identify exactly one physical PCB port.`);let port=ports[0],pcbPort=port?.pcb_port_id?db22.pcb_port.get(port.pcb_port_id):null,hasPhysicalPad=pcbPort&&(db22.pcb_smtpad.list({pcb_port_id:pcbPort.pcb_port_id}).length>0||db22.pcb_plated_hole.list({pcb_port_id:pcbPort.pcb_port_id}).length>0);return(!pcbPort||!hasPhysicalPad)&&excitation.renderError(`${role} selector "${selector2}" needs a physical PCB pad or plated-hole port.`),pcbPort},signalSource=resolvePcbPort(props.source,"Signal source"),signalLoad=resolvePcbPort(props.load,"Signal load"),returnSource=resolvePcbPort(props.returnSource,"Return source (load-side ground)"),returnSink=resolvePcbPort(props.returnSink,"Return sink (driver-side ground)");new Set([signalSource.pcb_port_id,signalLoad.pcb_port_id,returnSource.pcb_port_id,returnSink.pcb_port_id]).size!==4&&excitation.renderError("Signal source, signal load, return source and return sink must be four distinct physical PCB ports.");let groundNets=subcircuit.selectAll(props.ground.startsWith("net.")?"net":props.ground).filter(component=>component.componentName==="Net"&&(!props.ground.startsWith("net.")||component.getPortSelector()===props.ground));(groundNets.length!==1||!groundNets[0].source_net_id)&&excitation.renderError(`Ground selector "${props.ground}" must identify exactly one source net.`);let groundNet=db22.source_net.get(groundNets[0].source_net_id),groundConnectivityKey=groundNet.subcircuit_connectivity_map_key;for(let[pcbPort,selector2]of[[signalSource,props.source],[signalLoad,props.load]])groundConnectivityKey&&db22.source_port.get(pcbPort.source_port_id)?.subcircuit_connectivity_map_key===groundConnectivityKey&&excitation.renderError(`Signal terminal "${selector2}" is electrically connected to ground net "${groundNet.name}".`);for(let[pcbPort,selector2]of[[returnSource,props.returnSource],[returnSink,props.returnSink]]){let sourcePort=db22.source_port.get(pcbPort.source_port_id);(!groundConnectivityKey||sourcePort?.subcircuit_connectivity_map_key!==groundConnectivityKey)&&excitation.renderError(`Return contact "${selector2}" is not electrically connected to ground net "${groundNet.name}".`)}let contact=(pcbPort,selector2,requestedLayer,role)=>{let layers=[...new Set(pcbPort.layers)];!requestedLayer&&layers.length!==1&&excitation.renderError(`${role} "${selector2}" spans multiple layers; specify ${role==="Return source"?"returnSourceLayer":"returnSinkLayer"}.`);let layer=requestedLayer??layers[0];return layers.includes(layer)||excitation.renderError(`${role} "${selector2}" has no physical port on layer "${layer}".`),{contact_type:"pcb_port",pcb_port_id:pcbPort.pcb_port_id,x:pcbPort.x,y:pcbPort.y,layer}},returnSourceContact=contact(returnSource,props.returnSource,props.returnSourceLayer,"Return source"),returnSinkContact=contact(returnSink,props.returnSink,props.returnSinkLayer,"Return sink");for(let[signalPort,referenceContact]of[[signalSource,returnSinkContact],[signalLoad,returnSourceContact]])Math.hypot(signalPort.x-referenceContact.x,signalPort.y-referenceContact.y)<=positionToleranceMm&&signalPort.layers.includes(referenceContact.layer)&&excitation.renderError("A signal terminal and its ground reference must occupy different physical PCB locations on the same layer.");let selectedSourceTraceId;if(props.trace){let traces2=subcircuit.selectAll(props.trace).filter(component=>component.componentName==="Trace");(traces2.length!==1||!traces2[0].source_trace_id)&&excitation.renderError(`Trace selector "${props.trace}" must identify exactly one routed source trace.`),selectedSourceTraceId=traces2[0].source_trace_id}let endpointMatches=(endpoint,pcbPort,end)=>endpoint?.route_type==="wire"&&Math.hypot(endpoint.x-pcbPort.x,endpoint.y-pcbPort.y)<=positionToleranceMm&&pcbPort.layers.includes(endpoint.layer)&&(!endpoint[`${end}_pcb_port_id`]||endpoint[`${end}_pcb_port_id`]===pcbPort.pcb_port_id),traces=db22.pcb_trace.list().filter(pcbTrace=>{if(pcbTrace.subcircuit_id!==subcircuit.subcircuit_id||selectedSourceTraceId&&pcbTrace.source_trace_id!==selectedSourceTraceId)return!1;let sourceTrace=pcbTrace.source_trace_id?db22.source_trace.get(pcbTrace.source_trace_id):null;if(!sourceTrace||sourceTrace.connected_source_port_ids.length!==2||!sourceTrace.connected_source_port_ids.includes(signalSource.source_port_id)||!sourceTrace.connected_source_port_ids.includes(signalLoad.source_port_id))return!1;let first=pcbTrace.route[0],last=pcbTrace.route.at(-1);return endpointMatches(first,signalSource,"start")&&endpointMatches(last,signalLoad,"end")||endpointMatches(first,signalLoad,"start")&&endpointMatches(last,signalSource,"end")});traces.length!==1&&excitation.renderError(`The connection from "${props.source}" to "${props.load}" must have exactly one complete routed PCB trace${props.trace?` selected by "${props.trace}"`:"; use trace to disambiguate multiple routes"}. Split or branched routes are not supported.`);let previousExcitations=db22.simulation_return_current_excitation.list({simulation_experiment_id:simulation2.simulation_experiment_id});previousExcitations.some(previous=>previous.pcb_trace_id===traces[0].pcb_trace_id)&&excitation.renderError("A PCB return-current simulation can excite each signal trace only once. Use separate experiments to compare different currents or directions."),previousExcitations.some(previous=>previous.ground_source_net_id!==groundNet.source_net_id)&&excitation.renderError("All excitations in a PCB return-current simulation must use the same ground net. Use separate experiments for different ground nets.");let inserted=db22.simulation_return_current_excitation.insert({simulation_experiment_id:simulation2.simulation_experiment_id,pcb_trace_id:traces[0].pcb_trace_id,ground_source_net_id:groundNet.source_net_id,current:props.current,return_source:returnSourceContact,return_sink:returnSinkContact,source_port:{signal_pcb_port_id:signalSource.pcb_port_id,reference_pcb_port_id:returnSink.pcb_port_id,reference_layer:returnSinkContact.layer,resistance:props.sourceImpedance},load_port:{signal_pcb_port_id:signalLoad.pcb_port_id,reference_pcb_port_id:returnSource.pcb_port_id,reference_layer:returnSourceContact.layer,resistance:props.loadImpedance}});excitation.simulation_return_current_excitation_id=inserted.simulation_return_current_excitation_id}var PcbReturnCurrentExcitation=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"simulation_return_current_excitation_id",null)}get config(){return{componentName:"PcbReturnCurrentExcitation",zodProps:pcbReturnCurrentExcitationProps}}doInitialPcbSimulationRender(){PcbReturnCurrentExcitation_doInitialPcbSimulationRender(this)}updatePcbSimulationRender(){this.removePcbSimulationRender(),this.doInitialPcbSimulationRender()}removePcbSimulationRender(){this.simulation_return_current_excitation_id&&(this.root.db.simulation_return_current_excitation.delete(this.simulation_return_current_excitation_id),this.simulation_return_current_excitation_id=null)}};function getLabelBounds3(probePosition,labelText,alignment,labelOffset=.3){let labelWidth=Math.max(labelText.length*.1,.3),labelHeightWithPadding=.25+.2,anchorX=probePosition.x,anchorY=probePosition.y,offsetMultiplier=labelOffset+labelWidth/2;alignment.includes("top")?anchorY+=offsetMultiplier:alignment.includes("bottom")&&(anchorY-=offsetMultiplier),alignment.includes("right")?anchorX+=offsetMultiplier:alignment.includes("left")&&(anchorX-=offsetMultiplier);let minX,maxX,minY,maxY;return alignment.includes("left")?(minX=anchorX,maxX=anchorX+labelWidth):alignment.includes("right")?(minX=anchorX-labelWidth,maxX=anchorX):(minX=anchorX-labelWidth/2,maxX=anchorX+labelWidth/2),alignment.includes("top")?(minY=anchorY-labelHeightWithPadding,maxY=anchorY):alignment.includes("bottom")?(minY=anchorY,maxY=anchorY+labelHeightWithPadding):(minY=anchorY-labelHeightWithPadding/2,maxY=anchorY+labelHeightWithPadding/2),{minX,maxX,minY,maxY}}function getElementBounds(elm){let cx22,cy22,w23,h23;if(elm.type==="schematic_component")cx22=elm.center?.x,cy22=elm.center?.y,w23=elm.size?.width,h23=elm.size?.height;else if(elm.type==="schematic_text")cx22=elm.position?.x,cy22=elm.position?.y,w23=(elm.text?.length??0)*.1,h23=.2;else return null;return typeof cx22=="number"&&typeof cy22=="number"&&typeof w23=="number"&&typeof h23=="number"?{minX:cx22-w23/2,maxX:cx22+w23/2,minY:cy22-h23/2,maxY:cy22+h23/2}:null}function getOverlapArea(a23,b23){if(!doBoundsOverlap(a23,b23))return 0;let overlapWidth=Math.min(a23.maxX,b23.maxX)-Math.max(a23.minX,b23.minX),overlapHeight=Math.min(a23.maxY,b23.maxY)-Math.max(a23.minY,b23.minY);return overlapWidth*overlapHeight}function selectBestLabelAlignment({probePosition,labelText,schematicElements,defaultAlignment="top_right"}){let orderedAlignments=[defaultAlignment,...["top_right","top_left","bottom_right","bottom_left","top_center","bottom_center","center_right","center_left"].filter(a23=>a23!==defaultAlignment)],bestAlignment=defaultAlignment,minOverlapArea=1/0;for(let alignment of orderedAlignments){let labelBounds=getLabelBounds3(probePosition,labelText,alignment),totalOverlapArea=0;for(let element2 of schematicElements){let elementBounds=getElementBounds(element2);elementBounds&&(totalOverlapArea+=getOverlapArea(labelBounds,elementBounds))}if(totalOverlapArea===0)return alignment;totalOverlapArea<minOverlapArea&&(minOverlapArea=totalOverlapArea,bestAlignment=alignment)}return bestAlignment}var VoltageProbe=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"simulation_voltage_probe_id",null);__publicField(this,"schematic_voltage_probe_id",null);__publicField(this,"finalProbeName",null);__publicField(this,"color",null)}get config(){return{componentName:"VoltageProbe",zodProps:voltageProbeProps}}doInitialSimulationRender(){let{db:db22}=this.root,{connectsTo,name,referenceTo,color:color32,graphDisplayName,graphCenter,graphVerticalOffset,graphVoltagePerDiv}=this._parsedProps,subcircuit=this.getSubcircuit();if(!subcircuit){this.renderError("VoltageProbe must be inside a subcircuit");return}let targets=Array.isArray(connectsTo)?connectsTo:[connectsTo];if(targets.length!==1){this.renderError("VoltageProbe must connect to exactly one port or net");return}let targetSelector=targets[0],port=subcircuit.selectOne(targetSelector,{type:"port"}),net=port?null:subcircuit.selectOne(targetSelector,{type:"net"});if(net&&net.componentName!=="Net"){this.renderError(`VoltageProbe connection target "${targetSelector}" resolved to a non-net component "${net.componentName}".`);return}if(!port&&!net){this.renderError(`VoltageProbe could not find connection target "${targetSelector}"`);return}let connectedId=port?.source_port_id??net?.source_net_id;if(!connectedId){this.renderError("Could not identify connected source for VoltageProbe");return}let referencePort=null,referenceNet=null;if(referenceTo){let referenceTargets=Array.isArray(referenceTo)?referenceTo:[referenceTo];if(referenceTargets.length!==1){this.renderError("VoltageProbe must reference exactly one port or net");return}let referenceSelector=referenceTargets[0];if(referencePort=subcircuit.selectOne(referenceSelector,{type:"port"}),referenceNet=referencePort?null:subcircuit.selectOne(referenceSelector,{type:"net"}),referenceNet&&referenceNet.componentName!=="Net"){this.renderError(`VoltageProbe reference target "${referenceSelector}" resolved to a non-net component "${referenceNet.componentName}".`);return}if(!referencePort&&!referenceNet){this.renderError(`VoltageProbe could not find reference target "${referenceSelector}"`);return}}this.color=color32??getSimulationColorForId(connectedId);let finalName=name;finalName||(finalName=targets[0].split(" > ").map(s23=>s23.replace(/^\./,"")).join(".")),this.finalProbeName=finalName??null;let{simulation_voltage_probe_id}=db22.simulation_voltage_probe.insert({name:finalName,signal_input_source_port_id:port?.source_port_id??void 0,signal_input_source_net_id:net?.source_net_id??void 0,reference_input_source_port_id:referencePort?.source_port_id??void 0,reference_input_source_net_id:referenceNet?.source_net_id??void 0,subcircuit_id:subcircuit.subcircuit_id||void 0,color:this.color});if(this.simulation_voltage_probe_id=simulation_voltage_probe_id,graphDisplayName!==void 0||graphCenter!==void 0||graphVerticalOffset!==void 0||graphVoltagePerDiv!==void 0){let graphVoltagePerDivValue=parseSimulationGraphValue(graphVoltagePerDiv),graphVerticalOffsetValue=parseSimulationGraphValue(graphVerticalOffset);db22.simulation_oscilloscope_trace.insert({simulation_voltage_probe_id,display_name:graphDisplayName,color:color32??void 0,display_center_value:graphCenter,volts_per_div:graphVoltagePerDivValue,display_center_offset_divs:graphVerticalOffsetValue!==void 0&&graphVoltagePerDivValue!==void 0&&graphVoltagePerDivValue!==0?graphVerticalOffsetValue/graphVoltagePerDivValue:void 0})}}doInitialSchematicReplaceNetLabelsWithSymbols(){if(this.root?.schematicDisabled)return;let{db:db22}=this.root,{connectsTo,name}=this._parsedProps,subcircuit=this.getSubcircuit();if(!subcircuit)return;let targets=Array.isArray(connectsTo)?connectsTo:[connectsTo];if(targets.length!==1)return;let targetSelector=targets[0],port=subcircuit.selectOne(targetSelector,{type:"port"});if(!port||!port.schematic_port_id)return;let position22=port._getGlobalSchematicPositionAfterLayout(),targetTraceId=null;for(let trace of db22.schematic_trace.list()){for(let edge of trace.edges)if(Math.abs(edge.from.x-position22.x)<1e-6&&Math.abs(edge.from.y-position22.y)<1e-6||Math.abs(edge.to.x-position22.x)<1e-6&&Math.abs(edge.to.y-position22.y)<1e-6){targetTraceId=trace.schematic_trace_id;break}if(targetTraceId)break}if(!targetTraceId)return;let probeName=this.finalProbeName,labelAlignment=selectBestLabelAlignment({probePosition:position22,labelText:probeName,schematicElements:[...db22.schematic_component.list(),...db22.schematic_text.list()],defaultAlignment:"top_right"}),schematic_voltage_probe23=db22.schematic_voltage_probe.insert({name:probeName,position:position22,schematic_trace_id:targetTraceId,subcircuit_id:subcircuit.subcircuit_id||void 0,color:this.color??void 0,label_alignment:labelAlignment});this.schematic_voltage_probe_id=schematic_voltage_probe23.schematic_voltage_probe_id}},SpiceModel=class extends PrimitiveComponent{get config(){return{componentName:"SpiceModel",zodProps:spicemodelProps}}doInitialSimulationRender(){if(this.getInheritedProperty("analogSimulationDisabled"))return;let parent=this.parent;if(!parent)return;let parentSourceComponentId=parent.source_component_id;if(!parentSourceComponentId){this._insertSpiceModelError("spicemodel must be attached to a source component.",this._parsedProps);return}let{source,spicePinMapping}=this._parsedProps,subckt=parseSpiceNetlist(source).subckts[0]??null,spicePinNames=subckt?.pins.map(pin=>pin.name);if(!subckt||!spicePinNames||spicePinNames.length===0){this._insertSpiceModelError("spicemodel source must contain a .subckt declaration with a model name and pins.",source);return}let mapping=spicePinMapping??{};for(let spicePinName of Object.keys(mapping))if(!spicePinNames.includes(spicePinName)){this._insertSpiceModelError(`spicePinMapping references SPICE pin "${spicePinName}", but it is not present in .subckt ${subckt.name}.`,mapping);return}let spicePinToSourcePortMap={},seenSourcePortIds=new Set;for(let spicePinName of spicePinNames){let componentPinName=mapping[spicePinName]??spicePinName,matchingPorts=parent.selectAll("port").filter(port=>port instanceof Port&&port.isMatchingAnyOf([componentPinName]));if(matchingPorts.length!==1||!matchingPorts[0].source_port_id){this._insertSpiceModelError(`Could not resolve SPICE pin "${spicePinName}" to exactly one component port using "${componentPinName}".`,mapping);return}let sourcePortId=matchingPorts[0].source_port_id;if(seenSourcePortIds.has(sourcePortId)){this._insertSpiceModelError(`spicePinMapping maps more than one SPICE pin to component port "${componentPinName}".`,mapping);return}seenSourcePortIds.add(sourcePortId),spicePinToSourcePortMap[spicePinName]=sourcePortId}this.root.db.simulation_spice_subcircuit.insert({source_component_id:parentSourceComponentId,spice_pin_to_source_port_map:spicePinToSourcePortMap,subcircuit_source:source})}_insertSpiceModelError(message,propertyValue){this.root.db.source_invalid_component_property_error.insert({source_component_id:this.parent?.source_component_id||"",property_name:"spiceModel",property_value:propertyValue,message,error_type:"source_invalid_component_property_error"})}};function getPcbFlexBoardTransform(primitive){let boardId=primitive._getBoard()?.pcb_board_id,board=boardId?primitive.root.db.pcb_board.get(boardId):null;if(!board)throw new Error(`${primitive.componentName} must be inside a board`);let transform22=compose3(translate8(-board.center.x,-board.center.y),primitive._computePcbGlobalTransformBeforeLayout());return{board,transform:transform22}}var PcbBend=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"pcb_bend_id",null);__publicField(this,"tearReliefCutoutIds",[])}get config(){return{componentName:"PcbBend",zodProps:pcbBendProps}}doInitialPcbFlexRender(){if(this.root?.pcbDisabled)return;let{db:db22}=this.root,props=this._parsedProps,{board,transform:transform22}=getPcbFlexBoardTransform(this),bend=db22.pcb_bend.insert({pcb_board_id:board.pcb_board_id,pcb_group_id:this.getGroup()?.pcb_group_id??void 0,subcircuit_id:this.getSubcircuit().subcircuit_id??void 0,name:props.name,start:applyToPoint3(transform22,{x:props.x1,y:props.y1}),end:applyToPoint3(transform22,{x:props.x2,y:props.y2}),bend_angle:props.bendAngle,bend_radius:props.bendRadius,bend_side:props.bendSide});if(this.pcb_bend_id=bend.pcb_bend_id,props.tearReliefRadius!==void 0)for(let endpoint of[bend.start,bend.end]){let cutout=db22.pcb_cutout.insert({shape:"circle",center:{x:endpoint.x+board.center.x,y:endpoint.y+board.center.y},radius:props.tearReliefRadius,pcb_board_id:board.pcb_board_id,pcb_group_id:bend.pcb_group_id,subcircuit_id:bend.subcircuit_id});this.tearReliefCutoutIds.push(cutout.pcb_cutout_id)}}removePcbFlexRender(){for(let cutoutId of this.tearReliefCutoutIds)this.root.db.pcb_cutout.delete(cutoutId);this.tearReliefCutoutIds=[],this.pcb_bend_id&&(this.root.db.pcb_bend.delete(this.pcb_bend_id),this.pcb_bend_id=null)}},PcbStiffener=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"pcb_stiffener_id",null)}get config(){return{componentName:"PcbStiffener",zodProps:pcbStiffenerProps}}doInitialPcbFlexRender(){if(this.root?.pcbDisabled)return;let{db:db22}=this.root,props=this._parsedProps,{board,transform:transform22}=getPcbFlexBoardTransform(this),base={pcb_board_id:board.pcb_board_id,pcb_group_id:this.getGroup()?.pcb_group_id??void 0,subcircuit_id:this.getSubcircuit().subcircuit_id??void 0,name:props.name,layer:props.layer,material:props.material,thickness:props.thickness,adhesive_thickness:props.adhesiveThickness},geometry=props.shape==="rect"?{shape:"rect",center:applyToPoint3(transform22,{x:0,y:0}),rotation:decomposeTSR2(transform22).rotation.angle*180/Math.PI,width:props.width,height:props.height}:{shape:"polygon",outline:props.outline.map(point12=>applyToPoint3(transform22,point12))};this.pcb_stiffener_id=db22.pcb_stiffener.insert({...base,...geometry}).pcb_stiffener_id}doRemovePcbFlexRender(){this.pcb_stiffener_id&&(this.root.db.pcb_stiffener.delete(this.pcb_stiffener_id),this.pcb_stiffener_id=null)}},getAssemblyEulerAngles=transform22=>{let y23=Math.asin(Math.max(-1,Math.min(1,-transform22[2])));return(Math.abs(Math.cos(y23))>1e-8?[Math.atan2(transform22[6],transform22[10]),y23,Math.atan2(transform22[1],transform22[0])]:[0,y23,Math.atan2(-transform22[4],transform22[5])]).map(angle3=>angle3===0?0:angle3)},AssemblyPrintedPart=class extends AssemblyComponent{constructor(){super(...arguments);__publicField(this,"isAssemblyDeviceContainer",!0);__publicField(this,"compiledJscadInput");__publicField(this,"compiledJscad")}get config(){return{componentName:"AssemblyPrintedPart",zodProps:assemblyPrintedPartProps}}get printedPartPlan(){if(this._parsedProps.jscad){if(!this.compiledJscad||this.compiledJscadInput!==this._parsedProps.jscad){let{geometry,referencePlanes}=(0,import_jscad_planner9.resolveReferencePlanes)(renderToJscadPlan(this._parsedProps.jscad));if(!geometry)throw new Error(`assembly.printedpart "${this.name}" needs solid geometry in addition to references`);this.compiledJscad={geometry,referencePlanes},this.compiledJscadInput=this._parsedProps.jscad}return this.compiledJscad}}doInitialReactSubtreesRender(){(0,import_react13.isValidElement)(this.props.cadModel)&&this.add(createInstanceFromReactElement(this.props.cadModel))}doInitialSourceRender(){this.printedPartPlan,getPartReferenceSurfaces(this),this.source_component_id=this.root.db.source_component.insert({ftype:"printedpart",name:this.name,color:this._parsedProps.color,material:this._parsedProps.material}).source_component_id}doInitialCadModelRender(){if(!this.root||this.root.pcbDisabled||!this.source_component_id)return;renderPartReferenceSurfaces(this);let plan=this.printedPartPlan;if(!plan){let model110=resolveAssemblyModel(this._parsedProps)??this._parsedProps.cadModel,placement=resolveAssemblyPlacement(this);if(!model110||typeof model110=="object"&&"type"in model110)return;if(typeof model110=="object"&&"jscad"in model110){let{geometry}=(0,import_jscad_planner9.resolveReferencePlanes)(model110.jscad);if(!geometry)throw new Error(`assembly.printedpart "${this.name}" needs solid geometry in addition to references`);model110={...model110,jscad:geometry}}this.cad_component_id=renderAssemblyCadModel(this,model110,placement);return}let{transforms:transforms3,subcircuitId}=resolvePrintedPartMounts(this),transform22=transforms3.get(this),angles=getAssemblyEulerAngles(transform22);this.cad_component_id=renderAssemblyCadModel(this,{jscad:{type:"rotate",angles,shape:plan.geometry}},{position:{x:transform22[12],y:transform22[13],z:transform22[14]},pcbRotation:0,layer:"top",subcircuit_id:subcircuitId})}},bulletDiameterSchema2=external_exports.union([external_exports.literal(2),external_exports.literal(3),external_exports.literal(3.5),external_exports.literal(4),external_exports.literal(5),external_exports.literal(5.5),external_exports.literal(6),external_exports.literal(8)]),bulletGenderSchema2=external_exports.enum(["male","female"]);function getBulletConnector({diameter,gender,pinCount=1,pitch=diameter+2}){let contactDepth=diameter*2,bodyDiameter=diameter+(gender==="female"?1:.6);return{kind:gender==="male"?"bullet_male":"bullet_female",diameter,contactDepth,pinCount,pitch,bodyWidth:bodyDiameter+(pinCount-1)*pitch,bodyHeight:bodyDiameter,bodyDepth:contactDepth+diameter*1.5}}var cableStandardSchema2=external_exports.enum(["usb_c","jst_sh","jst_ph","us_mains","bullet","adaptercable"]),dimension2=external_exports.number().finite().positive(),color4=external_exports.string().regex(/^#[0-9a-fA-F]{6}$/),body2={bodyWidth:dimension2,bodyHeight:dimension2,bodyDepth:dimension2},cableConnectorSchema2=external_exports.discriminatedUnion("kind",[external_exports.object({kind:external_exports.literal("bullet_male"),...body2,diameter:bulletDiameterSchema2,pinCount:external_exports.number().int().min(1).max(16).default(1),pitch:dimension2,contactDepth:dimension2}).strict(),external_exports.object({kind:external_exports.literal("bullet_female"),...body2,diameter:bulletDiameterSchema2,pinCount:external_exports.number().int().min(1).max(16).default(1),pitch:dimension2,contactDepth:dimension2}).strict(),external_exports.object({kind:external_exports.literal("usb_c_plug"),...body2,shellWidth:dimension2,shellHeight:dimension2,shellDepth:dimension2}).strict(),external_exports.object({kind:external_exports.literal("jst_sh_housing"),...body2,pinCount:external_exports.number().int().min(2).max(15),pitch:external_exports.literal(1)}).strict(),external_exports.object({kind:external_exports.literal("jst_ph_housing"),...body2,pinCount:external_exports.number().int().min(2).max(16),pitch:external_exports.literal(2)}).strict(),external_exports.object({kind:external_exports.literal("nema_5_15p"),...body2}).strict(),external_exports.object({kind:external_exports.literal("iec_c13"),...body2}).strict()]),cableCrossSectionSchema2=external_exports.discriminatedUnion("kind",[external_exports.object({kind:external_exports.literal("round_jacket"),diameter:dimension2,color:color4}).strict(),external_exports.object({kind:external_exports.literal("wire_bundle"),wires:external_exports.array(external_exports.object({diameter:dimension2,color:color4}).strict()).min(2),wirePitch:dimension2}).strict()]),cableDefinitionSchema2=external_exports.object({standard:cableStandardSchema2,connectorA:cableConnectorSchema2,connectorB:cableConnectorSchema2,crossSection:cableCrossSectionSchema2}).strict().superRefine((cable,ctx)=>{let{connectorA,connectorB,crossSection}=cable,expected={usb_c:["usb_c_plug","usb_c_plug"],jst_sh:["jst_sh_housing","jst_sh_housing"],jst_ph:["jst_ph_housing","jst_ph_housing"],us_mains:["nema_5_15p","iec_c13"],bullet:[connectorA.kind,connectorB.kind],adaptercable:[connectorA.kind,connectorB.kind]}[cable.standard];if((connectorA.kind!==expected[0]||connectorB.kind!==expected[1])&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"Connector kinds must match the cable standard"}),cable.standard==="bullet"){(!("diameter"in connectorA)||!("diameter"in connectorB)||connectorA.diameter!==connectorB.diameter||"pinCount"in connectorA&&"pinCount"in connectorB&&connectorA.pinCount!==connectorB.pinCount)&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"Bullet connectors require supported nominal diameters and matching contact counts"}),"pinCount"in connectorA&&(connectorA.pinCount===1&&crossSection.kind!=="round_jacket"||connectorA.pinCount>1&&crossSection.kind!=="wire_bundle")&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"Bullet cables require one insulated wire per contact"});for(let connector of[connectorA,connectorB])"diameter"in connector&&(connector.bodyHeight<=connector.diameter||connector.pitch<connector.bodyHeight||Math.abs(connector.bodyWidth-(connector.bodyHeight+(connector.pinCount-1)*connector.pitch))>1e-6||crossSection.kind==="wire_bundle"&&(crossSection.wirePitch!==connector.pitch||crossSection.wires.some(wire=>wire.diameter>connector.bodyHeight))||connector.contactDepth>=connector.bodyDepth||crossSection.kind==="round_jacket"&&crossSection.diameter>connector.bodyHeight)&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"Bullet contact, body, and wire dimensions must fit"})}else cable.standard!=="adaptercable"&&("diameter"in connectorA||"diameter"in connectorB)&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"Bullet connectors require the bullet cable standard"});if(cable.standard==="adaptercable"){"pinCount"in connectorA&&"pinCount"in connectorB&&connectorA.pinCount!==connectorB.pinCount&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"Adapter connector pin counts must match"}),"pinCount"in connectorA&&"pinCount"in connectorB&&connectorA.pinCount>1&&crossSection.kind!=="wire_bundle"&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"Adapter cables require one wire per explicit contact"});for(let connector of[connectorA,connectorB])"diameter"in connector&&(connector.bodyHeight<=connector.diameter||connector.pitch<connector.bodyHeight||Math.abs(connector.bodyWidth-(connector.bodyHeight+(connector.pinCount-1)*connector.pitch))>1e-6||connector.contactDepth>=connector.bodyDepth||connector.pinCount===1&&(crossSection.kind!=="round_jacket"||crossSection.diameter>connector.bodyHeight)||connector.pinCount>1&&(crossSection.kind!=="wire_bundle"||crossSection.wires.some(wire=>wire.diameter>connector.bodyHeight)))&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"Bullet contact, body, and wire dimensions must fit"})}if(crossSection.kind==="wire_bundle"){for(let connector of[connectorA,connectorB])(!("pinCount"in connector)||connector.pinCount!==crossSection.wires.length)&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"Bundle wire count must match each connector pin count"}),"pitch"in connector&&crossSection.wires.some(wire=>wire.diameter>connector.pitch)&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"Insulated wires must fit each connector pitch"});crossSection.wires.some(wire=>wire.diameter>crossSection.wirePitch)&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"Bundle wires must not overlap in the cross section"})}else(cable.standard==="jst_sh"||cable.standard==="jst_ph")&&ctx.addIssue({code:external_exports.ZodIssueCode.custom,message:"JST cables require a wire bundle"})}),adapterCableInputSchema2=external_exports.object({standard:external_exports.literal("adaptercable"),connectorA:cableConnectorSchema2,connectorB:cableConnectorSchema2,crossSection:cableCrossSectionSchema2.optional()}).strict(),color22=external_exports.string().regex(/^#[0-9a-fA-F]{6}$/),jacket2={jacketDiameter:external_exports.number().finite().positive().default(4),color:color22.default("#263449")},cableInputSchema2=external_exports.discriminatedUnion("standard",[external_exports.object({standard:external_exports.literal("bullet"),diameter:bulletDiameterSchema2,pinCount:external_exports.number().int().min(1).max(16).default(1),genderA:bulletGenderSchema2.default("male"),genderB:bulletGenderSchema2.default("female"),wireDiameter:external_exports.number().finite().positive().default(2),color:color22.default("#263449")}).strict(),external_exports.object({standard:external_exports.literal("usb_c"),...jacket2}).strict(),external_exports.object({standard:external_exports.literal("jst_sh"),pinCount:external_exports.number().int().min(2).max(15).default(4),wireDiameter:external_exports.number().finite().min(.4).max(.8).default(.6)}).strict(),external_exports.object({standard:external_exports.literal("jst_ph"),pinCount:external_exports.number().int().min(2).max(16).default(2),wireDiameter:external_exports.number().finite().min(.8).max(1.5).default(1.2)}).strict(),external_exports.object({standard:external_exports.literal("us_mains"),...jacket2,jacketDiameter:jacket2.jacketDiameter.default(6.2)}).strict(),adapterCableInputSchema2]),wireColors=["#df4049","#263449","#e1b13c","#347dc9","#27a782","#af62bd"];function getAdapterCableDefinition(input2){let cable=adapterCableInputSchema2.parse({standard:"adaptercable",...input2}),{connectorA,connectorB}=cable,bundled="pinCount"in connectorA&&"pinCount"in connectorB&&connectorA.pinCount>1,pitches=[connectorA,connectorB].flatMap(connector=>"pitch"in connector?[connector.pitch]:[]),wireDiameter=Math.min(2,...pitches.map(pitch=>pitch*.6));return cableDefinitionSchema2.parse({...cable,crossSection:cable.crossSection??(bundled?{kind:"wire_bundle",wirePitch:Math.max(...pitches),wires:Array.from({length:connectorA.pinCount},(_23,index2)=>({diameter:wireDiameter,color:wireColors[index2%wireColors.length]}))}:{kind:"round_jacket",diameter:Math.min(4,connectorA.bodyHeight,connectorB.bodyHeight,...pitches.map(pitch=>Math.min(2,pitch*.6))),color:"#263449"})})}var wireColors2=["#df4049","#263449","#e1b13c","#347dc9","#27a782","#af62bd"];function getCableDefinition(cableInput){let cable=cableInputSchema2.parse(cableInput);if(cable.standard==="adaptercable")return getAdapterCableDefinition(cable);if(cable.standard==="bullet"){let pitch=cable.diameter+2;return cableDefinitionSchema2.parse({standard:"bullet",connectorA:getBulletConnector({diameter:cable.diameter,gender:cable.genderA,pinCount:cable.pinCount,pitch}),connectorB:getBulletConnector({diameter:cable.diameter,gender:cable.genderB,pinCount:cable.pinCount,pitch}),crossSection:cable.pinCount===1?{kind:"round_jacket",diameter:cable.wireDiameter,color:cable.color}:{kind:"wire_bundle",wirePitch:pitch,wires:Array.from({length:cable.pinCount},(_23,index2)=>({diameter:cable.wireDiameter,color:wireColors2[index2%wireColors2.length]}))}})}if(cable.standard==="usb_c"){let connector2={kind:"usb_c_plug",bodyWidth:12,bodyHeight:6,bodyDepth:18,shellWidth:8.25,shellHeight:2.4,shellDepth:6.5};return cableDefinitionSchema2.parse({standard:cable.standard,connectorA:connector2,connectorB:{...connector2},crossSection:{kind:"round_jacket",diameter:cable.jacketDiameter,color:cable.color}})}if(cable.standard==="us_mains")return cableDefinitionSchema2.parse({standard:cable.standard,connectorA:{kind:"nema_5_15p",bodyWidth:32,bodyHeight:28,bodyDepth:35},connectorB:{kind:"iec_c13",bodyWidth:24,bodyHeight:18,bodyDepth:30},crossSection:{kind:"round_jacket",diameter:cable.jacketDiameter,color:cable.color}});let isSh=cable.standard==="jst_sh",connector={kind:isSh?"jst_sh_housing":"jst_ph_housing",pinCount:cable.pinCount,pitch:isSh?1:2,bodyWidth:isSh?cable.pinCount+1:(cable.pinCount-1)*2+3.8,bodyHeight:isSh?2.8:4.5,bodyDepth:isSh?5:6.85};return cableDefinitionSchema2.parse({standard:cable.standard,connectorA:connector,connectorB:{...connector},crossSection:{kind:"wire_bundle",wirePitch:connector.pitch,wires:Array.from({length:cable.pinCount},(_23,index2)=>({diameter:cable.wireDiameter,color:wireColors2[index2%wireColors2.length]}))}})}function parseConnectorString(connectorString){let name=connectorString.trim().toLowerCase(),bullet=/^bullet([1-9][0-9]*)?_(.+)$/.exec(name);if(bullet){let diameter,gender,seen=new Set;for(let parameter of bullet[2].split("_")){let match2=/^d([0-9]+(?:\.[0-9]+)?)mm$/.exec(parameter)??/^g(male|female)$/.exec(parameter),key=parameter[0];if(!match2||seen.has(key))throw new Error(`Invalid or duplicate connector parameter: "${parameter}"`);seen.add(key),key==="d"?diameter=Number(match2[1]):gender=match2[1]}if(diameter===void 0||gender===void 0)throw new Error("Bullet connector strings require dNmm and gmale or gfemale");return getCableDefinition({standard:"bullet",diameter:bulletDiameterSchema2.parse(diameter),pinCount:bullet[1]?Number(bullet[1]):1,genderA:gender}).connectorA}let jst2=/^(jst_sh|jst_ph)(?:_pins([0-9]+))?$/.exec(name);if(jst2)return getCableDefinition({standard:jst2[1],...jst2[2]?{pinCount:Number(jst2[2])}:{}}).connectorA;if(name==="usb_c")return getCableDefinition({standard:"usb_c"}).connectorA;if(name==="nema_5_15p")return getCableDefinition({standard:"us_mains"}).connectorA;if(name==="iec_c13")return getCableDefinition({standard:"us_mains"}).connectorB;throw new Error(`Unsupported connector string: "${connectorString}"`)}function parseCableString2(cableString){let cableName=cableString.trim().toLowerCase();if(cableName.startsWith("adaptercable")){let adapter2=/^adaptercable_(a|b)\(([^()]+)\)_(a|b)\(([^()]+)\)$/.exec(cableName);if(!adapter2||adapter2[1]===adapter2[3])throw new Error("Adapter cables require exactly one named a(CONNECTOR) and b(CONNECTOR)");let first=parseConnectorString(adapter2[2]),second=parseConnectorString(adapter2[4]);return getAdapterCableDefinition({connectorA:adapter2[1]==="a"?first:second,connectorB:adapter2[1]==="b"?first:second})}if(cableName==="usb_c"||cableName==="us_mains")return getCableDefinition({standard:cableName});let bulletMatch=/^bullet([1-9][0-9]*)?_(.+)$/.exec(cableName);if(bulletMatch){let diameter,genderA,genderB,seen=new Set;for(let parameter of bulletMatch[2].split("_")){let match2=/^d([0-9]+(?:\.[0-9]+)?)mm$/.exec(parameter)??/^(a|b)(male|female)$/.exec(parameter),key=parameter[0];if(!match2||seen.has(key))throw new Error(`Invalid or duplicate bullet parameter: "${parameter}"`);seen.add(key),key==="d"?diameter=Number(match2[1]):key==="a"?genderA=match2[2]:genderB=match2[2]}if(diameter===void 0)throw new Error("Bullet cables require dNmm");return getCableDefinition({standard:"bullet",diameter:bulletDiameterSchema2.parse(diameter),pinCount:bulletMatch[1]?Number(bulletMatch[1]):1,genderA:genderA??"male",genderB:genderB??"female"})}let jstMatch=/^(jst_sh|jst_ph)(?:_pins([0-9]+))?$/.exec(cableName);if(jstMatch)return getCableDefinition({standard:jstMatch[1],...jstMatch[2]?{pinCount:Number(jstMatch[2])}:{}});throw new Error(`Unsupported cable string: "${cableString}". Expected usb_c, jst_sh[_pinsN], jst_ph[_pinsN], us_mains, bullet[CONTACTS]_dNmm[_amale][_bfemale], or adaptercable_a(CONNECTOR)_b(CONNECTOR).`)}function getConnectorPins(cable,connector){let db22=cable.root.db;return db22.source_port.list().flatMap(sourcePort=>{if(sourcePort.source_component_id!==connector.source_component_id)return[];let pcbPort=db22.pcb_port.list().find(port=>port.source_port_id===sourcePort.source_port_id&&port.pcb_component_id===connector.pcb_component_id);if(!pcbPort)return[];let hint=[sourcePort.name,...sourcePort.port_hints??[]].find(name=>/^(?:pin)?\d+$/.test(name)),pin=sourcePort.pin_number??(hint?Number(hint.replace(/^pin/,"")):void 0);return[{position:pcbPort,pin}]})}function resolveAssemblyCableContactRowCenter(cable,connector,outward,rowOffset){let pins=getConnectorPins(cable,connector),first=pins.find(({pin})=>pin===1)?.position;if(!first||pins.length<2)return;let center2=pins.reduce((sum,{position:position22})=>({x:sum.x+position22.x/pins.length,y:sum.y+position22.y/pins.length}),{x:0,y:0}),row=vec3_exports.normalize(vec3_exports.create(),[center2.x-first.x,center2.y-first.y,0]),towardHoldDowns=vec3_exports.cross(vec3_exports.create(),[outward.x,outward.y,outward.z],row);return{x:center2.x+towardHoldDowns[0]*rowOffset,y:center2.y+towardHoldDowns[1]*rowOffset}}function resolveAssemblyCablePin1Position(cable,connector,matingCenter,outward){let pins=getConnectorPins(cable,connector),pin1=pins.find(({pin})=>pin===1)?.position;if(!pin1||pins.length<2)return;let center2=pins.reduce((sum,{position:position22})=>({x:sum.x+position22.x/pins.length,y:sum.y+position22.y/pins.length}),{x:0,y:0}),offset3=vec3_exports.fromValues(pin1.x-center2.x,pin1.y-center2.y,0),axis=vec3_exports.normalize(vec3_exports.create(),[outward.x,outward.y,outward.z]);if(vec3_exports.scaleAndAdd(offset3,offset3,axis,-vec3_exports.dot(offset3,axis)),!(vec3_exports.length(offset3)<1e-6))return{x:matingCenter.x+offset3[0],y:matingCenter.y+offset3[1],z:matingCenter.z+offset3[2]}}function resolveAssemblyCableEndpoint(cable,selector2,cableConnector){let scoped=getComponentsInAssemblyScope(cable),motorReference=selector2.match(/^(.+)\.wireside$/);if(motorReference){let motors=scoped.filter(part=>part.componentName==="AssemblyMotor"&&part.name===motorReference[1]);if(motors.length!==1)throw new Error(`assembly.cable "${cable.name}" endpoint "${selector2}" must match exactly one motor in its assembly device`);let motor=motors[0],motorConnector=getJstMotorConnector2(motor.motorModel.wireConnection);if(!motorConnector)throw new Error(`assembly.cable "${cable.name}" requires motor "${motor.name}" to have a JST PH or SH wireConnection, e.g. "jst4_ph" or "jst4_sh", for its connector endpoint`);let faceMount=resolveMotorFaceMount(motor),placement=faceMount?{position:faceMount.position,pcbRotation:0,layer:"top"}:resolveAssemblyMotorPlacement(motor),offset3=faceMount?.rotation??resolveAssemblyMotorRotation(motor,placement),orientation32=mat4_exports.create(),bottom=placement.layer==="bottom";mat4_exports.rotateX(orientation32,orientation32,offset3.x*Math.PI/180),mat4_exports.rotateY(orientation32,orientation32,(offset3.y+(bottom?180:0))*Math.PI/180),mat4_exports.rotateZ(orientation32,orientation32,(bottom?-1:1)*(placement.pcbRotation+offset3.z)*Math.PI/180);let reference4=motor.motorReferencePoints.wireside,direction22=vec3_exports.transformMat4(vec3_exports.create(),[reference4.direction.x,reference4.direction.y,reference4.direction.z],orientation32),point12=vec3_exports.transformMat4(vec3_exports.create(),[reference4.position.x,reference4.position.y,reference4.position.z+motorConnector.contactOffsetZ],orientation32),halfPinSpan=(motorConnector.pinCount-1)*motorConnector.pitch/2,pin1Offset=vec3_exports.transformMat4(vec3_exports.create(),[reference4.direction.y*halfPinSpan,-reference4.direction.x*halfPinSpan,0],orientation32),tipDepth=motorConnector.matingDepth-motorConnector.plugInsertionDepth,board2;if(cable._parsedProps.waypoints?.length){let boardAncestor=motor.parent,subcircuitId=faceMount?.subcircuit_id??placement.subcircuit_id;if(subcircuitId){let mountedSubcircuit=scoped.find(part=>part.isSubcircuit&&part.getSubcircuit().subcircuit_id===subcircuitId);if(!mountedSubcircuit)throw new Error(`assembly.cable "${cable.name}" motor "${motor.name}" mounting subcircuit is not in its assembly device`);boardAncestor=mountedSubcircuit}for(;boardAncestor&&boardAncestor.componentName!=="Board"&&boardAncestor.componentName!=="MountedBoard";)boardAncestor=boardAncestor.parent;board2=boardAncestor?._getBoard()}return{sourceComponentId:motor.source_component_id,board:board2,position:{x:point12[0]+placement.position.x+direction22[0]*tipDepth,y:point12[1]+placement.position.y+direction22[1]*tipDepth,z:point12[2]+placement.position.z+direction22[2]*tipDepth},pin1Position:{x:point12[0]+placement.position.x+direction22[0]*tipDepth+pin1Offset[0],y:point12[1]+placement.position.y+direction22[1]*tipDepth+pin1Offset[1],z:point12[2]+placement.position.z+direction22[2]*tipDepth+pin1Offset[2]},direction:{x:direction22[0],y:direction22[1],z:direction22[2]},cableInput:{standard:motorConnector.standard,pinCount:motorConnector.pinCount}}}let scope=getAssemblyScope(cable),matches=selectAll(preprocessSelector(selector2,cable),scope,{adapter:cssSelectPrimitiveComponentAdapter}).filter(part=>scoped.includes(part));if(matches.length!==1)throw new Error(`assembly.cable "${cable.name}" endpoint "${selector2}" matched ${matches.length} components; expected exactly one in its assembly device`);let connector=matches[0];if(!(connector instanceof NormalComponent)||connector.componentName!=="Connector"||!connector.pcb_component_id||!connector.source_component_id)throw new Error(`assembly.cable "${cable.name}" endpoint "${selector2}" must name a PCB connector or MOTOR.wireside`);let props=connector._parsedProps;if(!cableConnector&&props.standard!=="usb_c"&&props.standard!=="jst_sh"&&props.standard!=="jst_ph")throw new Error(`assembly.cable "${cable.name}" cannot infer endpoint "${selector2}"; use a connector with standard="usb_c", "jst_sh", or "jst_ph"`);let pcb=cable.root.db.pcb_component.get(connector.pcb_component_id),board=connector._getBoard(),layer=pcb.layer==="bottom"?"bottom":"top",inferredCenter=pcb.cable_insertion_center??pcb.center,inferredDirection=vec3_exports.normalize(vec3_exports.create(),[inferredCenter.x-pcb.center.x,inferredCenter.y-pcb.center.y,0]),direction4=connector._getPcbComponentInsertionAxisDirection(layer,pcb.rotation)??(props.standard==="usb_c"&&vec3_exports.length(inferredDirection)>0?{x:inferredDirection[0],y:inferredDirection[1],z:0}:{x:0,y:0,z:layer==="bottom"?-1:1}),jstProfile=props.standard==="jst_ph"||props.standard==="jst_sh"?getJstMotorConnector2(`jst-${props.standard==="jst_ph"?"ph":"sh"}-${props.pinCount}`):void 0,center2=Math.abs(direction4.z)>.5?jstProfile&&resolveAssemblyCableContactRowCenter(cable,connector,direction4,jstProfile.pcbContactRowOffset)||pcb.center:inferredCenter,sign=layer==="bottom"?-1:1,height10=!props.standard&&cableConnector?Math.abs(direction4.z)>.5?cableConnector.bodyDepth:cableConnector.bodyHeight/2:Math.abs(direction4.z)>.5?jstProfile?jstProfile.matingDepth-jstProfile.plugInsertionDepth:1.5:props.standard==="usb_c"?1.5:props.standard==="jst_sh"?1.4:2.25,position22={x:center2.x,y:center2.y,z:sign*(board.boardThickness/2+height10)};return{sourceComponentId:connector.source_component_id,board,position:position22,pin1Position:resolveAssemblyCablePin1Position(cable,connector,position22,direction4),direction:direction4,cableInput:props.standard==="usb_c"?{standard:"usb_c"}:props.standard==="jst_sh"||props.standard==="jst_ph"?{standard:props.standard,pinCount:props.pinCount}:void 0}}function inferAssemblyCablePath({from,to:to3,fromDirection,toDirection}){let distance29=Math.hypot(to3.x-from.x,to3.y-from.y,to3.z-from.z);if(distance29<1e-6)throw new Error("Cable wire exits must be at different positions");let chord=vec3_exports.fromValues(to3.x-from.x,to3.y-from.y,to3.z-from.z),routeNormal=vec3_exports.cross(vec3_exports.create(),chord,[fromDirection.x,fromDirection.y,fromDirection.z]);vec3_exports.length(routeNormal)<1e-6&&vec3_exports.cross(routeNormal,chord,Math.abs(chord[2])/distance29>.95?[0,1,0]:[0,0,1]);let archDirection=vec3_exports.normalize(vec3_exports.create(),vec3_exports.cross(vec3_exports.create(),routeNormal,chord)),archSide=from.z<0&&to3.z<0?-1:1;archDirection[2]*archSide<0&&vec3_exports.scale(archDirection,archDirection,-1);let clearance=Math.min(25,Math.max(8,distance29/3)),controlA={x:from.x+fromDirection.x*clearance,y:from.y+fromDirection.y*clearance,z:from.z+fromDirection.z*clearance},controlB={x:to3.x+toDirection.x*clearance,y:to3.y+toDirection.y*clearance,z:to3.z+toDirection.z*clearance},path=[from,{x:from.x+fromDirection.x*.1,y:from.y+fromDirection.y*.1,z:from.z+fromDirection.z*.1}];for(let i23=1;i23<48;i23++){let t48=i23/48,u23=1-t48,arch=Math.sin(Math.PI*t48)**2*Math.min(12,distance29*.15);path.push({x:u23**3*from.x+3*u23**2*t48*controlA.x+3*u23*t48**2*controlB.x+t48**3*to3.x+archDirection[0]*arch,y:u23**3*from.y+3*u23**2*t48*controlA.y+3*u23*t48**2*controlB.y+t48**3*to3.y+archDirection[1]*arch,z:u23**3*from.z+3*u23**2*t48*controlA.z+3*u23*t48**2*controlB.z+t48**3*to3.z+archDirection[2]*arch})}return path.push({x:to3.x+toDirection.x*.1,y:to3.y+toDirection.y*.1,z:to3.z+toDirection.z*.1},to3),path}var CONNECTOR_TANGENT_LENGTH_MM=.1,MIN_SEGMENT_LENGTH_MM=1e-6,MIN_TANGENT_LENGTH=1e-6,BEZIER_HANDLE_LENGTH_RATIO=1/3,CURVE_SAMPLES_PER_SPAN=12;function resolveAuthoredAssemblyCablePath({cable,from,to:to3,fromExit,toExit,waypoints}){let{waypointAnchor,waypointAxisOrientation}=cable._parsedProps,anchor3=from.position;waypointAnchor==="end"&&(anchor3=to3.position);let board=from.board;if(waypointAxisOrientation==="board_at_end"&&(board=to3.board),!board){let endpoint=cable._parsedProps.from;throw waypointAxisOrientation==="board_at_end"&&(endpoint=cable._parsedProps.to),new Error(`assembly.cable "${cable.name}" endpoint "${endpoint}" has no board for waypointAxisOrientation="${waypointAxisOrientation}"`)}let boardToWorld={...board._computePcbGlobalTransformBeforeLayout(),e:0,f:0},fromTangent=vec3_exports.scaleAndAdd(vec3_exports.create(),[fromExit.x,fromExit.y,fromExit.z],[from.direction.x,from.direction.y,from.direction.z],CONNECTOR_TANGENT_LENGTH_MM),toTangent=vec3_exports.scaleAndAdd(vec3_exports.create(),[toExit.x,toExit.y,toExit.z],[to3.direction.x,to3.direction.y,to3.direction.z],CONNECTOR_TANGENT_LENGTH_MM),path=[fromExit,{x:fromTangent[0],y:fromTangent[1],z:fromTangent[2]},...waypoints.map(waypoint=>{let offset3=applyToPoint3(boardToWorld,waypoint);return{x:anchor3.x+offset3.x,y:anchor3.y+offset3.y,z:anchor3.z+waypoint.z}}),{x:toTangent[0],y:toTangent[1],z:toTangent[2]},toExit],directions22=[],segmentLengths=[],previousDirection;for(let vertex=1;vertex<path.length;vertex++){let previous=path[vertex-1],current23=path[vertex],direction4=vec3_exports.subtract([0,0,0],[current23.x,current23.y,current23.z],[previous.x,previous.y,previous.z]),segmentLength=vec3_exports.length(direction4);if(segmentLength<MIN_SEGMENT_LENGTH_MM)throw new Error(`assembly.cable "${cable.name}" waypoints must leave distinct consecutive path points, including connector exits`);if(vec3_exports.normalize(direction4,direction4),previousDirection&&vec3_exports.length(vec3_exports.add([0,0,0],previousDirection,direction4))<MIN_TANGENT_LENGTH)throw new Error(`assembly.cable "${cable.name}" waypoints must not reverse direction at a path point`);directions22.push(direction4),segmentLengths.push(segmentLength),previousDirection=direction4}let tangents=[directions22[0]];for(let vertex=2;vertex<path.length-2;vertex++){let tangent=vec3_exports.add([0,0,0],directions22[vertex-1],directions22[vertex]);vec3_exports.normalize(tangent,tangent),tangents.push(tangent)}tangents.push(directions22.at(-1));let smoothPath=[path[0],path[1]];for(let vertex=1;vertex<path.length-2;vertex++){let start=path[vertex],end=path[vertex+1],startPoint=[start.x,start.y,start.z],endPoint=[end.x,end.y,end.z],handleLength=segmentLengths[vertex]*BEZIER_HANDLE_LENGTH_RATIO,controlA=vec3_exports.scaleAndAdd([0,0,0],startPoint,tangents[vertex-1],handleLength),controlB=vec3_exports.scaleAndAdd([0,0,0],endPoint,tangents[vertex],-handleLength);for(let sample=1;sample<CURVE_SAMPLES_PER_SPAN;sample++){let point12=vec3_exports.bezier([0,0,0],startPoint,controlA,controlB,endPoint,sample/CURVE_SAMPLES_PER_SPAN);smoothPath.push({x:point12[0],y:point12[1],z:point12[2]})}smoothPath.push(end)}smoothPath.push(path.at(-1));let validatedPath=cad_cable.shape.path.safeParse(smoothPath);if(!validatedPath.success)throw new Error(`assembly.cable "${cable.name}" waypoints produce invalid curve points; adjust their positions or spacing`);previousDirection=void 0;for(let vertex=1;vertex<validatedPath.data.length;vertex++){let previous=validatedPath.data[vertex-1],current23=validatedPath.data[vertex],direction4=vec3_exports.subtract([0,0,0],[current23.x,current23.y,current23.z],[previous.x,previous.y,previous.z]);if(vec3_exports.normalize(direction4,direction4),previousDirection&&vec3_exports.length(vec3_exports.add([0,0,0],previousDirection,direction4))<MIN_TANGENT_LENGTH)throw new Error(`assembly.cable "${cable.name}" smooth curve must not reverse direction; adjust the nearby waypoints`);previousDirection=direction4}return validatedPath.data}var wireExitDepth=connector=>connector.bodyDepth+(connector.kind==="usb_c_plug"?connector.shellDepth:0);function resolveAssemblyCable(cable){let model110=cable._parsedProps.model,explicitDefinition=model110?parseCableString2(model110):void 0,from=resolveAssemblyCableEndpoint(cable,cable._parsedProps.from,explicitDefinition?.connectorA),to3=resolveAssemblyCableEndpoint(cable,cable._parsedProps.to,explicitDefinition?.connectorB),fromDefinition=explicitDefinition??getCableDefinition(from.cableInput),toDefinition=explicitDefinition??getCableDefinition(to3.cableInput);if(from.sourceComponentId===to3.sourceComponentId)throw new Error(`assembly.cable "${cable.name}" must connect two different endpoints`);if(!explicitDefinition&&(fromDefinition.standard!==toDefinition.standard||fromDefinition.connectorA.kind!==toDefinition.connectorA.kind||"pinCount"in fromDefinition.connectorA&&"pinCount"in toDefinition.connectorA&&fromDefinition.connectorA.pinCount!==toDefinition.connectorA.pinCount))throw new Error(`assembly.cable "${cable.name}" endpoints "${cable._parsedProps.from}" and "${cable._parsedProps.to}" have incompatible connector standards or pin counts`);if(cable._parsedProps.standard&&cable._parsedProps.standard!==fromDefinition.standard)throw new Error(`assembly.cable "${cable.name}" standard="${cable._parsedProps.standard}" conflicts with its endpoints`);let definition=fromDefinition,endpointExit=(position22,direction4,depth)=>{let exit=vec3_exports.scaleAndAdd(vec3_exports.create(),[position22.x,position22.y,position22.z],[direction4.x,direction4.y,direction4.z],depth);return{x:exit[0],y:exit[1],z:exit[2]}},fromExit=endpointExit(from.position,from.direction,wireExitDepth(definition.connectorA)),toExit=endpointExit(to3.position,to3.direction,wireExitDepth(definition.connectorB)),path,waypoints=cable._parsedProps.waypoints;return waypoints?.length?path=resolveAuthoredAssemblyCablePath({cable,from,to:to3,fromExit,toExit,waypoints}):path=inferAssemblyCablePath({from:fromExit,to:toExit,fromDirection:from.direction,toDirection:to3.direction}),{name:cable.name,from_source_component_id:from.sourceComponentId,to_source_component_id:to3.sourceComponentId,from_connector_pin1_position:from.pin1Position,to_connector_pin1_position:to3.pin1Position,cableprinter_string:model110??("pinCount"in definition.connectorA?`${definition.standard}_pins${definition.connectorA.pinCount}`:definition.standard),path}}var AssemblyCable=class extends AssemblyComponent{constructor(){super(...arguments);__publicField(this,"cadCableId")}get config(){return{componentName:"AssemblyCable",zodProps:assemblyCableProps}}doInitialCadModelRender(){if(!this.root||this.root.pcbDisabled)return;let cable=resolveAssemblyCable(this);this.cadCableId=this.root.db.cad_cable.insert(cable).cad_cable_id}onPropsChange(){super.onPropsChange(),this._markDirty("CadModelRender")}updateCadModelRender(){!this.root||this.root.pcbDisabled||!this.cadCableId||this.root.db.cad_cable.update(this.cadCableId,resolveAssemblyCable(this))}},AssemblyDrawingTitleBlock=class extends PrimitiveComponent{get config(){return{componentName:"AssemblyDrawingTitleBlock",zodProps:assemblyDrawingTitleBlockProps}}doInitialAssignNameToUnnamedComponents(){}doInitialSourceRender(){if(this.parent?.componentName!=="AssemblyDrawingPage")throw new Error("assembly.drawing.titleblock must belong to a drawing page");if(this.children.length)throw new Error("assembly.drawing.titleblock cannot contain children")}},AssemblyDrawingPartView=class extends PrimitiveComponent{get config(){return{componentName:"AssemblyDrawingPartView",zodProps:assemblyDrawingPartViewProps}}doInitialAssignNameToUnnamedComponents(){}doInitialSourceRender(){if(this.parent?.componentName!=="AssemblyDrawingPage")throw new Error("assembly.drawing.partview must belong to a drawing page");if(this.children.some(child=>child.componentName!=="AssemblyDrawingDimension"))throw new Error("assembly.drawing.partview can contain only dimensions")}};function resolveDrawingViewCenters(page){let views=page.children.filter(child=>child instanceof AssemblyDrawingPartView),centers={x:new Map,y:new Map},resolving={x:new Set,y:new Set},resolveAxis=(view,axis)=>{if(centers[axis].has(view))return centers[axis].get(view);if(resolving[axis].has(view))throw new Error(`Drawing placement cycle at part view "${view.name||"unnamed part view"}" on ${axis} axis`);resolving[axis].add(view);let props=view._parsedProps,negative=axis==="x"?props.leftOfRef:props.belowRef,positive12=axis==="x"?props.rightOfRef:props.aboveRef,selector2=negative??positive12,center2=(axis==="x"?props.centerX:props.centerY)??0;if(selector2){let matches=selectAll(preprocessSelector(selector2,view),page,{adapter:cssSelectPrimitiveComponentAdapter}).filter(child=>views.includes(child));if(matches.length!==1)throw new Error(`Part view "${view.name||"unnamed part view"}" placement selector "${selector2}" matched ${matches.length} sibling views; expected exactly one`);let reference4=matches[0];if(reference4===view)throw new Error(`Part view "${view.name||"unnamed part view"}" cannot reference itself for placement`);let size23=axis==="x"?props.width:props.height,referenceSize=axis==="x"?reference4._parsedProps.width:reference4._parsedProps.height;center2=resolveAxis(reference4,axis)+(negative?-1:1)*(size23+referenceSize)/2}return resolving[axis].delete(view),centers[axis].set(view,center2),center2};return views.map(view=>({view,center:{x:resolveAxis(view,"x"),y:resolveAxis(view,"y")}}))}function resolveDrawingPartSelection(view){let selector2=view._parsedProps.partRef,scope=getAssemblyScope(view),matches=selectAll(preprocessSelector(selector2,view),[scope],{adapter:cssSelectPrimitiveComponentAdapter});if(matches.length!==1)throw new Error(`Part view "${view.name||"unnamed part view"}" partRef "${selector2}" matched ${matches.length} parts; expected exactly one`);let target=matches[0];if(target.source_group_id)return{source_group_id:target.source_group_id};let sourceComponentIds=[...new Set([target,...target.getDescendants()].flatMap(part=>part.source_component_id?[part.source_component_id]:[]))];if(!sourceComponentIds.length)throw new Error(`Part view "${view.name||"unnamed part view"}" partRef "${selector2}" has no source geometry`);return{source_component_ids:sourceComponentIds}}var directions3={"x+":"x_positive","x-":"x_negative","y+":"y_positive","y-":"y_negative","z+":"z_positive","z-":"z_negative",isometric:"isometric"};function AssemblyDrawingPage_doInitialDrawingRender(page){let{db:db22}=page.root,props=page._parsedProps,views=resolveDrawingViewCenters(page).map(({view,center:center2})=>({view,center:center2,selection:resolveDrawingPartSelection(view)})),preparedViews=views.map(({view,center:center2,selection})=>{let viewProps=view._parsedProps,drawingView={...selection,name:viewProps.name,display_name:viewProps.displayName,direction:directions3[viewProps.direction],center:center2,width:viewProps.width,height:viewProps.height,show_hidden_edges:viewProps.showHiddenEdges,section:viewProps.section?{axis:viewProps.section.axis,offset:viewProps.section.offset,keep_side:viewProps.section.keepSide,hatch_spacing:viewProps.section.hatchSpacing}:void 0};return{view,drawingView,dimensions:[]}}),insertPage=()=>{let{drawing_page_id}=db22.drawing_page.insert({name:props.name,display_name:props.displayName,width:props.width,height:props.height,page_size:props.size,orientation:props.size?props.orientation??"landscape":void 0});for(let{drawingView,dimensions:dimensions6}of preparedViews){let{drawing_part_view_id}=db22.drawing_part_view.insert({drawing_page_id,...drawingView});for(let dimension22 of dimensions6)db22.drawing_dimension_line.insert({drawing_part_view_id,...dimension22})}let block=page.children.find(child=>child instanceof AssemblyDrawingTitleBlock)?._parsedProps;block&&db22.drawing_page_title_block.insert({drawing_page_id,title:block.title,legal_owner:block.legalOwner,identification_number:block.identificationNumber,revision_index:block.revisionIndex,date_of_issue:block.dateOfIssue,creator:block.creator,approval_person:block.approvalPerson,sheet_number:block.sheetNumber,number_of_sheets:block.numberOfSheets})};if(!views.some(({view})=>view.children.length)){insertPage();return}let circuitJson=db22.toArray();page._queueAsyncEffect("resolve-drawing-dimensions",async()=>{try{let{resolveDrawingDimensions:resolveDrawingDimensions2}=await Promise.resolve().then(()=>(init_resolve_drawing_dimensions_EUYVRY2N(),resolve_drawing_dimensions_EUYVRY2N_exports));for(let prepared of preparedViews)prepared.dimensions=await resolveDrawingDimensions2(prepared.view,prepared.drawingView,circuitJson);insertPage()}catch(error2){page.drawingRenderError=error2,page._markDirty("DrawingRender")}})}var AssemblyDrawingPage=class extends PrimitiveComponent{constructor(){super(...arguments);__publicField(this,"drawingRenderError")}get config(){return{componentName:"AssemblyDrawingPage",zodProps:assemblyDrawingPageProps}}doInitialAssignNameToUnnamedComponents(){}doInitialSourceRender(){if(this.children.some(child=>child.componentName!=="AssemblyDrawingPartView"&&child.componentName!=="AssemblyDrawingTitleBlock"))throw new Error("Drawing pages can contain only part views and a title block");if(this.children.filter(child=>child.componentName==="AssemblyDrawingTitleBlock").length>1)throw new Error("A drawing page can contain at most one title block")}updateDrawingRender(){if(this.drawingRenderError)throw this.drawingRenderError}doInitialDrawingRender(){AssemblyDrawingPage_doInitialDrawingRender(this)}},AssemblyDrawingDimension=class extends PrimitiveComponent{get config(){return{componentName:"AssemblyDrawingDimension",zodProps:assemblyDrawingDimensionProps}}doInitialAssignNameToUnnamedComponents(){}doInitialSourceRender(){if(this.parent?.componentName!=="AssemblyDrawingPartView")throw new Error("assembly.drawing.dimension must belong to a drawing part view");if(this.children.length)throw new Error("assembly.drawing.dimension cannot contain children")}},resolveAssemblyBoltModel=bolt=>{let props=bolt._parsedProps;if(props.diameter===void 0)return resolveAssemblyModel(props);try{let head=props.headType??"socket",model110=`${{socket:"hexsocketbolt",hex:"hexbolt",pan:"panscrew",countersunk:"flatheadscrew"}[head]}_m${props.diameter}_l${props.length}mm`;if(props.threadPitch!==void 0)if(head==="socket"){let standard=hexSocketBoltDimensions2[`M${props.diameter}`];if(props.threadPitch!==standard?.threadPitch)throw new Error("Socket-head bolts require the standard coarse thread pitch; supply cadModel for a custom thread")}else model110+=`_threadpitch${props.threadPitch}mm`;return parseModelString(model110),resolveAssemblyModel({model:model110})}catch{throw new Error(`Bolt "${bolt.name}" has an unsupported model or dimensions; use a supported modelprinter bolt or supply cadModel`)}},AssemblyBolt=class extends AssemblyComponent{constructor(){super(...arguments);__publicField(this,"isAssemblyDeviceContainer",!0)}get config(){return{componentName:"AssemblyBolt",zodProps:assemblyBoltProps}}doInitialReactSubtreesRender(){(0,import_react14.isValidElement)(this.props.cadModel)&&this.add(createInstanceFromReactElement(this.props.cadModel))}doInitialSourceRender(){getPartReferenceSurfaces(this),this.source_component_id=this.root.db.source_component.insert({ftype:"subassembly",name:this.name,display_name:this._parsedProps.displayName}).source_component_id}doInitialCadModelRender(){if(!this.root||this.root.pcbDisabled||!this.source_component_id)return;renderPartReferenceSurfaces(this);let model110=resolveAssemblyBoltModel(this)??this._parsedProps.cadModel;model110&&!(typeof model110=="object"&&"type"in model110)&&(this.cad_component_id=renderAssemblyCadModel(this,model110,resolveAssemblyPlacement(this)))}},Toolingrail=class extends Group{get isGroup(){return!0}doInitialSchematicComponentRender(){}doInitialSchematicLayout(){}doInitialSchematicTraceRender(){}get config(){return{componentName:"Toolingrail",zodProps:toolingrailProps}}_getPcbLayoutMode(){return"none"}_getRailGeometry(){let panel=getOwningPanel(this);if(!panel)return;let panelSize=panel._getPanelSize();if(!panelSize)throw new Error('<toolingrail> needs a panel with a known size. Use layoutMode="grid" or set the panel width and height.');let{width:width10,height:height10}=panelSize,railWidth=this._parsedProps.width,side=this._parsedProps.panelSide,availablePadding=panel._getEdgePadding()[side];if(railWidth>availablePadding)throw new Error(`Tooling rail width ${railWidth} mm exceeds the ${side} edge padding of ${availablePadding} mm. Increase that panel edge padding.`);return{x:side==="left"?-width10/2+railWidth/2:side==="right"?width10/2-railWidth/2:0,y:side==="bottom"?-height10/2+railWidth/2:side==="top"?height10/2-railWidth/2:0,width:side==="left"||side==="right"?railWidth:width10,height:side==="top"||side==="bottom"?railWidth:height10}}_computePcbGlobalTransformBeforeLayout(){let railToWorldTransform=super._computePcbGlobalTransformBeforeLayout(),rail=this._getRailGeometry();if(!rail||!this.parent)return railToWorldTransform;let panelToWorldTransform=this.parent._computePcbGlobalTransformBeforeLayout(),worldToPanelTransform=inverse6(panelToWorldTransform);return compose3(panelToWorldTransform,translate8(rail.x,rail.y),worldToPanelTransform,railToWorldTransform)}getPcbSize(){let rail=this._getRailGeometry();return{width:rail?.width??0,height:rail?.height??0}}calculatePcbGroupBounds(){if(this.root?.pcbDisabled||!this.pcb_group_id)return;let rail=this._getRailGeometry();if(!rail)return;let center2=applyToPoint3(this._computePcbGlobalTransformBeforeLayout(),{x:0,y:0});this.root.db.pcb_group.update(this.pcb_group_id,{center:center2,width:rail.width,height:rail.height})}doInitialPcbComponentRender(){if(this.parent?.componentName!=="Panel")throw new Error("<toolingrail> must be a direct child of <panel>");this._getRailGeometry(),super.doInitialPcbComponentRender(),this.pcb_group_id&&this.root.db.pcb_group.update(this.pcb_group_id,{anchor_alignment:pcb_group.shape.anchor_alignment.parse(this._parsedProps.pcbAnchorAlignment??"center")})}},createNamespacedElement=hostType=>{let Component2=props=>(0,import_react15.createElement)(hostType,props);return Component2.displayName=hostType,Component2},analog={digitalstimulus:createNamespacedElement("analogdigitalstimulus"),eyediagram:createNamespacedElement("analogeyediagram"),transientsimulation:createNamespacedElement("analogtransientsimulation"),dcoperatingpointsimulation:createNamespacedElement("analogdcoperatingpointsimulation"),dcsweepsimulation:createNamespacedElement("analogdcsweepsimulation"),acsweepsimulation:createNamespacedElement("analogacsweepsimulation"),sweepparameter:createNamespacedElement("analogsweepparameter")},assembly={drawing:{dimension:createNamespacedElement("assembly.drawing.dimension"),page:createNamespacedElement("assembly.drawing.page"),partview:createNamespacedElement("assembly.drawing.partview"),titleblock:createNamespacedElement("assembly.drawing.titleblock")},explosion:{stage:createNamespacedElement("assembly.explosion.stage"),move:createNamespacedElement("assembly.explosion.move")},referencesurface:createNamespacedElement("assembly.referencesurface"),bolt:createNamespacedElement("assembly.bolt"),part:createNamespacedElement("assembly.part"),cable:createNamespacedElement("assembly.cable"),printedpart:createNamespacedElement("assembly.printedpart"),motor:createNamespacedElement("assembly.motor"),subassembly:createNamespacedElement("assembly.subassembly"),cadassembly:createNamespacedElement("assembly.cadassembly"),device:createNamespacedElement("assembly.device"),screen:createNamespacedElement("assembly.screen")},EnclosureFdmBoxElement=createNamespacedElement("enclosure.fdm.box"),enclosure={cutoutaperture:createNamespacedElement("enclosure.cutoutaperture"),fdm:{box:EnclosureFdmBoxElement,Box:EnclosureFdmBoxElement}},simulation={pcbreturncurrentsimulation:createNamespacedElement("pcbreturncurrentsimulation"),pcbreturncurrentexcitation:createNamespacedElement("pcbreturncurrentexcitation")},systemblock={page:createNamespacedElement("systemblockpage"),group:createNamespacedElement("systemblockgroup"),component:createNamespacedElement("systemblockcomponent"),connection:createNamespacedElement("systemblockconnection")},RootCircuit=class extends IsolatedCircuit{constructor({platform,projectUrl}={}){super({platform,projectUrl,cachedSubcircuits:new Map,pendingSubcircuitRenders:new Map});__publicField(this,"isRootCircuit",!0);this.root=this}},Project2=RootCircuit,Circuit=RootCircuit,useRenderedCircuit=reactElements=>{let[isLoading,setIsLoading]=import_react16.default.useState(!0),[error2,setError]=import_react16.default.useState(null),[circuit,setCircuit]=import_react16.default.useState(),[circuitJson,setCircuitJson]=import_react16.default.useState();return import_react16.default.useEffect(()=>{setIsLoading(!0),setError(null),reactElements&&setTimeout(()=>{try{let circuit2=new RootCircuit;circuit2.add(reactElements),setCircuit(circuit2),setCircuitJson(circuit2.toJson())}catch(error22){setError(error22)}setIsLoading(!1)},1)},[reactElements]),{isLoading,error:error2,circuit,circuitJson}},createUseComponent=(Component2,pins)=>(name,props)=>{let pinLabelsFlatArray=[];Array.isArray(pins)?pinLabelsFlatArray.push(...pins.flat()):typeof pins=="object"&&pinLabelsFlatArray.push(...Object.values(pins).flat(),...Object.keys(pins));let R23=props2=>{if(props2?.name&&props2.name!==name)throw new Error(`Component name mismatch. Hook name: ${name}, Component prop name: ${props2.name}`);let combinedProps={...props,...props2,name},tracesToCreate=[];for(let portLabel of pinLabelsFlatArray)if(combinedProps[portLabel]){let from=`.${name} > .${portLabel}`,to3=combinedProps[portLabel];tracesToCreate.push({from,to:to3}),delete combinedProps[portLabel]}return(0,import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment,{children:[(0,import_jsx_runtime32.jsx)(Component2,{...combinedProps}),tracesToCreate.map((trace,i23)=>(0,import_jsx_runtime32.jsx)("trace",{...trace},i23))]})};for(let port of pinLabelsFlatArray)R23[port]=`.${name} > .${port}`;return R23},useCapacitor=createUseComponent(props=>(0,import_jsx_runtime33.jsx)("capacitor",{...props}),capacitorPins),useChip=pinLabels=>createUseComponent(props=>(0,import_jsx_runtime34.jsx)("chip",{pinLabels,...props}),pinLabels),useDiode=createUseComponent(props=>(0,import_jsx_runtime35.jsx)("diode",{...props}),diodePins),useLed=createUseComponent(props=>(0,import_jsx_runtime36.jsx)("led",{...props}),ledPins),useResistor=createUseComponent(props=>(0,import_jsx_runtime37.jsx)("resistor",{...props}),resistorPins),sel=new Proxy(refdes=>new Proxy({},{get:(_23,pin)=>`.${refdes} > .${pin}`}),{get:(_23,prop1)=>{let fn3=(...args)=>{let chipFnOrPinType=args[0];return new Proxy({},{get:(_33,pinName)=>`.${prop1} > .${pinName}`})};return new Proxy(fn3,{get:(_33,prop2)=>prop1==="net"?`net.${prop2}`:prop1==="subcircuit"?new Proxy({},{get:(_42,prop3)=>new Proxy({},{get:(_52,prop4)=>`subcircuit.${prop2} > .${prop3} > .${prop4}`})}):`.${prop1} > .${prop2}`,apply:(target,_33,args)=>prop1==="net"?new Proxy({},{get:(_42,netName)=>`net.${netName}`}):new Proxy({},{get:(_42,pinOrSubComponentName)=>{let pinResult=`.${prop1} > .${pinOrSubComponentName}`;return["U","J","CN"].some(p23=>prop1.startsWith(p23))?pinResult:new Proxy(new String(pinResult),{get:(_52,nestedProp)=>typeof nestedProp=="symbol"||nestedProp==="toString"?()=>pinResult:`.${prop1} > .${pinOrSubComponentName} > .${nestedProp}`})}})})}});extendCatalogue(components_exports);extendCatalogue({"assembly.drawing.dimension":AssemblyDrawingDimension,"assembly.drawing.page":AssemblyDrawingPage,"assembly.drawing.partview":AssemblyDrawingPartView,"assembly.drawing.titleblock":AssemblyDrawingTitleBlock,"assembly.cable":AssemblyCable,"assembly.device":AssemblyDevice,"assembly.explosion.stage":AssemblyExplosionStage,"assembly.explosion.move":AssemblyExplosionMove,"assembly.motor":AssemblyMotor,"assembly.bolt":AssemblyBolt,"assembly.part":AssemblyPart,"assembly.referencesurface":AssemblyReferenceSurface,"assembly.printedpart":AssemblyPrintedPart,"assembly.screen":AssemblyScreen,"assembly.subassembly":AssemblySubassembly,"assembly.cadassembly":AssemblySubassembly,Bug:Chip,"enclosure.cutoutaperture":EnclosureCutoutAperture,"enclosure.fdm.box":EnclosureFdmBox,Fanout:Breakout,FanoutPoint:BreakoutPoint});function serializeAssemblyExplosion(roots,assembled){let nextStageId=0,records=resolveAssemblyExplosionRecords(roots,assembled,()=>`cad_explosion_stage_${nextStageId++}`),stageOrderById=new Map([...records.stages.values()].map(stage=>[stage.cad_explosion_stage_id,stage.order]));return[...records.stages.values(),...[...records.moves.values()].map(move=>({...move,cad_explosion_move_id:`cad_explosion_move_${stageOrderById.get(move.cad_explosion_stage_id)}_${move.order}`}))]}var React4=__toESM(require_react(),1),ReactJsxRuntime=__toESM(require_jsx_runtime(),1);init_dist2();var fabricatorPresets={jlcpcb_economy_20260912:{minimumViaHoleDiameterWithoutExtraCharge:.3},jlcpcb_standard_20260912:{minimumViaHoleDiameterWithoutExtraCharge:.3}},presetAliases={jlcpcb_economy:"jlcpcb_economy_20260912",jlcpcb_standard:"jlcpcb_standard_20260912"};function resolvePreset(name){let resolved=Object.hasOwn(presetAliases,name)?presetAliases[name]:name;return Object.hasOwn(fabricatorPresets,resolved)?fabricatorPresets[resolved]:void 0}function runDrcChecks({circuitJson,fabricatorPreset,pcbBoardId}){let preset=resolvePreset(fabricatorPreset);if(!preset)return[];let threshold=preset.minimumViaHoleDiameterWithoutExtraCharge,smallVias=circuitJson.filter(element2=>element2.type==="pcb_via").filter(via=>via.hole_diameter<threshold);return smallVias.length===0?[]:[pcb_fabricator_extra_charge_warning.parse({type:"pcb_fabricator_extra_charge_warning",fabricator_preset:fabricatorPreset,pcb_board_id:pcbBoardId,pcb_via_ids:smallVias.map(via=>via.pcb_via_id),message:`${fabricatorPreset}: ${smallVias.length} via(s) have a hole diameter below ${threshold} mm and incur an extra fabrication charge. Use a hole diameter of at least ${threshold} mm to avoid this charge.`})]}var fabricatorEngine2={runDrcChecks};var __create4=Object.create,__defProp8=Object.defineProperty,__getOwnPropDesc4=Object.getOwnPropertyDescriptor,__getOwnPropNames4=Object.getOwnPropertyNames,__getProtoOf4=Object.getPrototypeOf,__hasOwnProp5=Object.prototype.hasOwnProperty,__commonJS4=(cb3,mod)=>function(){return mod||(0,cb3[__getOwnPropNames4(cb3)[0]])((mod={exports:{}}).exports,mod),mod.exports},__export5=(target,all)=>{for(var name in all)__defProp8(target,name,{get:all[name],enumerable:!0})},__copyProps4=(to3,from,except,desc)=>{if(from&&typeof from=="object"||typeof from=="function")for(let key of __getOwnPropNames4(from))!__hasOwnProp5.call(to3,key)&&key!==except&&__defProp8(to3,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc4(from,key))||desc.enumerable});return to3},__toESM4=(mod,isNodeMode,target)=>(target=mod!=null?__create4(__getProtoOf4(mod)):{},__copyProps4(isNodeMode||!mod||!mod.__esModule?__defProp8(target,"default",{value:mod,enumerable:!0}):target,mod)),require_react_production=__commonJS4({"node_modules/react/cjs/react.production.js"(exports){"use strict";var REACT_ELEMENT_TYPE=Symbol.for("react.transitional.element"),REACT_PORTAL_TYPE=Symbol.for("react.portal"),REACT_FRAGMENT_TYPE=Symbol.for("react.fragment"),REACT_STRICT_MODE_TYPE=Symbol.for("react.strict_mode"),REACT_PROFILER_TYPE=Symbol.for("react.profiler"),REACT_CONSUMER_TYPE=Symbol.for("react.consumer"),REACT_CONTEXT_TYPE=Symbol.for("react.context"),REACT_FORWARD_REF_TYPE=Symbol.for("react.forward_ref"),REACT_SUSPENSE_TYPE=Symbol.for("react.suspense"),REACT_MEMO_TYPE=Symbol.for("react.memo"),REACT_LAZY_TYPE=Symbol.for("react.lazy"),MAYBE_ITERATOR_SYMBOL=Symbol.iterator;function getIteratorFn(maybeIterable){return maybeIterable===null||typeof maybeIterable!="object"?null:(maybeIterable=MAYBE_ITERATOR_SYMBOL&&maybeIterable[MAYBE_ITERATOR_SYMBOL]||maybeIterable["@@iterator"],typeof maybeIterable=="function"?maybeIterable:null)}var ReactNoopUpdateQueue={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},assign=Object.assign,emptyObject={};function Component(props,context,updater){this.props=props,this.context=context,this.refs=emptyObject,this.updater=updater||ReactNoopUpdateQueue}Component.prototype.isReactComponent={},Component.prototype.setState=function(partialState,callback){if(typeof partialState!="object"&&typeof partialState!="function"&&partialState!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,partialState,callback,"setState")},Component.prototype.forceUpdate=function(callback){this.updater.enqueueForceUpdate(this,callback,"forceUpdate")};function ComponentDummy(){}ComponentDummy.prototype=Component.prototype;function PureComponent(props,context,updater){this.props=props,this.context=context,this.refs=emptyObject,this.updater=updater||ReactNoopUpdateQueue}var pureComponentPrototype=PureComponent.prototype=new ComponentDummy;pureComponentPrototype.constructor=PureComponent,assign(pureComponentPrototype,Component.prototype),pureComponentPrototype.isPureReactComponent=!0;var isArrayImpl=Array.isArray,ReactSharedInternals={H:null,A:null,T:null,S:null,V:null},hasOwnProperty=Object.prototype.hasOwnProperty;function ReactElement(type,key,self2,source,owner,props){return self2=props.ref,{$$typeof:REACT_ELEMENT_TYPE,type,key,ref:self2!==void 0?self2:null,props}}function cloneAndReplaceKey(oldElement,newKey){return ReactElement(oldElement.type,newKey,void 0,void 0,void 0,oldElement.props)}function isValidElement33(object){return typeof object=="object"&&object!==null&&object.$$typeof===REACT_ELEMENT_TYPE}function escape2(key){var escaperLookup={"=":"=0",":":"=2"};return"$"+key.replace(/[=:]/g,function(match2){return escaperLookup[match2]})}var userProvidedKeyEscapeRegex=/\/+/g;function getElementKey(element2,index2){return typeof element2=="object"&&element2!==null&&element2.key!=null?escape2(""+element2.key):index2.toString(36)}function noop$1(){}function resolveThenable(thenable){switch(thenable.status){case"fulfilled":return thenable.value;case"rejected":throw thenable.reason;default:switch(typeof thenable.status=="string"?thenable.then(noop$1,noop$1):(thenable.status="pending",thenable.then(function(fulfilledValue){thenable.status==="pending"&&(thenable.status="fulfilled",thenable.value=fulfilledValue)},function(error2){thenable.status==="pending"&&(thenable.status="rejected",thenable.reason=error2)})),thenable.status){case"fulfilled":return thenable.value;case"rejected":throw thenable.reason}}throw thenable}function mapIntoArray(children,array2,escapedPrefix,nameSoFar,callback){var type=typeof children;(type==="undefined"||type==="boolean")&&(children=null);var invokeCallback=!1;if(children===null)invokeCallback=!0;else switch(type){case"bigint":case"string":case"number":invokeCallback=!0;break;case"object":switch(children.$$typeof){case REACT_ELEMENT_TYPE:case REACT_PORTAL_TYPE:invokeCallback=!0;break;case REACT_LAZY_TYPE:return invokeCallback=children._init,mapIntoArray(invokeCallback(children._payload),array2,escapedPrefix,nameSoFar,callback)}}if(invokeCallback)return callback=callback(children),invokeCallback=nameSoFar===""?"."+getElementKey(children,0):nameSoFar,isArrayImpl(callback)?(escapedPrefix="",invokeCallback!=null&&(escapedPrefix=invokeCallback.replace(userProvidedKeyEscapeRegex,"$&/")+"/"),mapIntoArray(callback,array2,escapedPrefix,"",function(c11){return c11})):callback!=null&&(isValidElement33(callback)&&(callback=cloneAndReplaceKey(callback,escapedPrefix+(callback.key==null||children&&children.key===callback.key?"":(""+callback.key).replace(userProvidedKeyEscapeRegex,"$&/")+"/")+invokeCallback)),array2.push(callback)),1;invokeCallback=0;var nextNamePrefix=nameSoFar===""?".":nameSoFar+":";if(isArrayImpl(children))for(var i10=0;i10<children.length;i10++)nameSoFar=children[i10],type=nextNamePrefix+getElementKey(nameSoFar,i10),invokeCallback+=mapIntoArray(nameSoFar,array2,escapedPrefix,type,callback);else if(i10=getIteratorFn(children),typeof i10=="function")for(children=i10.call(children),i10=0;!(nameSoFar=children.next()).done;)nameSoFar=nameSoFar.value,type=nextNamePrefix+getElementKey(nameSoFar,i10++),invokeCallback+=mapIntoArray(nameSoFar,array2,escapedPrefix,type,callback);else if(type==="object"){if(typeof children.then=="function")return mapIntoArray(resolveThenable(children),array2,escapedPrefix,nameSoFar,callback);throw array2=String(children),Error("Objects are not valid as a React child (found: "+(array2==="[object Object]"?"object with keys {"+Object.keys(children).join(", ")+"}":array2)+"). If you meant to render a collection of children, use an array instead.")}return invokeCallback}function mapChildren(children,func,context){if(children==null)return children;var result=[],count=0;return mapIntoArray(children,result,"","",function(child){return func.call(context,child,count++)}),result}function lazyInitializer(payload){if(payload._status===-1){var ctor=payload._result;ctor=ctor(),ctor.then(function(moduleObject){(payload._status===0||payload._status===-1)&&(payload._status=1,payload._result=moduleObject)},function(error2){(payload._status===0||payload._status===-1)&&(payload._status=2,payload._result=error2)}),payload._status===-1&&(payload._status=0,payload._result=ctor)}if(payload._status===1)return payload._result.default;throw payload._result}var reportGlobalError=typeof reportError=="function"?reportError:function(error2){if(typeof window=="object"&&typeof window.ErrorEvent=="function"){var event=new window.ErrorEvent("error",{bubbles:!0,cancelable:!0,message:typeof error2=="object"&&error2!==null&&typeof error2.message=="string"?String(error2.message):String(error2),error:error2});if(!window.dispatchEvent(event))return}else if(typeof process=="object"&&typeof process.emit=="function"){process.emit("uncaughtException",error2);return}console.error(error2)};function noop(){}exports.Children={map:mapChildren,forEach:function(children,forEachFunc,forEachContext){mapChildren(children,function(){forEachFunc.apply(this,arguments)},forEachContext)},count:function(children){var n10=0;return mapChildren(children,function(){n10++}),n10},toArray:function(children){return mapChildren(children,function(child){return child})||[]},only:function(children){if(!isValidElement33(children))throw Error("React.Children.only expected to receive a single React element child.");return children}},exports.Component=Component,exports.Fragment=REACT_FRAGMENT_TYPE,exports.Profiler=REACT_PROFILER_TYPE,exports.PureComponent=PureComponent,exports.StrictMode=REACT_STRICT_MODE_TYPE,exports.Suspense=REACT_SUSPENSE_TYPE,exports.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=ReactSharedInternals,exports.__COMPILER_RUNTIME={__proto__:null,c:function(size32){return ReactSharedInternals.H.useMemoCache(size32)}},exports.cache=function(fn3){return function(){return fn3.apply(null,arguments)}},exports.cloneElement=function(element2,config,children){if(element2==null)throw Error("The argument must be a React element, but you passed "+element2+".");var props=assign({},element2.props),key=element2.key,owner=void 0;if(config!=null)for(propName in config.ref!==void 0&&(owner=void 0),config.key!==void 0&&(key=""+config.key),config)!hasOwnProperty.call(config,propName)||propName==="key"||propName==="__self"||propName==="__source"||propName==="ref"&&config.ref===void 0||(props[propName]=config[propName]);var propName=arguments.length-2;if(propName===1)props.children=children;else if(1<propName){for(var childArray=Array(propName),i10=0;i10<propName;i10++)childArray[i10]=arguments[i10+2];props.children=childArray}return ReactElement(element2.type,key,void 0,void 0,owner,props)},exports.createContext=function(defaultValue){return defaultValue={$$typeof:REACT_CONTEXT_TYPE,_currentValue:defaultValue,_currentValue2:defaultValue,_threadCount:0,Provider:null,Consumer:null},defaultValue.Provider=defaultValue,defaultValue.Consumer={$$typeof:REACT_CONSUMER_TYPE,_context:defaultValue},defaultValue},exports.createElement=function(type,config,children){var propName,props={},key=null;if(config!=null)for(propName in config.key!==void 0&&(key=""+config.key),config)hasOwnProperty.call(config,propName)&&propName!=="key"&&propName!=="__self"&&propName!=="__source"&&(props[propName]=config[propName]);var childrenLength=arguments.length-2;if(childrenLength===1)props.children=children;else if(1<childrenLength){for(var childArray=Array(childrenLength),i10=0;i10<childrenLength;i10++)childArray[i10]=arguments[i10+2];props.children=childArray}if(type&&type.defaultProps)for(propName in childrenLength=type.defaultProps,childrenLength)props[propName]===void 0&&(props[propName]=childrenLength[propName]);return ReactElement(type,key,void 0,void 0,null,props)},exports.createRef=function(){return{current:null}},exports.forwardRef=function(render3){return{$$typeof:REACT_FORWARD_REF_TYPE,render:render3}},exports.isValidElement=isValidElement33,exports.lazy=function(ctor){return{$$typeof:REACT_LAZY_TYPE,_payload:{_status:-1,_result:ctor},_init:lazyInitializer}},exports.memo=function(type,compare2){return{$$typeof:REACT_MEMO_TYPE,type,compare:compare2===void 0?null:compare2}},exports.startTransition=function(scope){var prevTransition=ReactSharedInternals.T,currentTransition={};ReactSharedInternals.T=currentTransition;try{var returnValue=scope(),onStartTransitionFinish=ReactSharedInternals.S;onStartTransitionFinish!==null&&onStartTransitionFinish(currentTransition,returnValue),typeof returnValue=="object"&&returnValue!==null&&typeof returnValue.then=="function"&&returnValue.then(noop,reportGlobalError)}catch(error2){reportGlobalError(error2)}finally{ReactSharedInternals.T=prevTransition}},exports.unstable_useCacheRefresh=function(){return ReactSharedInternals.H.useCacheRefresh()},exports.use=function(usable){return ReactSharedInternals.H.use(usable)},exports.useActionState=function(action,initialState,permalink){return ReactSharedInternals.H.useActionState(action,initialState,permalink)},exports.useCallback=function(callback,deps){return ReactSharedInternals.H.useCallback(callback,deps)},exports.useContext=function(Context){return ReactSharedInternals.H.useContext(Context)},exports.useDebugValue=function(){},exports.useDeferredValue=function(value,initialValue){return ReactSharedInternals.H.useDeferredValue(value,initialValue)},exports.useEffect=function(create10,createDeps,update2){var dispatcher=ReactSharedInternals.H;if(typeof update2=="function")throw Error("useEffect CRUD overload is not enabled in this build of React.");return dispatcher.useEffect(create10,createDeps)},exports.useId=function(){return ReactSharedInternals.H.useId()},exports.useImperativeHandle=function(ref,create10,deps){return ReactSharedInternals.H.useImperativeHandle(ref,create10,deps)},exports.useInsertionEffect=function(create10,deps){return ReactSharedInternals.H.useInsertionEffect(create10,deps)},exports.useLayoutEffect=function(create10,deps){return ReactSharedInternals.H.useLayoutEffect(create10,deps)},exports.useMemo=function(create10,deps){return ReactSharedInternals.H.useMemo(create10,deps)},exports.useOptimistic=function(passthrough,reducer){return ReactSharedInternals.H.useOptimistic(passthrough,reducer)},exports.useReducer=function(reducer,initialArg,init){return ReactSharedInternals.H.useReducer(reducer,initialArg,init)},exports.useRef=function(initialValue){return ReactSharedInternals.H.useRef(initialValue)},exports.useState=function(initialState){return ReactSharedInternals.H.useState(initialState)},exports.useSyncExternalStore=function(subscribe,getSnapshot,getServerSnapshot){return ReactSharedInternals.H.useSyncExternalStore(subscribe,getSnapshot,getServerSnapshot)},exports.useTransition=function(){return ReactSharedInternals.H.useTransition()},exports.version="19.1.0"}}),require_react_development2=__commonJS4({"node_modules/react/cjs/react.development.js"(exports,module){"use strict";(function(){function defineDeprecationWarning(methodName,info){Object.defineProperty(Component.prototype,methodName,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",info[0],info[1])}})}function getIteratorFn(maybeIterable){return maybeIterable===null||typeof maybeIterable!="object"?null:(maybeIterable=MAYBE_ITERATOR_SYMBOL&&maybeIterable[MAYBE_ITERATOR_SYMBOL]||maybeIterable["@@iterator"],typeof maybeIterable=="function"?maybeIterable:null)}function warnNoop(publicInstance,callerName){publicInstance=(publicInstance=publicInstance.constructor)&&(publicInstance.displayName||publicInstance.name)||"ReactClass";var warningKey=publicInstance+"."+callerName;didWarnStateUpdateForUnmountedComponent[warningKey]||(console.error("Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.",callerName,publicInstance),didWarnStateUpdateForUnmountedComponent[warningKey]=!0)}function Component(props,context,updater){this.props=props,this.context=context,this.refs=emptyObject,this.updater=updater||ReactNoopUpdateQueue}function ComponentDummy(){}function PureComponent(props,context,updater){this.props=props,this.context=context,this.refs=emptyObject,this.updater=updater||ReactNoopUpdateQueue}function testStringCoercion(value){return""+value}function checkKeyStringCoercion(value){try{testStringCoercion(value);var JSCompiler_inline_result=!1}catch{JSCompiler_inline_result=!0}if(JSCompiler_inline_result){JSCompiler_inline_result=console;var JSCompiler_temp_const=JSCompiler_inline_result.error,JSCompiler_inline_result$jscomp$0=typeof Symbol=="function"&&Symbol.toStringTag&&value[Symbol.toStringTag]||value.constructor.name||"Object";return JSCompiler_temp_const.call(JSCompiler_inline_result,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",JSCompiler_inline_result$jscomp$0),testStringCoercion(value)}}function getComponentNameFromType(type){if(type==null)return null;if(typeof type=="function")return type.$$typeof===REACT_CLIENT_REFERENCE?null:type.displayName||type.name||null;if(typeof type=="string")return type;switch(type){case REACT_FRAGMENT_TYPE:return"Fragment";case REACT_PROFILER_TYPE:return"Profiler";case REACT_STRICT_MODE_TYPE:return"StrictMode";case REACT_SUSPENSE_TYPE:return"Suspense";case REACT_SUSPENSE_LIST_TYPE:return"SuspenseList";case REACT_ACTIVITY_TYPE:return"Activity"}if(typeof type=="object")switch(typeof type.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),type.$$typeof){case REACT_PORTAL_TYPE:return"Portal";case REACT_CONTEXT_TYPE:return(type.displayName||"Context")+".Provider";case REACT_CONSUMER_TYPE:return(type._context.displayName||"Context")+".Consumer";case REACT_FORWARD_REF_TYPE:var innerType=type.render;return type=type.displayName,type||(type=innerType.displayName||innerType.name||"",type=type!==""?"ForwardRef("+type+")":"ForwardRef"),type;case REACT_MEMO_TYPE:return innerType=type.displayName||null,innerType!==null?innerType:getComponentNameFromType(type.type)||"Memo";case REACT_LAZY_TYPE:innerType=type._payload,type=type._init;try{return getComponentNameFromType(type(innerType))}catch{}}return null}function getTaskName(type){if(type===REACT_FRAGMENT_TYPE)return"<>";if(typeof type=="object"&&type!==null&&type.$$typeof===REACT_LAZY_TYPE)return"<...>";try{var name=getComponentNameFromType(type);return name?"<"+name+">":"<...>"}catch{return"<...>"}}function getOwner(){var dispatcher=ReactSharedInternals.A;return dispatcher===null?null:dispatcher.getOwner()}function UnknownOwner(){return Error("react-stack-top-frame")}function hasValidKey(config){if(hasOwnProperty.call(config,"key")){var getter=Object.getOwnPropertyDescriptor(config,"key").get;if(getter&&getter.isReactWarning)return!1}return config.key!==void 0}function defineKeyPropWarningGetter(props,displayName){function warnAboutAccessingKey(){specialPropKeyWarningShown||(specialPropKeyWarningShown=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",displayName))}warnAboutAccessingKey.isReactWarning=!0,Object.defineProperty(props,"key",{get:warnAboutAccessingKey,configurable:!0})}function elementRefGetterWithDeprecationWarning(){var componentName=getComponentNameFromType(this.type);return didWarnAboutElementRef[componentName]||(didWarnAboutElementRef[componentName]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),componentName=this.props.ref,componentName!==void 0?componentName:null}function ReactElement(type,key,self2,source,owner,props,debugStack,debugTask){return self2=props.ref,type={$$typeof:REACT_ELEMENT_TYPE,type,key,props,_owner:owner},(self2!==void 0?self2:null)!==null?Object.defineProperty(type,"ref",{enumerable:!1,get:elementRefGetterWithDeprecationWarning}):Object.defineProperty(type,"ref",{enumerable:!1,value:null}),type._store={},Object.defineProperty(type._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(type,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(type,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:debugStack}),Object.defineProperty(type,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:debugTask}),Object.freeze&&(Object.freeze(type.props),Object.freeze(type)),type}function cloneAndReplaceKey(oldElement,newKey){return newKey=ReactElement(oldElement.type,newKey,void 0,void 0,oldElement._owner,oldElement.props,oldElement._debugStack,oldElement._debugTask),oldElement._store&&(newKey._store.validated=oldElement._store.validated),newKey}function isValidElement33(object){return typeof object=="object"&&object!==null&&object.$$typeof===REACT_ELEMENT_TYPE}function escape2(key){var escaperLookup={"=":"=0",":":"=2"};return"$"+key.replace(/[=:]/g,function(match2){return escaperLookup[match2]})}function getElementKey(element2,index2){return typeof element2=="object"&&element2!==null&&element2.key!=null?(checkKeyStringCoercion(element2.key),escape2(""+element2.key)):index2.toString(36)}function noop$1(){}function resolveThenable(thenable){switch(thenable.status){case"fulfilled":return thenable.value;case"rejected":throw thenable.reason;default:switch(typeof thenable.status=="string"?thenable.then(noop$1,noop$1):(thenable.status="pending",thenable.then(function(fulfilledValue){thenable.status==="pending"&&(thenable.status="fulfilled",thenable.value=fulfilledValue)},function(error2){thenable.status==="pending"&&(thenable.status="rejected",thenable.reason=error2)})),thenable.status){case"fulfilled":return thenable.value;case"rejected":throw thenable.reason}}throw thenable}function mapIntoArray(children,array2,escapedPrefix,nameSoFar,callback){var type=typeof children;(type==="undefined"||type==="boolean")&&(children=null);var invokeCallback=!1;if(children===null)invokeCallback=!0;else switch(type){case"bigint":case"string":case"number":invokeCallback=!0;break;case"object":switch(children.$$typeof){case REACT_ELEMENT_TYPE:case REACT_PORTAL_TYPE:invokeCallback=!0;break;case REACT_LAZY_TYPE:return invokeCallback=children._init,mapIntoArray(invokeCallback(children._payload),array2,escapedPrefix,nameSoFar,callback)}}if(invokeCallback){invokeCallback=children,callback=callback(invokeCallback);var childKey=nameSoFar===""?"."+getElementKey(invokeCallback,0):nameSoFar;return isArrayImpl(callback)?(escapedPrefix="",childKey!=null&&(escapedPrefix=childKey.replace(userProvidedKeyEscapeRegex,"$&/")+"/"),mapIntoArray(callback,array2,escapedPrefix,"",function(c11){return c11})):callback!=null&&(isValidElement33(callback)&&(callback.key!=null&&(invokeCallback&&invokeCallback.key===callback.key||checkKeyStringCoercion(callback.key)),escapedPrefix=cloneAndReplaceKey(callback,escapedPrefix+(callback.key==null||invokeCallback&&invokeCallback.key===callback.key?"":(""+callback.key).replace(userProvidedKeyEscapeRegex,"$&/")+"/")+childKey),nameSoFar!==""&&invokeCallback!=null&&isValidElement33(invokeCallback)&&invokeCallback.key==null&&invokeCallback._store&&!invokeCallback._store.validated&&(escapedPrefix._store.validated=2),callback=escapedPrefix),array2.push(callback)),1}if(invokeCallback=0,childKey=nameSoFar===""?".":nameSoFar+":",isArrayImpl(children))for(var i10=0;i10<children.length;i10++)nameSoFar=children[i10],type=childKey+getElementKey(nameSoFar,i10),invokeCallback+=mapIntoArray(nameSoFar,array2,escapedPrefix,type,callback);else if(i10=getIteratorFn(children),typeof i10=="function")for(i10===children.entries&&(didWarnAboutMaps||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),didWarnAboutMaps=!0),children=i10.call(children),i10=0;!(nameSoFar=children.next()).done;)nameSoFar=nameSoFar.value,type=childKey+getElementKey(nameSoFar,i10++),invokeCallback+=mapIntoArray(nameSoFar,array2,escapedPrefix,type,callback);else if(type==="object"){if(typeof children.then=="function")return mapIntoArray(resolveThenable(children),array2,escapedPrefix,nameSoFar,callback);throw array2=String(children),Error("Objects are not valid as a React child (found: "+(array2==="[object Object]"?"object with keys {"+Object.keys(children).join(", ")+"}":array2)+"). If you meant to render a collection of children, use an array instead.")}return invokeCallback}function mapChildren(children,func,context){if(children==null)return children;var result=[],count=0;return mapIntoArray(children,result,"","",function(child){return func.call(context,child,count++)}),result}function lazyInitializer(payload){if(payload._status===-1){var ctor=payload._result;ctor=ctor(),ctor.then(function(moduleObject){(payload._status===0||payload._status===-1)&&(payload._status=1,payload._result=moduleObject)},function(error2){(payload._status===0||payload._status===-1)&&(payload._status=2,payload._result=error2)}),payload._status===-1&&(payload._status=0,payload._result=ctor)}if(payload._status===1)return ctor=payload._result,ctor===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
1052
1052
 
1053
1053
  Your code should look like:
1054
1054
  const MyComponent = lazy(() => import('./MyComponent'))